package uk.ac.ic.wlgitbridge.snapshot.base; import com.google.api.client.http.*; import com.google.gson.JsonElement; import com.ning.http.client.AsyncHttpClient; import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException; import uk.ac.ic.wlgitbridge.util.Instance; import uk.ac.ic.wlgitbridge.util.Log; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; /** * Created by Winston on 06/11/14. */ public abstract class Request<T extends Result> { public static final AsyncHttpClient httpClient = new AsyncHttpClient(); private final String url; private Future<HttpResponse> future; public Request(String url) { this.url = url; } public void request() { switch (httpMethod()) { case GET: performGetRequest(); break; case POST: performPostRequest(); break; default: break; } } public T getResult() throws FailedConnectionException, ForbiddenException { try { HttpResponse response = future.get(); Log.info( "{} {} ({}B) -> " + url, response.getStatusCode(), response.getStatusMessage(), response.getHeaders().getContentLength() ); JsonElement json = Instance.gson.fromJson( response.parseAsString(), JsonElement.class ); return parseResponse(json); } catch (InterruptedException e) { throw new FailedConnectionException(); } catch (ExecutionException e) { Throwable cause = e.getCause(); if (cause instanceof HttpResponseException && (((HttpResponseException) cause).getStatusCode() == HttpServletResponse.SC_UNAUTHORIZED || ((HttpResponseException) cause).getStatusCode() == HttpServletResponse.SC_FORBIDDEN)) { throw new ForbiddenException(); } else { throw new FailedConnectionException(cause); } } catch (IOException e) { Log.error("Failed to parse JSON.", e); throw new FailedConnectionException(); } } protected abstract HTTPMethod httpMethod(); protected void onBeforeRequest(HttpRequest request) throws IOException { } protected abstract T parseResponse(JsonElement json) throws FailedConnectionException; protected String getPostBody() { return null; } private void performGetRequest() { Log.info("GET -> " + url); try { HttpRequest request = Instance.httpRequestFactory.buildGetRequest( new GenericUrl(url) ); request(request); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } } private void performPostRequest() { Log.info("POST -> " + url); try { HttpRequest request = Instance.httpRequestFactory.buildPostRequest( new GenericUrl(url), new ByteArrayContent( "application/json", getPostBody().getBytes() ) ); request(request); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } } private void request(HttpRequest request) throws IOException { onBeforeRequest(request); future = request.executeAsync(); } }