package com.aol.micro.server.rest.client; import java.util.concurrent.CompletableFuture; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.experimental.Wither; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.ClientProperties; import com.aol.micro.server.rest.jackson.JacksonFeature; import com.aol.micro.server.rest.jackson.JacksonUtil; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; @Wither @Builder @AllArgsConstructor public class RestClient<T> { private final Client client; private final String contentType; private final String accept; private final Class<T> response; private final JavaType genericResponse; /** * Create a new rest client. * @param readTimeoutMillis Read timeout, in milliseconds * @param connectTimeoutMillis Connect timeout, in milliseconds */ public RestClient(int readTimeoutMillis, int connectTimeoutMillis) { this.client = initClient(readTimeoutMillis, connectTimeoutMillis); contentType = MediaType.APPLICATION_JSON; accept = MediaType.APPLICATION_JSON; response = (Class<T>) String.class; genericResponse = null; } public <R> RestClient<R> withResponse(Class<R> response) { return new RestClient<R>(client, contentType, accept, response,null); } public <R> RestClient<R> withGenericResponse(Class<R> responseClass, Class... genericResponse) { return new RestClient<R>(client, contentType, accept, null,JacksonUtil.getMapper().getTypeFactory().constructParametricType(responseClass,genericResponse)); } protected Client initClient(int rt, int ct) { ClientConfig clientConfig = new ClientConfig(); clientConfig.property(ClientProperties.CONNECT_TIMEOUT, ct); clientConfig.property(ClientProperties.READ_TIMEOUT, rt); ClientBuilder.newBuilder().register(JacksonFeature.class); Client client = ClientBuilder.newClient(clientConfig); client.register(JacksonFeature.class); JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(); provider.setMapper(JacksonUtil.getMapper()); client.register(provider); return client; } public T get(final String url) { final WebTarget webResource = client.target(url); String s = webResource.request(accept).accept(accept) .get(String.class); return buildResponse(s); } private T buildResponse( String complete) { if(normalNotGenericResponseType()){ if (shouldJustReturnString()){ return (T)complete; } else{ return convertToStandardEntity( complete); } } else return convertToGenericEntity(complete); } private T convertToGenericEntity( String complete) { return (T) JacksonUtil.convertFromJson( complete, genericResponse); } private T convertToStandardEntity( String complete) { return (T) JacksonUtil.convertFromJson( complete, response); } private boolean shouldJustReturnString() { return String.class.equals(response); } private boolean normalNotGenericResponseType() { return this.genericResponse==null; } public <V> T post(final String queryResourceUrl, final V request) { final WebTarget webResource = client.target(queryResourceUrl); return buildResponse(webResource .request(accept) .accept(accept) .post(Entity.entity(request, contentType),String.class)); } public <V> T put(final String queryResourceUrl, final V request) { CompletableFuture<T> result = new CompletableFuture<>(); final WebTarget webResource = client.target(queryResourceUrl); return buildResponse(webResource .request(accept) .accept(accept) .put(Entity.entity(request, contentType),String.class)); } public T delete(final String queryResourceUrl) { CompletableFuture<T> result = new CompletableFuture<>(); final WebTarget webResource = client.target(queryResourceUrl); return buildResponse(webResource .request(accept) .accept(accept) .delete(String.class)); } }