com.monarchapis.client.resource.AbstractResource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rest-client Show documentation
Show all versions of rest-client Show documentation
A Fluent API wrapper around Apache HTTP Client that handles both synchronous and asynchronous REST calls.
The newest version!
/*
* Copyright (C) 2015 CapTech Ventures, Inc.
* (http://www.captechconsulting.com) All Rights Reserved.
*
* 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 com.monarchapis.client.resource;
import java.lang.reflect.Type;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.monarchapis.client.rest.AsyncFuture;
import com.monarchapis.client.rest.BaseClient;
import com.monarchapis.client.rest.Callback;
import com.monarchapis.client.rest.RequestProcessor;
import com.monarchapis.client.rest.RestAsyncClient;
import com.monarchapis.client.rest.RestClient;
import com.monarchapis.client.rest.RestClientFactory;
import com.monarchapis.client.rest.RestException;
import com.monarchapis.client.rest.RestResponse;
public abstract class AbstractResource {
private static ObjectMapper MAPPER = getObjectMapper();
private String baseUrl;
private List requestSigners;
private RestClientFactory clientFactory;
public AbstractResource(String baseUrl, RestClientFactory clientFactory) {
this(baseUrl, clientFactory, null);
}
public AbstractResource(String baseUrl, RestClientFactory clientFactory, List requestSigners) {
baseUrl = StringUtils.removeEnd(baseUrl, "/");
if (StringUtils.isBlank(baseUrl)) {
throw new IllegalArgumentException("baseUrl must not be blank or null");
}
if (clientFactory == null) {
throw new IllegalArgumentException("clientFactory must not be null");
}
this.baseUrl = baseUrl;
this.clientFactory = clientFactory;
this.requestSigners = requestSigners;
}
public RestClient newClient(String method, String path) {
return clientFactory.create(method, getBaseUrl() + path);
}
public RestAsyncClient newAsyncClient(String method, String path) {
return clientFactory.createAsync(method, getBaseUrl() + path);
}
public String getBaseUrl() {
return baseUrl;
}
public void setRequestSigner(List requestSigners) {
this.requestSigners = requestSigners;
}
public List getRequestSigners() {
return requestSigners;
}
protected static void require(String argument, String message) {
if (StringUtils.isBlank(argument)) {
throw new IllegalArgumentException(message);
}
}
protected static void require(Object argument, String message) {
if (argument == null) {
throw new IllegalArgumentException(message);
}
}
protected String convert(String value) {
return value;
}
protected String convert(DateTime dateTime) {
return dateTime != null ? dateTime.toString() : null;
}
protected String convert(Object value) {
return value != null ? String.valueOf(value) : null;
}
protected String toJson(Object value) {
try {
return MAPPER.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RestException(e);
}
}
protected void signRequest(BaseClient> client) {
if (requestSigners != null) {
for (RequestProcessor requestSigner : requestSigners) {
requestSigner.processRequest(client);
}
}
}
protected T parseAs(RestResponse response, Class clazz) {
checkStatusCode(response);
return parseAs(response.getResponseBody(), clazz);
}
protected T parseAs(RestResponse response, TypeReference reference) {
checkStatusCode(response);
return parseAs(response.getResponseBody(), reference);
}
@SuppressWarnings("unchecked")
protected static T parseAs(String response, Class clazz) {
try {
if (clazz == Void.class) {
return (T) Void.TYPE;
}
return MAPPER.readValue(response, clazz);
} catch (Exception e) {
throw new RestException(e);
}
}
protected static T parseAs(String response, final TypeReference reference) {
try {
return MAPPER.readValue(response, new com.fasterxml.jackson.core.type.TypeReference() {
public Type getType() {
return reference.getType();
}
});
} catch (Exception e) {
throw new RestException(e);
}
}
protected void checkStatusCode(RestResponse response) {
if (response.getStatusCode() >= 400) {
throwErrorException(response);
}
}
protected abstract void throwErrorException(RestResponse response);
private static ObjectMapper getObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
mapper.registerModule(new GuavaModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
protected CallbackAdapter callbackAdapter(final AsyncFuture callback, Class clazz) {
return new CallbackAdapter(callback, clazz);
}
protected CallbackAdapter callbackAdapter(final AsyncFuture callback, TypeReference typeReference) {
return new CallbackAdapter(callback, typeReference);
}
protected static class CallbackAdapter implements Callback {
final private AsyncFuture callback;
final private Class clazz;
final private TypeReference typeReference;
public CallbackAdapter(AsyncFuture callback, Class clazz) {
this.callback = callback;
this.clazz = clazz;
this.typeReference = null;
}
public CallbackAdapter(AsyncFuture callback, TypeReference typeReference) {
this.callback = callback;
this.clazz = null;
this.typeReference = typeReference;
}
@Override
public void completed(RestResponse response) {
try {
T result;
if (clazz != null) {
result = parseAs(response.getResponseBody(), clazz);
} else {
result = parseAs(response.getResponseBody(), typeReference);
}
callback.completed(result);
} catch (Exception ex) {
callback.failed(ex);
}
}
@Override
public void failed(Exception ex) {
callback.failed(ex);
}
@Override
public void cancelled() {
callback.cancel(true);
}
}
}