Java tutorial
/* * Copyright (C) 2012 tamtam180 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package at.orz.arangodb.http; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpPatch; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.orz.arangodb.ArangoConfigure; import at.orz.arangodb.ArangoException; import at.orz.arangodb.http.HttpRequestEntity.RequestType; import at.orz.arangodb.util.IOUtils; /** * @author tamtam180 - kirscheless at gmail.com * */ public class HttpManager { private static final ContentType APPLICATION_JSON_UTF8 = ContentType.create("application/json", "utf-8"); private Logger logger = LoggerFactory.getLogger(HttpManager.class); private PoolingClientConnectionManager cm; private DefaultHttpClient client; private ArangoConfigure configure; // private int defaultMaxPerRoute = 20; // private int maxTotal = 20; // private String proxyHost; // private int proxyPort; // /** connection-timeout */ // private int conTimeout = -1; // /** socket-read-timeout */ // private int soTimeout = -1; // /** retry count */ // private int retryCount = 3; // // /** Basic auth user */ // private String user; // /** Basic auth password */ // private String password; // private Credentials credentials; public HttpManager(ArangoConfigure configure) { this.configure = configure; } // public HttpManager setDefaultMaxPerRoute(int max) { // defaultMaxPerRoute = max; // return this; // } // public HttpManager setMaxTotal(int max) { // maxTotal = max; // return this; // } // // public HttpManager setProxyHost(String host) { // this.proxyHost = host; // return this; // } // public HttpManager setProxyPort(int port) { // this.proxyPort = port; // return this; // } // // public HttpManager setConTimeout(int timeoutMs) { // this.conTimeout = timeoutMs; // return this; // } // public HttpManager setSoTimeout(int timeoutMs) { // this.soTimeout = timeoutMs; // return this; // } // public HttpManager setRetryCount(int retryCount) { // this.retryCount = retryCount; // return this; // } // // public HttpManager setUser(String user) { // this.user = user; // return this; // } // public HttpManager setPassword(String password) { // this.password = password; // return this; // } public void init() { // ConnectionManager cm = new PoolingClientConnectionManager(); cm.setDefaultMaxPerRoute(configure.getMaxPerConnection()); cm.setMaxTotal(configure.getMaxTotalConnection()); // Params HttpParams params = new BasicHttpParams(); if (configure.getConnectionTimeout() >= 0) { HttpConnectionParams.setConnectionTimeout(params, configure.getConnectionTimeout()); } if (configure.getTimeout() >= 0) { HttpConnectionParams.setSoTimeout(params, configure.getTimeout()); } // Client client = new DefaultHttpClient(cm, params); // TODO KeepAlive Strategy // Proxy if (configure.getProxyHost() != null && configure.getProxyPort() != 0) { HttpHost proxy = new HttpHost(configure.getProxyHost(), configure.getProxyPort(), "http"); client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); } // Basic Auth //if (configure.getUser() != null && configure.getPassword() != null) { //AuthScope scope = AuthScope.ANY; // TODO //this.credentials = new UsernamePasswordCredentials(configure.getUser(), configure.getPassword()); //client.getCredentialsProvider().setCredentials(scope, credentials); //} // Retry Handler client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(configure.getRetryCount(), false)); } public void destroy() { if (cm != null) { cm.shutdown(); } configure = null; } public HttpResponseEntity doGet(String url) throws ArangoException { return doGet(url, null); } public HttpResponseEntity doGet(String url, Map<String, Object> params) throws ArangoException { return doHeadGetDelete(RequestType.GET, url, null, params); } public HttpResponseEntity doGet(String url, Map<String, Object> headers, Map<String, Object> params) throws ArangoException { return doHeadGetDelete(RequestType.GET, url, headers, params); } public HttpResponseEntity doGet(String url, Map<String, Object> headers, Map<String, Object> params, String username, String password) throws ArangoException { return doHeadGetDelete(RequestType.GET, url, headers, params, username, password); } public HttpResponseEntity doHead(String url, Map<String, Object> params) throws ArangoException { return doHeadGetDelete(RequestType.HEAD, url, null, params); } public HttpResponseEntity doDelete(String url, Map<String, Object> params) throws ArangoException { return doHeadGetDelete(RequestType.DELETE, url, null, params); } public HttpResponseEntity doDelete(String url, Map<String, Object> headers, Map<String, Object> params) throws ArangoException { return doHeadGetDelete(RequestType.DELETE, url, headers, params); } public HttpResponseEntity doHeadGetDelete(RequestType type, String url, Map<String, Object> headers, Map<String, Object> params) throws ArangoException { return doHeadGetDelete(type, url, headers, params, null, null); } public HttpResponseEntity doHeadGetDelete(RequestType type, String url, Map<String, Object> headers, Map<String, Object> params, String username, String password) throws ArangoException { HttpRequestEntity requestEntity = new HttpRequestEntity(); requestEntity.type = type; requestEntity.url = url; requestEntity.headers = headers; requestEntity.parameters = params; requestEntity.username = username; requestEntity.password = password; return execute(requestEntity); } public HttpResponseEntity doPost(String url, Map<String, Object> headers, Map<String, Object> params, String bodyText) throws ArangoException { return doPostPutPatch(RequestType.POST, url, headers, params, bodyText, null); } public HttpResponseEntity doPost(String url, Map<String, Object> params, String bodyText) throws ArangoException { return doPostPutPatch(RequestType.POST, url, null, params, bodyText, null); } public HttpResponseEntity doPost(String url, Map<String, Object> params, HttpEntity entity) throws ArangoException { return doPostPutPatch(RequestType.POST, url, null, params, null, entity); } public HttpResponseEntity doPut(String url, Map<String, Object> headers, Map<String, Object> params, String bodyText) throws ArangoException { return doPostPutPatch(RequestType.PUT, url, headers, params, bodyText, null); } public HttpResponseEntity doPut(String url, Map<String, Object> params, String bodyText) throws ArangoException { return doPostPutPatch(RequestType.PUT, url, null, params, bodyText, null); } public HttpResponseEntity doPatch(String url, Map<String, Object> headers, Map<String, Object> params, String bodyText) throws ArangoException { return doPostPutPatch(RequestType.PATCH, url, headers, params, bodyText, null); } public HttpResponseEntity doPatch(String url, Map<String, Object> params, String bodyText) throws ArangoException { return doPostPutPatch(RequestType.PATCH, url, null, params, bodyText, null); } private HttpResponseEntity doPostPutPatch(RequestType type, String url, Map<String, Object> headers, Map<String, Object> params, String bodyText, HttpEntity entity) throws ArangoException { HttpRequestEntity requestEntity = new HttpRequestEntity(); requestEntity.type = type; requestEntity.url = url; requestEntity.headers = headers; requestEntity.parameters = params; requestEntity.bodyText = bodyText; requestEntity.entity = entity; return execute(requestEntity); } /** * * @param requestEntity * @return * @throws ArangoException */ public HttpResponseEntity execute(HttpRequestEntity requestEntity) throws ArangoException { String url = buildUrl(requestEntity); if (logger.isDebugEnabled()) { if (requestEntity.type == RequestType.POST || requestEntity.type == RequestType.PUT || requestEntity.type == RequestType.PATCH) { logger.debug("[REQ]http-{}: url={}, headers={}, body={}", new Object[] { requestEntity.type, url, requestEntity.headers, requestEntity.bodyText }); } else { logger.debug("[REQ]http-{}: url={}, headers={}", new Object[] { requestEntity.type, url, requestEntity.headers }); } } HttpRequestBase request = null; switch (requestEntity.type) { case GET: request = new HttpGet(url); break; case POST: HttpPost post = new HttpPost(url); configureBodyParams(requestEntity, post); request = post; break; case PUT: HttpPut put = new HttpPut(url); configureBodyParams(requestEntity, put); request = put; break; case PATCH: HttpPatch patch = new HttpPatch(url); configureBodyParams(requestEntity, patch); request = patch; break; case HEAD: request = new HttpHead(url); break; case DELETE: request = new HttpDelete(url); break; } // common-header String userAgent = "Mozilla/5.0 (compatible; ArangoDB-JavaDriver/1.0; +http://mt.orz.at/)"; // TODO: request.setHeader("User-Agent", userAgent); //request.setHeader("Content-Type", "binary/octet-stream"); // optinal-headers if (requestEntity.headers != null) { for (Entry<String, Object> keyValue : requestEntity.headers.entrySet()) { request.setHeader(keyValue.getKey(), keyValue.getValue().toString()); } } // Basic Auth Credentials credentials = null; if (requestEntity.username != null && requestEntity.password != null) { credentials = new UsernamePasswordCredentials(requestEntity.username, requestEntity.password); } else if (configure.getUser() != null && configure.getPassword() != null) { credentials = new UsernamePasswordCredentials(configure.getUser(), configure.getPassword()); } if (credentials != null) { request.addHeader(BasicScheme.authenticate(credentials, "US-ASCII", false)); } // CURL/httpie Logger if (configure.isEnableCURLLogger()) { CURLLogger.log(url, requestEntity, userAgent, credentials); } HttpResponse response = null; try { response = client.execute(request); if (response == null) { return null; } HttpResponseEntity responseEntity = new HttpResponseEntity(); // http status StatusLine status = response.getStatusLine(); responseEntity.statusCode = status.getStatusCode(); responseEntity.statusPhrase = status.getReasonPhrase(); logger.debug("[RES]http-{}: statusCode={}", requestEntity.type, responseEntity.statusCode); // ?? //// TODO etag??? Header etagHeader = response.getLastHeader("etag"); if (etagHeader != null) { responseEntity.etag = Long.parseLong(etagHeader.getValue().replace("\"", "")); } // Map??? responseEntity.headers = new TreeMap<String, String>(); for (Header header : response.getAllHeaders()) { responseEntity.headers.put(header.getName(), header.getValue()); } // ??? HttpEntity entity = response.getEntity(); if (entity != null) { Header contentType = entity.getContentType(); if (contentType != null) { responseEntity.contentType = contentType.getValue(); if (responseEntity.isDumpResponse()) { responseEntity.stream = entity.getContent(); logger.debug("[RES]http-{}: stream, {}", requestEntity.type, contentType.getValue()); } } // Close stream in this method. if (responseEntity.stream == null) { responseEntity.text = IOUtils.toString(entity.getContent()); logger.debug("[RES]http-{}: text={}", requestEntity.type, responseEntity.text); } } return responseEntity; } catch (ClientProtocolException e) { throw new ArangoException(e); } catch (IOException e) { throw new ArangoException(e); } } private static String buildUrl(HttpRequestEntity requestEntity) { if (requestEntity.parameters != null && !requestEntity.parameters.isEmpty()) { String paramString = URLEncodedUtils.format(toList(requestEntity.parameters), "utf-8"); if (requestEntity.url.contains("?")) { return requestEntity.url + "&" + paramString; } else { return requestEntity.url + "?" + paramString; } } return requestEntity.url; } private static List<NameValuePair> toList(Map<String, Object> parameters) { ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>(parameters.size()); for (Entry<String, Object> param : parameters.entrySet()) { if (param.getValue() != null) { paramList.add(new BasicNameValuePair(param.getKey(), param.getValue().toString())); } } return paramList; } private static void configureBodyParams(HttpRequestEntity requestEntity, HttpEntityEnclosingRequestBase request) { if (requestEntity.entity != null) { request.setEntity(requestEntity.entity); } else if (requestEntity.bodyText != null) { request.setEntity(new StringEntity(requestEntity.bodyText, APPLICATION_JSON_UTF8)); } } public static boolean is400Error(ArangoException e) { return e.getCode() == HttpStatus.SC_BAD_REQUEST; } public static boolean is404Error(ArangoException e) { return e.getCode() == HttpStatus.SC_NOT_FOUND; } public static boolean is412Error(ArangoException e) { return e.getCode() == HttpStatus.SC_PRECONDITION_FAILED; } public static boolean is200(HttpResponseEntity res) { return res.getStatusCode() == HttpStatus.SC_OK; } public static boolean is400Error(HttpResponseEntity res) { return res.getStatusCode() == HttpStatus.SC_BAD_REQUEST; } public static boolean is404Error(HttpResponseEntity res) { return res.getStatusCode() == HttpStatus.SC_NOT_FOUND; } public static boolean is412Error(HttpResponseEntity res) { return res.getStatusCode() == HttpStatus.SC_PRECONDITION_FAILED; } }