Skip to content

Instantly share code, notes, and snippets.

@He-Pin
Created November 26, 2013 09:17
Show Gist options
  • Save He-Pin/7655526 to your computer and use it in GitHub Desktop.
Save He-Pin/7655526 to your computer and use it in GitHub Desktop.
builder
package com.pekall.cd.mdm.web.adminweb.rpc.builder;
import com.fasterxml.jackson.databind.JsonNode;
import com.ning.http.client.*;
import com.ning.http.multipart.FilePart;
import com.pekall.cd.mdm.web.adminweb.rpc.PageSplit;
import com.pekall.cd.mdm.web.adminweb.rpc.http.constant.MDMWebConstants;
import com.pekall.cd.mdm.web.adminweb.rpc.http.constant.MDMWebQueryKey;
import play.Logger;
import play.libs.F;
import play.libs.F.Function;
import play.libs.F.Promise;
import play.libs.WS;
import play.libs.WS.Response;
import play.libs.WS.WSRequest;
import play.mvc.Result;
import play.mvc.Results;
import play.mvc.Results.AsyncResult;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Author: kerr
* Mail: pin.he@pekall.com
*/
/**
* Custom request need extents this class to implement the request
* add call the execute to get the async response from the MDM-server
*/
public abstract class AbstractBuilder implements Builder {
protected static final int INVALIDATE_VALUE = -1;
private static final PerRequestConfig config;
static {
config = new PerRequestConfig();
config.setRequestTimeoutInMs(MDMWebConstants.WS_TIMEOUT);
}
private final WSRequest builder;
protected String token;
private AtomicBoolean validate = new AtomicBoolean(false);
public AbstractBuilder setToken(String token) {
this.token = token;
return this;
}
protected AbstractBuilder(final String method) {
this.builder = new WSRequest(method);
}
public AbstractBuilder setURl(final String url) {
builder.setUrl(url);
return this;
}
public AbstractBuilder setHeader(final String key, final String value) {
if (value == null){
return this;
}
builder.setHeader(key, value);
return this;
}
public AbstractBuilder addHeader(final String key, final String value) {
if (value == null){
return this;
}
builder.addHeader(key, value);
return this;
}
public AbstractBuilder addParameter(final String key, final String value) {
if (value == null){
return this;
}
builder.addParameter(key, value);
return this;
}
public AbstractBuilder addQueryParameter(final String key, final String value) {
if (value == null){
return this;
}
builder.addQueryParameter(key, value);
return this;
}
public AbstractBuilder setBody(final String body) {
builder.setBody(body);
return this;
}
public AbstractBuilder setBody(final byte[] data){
builder.setBody(data);
return this;
}
public AbstractBuilder setBody(final File file){
builder.setBody(file);
return this;
}
public AbstractBuilder setBody(final BodyGenerator bodyGenerator){
builder.setBody(bodyGenerator);
return this;
}
public AbstractBuilder addBody(final String filename,final File file){
final Part bodyPart;
try {
bodyPart = new FilePart(filename,file);
builder.addBodyPart(bodyPart);
return this;
} catch (FileNotFoundException e) {
e.printStackTrace();
return this;
}
}
public AbstractBuilder authorization(final String token) {
builder.addHeader("Authorization", token);
return this;
}
public void setPageSplit(final PageSplit pageSplit){
if (pageSplit == null){
return;
}
if (pageSplit.startIndexValid()){
this.addQueryParameter(MDMWebQueryKey.START_INDEX,String.valueOf(pageSplit.getStartIndex()));
}
if (pageSplit.countValid()){
this.addQueryParameter(MDMWebQueryKey.COUNT,String.valueOf(pageSplit.getCount()));
}
}
@Override
public Builder build() {
Logger.info("\n"+
"+----------------------------------------------------------------------------------------------+\n"+
" Request Builder Data \n"+
"\n"+
"Authorization: " +token + "\n" +
this+"\n"+
"+----------------------------------------------------------------------------------------------+\n");
if (!validated()) {
throw new IllegalStateException("is not validated,need more stable state");
}
preBuild();
updateValidateAtomically(true);
return this;
}
abstract protected void preBuild();
protected boolean validated() {
return false;
}
private boolean updateValidateAtomically(boolean newValue) {
for (; ; ) {
boolean current = validate.get();
if (validate.compareAndSet(current, newValue))
return current;
}
}
private static final F.Callback<Response> loggerCallback = new F.Callback<Response>() {
@Override
public void invoke(Response response) throws Throwable {
Logger.info("\n"+
"+----------------------------------------------------------------------------------------------+\n"+
" MDM Server Response \n"+
"\n"+
response.getBody()+"\n"+
"+----------------------------------------------------------------------------------------------+\n");
}
};
@Override
public Promise<Response> execute() {
if (!validate.get()) {
throw new IllegalStateException("must call build first");
}
builder.setPerRequestConfig(config);
builder.setFollowRedirects(true);
// here we need recover the result to an response,but for now,
// I can't find an better way to make a response
Promise<Response> result = builder.execute();
Request request = builder.build();
Logger.info("\n" +
"+----------------------------------------------------------------------------------------------+\n" +
" Call MDM Server \n" +
"\n" +
"Method :"+ request.getMethod() + "\n" +
"URL :"+request.getUrl() + "\n" +
"Header :\n" + request.getHeaders() + "\n" +
"Params :\n" + request.getParams() + "\n" +
"+----------------------------------------------------------------------------------------------+\n");
result.onRedeem(loggerCallback);
return result;
}
private static AsyncHttpClient client() {
return play.api.libs.ws.WS.client();
}
public Promise<Response> execute(final ProgressHandler handler) {
final scala.concurrent.Promise<Response> scalaPromise = scala.concurrent.Promise$.MODULE$.<Response>apply();
try {
client().executeRequest(builder.build(), new AsyncCompletionHandler<com.ning.http.client.Response>() {
@Override
public com.ning.http.client.Response onCompleted(com.ning.http.client.Response response) {
final com.ning.http.client.Response ahcResponse = response;
scalaPromise.success(new Response(ahcResponse));
if (handler != null){
handler.onCompleted();
}
return response;
}
@Override
public void onThrowable(Throwable t) {
scalaPromise.failure(t);
}
@Override
public STATE onHeaderWriteCompleted() {
if (handler != null){
handler.onHeaderWriteCompleted();
}
return super.onHeaderWriteCompleted();
}
@Override
public STATE onContentWriteCompleted() {
if (handler != null){
handler.onContentWriteCompleted();
}
return super.onContentWriteCompleted();
}
@Override
public STATE onContentWriteProgress(long amount, long current, long total) {
if (handler != null){
handler.onContentWriteProgress(amount,current,total);
}
return super.onContentWriteProgress(amount, current, total);
}
});
} catch (IOException exception) {
scalaPromise.failure(exception);
}
return new Promise<Response>(scalaPromise.future());
}
public static interface ProgressHandler{
void onHeaderWriteCompleted();
void onContentWriteCompleted();
void onContentWriteProgress(long amount, long current, long total);
void onCompleted();
}
@Override
public WS.Response executeAndGet() {
return execute().get();
}
@Override
public String executeAndGetBodyAsString() {
Logger.info("\n"+
"+-----------------------------------------------------------------------------------------------+\n"+
" Call MDM Server \n"+
"\n"+
builder.getMethod()+"\n" + builder.getUrl() + "\n"+
"+-----------------------------------------------------------------------------------------------+\n");
final String responseBody = executeAndGet().getBody();
return responseBody;
}
@Override
public JsonNode executeAndGetBodyAsJsonNode() {
return executeAndGet().asJson();
}
@Override
public AsyncResult executeAndAsyncHandle(final Function<Response, Result> function) {
return Results.async(execute().map(function));
}
// private static Response buildErrorResponse(final Object bean){
// com.ning.http.client.Response ahcResponse = null;
// com.ning.http.client.Response.ResponseBuilder responseBuilder
// = new com.ning.http.client.Response.ResponseBuilder();
// com.ning.http.client.HttpResponseStatus status;
// com.ning.http.client.HttpResponseHeaders headers;
// responseBuilder.accumulate(null);
// final Response response = new Response(ahcResponse);
// return null;
// }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment