
org.jbpm.process.longrest.RemoteInvoker Maven / Gradle / Ivy
/*
* Copyright 2021 Red Hat, Inc. and/or its affiliates.
*
* 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 org.jbpm.process.longrest;
import java.io.IOException;
import java.net.HttpCookie;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import main.java.org.jbpm.process.longrest.authentication.OidcClient;
import org.apache.commons.text.StringSubstitutor;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.jbpm.process.longrest.util.Mapper;
import org.jbpm.process.longrest.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.jbpm.process.longrest.Constant.CONTAINER_ID_VARIABLE;
import static org.jbpm.process.longrest.Constant.PROCESS_INSTANCE_ID_VARIABLE;
/**
* @author Matej Lazar
*/
public class RemoteInvoker {
private static final Logger logger = LoggerFactory.getLogger(RemoteInvoker.class);
private final long processInstanceId;
private final String containerId;
private final HttpClient httpClient;
private final boolean authTokenRequired;
public RemoteInvoker(
String containerId,
long processInstanceId,
int socketTimeout,
int connectTimeout,
int connectionRequestTimeout,
boolean authTokenRequired) {
this.containerId = containerId;
this.processInstanceId = processInstanceId;
this.authTokenRequired = authTokenRequired;
RequestConfig config = RequestConfig.custom()
.setSocketTimeout(socketTimeout)
.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout)
.build();
HttpClientBuilder clientBuilder = HttpClientBuilder.create()
.setDefaultRequestConfig(config);
httpClient = clientBuilder.build();
}
public RemoteInvocationResult invoke(
String httpMethod,
String requestUrl,
String requestTemplate,
String cancelUrlJsonPointer,
String cancelUrlTemplate,
String requestHeaders,
Map cookies) throws RemoteInvocationException, ResponseProcessingException {
logger.trace("requestTemplate: {}", requestTemplate);
Map variables = new HashMap<>();
variables.put(PROCESS_INSTANCE_ID_VARIABLE, processInstanceId);
variables.put(CONTAINER_ID_VARIABLE, containerId);
StringSubstitutor sub = new StringSubstitutor(variables, "$(", ")");
String requestBodyEvaluated;
if (requestTemplate != null && !requestTemplate.isEmpty()) {
requestBodyEvaluated = sub.replace(requestTemplate);
} else {
requestBodyEvaluated = "";
}
Map requestHeadersMap = new HashMap<>();
// Add cookies to the request
if (cookies != null) {
String cookieHeader = cookies.entrySet().stream()
.map(c -> c.getKey() + "=" + c.getValue())
.collect(Collectors.joining("; "));
requestHeadersMap.put("Cookie", cookieHeader);
}
requestHeadersMap.putAll(Strings.toMap(requestHeaders));
if (authTokenRequired) {
requestHeadersMap.put(HttpHeaders.AUTHORIZATION, "Bearer " + OidcClient.getAccessToken());
}
HttpResponse httpResponse = httpRequest(
httpMethod,
requestUrl,
requestBodyEvaluated,
requestHeadersMap);
int statusCode = httpResponse.getStatusLine().getStatusCode();
logger.info("Remote endpoint returned status: {}.", statusCode);
Map responseCookies = getCookies(httpResponse);
HttpEntity responseEntity = httpResponse.getEntity();
if (responseEntity == null || responseEntity.getContentLength() == 0L) {
if (statusCode >= 200 && statusCode < 300) {
//there is no content and the status is success
return new RemoteInvocationResult(statusCode, responseCookies, Collections.emptyMap(), "", null);
} else {
logger.warn("Remote service responded with error status code {} and reason: {}. ProcessInstanceId {}.", statusCode, httpResponse.getStatusLine().getReasonPhrase(), processInstanceId);
return new RemoteInvocationResult(statusCode, responseCookies, Collections.emptyMap(), "", new FailedResponseException(httpResponse.getStatusLine().getReasonPhrase(), statusCode));
}
} else {
//process entity body
String responseString;
try {
responseString = EntityUtils.toString(responseEntity, "UTF-8");
logger.debug("Invocation response: {}", responseString);
} catch (IOException e) {
throw new ResponseProcessingException("Cannot read remote entity.", e);
}
JsonNode root;
Map serviceResponse;
try {
root = Mapper.getInstance().readTree(responseString);
if (JsonNodeType.ARRAY.equals(root.getNodeType())) {
//convert array to indexed map
serviceResponse = new LinkedHashMap<>();
Object[] array = Mapper.getInstance().convertValue(root, new TypeReference
© 2015 - 2025 Weber Informatics LLC | Privacy Policy