org.camunda.bpm.client.impl.RequestExecutor Maven / Gradle / Ivy
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; 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 org.camunda.bpm.client.impl;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.AbstractResponseHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.camunda.bpm.client.exception.EngineException;
import org.camunda.bpm.client.exception.RestException;
import org.camunda.bpm.client.interceptor.impl.RequestInterceptorHandler;
import org.camunda.commons.utils.IoUtil;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author Tassilo Weidner
*/
public class RequestExecutor {
protected static final EngineClientLogger LOG = ExternalTaskClientLogger.ENGINE_CLIENT_LOGGER;
protected static final Header HEADER_CONTENT_TYPE_JSON = new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/json");
protected static final Header HEADER_USER_AGENT = new BasicHeader(HttpHeaders.USER_AGENT, "Camunda External Task Client");
protected HttpClient httpClient;
protected ObjectMapper objectMapper;
protected RequestExecutor(RequestInterceptorHandler requestInterceptorHandler, ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
initHttpClient(requestInterceptorHandler);
}
protected T postRequest(String resourceUrl, RequestDto requestDto, Class responseClass) {
ByteArrayEntity serializedRequest = serializeRequest(requestDto);
HttpUriRequest httpRequest = RequestBuilder.post(resourceUrl)
.addHeader(HEADER_USER_AGENT)
.addHeader(HEADER_CONTENT_TYPE_JSON)
.setEntity(serializedRequest)
.build();
return executeRequest(httpRequest, responseClass);
}
protected byte[] getRequest(String resourceUrl) {
HttpUriRequest httpRequest = RequestBuilder.get(resourceUrl)
.addHeader(HEADER_USER_AGENT)
.addHeader(HEADER_CONTENT_TYPE_JSON)
.build();
return executeRequest(httpRequest, byte[].class);
}
protected T executeRequest(HttpUriRequest httpRequest, Class responseClass) {
try {
return httpClient.execute(httpRequest, handleResponse(responseClass));
} catch (RestException e) { // catches >= 300 HTTP status responses
throw LOG.exceptionWhileReceivingResponse(httpRequest, e);
} catch (IOException e) { // connection was aborted
throw LOG.exceptionWhileEstablishingConnection(httpRequest, e);
}
}
protected ResponseHandler handleResponse(final Class responseClass) {
return new AbstractResponseHandler() {
@SuppressWarnings("unchecked")
public T handleEntity(HttpEntity responseEntity) throws IOException {
T response = null;
if (responseClass.isAssignableFrom(byte[].class)) {
InputStream inputStream = null;
try {
inputStream = responseEntity.getContent();
response = (T) IoUtil.inputStreamAsByteArray(inputStream);
} finally {
IoUtil.closeSilently(inputStream);
}
} else if (!responseClass.isAssignableFrom(Void.class)) {
response = deserializeResponse(responseEntity, responseClass);
}
try {
EntityUtils.consume(responseEntity);
}
catch (IOException e) {
LOG.exceptionWhileClosingResourceStream(response, e);
}
return response;
}
@Override
public T handleResponse(HttpResponse response) throws IOException {
final StatusLine statusLine = response.getStatusLine();
final HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
try {
RestException engineException = deserializeResponse(entity, EngineRestExceptionDto.class).toRestException();
int statusCode = statusLine.getStatusCode();
engineException.setHttpStatusCode(statusCode);
throw engineException;
} finally {
EntityUtils.consume(entity);
}
}
return entity == null ? null : handleEntity(entity);
}
};
}
protected T deserializeResponse(HttpEntity httpEntity, Class responseClass) {
InputStream inputStream = null;
try {
inputStream = httpEntity.getContent();
return objectMapper.readValue(inputStream, responseClass);
} catch (JsonParseException e) {
throw LOG.exceptionWhileParsingJsonObject(responseClass, e);
} catch (JsonMappingException e) {
throw LOG.exceptionWhileMappingJsonObject(responseClass, e);
} catch (IOException e) {
throw LOG.exceptionWhileDeserializingJsonObject(responseClass, e);
} finally {
IoUtil.closeSilently(inputStream);
}
}
protected ByteArrayEntity serializeRequest(RequestDto dto) {
byte[] serializedRequest = null;
try {
serializedRequest = objectMapper.writeValueAsBytes(dto);
} catch (JsonProcessingException e) {
throw LOG.exceptionWhileSerializingJsonObject(dto, e);
}
ByteArrayEntity byteArrayEntity = null;
if (serializedRequest != null) {
byteArrayEntity = new ByteArrayEntity(serializedRequest);
}
return byteArrayEntity;
}
protected void initHttpClient(RequestInterceptorHandler requestInterceptorHandler) {
HttpClientBuilder httpClientBuilder = HttpClients.custom()
.useSystemProperties()
.addInterceptorLast(requestInterceptorHandler);
this.httpClient = httpClientBuilder.build();
}
}