How to make HTTPS call


#1

Hi,
I am new to camunda and have a requirement to call a HTTPS endpoint. I am getting the error as below:

SEVERE [http-nio-8080-exec-4] org.camunda.commons.logging.BaseLogger.logError ENGINE-16004 Exception while closing command context: HTCL-02007 Unable to execute HTTP request
org.camunda.connect.ConnectorRequestException: HTCL-02007 Unable to execute HTTP request
at org.camunda.connect.httpclient.impl.HttpConnectorLogger.unableToExecuteRequest(HttpConnectorLogger.java:48)
at org.camunda.connect.httpclient.impl.AbstractHttpConnector.execute(AbstractHttpConnector.java:72)
at org.camunda.connect.httpclient.impl.AbstractHttpConnector.execute(AbstractHttpConnector.java:38)
at org.camunda.connect.impl.AbstractConnectorRequest.execute(AbstractConnectorRequest.java:42)
at org.camunda.connect.plugin.impl.ServiceTaskConnectorActivityBehavior$1.call(ServiceTaskConnectorActivityBehavior.java:57)
at org.camunda.connect.plugin.impl.ServiceTaskConnectorActivityBehavior$1.call(ServiceTaskConnectorActivityBehavior.java:51)
at org.camunda.bpm.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior.executeWithErrorPropagation(AbstractBpmnActivityBehavior.java:108)


Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at connectjar.org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:275)
at connectjar.org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:254)
at connectjar.org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:117)
at connectjar.org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:314)
at connectjar.org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
at connectjar.org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
at connectjar.org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at connectjar.org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at connectjar.org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at connectjar.org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
at connectjar.org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at connectjar.org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at connectjar.org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at org.camunda.connect.httpclient.impl.HttpRequestInvocation.invokeTarget(HttpRequestInvocation.java:35)
at org.camunda.connect.impl.AbstractRequestInvocation.proceed(AbstractRequestInvocation.java:60)
at org.camunda.connect.httpclient.impl.AbstractHttpConnector.execute(AbstractHttpConnector.java:70)
… 122 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)

I have done the following steps. Please advise if anyone has any idea.

  1. In bpm file
    camunda:connector
    camunda:inputOutput
    <camunda:inputParameter name=“url”>https://<ACTUAL_SERVICE_ENDPOINT></camunda:inputParameter>
    <camunda:inputParameter name=“method”>POST</camunda:inputParameter>

2 Created a custom connectorconfigurator file named org.camunda.connect.spi.ConnectorConfigurator. It has the following content:
package org.camunda.connect.example;

import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.camunda.connect.httpclient.HttpConnector;
import org.camunda.connect.httpclient.impl.AbstractHttpConnector;
import org.camunda.connect.spi.ConnectorConfigurator;

public class HttpConnectorConfigurator implements ConnectorConfigurator {

public Class getConnectorClass() {
return HttpConnector.class;
}

public void configure(HttpConnector connector) {

TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}

    public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
        return;
    }

    public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
        return;
    }
}

};

SSLContext sc = null;
try {

sc = SSLContext.getInstance(“SSL”);
sc.init(null, trustAllCerts, new SecureRandom());
} catch (Exception e) {
throw new RuntimeException(“Could not change SSL TrustManager to accept arbitray certificates”, e);
}

HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {

  if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
      System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
  }
  return true;

}
};

CloseableHttpClient client = HttpClients.custom()
.setSSLContext(sc)
.setSSLHostnameVerifier(hv)
.build();
((AbstractHttpConnector) connector).setHttpClient(client);
}

}

  1. Put this file inside \webapps\engine-rest\WEB-INF\classes\META-INF\services

#2

Hi,

I have tried to implement https calls as well but havent manged to do that and had no time to invest more time to it so I have used my own service task for inspiration the below is class I have used for testing:

package https.test;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;

public class testHTTPS3 implements JavaDelegate {

	 public static void main(String[] args) throws IOException {
	        CloseableHttpClient client = testHTTPS3.createSSLInsecureClient();

	        CloseableHttpResponse res = client.execute(new HttpGet("https://account:pass@address"));
	        System.out.println(EntityUtils.toString(res.getEntity()));
	 }
	
	
	public  void execute(DelegateExecution execution) throws Exception {	
		
			String BPMNInput = (String) execution.getVariable("OskarEndpoint");			
	      
			try {
			CloseableHttpClient client = testHTTPS3.createSSLInsecureClient();

	        CloseableHttpResponse res = client.execute(new HttpGet(BPMNInput));
	        
	        //check HTTP response
	        if (res.getStatusLine().getStatusCode() != 200) {
				throw new org.camunda.bpm.engine.delegate.BpmnError("CustomError",res.getStatusLine().getReasonPhrase());
			}
	       
	        System.out.println(res.getStatusLine().getStatusCode()); 
	        System.out.println(EntityUtils.toString(res.getEntity()));
			} catch (IOException e) {
				System.out.println (e.toString());
		        System.out.println("Something is wrong [SEVERE] for the Endpoint: " + BPMNInput);
			}
	        
	 }
	 
	public static CloseableHttpClient createSSLInsecureClient() {
        SSLContext sslcontext = createSSLContext();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new HostnameVerifier() {

            @Override
            public boolean verify(String paramString, SSLSession paramSSLSession) {
                return true;
            }
        });
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        return httpclient;
    }


    private static SSLContext createSSLContext() {
        SSLContext sslcontext = null;
        try {
            sslcontext = SSLContext.getInstance("TLS");
            sslcontext.init(null, new TrustManager[] {new TrustAnyTrustManager()}, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslcontext;
    }


    private static class TrustAnyTrustManager implements X509TrustManager {

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    }
	}

#3

@sahaUser, please format code and log extracts as described here: How to format code blocks?


#4

Why does this issue linger?! I also need to call SSL and http-connector fails. How to resolve this so it works for all future https requests?

https://app.bic-boxtech.org/oauth/token

Andrew


#5

Take a look at the above. Use jsoup and can connect to your https


#6

Thanks for the tip. I’ll try anything once. Why is https so hard?


#7

http connector just seems to be fairly old implementation and does not get a lot of feature updates.

As another example, HTTP-connector does not support binrary data, so if you dealing with files, it would fail as the binary data is converted into a string Can HTTP-Connector Receive Binary Data?


#8

Stephen is right - connectors are not the primary way we suggest you communicate to external services so it’s not likely there will be many updates to it.
Instead we suggest you use the External Task Pattern in many ways it’s a much better choice.


#9

So connectors are being deprecated? Is there an end-of-life time frame?


#10

As a side note: there is nothing special about the http connector: it’s essentially a java delegate using local variables/input mappings, but it’s in a “connector” scope. You can recreate http connector with something like Jsoup, or just recreate a java delegate with very little effort.


#11

FWIW…I recently came across yet another HTTP request library - OkHttp. Its very easy to use and Ive found that PostMan can generate Java code using this framework. Building service tasks to an API is super quick!

regards

Rob


#12

Actually, I gave up on using a connector since it’s not sufficiently supported. I’ve created an external worker task, which is able to make the OAuth connection I need.

My current dilemma is that the external task data type of map does not seem to be supported. I get a crazy error:

^2019-04-25 15:29:47,395 [TopicSubscriptionManager] ERROR org.camunda.bpm.client - CAMUNDA_EXTERNAL_TASK_CLIENT-03005 Exception while deserializing variables 'org.camunda.bpm.client.impl.EngineClientException: CAMUNDA_EXTERNAL_TASK_CLIENT-02010 Exception while deserializing variable headers: value does not match to the type object'