This is an automated email from the git hooks/post-receive script. New commit to branch feature/7463 in repository observe. See http://git.codelutin.com/observe.git commit ae4d46b7247434c8131586153e27e334191ff3ee Author: Tony CHEMIT <chemit@codelutin.com> Date: Sun Sep 6 11:07:42 2015 +0200 Revue du client reste --- ...bserveDataSourceConfigurationRestConstants.java | 6 + .../ObserveDataSourceConnectionAdapter.java | 24 + .../services/ObserveServiceFactoryRest.java | 209 +++++--- .../ird/observe/services/http/ObserveRequest.java | 77 +++ .../services/http/ObserveRequestBuilder.java | 134 ++++++ .../services/http/ObserveRequestMethod.java | 13 + .../ird/observe/services/http/ObserveResponse.java | 140 ++++++ .../services/http/ObserveResponseBuilder.java | 396 +++++++++++++++ .../ird/observe/services/http/RequestBuilder.java | 531 --------------------- .../ird/observe/services/http/RequestResult.java | 86 ---- .../fr/ird/observe/services/TestClassResource.java | 15 + .../service/DataSourceServiceRestTest.java | 18 +- .../service/seine/TripSeineServiceTest.java | 4 +- 13 files changed, 971 insertions(+), 682 deletions(-) diff --git a/observe-services-configuration-rest/src/main/java/fr/ird/observe/services/configuration/ObserveDataSourceConfigurationRestConstants.java b/observe-services-configuration-rest/src/main/java/fr/ird/observe/services/configuration/ObserveDataSourceConfigurationRestConstants.java index 4df18a0..8bb72a4 100644 --- a/observe-services-configuration-rest/src/main/java/fr/ird/observe/services/configuration/ObserveDataSourceConfigurationRestConstants.java +++ b/observe-services-configuration-rest/src/main/java/fr/ird/observe/services/configuration/ObserveDataSourceConfigurationRestConstants.java @@ -1,5 +1,7 @@ package fr.ird.observe.services.configuration; +import fr.ird.observe.services.service.DataSourceService; + /** * Created on 04/09/15. * @@ -7,6 +9,10 @@ package fr.ird.observe.services.configuration; */ public interface ObserveDataSourceConfigurationRestConstants { + Package ROOT_SERVICES_PACKAGE = DataSourceService.class.getPackage(); + + String PARAMETER_DATA_SOURCE_CONFIGURATION = "dataSourceConfiguration"; + String REQUEST_APPLICATION_LOCALE = "applicationLocale"; String REQUEST_REFERENTIAL_LOCALE = "referentialLocale"; diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/ObserveDataSourceConnectionAdapter.java b/observe-services-rest/src/main/java/fr/ird/observe/services/ObserveDataSourceConnectionAdapter.java new file mode 100644 index 0000000..dfb45b2 --- /dev/null +++ b/observe-services-rest/src/main/java/fr/ird/observe/services/ObserveDataSourceConnectionAdapter.java @@ -0,0 +1,24 @@ +package fr.ird.observe.services; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import fr.ird.observe.services.configuration.ObserveDataSourceConnection; +import fr.ird.observe.services.configuration.ObserveDataSourceConnectionRest; + +import java.lang.reflect.Type; + +/** + * Created on 05/09/15. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ObserveDataSourceConnectionAdapter implements JsonDeserializer<ObserveDataSourceConnection> { + + @Override + public ObserveDataSourceConnection deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return context.deserialize(json, ObserveDataSourceConnectionRest.class); + } + +} diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/ObserveServiceFactoryRest.java b/observe-services-rest/src/main/java/fr/ird/observe/services/ObserveServiceFactoryRest.java index d0f262c..966f40d 100644 --- a/observe-services-rest/src/main/java/fr/ird/observe/services/ObserveServiceFactoryRest.java +++ b/observe-services-rest/src/main/java/fr/ird/observe/services/ObserveServiceFactoryRest.java @@ -3,8 +3,10 @@ package fr.ird.observe.services; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableSet; import com.google.common.reflect.Reflection; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.thoughtworks.paranamer.CachingParanamer; import com.thoughtworks.paranamer.Paranamer; import fr.ird.observe.services.configuration.ObserveDataSourceConfiguration; @@ -13,7 +15,11 @@ import fr.ird.observe.services.configuration.ObserveDataSourceConfigurationRestC import fr.ird.observe.services.configuration.ObserveDataSourceConnection; import fr.ird.observe.services.configuration.ObserveDataSourceConnectionRest; import fr.ird.observe.services.dto.gson.ObserveDtoGsonSupplier; -import fr.ird.observe.services.http.RequestBuilder; +import fr.ird.observe.services.http.ObserveRequest; +import fr.ird.observe.services.http.ObserveRequestBuilder; +import fr.ird.observe.services.http.ObserveRequestMethod; +import fr.ird.observe.services.http.ObserveResponse; +import fr.ird.observe.services.http.ObserveResponseBuilder; import fr.ird.observe.services.service.DataSourceService; import fr.ird.observe.services.spi.Write; import org.apache.commons.logging.Log; @@ -22,7 +28,6 @@ import org.apache.commons.logging.LogFactory; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import java.lang.reflect.Type; import java.util.Collection; /** @@ -35,11 +40,23 @@ public class ObserveServiceFactoryRest extends ObserveServiceFactorySupport impl /** Logger. */ private static final Log log = LogFactory.getLog(ObserveServiceFactoryRest.class); - protected static final Package ROOT_SERVICES_PACKAGE = DataSourceService.class.getPackage(); - protected final CachingParanamer paranamer = new CachingParanamer(); - protected final Supplier<Gson> gsonSupplier = new ObserveDtoGsonSupplier(); + protected final Supplier<Gson> gsonSupplier = new ObserveDtoGsonSupplier() { + + @Override + protected GsonBuilder getGsonBuilder(boolean prettyPrint) { + + GsonBuilder builder = super.getGsonBuilder(prettyPrint); + + // Les ObserveDataSourceConnection sont obligatoirement de type ObserveDataSourceConnectionRest + builder.registerTypeAdapter(ObserveDataSourceConnection.class, new ObserveDataSourceConnectionAdapter()); + return builder; + + } + }; + + protected final ObserveResponseBuilder responseBuilder = ObserveResponseBuilder.create(gsonSupplier); @Override public <S extends ObserveService> boolean accept(ObserveDataSourceConfiguration dataSourceConfiguration, Class<S> serviceType) { @@ -70,12 +87,13 @@ public class ObserveServiceFactoryRest extends ObserveServiceFactorySupport impl if (observeServiceInitializer.withDataSourceConnection()) { + // Connecté ObserveDataSourceConnection dataSourceConnection = observeServiceInitializer.getDataSourceConnection(); Preconditions.checkArgument(dataSourceConnection instanceof ObserveDataSourceConnectionRest, "dataSourceConfiguration must be of type " + ObserveDataSourceConnectionRest.class.getName()); } else { - // Pas encore connecte on utilise la configuration de la source de données + // Pas encore connecté on utilise la configuration de la source de données ObserveDataSourceConfiguration dataSourceConfiguration = observeServiceInitializer.getDataSourceConfiguration(); Preconditions.checkNotNull(dataSourceConfiguration, "dataSourceConnection and dataSourceConfiguration can't be null."); Preconditions.checkArgument(dataSourceConfiguration instanceof ObserveDataSourceConfigurationRest, "dataSourceConfiguration must be of type " + ObserveDataSourceConfigurationRest.class.getName()); @@ -89,12 +107,12 @@ public class ObserveServiceFactoryRest extends ObserveServiceFactorySupport impl @Override public void close() { - //TODO Voir ce qu'il faut nettoyer, normalement pas grand chose + responseBuilder.close(); } protected <S extends ObserveService> S newRemoteProxyServiceInstance(Class<S> serviceType, ObserveServiceInitializer observeServiceInitializer) { - RemoteInvocationHandler handler = new RemoteInvocationHandler<>(paranamer, serviceType, observeServiceInitializer, gsonSupplier); + RemoteInvocationHandler handler = new RemoteInvocationHandler<>(paranamer, serviceType, observeServiceInitializer, gsonSupplier, responseBuilder); S result = Reflection.newProxy(serviceType, handler); return result; @@ -102,9 +120,7 @@ public class ObserveServiceFactoryRest extends ObserveServiceFactorySupport impl protected static class RemoteInvocationHandler<E extends ObserveService> implements InvocationHandler { - protected final ObserveDataSourceConfigurationRest dataSourceConfiguration; - - protected final ObserveDataSourceConnectionRest dataSourceConnection; + protected final ObserveServiceInitializer observeServiceInitializer; protected final Supplier<Gson> gsonSupplier; @@ -112,37 +128,69 @@ public class ObserveServiceFactoryRest extends ObserveServiceFactorySupport impl protected final Class<E> serviceClass; - protected final String serviceUrl; - protected final String applicationLocale; protected final String referentialLocale; - public RemoteInvocationHandler(Paranamer paranamer, Class<E> serviceClass, ObserveServiceInitializer observeServiceInitializer, Supplier<Gson> gsonSupplier) { + protected final String locateService; + + protected final ObserveResponseBuilder responseBuilder; + + public RemoteInvocationHandler(Paranamer paranamer, Class<E> serviceClass, ObserveServiceInitializer observeServiceInitializer, Supplier<Gson> gsonSupplier, ObserveResponseBuilder responseBuilder) { this.paranamer = paranamer; this.serviceClass = serviceClass; - String locateService = serviceClass.getCanonicalName().replace(ROOT_SERVICES_PACKAGE.getName(), ""); - locateService = locateService.replace(".", "/"); + this.locateService = serviceClass.getCanonicalName().replace(ROOT_SERVICES_PACKAGE.getName(), "").replace(".", "/"); - if (observeServiceInitializer.withDataSourceConnection()) { + this.observeServiceInitializer = observeServiceInitializer; - this.dataSourceConnection = (ObserveDataSourceConnectionRest) observeServiceInitializer.getDataSourceConnection(); - this.dataSourceConfiguration = null; - this.serviceUrl = dataSourceConnection.getServerUrl() + locateService; - - } else { + if (!observeServiceInitializer.withDataSourceConnection() && !observeServiceInitializer.withDataSourceConfiguration()) { + + throw new IllegalStateException("No data source configuration, nor connection defined"); - this.dataSourceConnection = null; - this.dataSourceConfiguration = (ObserveDataSourceConfigurationRest) observeServiceInitializer.getDataSourceConfiguration(); - this.serviceUrl = dataSourceConfiguration.getServerUrl() + locateService; - } this.gsonSupplier = gsonSupplier; this.applicationLocale = observeServiceInitializer.getApplicationLocale().toString(); - this.referentialLocale = observeServiceInitializer.getReferentialLocale().toString(); + this.referentialLocale = observeServiceInitializer.getReferentialLocale().getLocale().toString(); + this.responseBuilder = responseBuilder; + } + + protected String getServiceUrl() { + String serviceUrl; + if (observeServiceInitializer.withDataSourceConnection()) { + + ObserveDataSourceConnectionRest dataSourceConnection = (ObserveDataSourceConnectionRest) observeServiceInitializer.getDataSourceConnection(); + serviceUrl = dataSourceConnection.getServerUrl() + locateService; + + } else if (observeServiceInitializer.withDataSourceConfiguration()) { + + ObserveDataSourceConfigurationRest dataSourceConfiguration = (ObserveDataSourceConfigurationRest) observeServiceInitializer.getDataSourceConfiguration(); + serviceUrl = dataSourceConfiguration.getServerUrl() + locateService; + } else { + + throw new IllegalStateException("No data source configuration, nor connection defined"); + + } + return serviceUrl; + } + + protected ObserveDataSourceConfigurationRest getDataSourceConfiguration() { + ObserveDataSourceConfigurationRest dataSourceConnection = null; + if (observeServiceInitializer.withDataSourceConfiguration()) { + dataSourceConnection = (ObserveDataSourceConfigurationRest) observeServiceInitializer.getDataSourceConfiguration(); + } + return dataSourceConnection; + } + + protected ObserveDataSourceConnectionRest getDataSourceConnection() { + ObserveDataSourceConnectionRest dataSourceConnection = null; + if (observeServiceInitializer.withDataSourceConnection()) { + dataSourceConnection = (ObserveDataSourceConnectionRest) observeServiceInitializer.getDataSourceConnection(); + } + return dataSourceConnection; } + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); @@ -162,45 +210,79 @@ public class ObserveServiceFactoryRest extends ObserveServiceFactorySupport impl return null; } - String url = String.format("%s/%s", serviceUrl, methodName); - if (log.isDebugEnabled()) { - log.debug(String.format("Invoke remote service on endpoint: %s", url)); - } + ObserveRequest request = createRequest(method, methodName, args); - RequestBuilder requestBuilder = new RequestBuilder(url, gsonSupplier); - addParameters(requestBuilder, method, args); - addHeaders(requestBuilder); - Object result = getResult(method, requestBuilder); + ObserveResponse<?> response = responseBuilder.build(request, method.getGenericReturnType()); - return result; + Object result = response.getResultObject(); - } + if (DataSourceService.class.equals(serviceClass)) { - protected Object getResult(Method method, RequestBuilder requestBuilder) throws IOException { + if (OPEN_CONNECTION_METHOD_NAMES.contains(methodName)) { - Object result; - try { + ObserveDataSourceConnection dataSourceConnection = (ObserveDataSourceConnection) result; - boolean writeData = method.isAnnotationPresent(Write.class); + // On enregistre la connexion + observeServiceInitializer.setDataSourceConnection(dataSourceConnection); - Type genericReturnType = method.getGenericReturnType(); - if (writeData) { - result = requestBuilder.postAndGetJsonAndCloseConnection(genericReturnType); - } else { - result = requestBuilder.getJsonAndCloseConnection(genericReturnType); - } + // On supprime la configuration + observeServiceInitializer.setDataSourceConfiguration(null); + + } else if (CLOSE_CONNECTION_METHOD_NAMES.contains(methodName)) { + + // On supprime la connexion + observeServiceInitializer.setDataSourceConnection(null); - } catch (RuntimeException re) { - if (log.isWarnEnabled()) { - log.warn("An error occurred during remote service call", re); } - throw re; } + return result; } - protected void addParameters(RequestBuilder requestBuilder, Method method, Object... args) throws IOException { + protected ObserveRequest createRequest(Method method, String methodName, Object... args) throws IOException { + + ObserveRequestBuilder requestBuilder = ObserveRequestBuilder.create(gsonSupplier); + addParameters(requestBuilder, method, args); + addHeaders(requestBuilder); + + //FIXME On devrait utiliser des annotations POST, PUT et DELETE + boolean writeData = method.isAnnotationPresent(Write.class); + if (writeData) { + requestBuilder.setRequestMethod(ObserveRequestMethod.POST); + } else { + requestBuilder.setRequestMethod(ObserveRequestMethod.GET); + } + + String serviceUrl = getServiceUrl(); + String url = String.format("%s/%s", serviceUrl, methodName); + if (log.isDebugEnabled()) { + log.debug(String.format("Invoke remote service on endpoint: %s", url)); + } + + ObserveRequest request = requestBuilder.build(url); + return request; + + } + + protected static final ImmutableSet<String> OPEN_CONNECTION_METHOD_NAMES = ImmutableSet.of("create", "open"); + + protected static final ImmutableSet<String> CLOSE_CONNECTION_METHOD_NAMES = ImmutableSet.of("close"); + + protected void addParameters(ObserveRequestBuilder requestBuilder, Method method, Object... args) throws IOException { + + boolean reinjectConfiguration = false; + + if (DataSourceService.class.equals(serviceClass)) { + + if (OPEN_CONNECTION_METHOD_NAMES.contains(method.getName()) && getDataSourceConnection() == null && getDataSourceConfiguration() == null) { + + // On va essayer de réinjecter la configuration + reinjectConfiguration = true; + + } + + } String[] strings = paranamer.lookupParameterNames(method); int index = 0; @@ -215,14 +297,28 @@ public class ObserveServiceFactoryRest extends ObserveServiceFactorySupport impl requestBuilder.addParameter(name, value); } } + + if (reinjectConfiguration && PARAMETER_DATA_SOURCE_CONFIGURATION.equals(name)) { + observeServiceInitializer.setDataSourceConfiguration((ObserveDataSourceConfiguration) args[index]); + } + index++; + } } - protected void addHeaders(RequestBuilder requestBuilder) { + protected void addHeaders(ObserveRequestBuilder requestBuilder) { - if (dataSourceConfiguration != null) { + ObserveDataSourceConnectionRest dataSourceConnection = getDataSourceConnection(); + if (dataSourceConnection != null) { + + requestBuilder.addHeader(REQUEST_AUTHENTICATION_TOKEN, dataSourceConnection.getAuthenticationToken()); + + } else { + + ObserveDataSourceConfigurationRest dataSourceConfiguration = getDataSourceConfiguration(); + Preconditions.checkState(dataSourceConfiguration != null, "Must have at least a connection or a configuration"); requestBuilder.addHeader(REQUEST_USER_LOGIN, dataSourceConfiguration.getLogin()); requestBuilder.addHeader(REQUEST_USER_PASSWORD, new String(dataSourceConfiguration.getPassword())); @@ -232,11 +328,8 @@ public class ObserveServiceFactoryRest extends ObserveServiceFactorySupport impl } - } else { - - requestBuilder.addHeader(REQUEST_AUTHENTICATION_TOKEN, dataSourceConnection.getAuthenticationToken()); - } + if (!Strings.isNullOrEmpty(applicationLocale)) { requestBuilder.addHeader(REQUEST_APPLICATION_LOCALE, applicationLocale); } diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequest.java b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequest.java new file mode 100644 index 0000000..e26b40b --- /dev/null +++ b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequest.java @@ -0,0 +1,77 @@ +package fr.ird.observe.services.http; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import org.apache.http.NameValuePair; + +import java.io.File; + +/** + * Created on 06/09/15. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ObserveRequest { + + private final ObserveRequestMethod requestMethod; + + private final String baseUrl; + + private final String contentType; + + private final String requestBody; + + private final ImmutableMap<String, String> headers; + + private final ImmutableList<NameValuePair> parameters; + + private final ImmutableMap<String, File> files; + + public ObserveRequest(ObserveRequestMethod requestMethod, + String baseUrl, + String requestBody, + String contentType, + ImmutableMap<String, String> header, + ImmutableList<NameValuePair> params, + ImmutableMap<String, File> files) { + this.requestMethod = requestMethod; + this.baseUrl = baseUrl; + this.requestBody = requestBody; + this.contentType = contentType; + this.headers = header; + this.parameters = params; + this.files = files; + } + + public ObserveRequestMethod getRequestMethod() { + return requestMethod; + } + + public String getBaseUrl() { + return baseUrl; + } + + public String getContentType() { + return contentType; + } + + public String getRequestBody() { + return requestBody; + } + + public ImmutableMap<String, String> getHeaders() { + return headers; + } + + public ImmutableList<NameValuePair> getParameters() { + return parameters; + } + + public ImmutableMap<String, File> getFiles() { + return files; + } + + public boolean withoutFiles() { + return files.isEmpty(); + } +} diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequestBuilder.java b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequestBuilder.java new file mode 100644 index 0000000..7f59d2a --- /dev/null +++ b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequestBuilder.java @@ -0,0 +1,134 @@ +package fr.ird.observe.services.http; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; +import fr.ird.observe.services.dto.gson.ObserveDtoGsonSupplier; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +/** + * @author Arnaud Thimel - thimel@codelutin.com + */ +public class ObserveRequestBuilder { + + protected final ImmutableList.Builder<NameValuePair> parameters; + + protected final ImmutableMap.Builder<String, String> headers; + + protected final ImmutableMap.Builder<String, File> files; + + protected final Gson gson; + + protected String requestBody; + + protected String contentType; + + protected ObserveRequestMethod requestMethod; + + public static ObserveRequestBuilder create(Supplier<Gson> gsonSupplier) { + return new ObserveRequestBuilder(gsonSupplier); + } + + public ObserveRequest build(String baseUrl) { + + Preconditions.checkNotNull(baseUrl, "'baseUrl' can't be null"); + Preconditions.checkState(requestMethod != null, "'requestMethod' was not setted"); + + ObserveRequest request = new ObserveRequest( + requestMethod, + baseUrl, + contentType, + requestBody, + headers.build(), + parameters.build(), + files.build() + ); + return request; + } + + public ObserveRequestBuilder setRequestMethod(ObserveRequestMethod requestMethod) { + this.requestMethod = requestMethod; + return this; + } + + public ObserveRequestBuilder setRequestBody(String requestBody) { + this.requestBody = requestBody; + return this; + } + + public ObserveRequestBuilder setContentType(String contentType) { + this.contentType = contentType; + return this; + } + + public ObserveRequestBuilder addHeader(String key, String value) { + checkRequestNotNull(key, value); + headers.put(key, value); + return this; + } + + public ObserveRequestBuilder addParameter(String parameterName, String value) { + checkParameterNotNull(parameterName, value); + parameters.add(new BasicNameValuePair(parameterName, value)); + return this; + } + + public ObserveRequestBuilder addParameter(String parameterName, int value) { + return addParameter(parameterName, String.valueOf(value)); + } + + public ObserveRequestBuilder addParameter(String parameterName, File file) { + checkParameterNotNull(parameterName, file); + files.put(parameterName, file); + return this; + } + + public ObserveRequestBuilder addParameter(String parameterName, Object toJson) throws IOException { + String json = gson.toJson(toJson); + return addParameter(parameterName, json); + } + + public ObserveRequestBuilder addParameter(String parameterName, Collection<?> toJsonList) throws IOException { + + // we must add values with same paramName to get List<?> in service + for (Object toJson : toJsonList) { + if (toJson instanceof String) { + + // don't serialize String objects + addParameter(parameterName, (String) toJson); + } else { + addParameter(parameterName, toJson); + } + } + return this; + } + + protected ObserveRequestBuilder(Supplier<Gson> gsonSupplier) { + this.headers = new ImmutableMap.Builder<>(); + this.files = new ImmutableMap.Builder<>(); + this.parameters = new ImmutableList.Builder<>(); + this.gson = MoreObjects.firstNonNull(gsonSupplier, ObserveDtoGsonSupplier.DEFAULT_GSON_SUPPLIER).get(); + } + + protected void checkParameterNotNull(String parparameterNamemName, Object value) { + checkKeyValueNotNull(parparameterNamemName, value, "Parameter key must be not null", "Parameter value must be not null for paramName : " + parparameterNamemName); + } + + protected void checkRequestNotNull(String key, Object value) { + checkKeyValueNotNull(key, value, "Request key must be not null", "Request value must be not null for key : " + key); + } + + protected void checkKeyValueNotNull(String key, Object value, String keyErrorMessage, String valueErrorMessage) { + Preconditions.checkNotNull(key, keyErrorMessage); + Preconditions.checkNotNull(value, valueErrorMessage); + } + +} diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequestMethod.java b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequestMethod.java new file mode 100644 index 0000000..5c3bbcb --- /dev/null +++ b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveRequestMethod.java @@ -0,0 +1,13 @@ +package fr.ird.observe.services.http; + +/** + * Created on 06/09/15. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public enum ObserveRequestMethod { + GET, + POST, + PUT, + DELETE +} diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveResponse.java b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveResponse.java new file mode 100644 index 0000000..9e1011e --- /dev/null +++ b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveResponse.java @@ -0,0 +1,140 @@ +package fr.ird.observe.services.http; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; + +import java.io.IOException; +import java.lang.reflect.Type; + +/** + * @author Arnaud Thimel - thimel@codelutin.com + */ +public class ObserveResponse<T> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ObserveResponse.class); + + protected final int statusCode; + + protected final Header[] headers; + + protected final String responseAsString; + + protected final T resultObject; + + protected ObserveResponse(int statusCode, Header[] headers, String responseAsString, T resultObject) throws IOException { + this.statusCode = statusCode; + this.headers = headers; + this.resultObject = resultObject; + this.responseAsString = responseAsString; + } + + public int getStatusCode() { + return statusCode; + } + + public Header[] getHeaders() { + return headers; + } + + public String getHeader(String key) { + return getHeader(key, headers); + } + + public boolean containsHeader(String key) { + for (Header header : headers) { + if (key.equals(header.getName())) { + return true; + } + } + return false; + } + + protected String getHeader(String key, Header[] headers) { + + for (Header header : headers) { + if (key.equals(header.getName())) { + return header.getValue(); + } + } + throw new IllegalArgumentException(key + " key is not found in header"); + } + + public String getResponse() throws IOException { + return responseAsString; + } + + public T getResultObject() { + return resultObject; + } + + public static <T> T convertJson(String json, Type type, Gson gson) throws IOException { + + Preconditions.checkNotNull(json); + Preconditions.checkNotNull(gson); + + // we must try to convert json to a T instance + T result = null; + +// try { + + // let's first try to convert json to T + if (!Void.TYPE.equals(type)) { + result = gson.fromJson(json, type); + } + +// } catch (IOException e) { +// +// // conversion to T failed, we will throw a json exception +// RemoteCallUnexpectedJsonException remoteCallUnexpectedJsonException; +// +// try { +// +// // before, try to read json as an error message +// remoteCallUnexpectedJsonException = RemoteCallUnexpectedJsonException.newFromJson(json); +// +// if (log.isInfoEnabled()) { +// log.info("service returned a json showing an error occurred ", remoteCallUnexpectedJsonException); +// } +// +// } catch (IOException ee) { +// +// if (log.isErrorEnabled()) { +// log.error("json parsing failed, json=" + json, e); +// } +// +// // json is not of type T and not an error message, +// // throw the exception with e as cause cause it may be the real problem +// remoteCallUnexpectedJsonException = RemoteCallUnexpectedJsonException.newFromParsingException(e); +// +// } +// +// throw remoteCallUnexpectedJsonException; +// +// } + + if (log.isTraceEnabled()) { + log.trace("parsing json " + json + " returns " + result); + } + + + return result; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(). + append("HTTP ").append(statusCode).append('\n'); + if (headers != null) { + for (Header header : headers) { + buffer.append('[').append(header.getName()).append("] ").append(header.getValue()).append('\n'); + } + } + buffer.append('\n').append(responseAsString); + String result = buffer.toString(); + return result; + } +} diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveResponseBuilder.java b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveResponseBuilder.java new file mode 100644 index 0000000..821120a --- /dev/null +++ b/observe-services-rest/src/main/java/fr/ird/observe/services/http/ObserveResponseBuilder.java @@ -0,0 +1,396 @@ +package fr.ird.observe.services.http; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.base.Supplier; +import com.google.gson.Gson; +import fr.ird.observe.services.dto.gson.ObserveDtoGsonSupplier; +import org.apache.commons.io.Charsets; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +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.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.ClientConnectionManager; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntity; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.HttpParams; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Type; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @author Tony Chemit - chemit@codelutin.com + */ +public class ObserveResponseBuilder { + + private static final Log log = LogFactory.getLog(ObserveResponseBuilder.class); + + public static ObserveResponseBuilder create(Supplier<Gson> gsonSupplier) { + return new ObserveResponseBuilder(new DefaultHttpClient(new PoolingClientConnectionManager()), gsonSupplier); + } + + public static ObserveResponseBuilder create(HttpClient client, Supplier<Gson> gsonSupplier) { + return new ObserveResponseBuilder(client, gsonSupplier); + } + + protected final HttpClient client; + + protected final Gson gson; + + protected class ResponseContext { + + final Integer statusCode; + + final String responseAsString; + + final Header[] responseHeaders; + + public ResponseContext(Integer statusCode, String responseAsString, Header... responseHeaders) { + this.statusCode = statusCode; + this.responseAsString = responseAsString; + this.responseHeaders = responseHeaders; + } + + } + + public <T> ObserveResponse<T> build(ObserveRequest request, Type resultType) throws IOException { + + String baseUrl = request.getBaseUrl(); + Preconditions.checkNotNull(baseUrl, "'baseUrl' can't be null"); + + ObserveRequestMethod requestMethod = request.getRequestMethod(); + Preconditions.checkState(requestMethod != null, "'requestMethod' was not setted"); + + ResponseContext responseContext = executeRequest(request); + + if (responseContext.statusCode != 200 && log.isWarnEnabled()) { + log.warn(String.format("Unexpected status code for url: %s\n%s", baseUrl, responseContext.responseAsString)); + } + + T resultObject = convertJson(responseContext.responseAsString, resultType); + ObserveResponse<T> result = new ObserveResponse<>(responseContext.statusCode, responseContext.responseHeaders, responseContext.responseAsString, resultObject); + + return result; + + } + + protected ResponseContext executeRequest(ObserveRequest request) throws IOException { + + Pair<? extends HttpRequestBase, HttpResponse> responsePair = null; + + try { + + ObserveRequestMethod requestMethod = request.getRequestMethod(); + switch (requestMethod) { + case GET: + responsePair = get0(request); + break; + case POST: + responsePair = post0(request, null); + break; + case PUT: + responsePair = put0(request); + break; + case DELETE: + responsePair = delete0(request); + break; + default: + throw new IllegalStateException("Can't come here!"); + } + + HttpResponse response = responsePair.getRight(); + + ResponseContext responseContext = consumeResponse(request, response); + return responseContext; + + } finally { + if (responsePair != null) { + close(responsePair); + } + } + + } + + protected ResponseContext consumeResponse(ObserveRequest request, HttpResponse response) throws IOException { + + String baseUrl = request.getBaseUrl(); + + Header[] responseHeaders = response.getAllHeaders(); + int statusCode = response.getStatusLine().getStatusCode(); + if (log.isDebugEnabled()) { + log.debug(request.getRequestMethod() + " '" + baseUrl + "' return status code : " + statusCode); + } + + response.getEntity(); + + String responseAsString; + + try (InputStream inputStream = response.getEntity().getContent()) { + try (StringWriter writer = new StringWriter()) { + IOUtils.copy(inputStream, writer, "UTF-8"); + responseAsString = writer.toString(); + } + } + return new ResponseContext(statusCode, responseAsString, responseHeaders); + } + + protected ObserveResponseBuilder(HttpClient client, Supplier<Gson> gsonSupplier) { + this.client = client; + this.gson = MoreObjects.firstNonNull(gsonSupplier, ObserveDtoGsonSupplier.DEFAULT_GSON_SUPPLIER).get(); + } + + protected Pair<HttpGet, HttpResponse> get0(ObserveRequest request) throws IOException { + + String baseUrl = request.getBaseUrl(); + String url = buildUrlWithParameters(baseUrl, request.getParameters()); + + HttpGet getMethod = new HttpGet(url); + + addHeaders(getMethod, request.getHeaders()); + + HttpResponse response = client.execute(getMethod); + + if (log.isDebugEnabled()) { + log.debug("GET '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode()); + } + + return Pair.of(getMethod, response); + + } + + protected Pair<HttpPost, HttpResponse> post0(ObserveRequest request, Integer timeout) throws IOException { + + String baseUrl = request.getBaseUrl(); + String contentType = request.getContentType(); + String requestBody = request.getRequestBody(); + + HttpPost postMethod = new HttpPost(baseUrl); + + if (timeout != null) { + HttpParams httpParams = new BasicHttpParams(); + httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout); + httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout); + postMethod.setParams(httpParams); + } + + if (request.withoutFiles()) { + addHeaders(postMethod, request.getHeaders()); + addParameters(postMethod, contentType, request.getParameters()); + addRequestBody(postMethod, contentType, requestBody); + } else { + addHeaders(postMethod, request.getHeaders()); + addParameters(postMethod, contentType, request.getParameters()); + addRequestBody(postMethod, contentType, requestBody); + MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); + for (Map.Entry<String, File> paramFile : request.getFiles().entrySet()) { + entity.addPart(paramFile.getKey(), new FileBody(paramFile.getValue())); + } + for (NameValuePair param : request.getParameters()) { + if (StringUtils.isBlank(contentType)) { + contentType = "text/plain"; + } + entity.addPart(param.getName(), new StringBody(param.getValue(), contentType, + Charset.forName("UTF-8"))); + } + postMethod.setEntity(entity); + } + + HttpResponse response = client.execute(postMethod); + + if (log.isDebugEnabled()) { + log.debug("POST '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode()); + } + + return Pair.of(postMethod, response); + + } + + protected Pair<HttpPut, HttpResponse> put0(ObserveRequest request) throws IOException { + + String baseUrl = request.getBaseUrl(); + + HttpPut putMethod = new HttpPut(baseUrl); + addHeaders(putMethod, request.getHeaders()); + + String contentType = request.getContentType(); + addParameters(putMethod, contentType, request.getParameters()); + addRequestBody(putMethod, contentType, request.getRequestBody()); + + HttpResponse response = client.execute(putMethod); + + if (log.isDebugEnabled()) { + log.debug("PUT '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode()); + } + + return Pair.of(putMethod, response); + + } + + + protected Pair<HttpDelete, HttpResponse> delete0(ObserveRequest request) throws IOException { + + String baseUrl = request.getBaseUrl(); + + HttpDelete deleteMethod = new HttpDelete(buildUrlWithParameters(baseUrl, request.getParameters())); + + addHeaders(deleteMethod, request.getHeaders()); + + HttpResponse response = client.execute(deleteMethod); + + if (log.isDebugEnabled()) { + log.debug("DELETE '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode()); + } + + return Pair.of(deleteMethod, response); + + } + + protected String buildUrlWithParameters(String baseUrl, List<NameValuePair> parameters) { + String result = baseUrl; + if (!parameters.isEmpty()) { + result += "?" + URLEncodedUtils.format(parameters, Charsets.UTF_8); + } + return result; + } + + protected <M extends HttpRequestBase> void addHeaders(M httpMethod, Map<String, String> headers) { + for (Map.Entry<String, String> entry : headers.entrySet()) { + httpMethod.setHeader(entry.getKey(), entry.getValue()); + } + } + + protected <M extends HttpEntityEnclosingRequestBase> void addParameters(M method, String contentType, List<? extends NameValuePair> parameters) throws UnsupportedEncodingException { + UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(parameters, Charsets.UTF_8); + if (StringUtils.isNotBlank(contentType)) { + encodedFormEntity.setContentType(contentType); + } + method.setEntity(encodedFormEntity); + } + + protected <M extends HttpEntityEnclosingRequestBase> void addRequestBody(M method, String contentType, String requestBody) throws UnsupportedEncodingException { + if (StringUtils.isNotEmpty(requestBody)) { + if (StringUtils.isNotBlank(contentType)) { + method.setEntity(new StringEntity(requestBody, ContentType.parse(contentType))); + } else { + method.setEntity(new StringEntity(requestBody)); + } + } + } + + public <T> T convertJson(String json, Type type) throws IOException { + + Preconditions.checkNotNull(json); + Preconditions.checkNotNull(gson); + + // we must try to convert json to a T instance + T result = null; + +// try { + + // let's first try to convert json to T + if (!Void.TYPE.equals(type)) { + result = gson.fromJson(json, type); + } + +// } catch (IOException e) { +// +// // conversion to T failed, we will throw a json exception +// RemoteCallUnexpectedJsonException remoteCallUnexpectedJsonException; +// +// try { +// +// // before, try to read json as an error message +// remoteCallUnexpectedJsonException = RemoteCallUnexpectedJsonException.newFromJson(json); +// +// if (log.isInfoEnabled()) { +// log.info("service returned a json showing an error occurred ", remoteCallUnexpectedJsonException); +// } +// +// } catch (IOException ee) { +// +// if (log.isErrorEnabled()) { +// log.error("json parsing failed, json=" + json, e); +// } +// +// // json is not of type T and not an error message, +// // throw the exception with e as cause cause it may be the real problem +// remoteCallUnexpectedJsonException = RemoteCallUnexpectedJsonException.newFromParsingException(e); +// +// } +// +// throw remoteCallUnexpectedJsonException; +// +// } + + if (log.isTraceEnabled()) { + log.trace("parsing json " + json + " returns " + result); + } + + + return result; + } + + protected void close(Pair<? extends HttpRequestBase, HttpResponse> responsePair) throws IOException { + + HttpRequestBase httpRequestBase = responsePair.getLeft(); + HttpResponse response = responsePair.getRight(); + + + if (response != null && response.getEntity() != null) { + response.getEntity().getContent().close(); + } + + // Release the connection. + httpRequestBase.releaseConnection(); + + } + + public void close() { + if (getConnectionManager() != null) { + getConnectionManager().shutdown(); + } + } + + @Override + protected void finalize() throws Throwable { + if (getConnectionManager() != null) { + getConnectionManager().closeExpiredConnections(); + getConnectionManager().closeIdleConnections(1, TimeUnit.MINUTES); + } + super.finalize(); + } + + protected ClientConnectionManager getConnectionManager() { + return client.getConnectionManager(); + } + +} diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/http/RequestBuilder.java b/observe-services-rest/src/main/java/fr/ird/observe/services/http/RequestBuilder.java deleted file mode 100644 index 1a67ae0..0000000 --- a/observe-services-rest/src/main/java/fr/ird/observe/services/http/RequestBuilder.java +++ /dev/null @@ -1,531 +0,0 @@ -package fr.ird.observe.services.http; - -import com.google.common.base.Charsets; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.base.Supplier; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.gson.Gson; -import fr.ird.observe.services.dto.gson.ObserveDtoGsonSupplier; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -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.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.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.entity.mime.HttpMultipartMode; -import org.apache.http.entity.mime.MultipartEntity; -import org.apache.http.entity.mime.content.FileBody; -import org.apache.http.entity.mime.content.StringBody; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.PoolingClientConnectionManager; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.CoreConnectionPNames; -import org.apache.http.params.HttpParams; - -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Type; -import java.net.URLEncoder; -import java.nio.charset.Charset; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * @author Arnaud Thimel - thimel@codelutin.com - */ -public class RequestBuilder { - - private static final Log log = LogFactory.getLog(RequestBuilder.class); - - protected static final Supplier<Gson> DEFAULT_GSON_SUPPLIER = new Supplier<Gson>() { - - @Override - public Gson get() { - return new ObserveDtoGsonSupplier().get(); - } - }; - - protected HttpClient client; - - protected Map<String, String> header; - - protected List<NameValuePair> params; - - protected String baseUrl; - - protected String requestBody; - - protected String contentType; - - protected Map<String, File> files = Maps.newHashMap(); - - protected Supplier<Gson> gsonSupplier; - - protected Gson gson; - - public RequestBuilder(String baseUrl, HttpClient client, Supplier<Gson> gsonSupplier) { - this.baseUrl = baseUrl; - this.client = client; - this.header = Maps.newHashMap(); - this.params = Lists.newArrayList(); - this.gsonSupplier = MoreObjects.firstNonNull(gsonSupplier, DEFAULT_GSON_SUPPLIER); - } - -// public RequestBuilder(String baseUrl, HttpClient client) { -// this(baseUrl, client, null); -// } - - public RequestBuilder(String baseUrl, Supplier<Gson> gsonSupplier) { - this(baseUrl, new DefaultHttpClient(new PoolingClientConnectionManager()), gsonSupplier); - } - -// public RequestBuilder(String baseUrl) { -// this(baseUrl, (Supplier) null); -// } - - public RequestBuilder addToUrl(Collection<?> toJsonList) throws IOException { - - // we must add values with same paramName to get List<?> in service - for (Object toJson : toJsonList) { - if (toJson instanceof String) { - - // don't serialize String objects - addToUrl((String) toJson); - } else { - addToUrl(toJson); - } - } - return this; - } - - public Gson getGson() { - if (gson == null) { - gson = gsonSupplier.get(); - } - return gson; - } - - public RequestBuilder addToUrl(Object toJson) throws IOException { - String json = getGson().toJson(toJson); - return addToUrl(json); - } - - public RequestBuilder addToUrl(String url) throws UnsupportedEncodingException { - baseUrl = baseUrl + "/" + URLEncoder.encode(url, Charsets.UTF_8.name()); - return this; - } - - public RequestBuilder addHeader(String key, String value) { - checkRequestNotNull(key, value); - header.put(key, value); - return this; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public RequestBuilder addParameter(String paramName, File file) { - files.put(paramName, file); - return this; - } - - public RequestBuilder addParameter(String paramName, Collection<?> toJsonList) throws IOException { - - // we must add values with same paramName to get List<?> in service - for (Object toJson : toJsonList) { - if (toJson instanceof String) { - - // don't serialize String objects - addParameter(paramName, (String) toJson); - } else { - addParameter(paramName, toJson); - } - } - return this; - } - - public RequestBuilder addParameter(String paramName, Object toJson) throws IOException { - String json = getGson().toJson(toJson); - return addParameter(paramName, json); - } - - public RequestBuilder addParameter(String paramName, String value) { - checkParameterNotNull(paramName, value); - params.add(new BasicNameValuePair(paramName, value)); - return this; - } - - public RequestBuilder addParameter(String paramName, int value) { - return addParameter(paramName, String.valueOf(value)); - } - - public RequestBuilder addParameters(String paramName, String value, String... others) { - checkParameterNotNull(paramName, value); - params.add(new BasicNameValuePair(paramName, value)); - String name = null; - for (int i = 0; i < others.length; ) { - try { - name = others[i++]; - value = others[i++]; - checkParameterNotNull(paramName, value); - params.add(new BasicNameValuePair(name, value)); - } catch (ArrayIndexOutOfBoundsException eee) { - throw new IllegalArgumentException( - "Parameters number must be pair number : " - + (others.length + 2) + " Last parameter is : " + name, eee); - } - } - return this; - } - - public RequestBuilder setRequestBody(String requestBody) { - this.requestBody = requestBody; - return this; - } - - protected void checkParameterNotNull(String paramName, String value) { - checkKeyValueNotNull(paramName, value, "Parameter key must be not null", "Parameter value must be not null for paramName : " + paramName); - } - - protected void checkRequestNotNull(String key, String value) { - checkKeyValueNotNull(key, value, "Request key must be not null", "Request value must be not null for key : " + key); - } - - protected void checkKeyValueNotNull(String key, String value, String keyErrorMessage, String valueErrorMessage) { - Preconditions.checkNotNull(key, keyErrorMessage); - Preconditions.checkNotNull(value, valueErrorMessage); - } - - protected <M extends HttpRequestBase> M addHeaders(M httpMethod) { - for (Map.Entry<String, String> entry : header.entrySet()) { - httpMethod.setHeader(entry.getKey(), entry.getValue()); - } - return httpMethod; - } - - protected <M extends HttpEntityEnclosingRequestBase> M addParameters(M method) throws UnsupportedEncodingException { - UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(params, "UTF-8"); - if (StringUtils.isNotBlank(contentType)) { - encodedFormEntity.setContentType(contentType); - } - method.setEntity(encodedFormEntity); - return method; - } - - protected <M extends HttpEntityEnclosingRequestBase> M addRequestBody(M method) throws UnsupportedEncodingException { - if (StringUtils.isNotEmpty(requestBody)) { - if (StringUtils.isNotBlank(contentType)) { - method.setEntity(new StringEntity(requestBody, ContentType.parse(contentType))); - } else { - method.setEntity(new StringEntity(requestBody)); - } - } - return method; - } - - public String buildUrlWithParams(String baseUrl) { - return baseUrl + "?" + URLEncodedUtils.format(params, "UTF-8"); - } - - protected RequestResult get0() throws IOException { - - HttpGet getMethod = new HttpGet(buildUrlWithParams(baseUrl)); - - getMethod = addHeaders(getMethod); - - HttpResponse response = null; - try { - response = client.execute(getMethod); - - RequestResult result = new RequestResult(response); - if (log.isDebugEnabled()) { - log.debug("GET '" + baseUrl + "' return status code : " + result.getStatusCode()); - } - - return result; - } finally { - - if (response != null && response.getEntity() != null) { - response.getEntity().getContent().close(); - } - - // Release the connection. - getMethod.releaseConnection(); - } - } - - public RequestResult getAndCloseConnection() throws IOException { - - try { - RequestResult result = get0(); - return result; - } finally { - releaseConnections(); - } - } - - public <T> T getJsonAndCloseConnection(Type type) throws IOException { - RequestResult getResult = getAndCloseConnection(); - if (getResult.getStatusCode() != 200 && log.isWarnEnabled()) { - log.warn(String.format("Unexpected status code for url: %s%n%s", baseUrl, getResult)); - } - T result = convertJson(getResult.getResponse(), type, getGson()); - return result; - } - - protected RequestResult post0(Integer timeout) throws IOException { - - HttpPost postMethod = new HttpPost(baseUrl); - - if (timeout != null) { - HttpParams httpParams = new BasicHttpParams(); - httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout); - httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout); - postMethod.setParams(httpParams); - } - - if (files.isEmpty()) { - postMethod = addHeaders(postMethod); - postMethod = addParameters(postMethod); - postMethod = addRequestBody(postMethod); - } else { - postMethod = addHeaders(postMethod); - postMethod = addParameters(postMethod); - postMethod = addRequestBody(postMethod); - MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); - for (Map.Entry<String, File> paramFile : files.entrySet()) { - entity.addPart(paramFile.getKey(), new FileBody(paramFile.getValue())); - } - for (NameValuePair param : params) { - if (StringUtils.isBlank(contentType)) { - contentType = "text/plain"; - } - entity.addPart(param.getName(), new StringBody(param.getValue(), contentType, - Charset.forName("UTF-8"))); - } - postMethod.setEntity(entity); - } - - HttpResponse response = null; - try { - response = client.execute(postMethod); - - RequestResult result = new RequestResult(response); - if (log.isDebugEnabled()) { - log.debug("POST '" + baseUrl + "' return status code : " + result.getStatusCode()); - } - - return result; - } finally { - - if (response != null && response.getEntity() != null) { - response.getEntity().getContent().close(); - } - - // Release the connection. - postMethod.releaseConnection(); - } - } - - public RequestResult postAndCloseConnection() throws IOException { - RequestResult result = postAndCloseConnection(null); - return result; - } - - public RequestResult postAndCloseConnection(Integer timeout) throws IOException { - try { - RequestResult result = post0(timeout); - return result; -// } catch (ConnectTimeoutException cte) { -// throw new RemoteCallTimeoutException("Timeout (" + timeout + ") reached", cte); - } finally { - releaseConnections(); - } - } - - public <T> T postAndGetJsonAndCloseConnection(Type type) throws IOException { - RequestResult postResult = postAndCloseConnection(); - if (postResult.getStatusCode() != 200 && log.isWarnEnabled()) { - log.warn(String.format("Unexpected status code: %d\nResponse is: %s", postResult.getStatusCode(), postResult)); - } - T result = convertJson(postResult.getResponse(), type, getGson()); - return result; - } - - protected RequestResult put0() throws IOException { - - HttpPut putMethod = new HttpPut(baseUrl); - - putMethod = addHeaders(putMethod); - putMethod = addParameters(putMethod); - putMethod = addRequestBody(putMethod); - - HttpResponse response = null; - try { - response = client.execute(putMethod); - - RequestResult result = new RequestResult(response); - - if (log.isDebugEnabled()) { - log.debug("PUT '" + baseUrl + "' return status code : " + result.getStatusCode()); - if (result.getStatusCode() != HttpStatus.SC_OK) { - log.debug(result.getResponse()); - } - } - - return result; - } finally { - - if (response != null && response.getEntity() != null) { - response.getEntity().getContent().close(); - } - - // Release the connection. - putMethod.releaseConnection(); - } - } - - protected RequestResult delete0() throws IOException { - - HttpDelete deleteMethod = new HttpDelete(buildUrlWithParams(baseUrl)); - - deleteMethod = addHeaders(deleteMethod); - - HttpResponse response = null; - try { - response = client.execute(deleteMethod); - - RequestResult result = new RequestResult(response); - if (log.isDebugEnabled()) { - log.debug("DELETE '" + baseUrl + "' return status code : " + result.getStatusCode()); - } - - return result; - } finally { - - if (response != null && response.getEntity() != null) { - response.getEntity().getContent().close(); - } - - // Release the connection. - deleteMethod.releaseConnection(); - } - } - - public static <T> T convertJson(String json, Type type) throws IOException { - return convertJson(json, type, DEFAULT_GSON_SUPPLIER.get()); - } - - public static <T> T convertJson(String json, Type type, Gson gson) throws IOException { - - Preconditions.checkNotNull(json); - Preconditions.checkNotNull(gson); - - // we must try to convert json to a T instance - T result = null; - -// try { - - // let's first try to convert json to T - if (!Void.TYPE.equals(type)) { - result = gson.fromJson(json, type); - } - -// } catch (IOException e) { -// -// // conversion to T failed, we will throw a json exception -// RemoteCallUnexpectedJsonException remoteCallUnexpectedJsonException; -// -// try { -// -// // before, try to read json as an error message -// remoteCallUnexpectedJsonException = RemoteCallUnexpectedJsonException.newFromJson(json); -// -// if (log.isInfoEnabled()) { -// log.info("service returned a json showing an error occurred ", remoteCallUnexpectedJsonException); -// } -// -// } catch (IOException ee) { -// -// if (log.isErrorEnabled()) { -// log.error("json parsing failed, json=" + json, e); -// } -// -// // json is not of type T and not an error message, -// // throw the exception with e as cause cause it may be the real problem -// remoteCallUnexpectedJsonException = RemoteCallUnexpectedJsonException.newFromParsingException(e); -// -// } -// -// throw remoteCallUnexpectedJsonException; -// -// } - - if (log.isTraceEnabled()) { - log.trace("parsing json " + json + " returns " + result); - } - - - return result; - } - - @Override - public String toString() { - MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this).add("url", baseUrl); - if (header != null) { - for (Map.Entry<String, String> entry : header.entrySet()) { - String key = String.format("Header [%s]", entry.getKey()); - String value = entry.getValue(); - helper.add(key, value); - } - } - if (params != null) { - for (NameValuePair pair : params) { - String key = String.format("Param [%s]", pair.getName()); - String value = pair.getValue(); - helper.add(key, value); - } - } - - if (StringUtils.isNotBlank(contentType)) { - helper.add("Content-type", contentType); - } - - String result = helper.toString(); - return result; - } - - public void releaseConnections() { - if (client != null && client.getConnectionManager() != null) { - client.getConnectionManager().shutdown(); - } - } - - @Override - protected void finalize() throws Throwable { - if (client != null && client.getConnectionManager() != null) { - client.getConnectionManager().closeExpiredConnections(); - client.getConnectionManager().closeIdleConnections(1, TimeUnit.MINUTES); - } - super.finalize(); - } - -} diff --git a/observe-services-rest/src/main/java/fr/ird/observe/services/http/RequestResult.java b/observe-services-rest/src/main/java/fr/ird/observe/services/http/RequestResult.java deleted file mode 100644 index 47d7ed2..0000000 --- a/observe-services-rest/src/main/java/fr/ird/observe/services/http/RequestResult.java +++ /dev/null @@ -1,86 +0,0 @@ -package fr.ird.observe.services.http; - -import org.apache.commons.io.IOUtils; -import org.apache.http.Header; -import org.apache.http.HttpResponse; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; - -/** - * @author Arnaud Thimel - thimel@codelutin.com - */ -public class RequestResult { - - protected final int statusCode; - - protected final Header[] headers; - - protected final String responseAsString; - - public RequestResult(HttpResponse response) throws IOException { - this.statusCode = response.getStatusLine().getStatusCode(); - this.headers = response.getAllHeaders(); - response.getEntity(); - - try (InputStream inputStream = response.getEntity().getContent()) { - - try (StringWriter writer = new StringWriter()) { - - IOUtils.copy(inputStream, writer, "UTF-8"); - - responseAsString = writer.toString(); - } - } - } - - public int getStatusCode() { - return statusCode; - } - - public Header[] getHeaders() { - return headers; - } - - public String getHeader(String key) { - return getHeader(key, headers); - } - - public boolean containsHeader(String key) { - for (Header header : headers) { - if (key.equals(header.getName())) { - return true; - } - } - return false; - } - - protected String getHeader(String key, Header[] headers) { - - for (Header header : headers) { - if (key.equals(header.getName())) { - return header.getValue(); - } - } - throw new IllegalArgumentException(key + " key is not found in header"); - } - - public String getResponse() throws IOException { - return responseAsString; - } - - @Override - public String toString() { - StringBuilder buffer = new StringBuilder(). - append("HTTP ").append(statusCode).append('\n'); - if (headers != null) { - for (Header header : headers) { - buffer.append('[').append(header.getName()).append("] ").append(header.getValue()).append('\n'); - } - } - buffer.append('\n').append(responseAsString); - String result = buffer.toString(); - return result; - } -} diff --git a/observe-services-rest/src/test/java/fr/ird/observe/services/TestClassResource.java b/observe-services-rest/src/test/java/fr/ird/observe/services/TestClassResource.java index b3b2f24..a7f4de9 100644 --- a/observe-services-rest/src/test/java/fr/ird/observe/services/TestClassResource.java +++ b/observe-services-rest/src/test/java/fr/ird/observe/services/TestClassResource.java @@ -137,4 +137,19 @@ public class TestClassResource implements TestRule { } + public ObserveDataSourceConfigurationRest createDataSourceConfigurationRest(Class<?> testClass, + String login, + char... password) { + + ObserveDataSourceConfigurationRest configurationRest = new ObserveDataSourceConfigurationRest(); + configurationRest.setLabel(testClass.getSimpleName() + "#" + serverUrl); + configurationRest.setServerUrl(serverUrl); + configurationRest.setLogin(login); + configurationRest.setPassword(password); + configurationRest.setOptionalDatabaseName(Optional.<String>absent()); + + return configurationRest; + + } + } diff --git a/observe-services-rest/src/test/java/fr/ird/observe/services/service/DataSourceServiceRestTest.java b/observe-services-rest/src/test/java/fr/ird/observe/services/service/DataSourceServiceRestTest.java index 1dbab67..b3fb694 100644 --- a/observe-services-rest/src/test/java/fr/ird/observe/services/service/DataSourceServiceRestTest.java +++ b/observe-services-rest/src/test/java/fr/ird/observe/services/service/DataSourceServiceRestTest.java @@ -3,9 +3,11 @@ package fr.ird.observe.services.service; import fr.ird.observe.services.TestClassResource; import fr.ird.observe.services.TestMethodResource; import fr.ird.observe.services.configuration.ObserveDataSourceConfigurationRest; +import fr.ird.observe.services.configuration.ObserveDataSourceConnection; import fr.ird.observe.services.dto.DataSourceCreateConfigurationDto; import fr.ird.observe.services.dto.DataSourceCreateWithNoReferentialImportException; import fr.ird.observe.services.dto.IncompatibleDataSourceCreateConfigurationException; +import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.ClassRule; @@ -36,7 +38,7 @@ public class DataSourceServiceRestTest { service = testClassResource.newService(dataSourceConfiguration, DataSourceService.class); //TODO Tester si le serveur est accessible sinon on ignore le test - boolean serverExist = false; + boolean serverExist = true; Assume.assumeTrue("Serveur " + dataSourceConfiguration.getServerUrl() + " no found", serverExist); @@ -54,11 +56,17 @@ public class DataSourceServiceRestTest { public void testOpen() throws IOException, IncompatibleDataSourceCreateConfigurationException, DataSourceCreateWithNoReferentialImportException, DatabaseConnexionNotAuthorizedException, DatabaseNotFoundException { ObserveDataSourceConfigurationRest dataSourceConfiguration = testMethodResource.getDataSourceConfiguration(); - DataSourceCreateConfigurationDto dataSourceCreateConfiguration = new DataSourceCreateConfigurationDto(); - dataSourceCreateConfiguration.setCanCreateEmptyDatabase(true); - service.create(dataSourceConfiguration, dataSourceCreateConfiguration); + ObserveDataSourceConnection dataSourceConnection = service.open(dataSourceConfiguration); + Assert.assertNotNull(dataSourceConnection); + Assert.assertNotNull(dataSourceConnection.getAuthenticationToken()); - service.open(dataSourceConfiguration); + service.close(); + + dataSourceConnection = service.open(dataSourceConfiguration); + Assert.assertNotNull(dataSourceConnection); + Assert.assertNotNull(dataSourceConnection.getAuthenticationToken()); + + service.close(); } diff --git a/observe-services-rest/src/test/java/fr/ird/observe/services/service/seine/TripSeineServiceTest.java b/observe-services-rest/src/test/java/fr/ird/observe/services/service/seine/TripSeineServiceTest.java index 6e25e91..88c0ccd 100644 --- a/observe-services-rest/src/test/java/fr/ird/observe/services/service/seine/TripSeineServiceTest.java +++ b/observe-services-rest/src/test/java/fr/ird/observe/services/service/seine/TripSeineServiceTest.java @@ -4,7 +4,7 @@ import com.google.common.collect.Collections2; import com.google.common.collect.Iterables; import fr.ird.observe.services.TestClassResource; import fr.ird.observe.services.TestMethodResource; -import fr.ird.observe.services.configuration.ObserveDataSourceConfigurationRestSupport; +import fr.ird.observe.services.configuration.ObserveDataSourceConfigurationRest; import fr.ird.observe.services.dto.FormDto; import fr.ird.observe.services.dto.IdDtos; import fr.ird.observe.services.dto.ReferenceSetDto; @@ -49,7 +49,7 @@ public class TripSeineServiceTest { @Before public void setUp() throws Exception { - ObserveDataSourceConfigurationRestSupport dataSourceConfiguration = testMethodResource.getDataSourceConfiguration(); + ObserveDataSourceConfigurationRest dataSourceConfiguration = testMethodResource.getDataSourceConfiguration(); service = testClassResource.newService(dataSourceConfiguration, TripSeineService.class); } -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@list.forge.codelutin.com>.