Enabling SAP Transport in Micro Integrator Docker Image

This post is intended to show how we can enable SAP transport in WSO2 Micro Integrator Docker Image 6.5.0. Some of the steps here can be skipped if you are not running it using the Docker image provided by WSO2.

In order to enable SAP Transport in WSO2 EI 6.5.0 we can follow the instructions here, that basically in a high level are:

TL;DR

If you don’t want to read the full post, follow the final Dockerfile created for that:

FROM wso2/micro-integrator:1.0.0
MAINTAINER Francisco Ribeiro "fjunior87@gmail.com"

#Copying the required libraries to the installation
COPY lib/*.jar /home/wso2carbon/wso2mi/lib/
COPY lib/libsapjco3.so /opt/java/openjdk/lib/amd64/
#COPY the Sap transport jar files
COPY components/*.jar /home/wso2carbon/wso2mi/dropins/

#Axis2 Config Enabling SAPTransport
COPY conf/axis2/axis2.xml /home/wso2carbon/wso2mi/conf/axis2/axis2.xml
#SAP Client Config
COPY conf/sap/*.dest /home/wso2carbon/wso2mi/conf/sap/

#Sample Proxy Service
COPY proxy-service/*.xml /home/wso2carbon/wso2mi/repository/deployment/server/synapse-configs/default/proxy-services/

#Switching to root to install the required libraries for sapjco
USER root
RUN apk add libuuid

#Create required symlinks
RUN ln -s /usr/lib/libfontconfig.so.1 /usr/lib/libfontconfig.so && \
    ln -s /lib/libuuid.so.1 /usr/lib/libuuid.so.1 && \
    ln -s /lib/libc.musl-x86_64.so.1 /usr/lib/libc.musl-x86_64.so.1
#Export the LD_LIBRARY_PATH variable
ENV LD_LIBRARY_PATH /usr/lib
#Switch back to the wso2carbon user
USER wso2carbon

Basic Dockerfile with the Documentation instructions

Below we can see a basic example of a Dockerfile(post.Dockerfile) containing the steps given in the above section:

FROM wso2/micro-integrator:1.0.0
MAINTAINER Francisco Ribeiro "fjunior87@gmail.com"

#Copying the required libraries to the installation
COPY lib/*.jar /home/wso2carbon/wso2mi/lib/
COPY lib/libsapjco3.so /opt/java/openjdk/lib/amd64/

#Axis2 Config Enabling SAPTransport
COPY conf/axis2/axis2.xml /home/wso2carbon/wso2mi/conf/axis2/axis2.xml
#SAP Client Config
COPY conf/sap/*.dest /home/wso2carbon/wso2mi/conf/sap/
#Sample Proxy Service
COPY proxy-service/*.xml /home/wso2carbon/wso2mi/repository/deployment/server/synapse-configs/default/proxy-services/

We can now build the image using the command below:

docker build -t fjunior87/wso2mi-sap:1.0.0 -f post.Dockerfile .

And then run a container using the image we just created:

docker run -it -p 8290:8290 fjunior87/wso2mi-sap:1.0.0

When running that, we will see an error like below:

Caused by: java.lang.ClassNotFoundException: org.wso2.carbon.transports.sap.SAPTransportSender cannot be found by axis2_1.6.1.wso2v35
        at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
        at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at org.apache.axis2.util.Loader.loadClass(Loader.java:261)
        at org.apache.axis2.deployment.AxisConfigBuilder.processTransportSenders(AxisConfigBuilder.java:686)
        ... 43 more

This is happening because WSO2 Micro Integrator is not shipped with the SAP Transport jar file, so, we we need to add it. We can get it from the following maven repository link:

https://repo1.maven.org/maven2/org/wso2/carbon/mediation/org.wso2.carbon.transports.sap/4.6.151/org.wso2.carbon.transports.sap-4.6.151.jar

We need to put this jar into the EI_HOME/dropins folder. In order to do that, I have downloaded the jar file and placed it into a folder components that will be referenced by the Dockerfile and added the follow instruction to the Dockerfile:

#COPY the Sap transport jar files
COPY components/*.jar /home/wso2carbon/wso2mi/dropins/

After that, we can rebuild the image and try to run again using the commands provided previously. Now we see a different error:

[2019-10-18 05:40:36,484] [micro-integrator] FATAL - ServiceComponent WSO2 Carbon initialization Failed
java.lang.ExceptionInInitializerError: JCo initialization failed with java.lang.UnsatisfiedLinkError: /opt/java/openjdk/lib/amd64/libsapjco3.so: libuuid.so.1: cannot open shared object file: No such file or directory
        at com.sap.conn.jco.rt.MiddlewareJavaRfc.<clinit>(MiddlewareJavaRfc.java:230)
        at com.sap.conn.jco.rt.DefaultJCoRuntime.initialize(DefaultJCoRuntime.java:98)
        at com.sap.conn.jco.rt.JCoRuntimeFactory.<clinit>(JCoRuntimeFactory.java:23)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at com.sap.conn.jco.JCo.createJCo(JCo.java:52)
        at com.sap.conn.jco.JCo.<clinit>(JCo.java:26)
        at java.lang.Class.forName0(Native Method)

This is happening because the libsapjco3.so requires some other libraries that are not present by default in the Alpine Linux, that is the distro used by the WSO2 Micro Integrator Docker Image. To solve that, we need to install the libuuid, create some Symlinks and also set the LD_LIBRARY_PATH environment variable.

We can install the libuuid using the apk command, but for that we need to be root, so to do that, we will add the following commands to our Dockerfile:

#Switching to root to install the required libraries for sapjco
USER root
RUN apk add libuuid

#Create required symlinks
RUN ln -s /usr/lib/libfontconfig.so.1 /usr/lib/libfontconfig.so && \
    ln -s /lib/libuuid.so.1 /usr/lib/libuuid.so.1 && \
    ln -s /lib/libc.musl-x86_64.so.1 /usr/lib/libc.musl-x86_64.so.1
#Export the LD_LIBRARY_PATH variable
ENV LD_LIBRARY_PATH /usr/lib
#Switch back to the wso2carbon user
USER wso2carbon

If you are running micro integrator in another Linux distribution you probably could skip the steps above.

With those instructions added we can rebuild and run our new container. If everything worked as expected we should see no errors in the logs and also some logs like these below:

[2019-10-18 05:48:20,249] [micro-integrator]  INFO - SAPTransportSender BAPI Sender started
[2019-10-18 05:48:20,462] [micro-integrator]  INFO - SAPTransportSender IDOC Sender started
...
...
[2019-10-18 05:48:22,851] [micro-integrator]  INFO - SAPTransportListener BAPI listener started
[2019-10-18 05:48:22,874] [micro-integrator]  INFO - PassThroughListeningIOReactorManager Pass-through HTTP Listener started on 0.0.0.0:8290
[2019-10-18 05:48:22,879] [micro-integrator]  INFO - PassThroughListeningIOReactorManager Pass-through HTTPS Listener started on 0.0.0.0:8253
[2019-10-18 05:48:22,879] [micro-integrator]  INFO - SAPTransportListener IDOC listener started

The final Dockerfile can be seen here:

FROM wso2/micro-integrator:1.0.0
MAINTAINER Francisco Ribeiro "fjunior87@gmail.com"

#Copying the required libraries to the installation
COPY lib/*.jar /home/wso2carbon/wso2mi/lib/
COPY lib/libsapjco3.so /opt/java/openjdk/lib/amd64/
#COPY the Sap transport jar files
COPY components/*.jar /home/wso2carbon/wso2mi/dropins/

#Axis2 Config Enabling SAPTransport
COPY conf/axis2/axis2.xml /home/wso2carbon/wso2mi/conf/axis2/axis2.xml
#SAP Client Config
COPY conf/sap/*.dest /home/wso2carbon/wso2mi/conf/sap/

#Sample Proxy Service
COPY proxy-service/*.xml /home/wso2carbon/wso2mi/repository/deployment/server/synapse-configs/default/proxy-services/

#Switching to root to install the required libraries for sapjco
USER root
RUN apk add libuuid

#Create required symlinks
RUN ln -s /usr/lib/libfontconfig.so.1 /usr/lib/libfontconfig.so && \
    ln -s /lib/libuuid.so.1 /usr/lib/libuuid.so.1 && \
    ln -s /lib/libc.musl-x86_64.so.1 /usr/lib/libc.musl-x86_64.so.1
#Export the LD_LIBRARY_PATH variable
ENV LD_LIBRARY_PATH /usr/lib
#Switch back to the wso2carbon user
USER wso2carbon

Now, you can use your micro integrator along with SAP Transport :)

PS: I created this Dockerfile for some POCs, please review it and add any additional required steps for using it in production.

See you in the next post ;)

comments powered by Disqus