K8s Deployment Sample 3: JMS Sender/Receiver¶
Let's define a JMS (sender and receiver) scenario using WSO2 Micro Integrator and deploy it on your Kubernetes environment.
Prerequisites¶
-
Install and set up WSO2 Integration Studio.
Tip
Be sure to get the latest updates before trying this example.
-
Install a Kubernetes cluster and v1.11+ client. Alternatively, you can run Kubernetes locally via Minikube.
- Install Docker.
-
Install the EI Kubernetes operator.
-
Deploy an ActiveMQ pod inside your Kubernetes cluster.
Step 1: Create the integration solution¶
Follow the steps given below.
-
Create a Maven Multi Module project using WSO2 Integration Studio.
-
Create an ESB Config Project inside the Maven Multi Module project:
Right-click the Maven Multi Module project in the project explorer, go to New → Project, and select ESB Config Project to open the New ESB Config Project dialog.
-
Add the following proxy service configuration to your ESB Config Project. This service listens to messages from ActiveMQ and publishes to another queue in ActiveMQ.
-
Right-click the ESB Config project in the project explorer, go to New -> Proxy Service and create a custom proxy service named
JmsSenderListener
. -
You can then use the Source View to copy the following configuration.
Tip
Be sure to update the tcp://localhost:61616 URL given below with the actual/connecting URL that will be reachable from the Kubernetes pod.
<?xml version="1.0" encoding="UTF-8"?> <proxy name="JmsSenderListener" startOnLoad="true" transports="jms" xmlns="http://ws.apache.org/ns/synapse"> <target> <inSequence> <send> <endpoint> <address uri="jms:/secondQueue?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=failover:(tcp://localhost:61616,tcp://localhost:61617)?randomize=false&transport.jms.DestinationType=queue"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </address> </endpoint> </send> </inSequence> <outSequence/> <faultSequence/> </target> <parameter name="transport.jms.SessionAcknowledgement">AUTO_ACKNOWLEDGE</parameter> <parameter name="transport.jms.Destination">$SYSTEM:destination</parameter> <parameter name="transport.jms.ConnectionFactoryType">firstQueue</parameter> <parameter name="transport.jms.ContentType">$SYSTEM:contenttype</parameter> <parameter name="java.naming.provider.url">$SYSTEM:jmsurl</parameter> <parameter name="transport.jms.SessionTransacted">false</parameter> <parameter name="transport.jms.ConnectionFactoryJNDIName">$SYSTEM:jmsconfac</parameter> <parameter name="transport.jms.UserName">$SYSTEM:jmsuname</parameter> <parameter name="transport.jms.Password">$SYSTEM:jmspass</parameter> </proxy>
-
-
Create a Composite Application Project with the above proxy service inside the Maven Multi Module project.
- Right-click the maven multi modiule project, go to New → Project, select Composite Application Project, and click Next.
-
Be sure to select the proxy service under Dependencies as shown below.
-
Click Finish.
-
Create a Kubernetes Project inside the Maven Multi Module Project.
-
Right-click the Maven Multi Module project, go to New → Project, select Kubernetes Exporter Project, and click Next.
-
In the Kubernetes Project Information dialog that opens, enter the following details:
Parameter Description Kubernetes Project Name Give a unique name for the project. Integration Name This name will be used to identify the integration solution in the kubernetes custom resource. Let's use jms-example
as the integration name for this example.Number of Replicas Specify the number of pods that should be created in the kubernetes cluster. Base Image Repository Specify the base Micro Integrator Docker image for your solution. For this example, let's use the Micro Integrator docker image from the WSO2 public docker registry: wso2/wso2mi. Note that the image value format should be 'docker_user_name/repository_name'. Base Image Tag Give a tag name for the base Docker image. Target Image Repository The Docker repository to which the Docker image will be pushed: 'docker_user_name/repository_name'. Target Image Tag Give a tag name for the Docker image. -
This step is only required if you already have a Docker image (in your local Docker repository) with the same name as the base image specified above.
Info
In this scenario, WSO2 Integration Studio will first check if there is a difference in the two images before pulling the image specified in the Base Image Repository field. If the given base image is more updated, the existing image will be overwritten by this new image. Therefore, if you are currently using an older version, or if you have custom changes in your existing image, they will be replaced.
To avoid your existing custom/older images from being replaced, add the following property under dockerfile-maven-plugin -> executions -> execution -> configurations in the
pom.xml
file of your Kubernetes Exporter project. This configuration will ensure that the base image will not be pulled when a Docker image already exists with the same name.<pullNewerImage>false</pullNewerImage>
-
Open the integration_cr.yaml file inside the Kubernetes project and add the environment variables as shown below. These values will be injected to the parameters defined in the proxy service.
Tip
Be sure to update the tcp://localhost:61616 URL in the above configuration with the actual/connecting URL that will be reachable from the Kubernetes pod.
--- apiVersion: "integration.wso2.com/v1alpha1" kind: "Integration" metadata: name: "jms" spec: replicas: 1 image: "Docker/image/path/to/the/JMSSenderListner" port: 8290 env: - name: "jmsconfac" value: "TopicConnectionFactory" - name: "jmsuname" value: "admin" - name: "destination" value: "queue" - name: "jmsurl" value: "tcp://localhost:61616" - name: "jmspass" value: "admin" - name: "contenttype" value: "application/xml"
-
Finally, the created Maven Multi Module project should look as follows:
Step 2: Update JMS configurations¶
- Uncomment the following two commands in the Dockerfile inside the Kubernetes project.
COPY Libs/*.jar $WSO2_SERVER_HOME/lib/ COPY Conf/* $WSO2_SERVER_HOME/conf/
- Download Apache ActiveMQ.
-
Copy the following client libraries from the
<ACTIVEMQ_HOME>/lib
directory to the<MAVEN_MULTI_MODULE>/<KUBERNETES_PROJECT>/Lib
directory.ActiveMQ 5.8.0 and above
- activemq-broker-5.8.0.jar
- activemq-client-5.8.0.jar
- activemq-kahadb-store-5.8.0.jar
- geronimo-jms_1.1_spec-1.1.1.jar
- geronimo-j2ee-management_1.1_spec-1.0.1.jar
- geronimo-jta_1.0.1B_spec-1.0.1.jar
- hawtbuf-1.9.jar
- Slf4j-api-1.6.6.jar
- activeio-core-3.1.4.jar (available in the
/lib/optional directory)
Earlier version of ActiveMQ
- activemq-core-5.5.1.jar
- geronimo-j2ee-management_1.0_spec-1.0.jar
- geronimo-jms_1.1_spec-1.1.1.jar
-
Open the
deployment.toml
file in your Kubernetes project and add the following content to enable the JMS sender and listener:Tip
Be sure to update the tcp://localhost:61616 URL in the above configuration with the actual/connecting URL that will be reachable from the Kubernetes pod.
[server] hostname = "localhost" [keystore.tls] file_name = "wso2carbon.jks" password = "wso2carbon" alias = "wso2carbon" key_password = "wso2carbon" [truststore] file_name = "client-truststore.jks" password = "wso2carbon" alias = "symmetric.key.value" algorithm = "AES" [[transport.jms.listener]] name = "default" parameter.initial_naming_factory = "org.apache.activemq.jndi.ActiveMQInitialContextFactory" parameter.provider_url = "tcp://localhost:61616" parameter.connection_factory_name = "QueueConnectionFactory" parameter.connection_factory_type = "queue" [[custom_transport.sender]] protocol = "jms" class="org.apache.axis2.transport.jms.JMSSender"
Step 3: Package and build the solution¶
You need to build a Docker image of the integration solution and push it to your Docker registry.
- Start the Docker daemon in the host machine.
- Open the pom.xml file in the Kubernetes project and ensure that the composite application is selected under Dependencies.
- Leave the Automatically deploy configurations check box selected. This ensures that deployment configurations are automatically deployed to the base image.
-
Click Build and Push. In the dialog that opens, enter the credentials of your Docker registry to which the image should be pushed.
Info
Alternatively, you can build the Docker image and push it to the Docker registry as follows:
- Navigate to the Maven Multi Module project and run the following command to build the project. It will create a docker image with the provided target repository and tag once the build is successfull.
mvn clean install -Dmaven.test.skip=true
- Navigate to the Kubernetes project inside the MavenParentProject and run the following command to push the docker image to the remote docker registry.
mvn dockerfile:push -Ddockerfile.username={username} -Ddockerfile.password={password}
- Navigate to the Maven Multi Module project and run the following command to build the project. It will create a docker image with the provided target repository and tag once the build is successfull.
-
Run the
docker image ls
command to verify that the Docker image is created.
Step 4: Deploy the solution in K8s¶
Info
Before you begin, be sure that the system requrements are in place, and that the EI Kubernetes Operator is installed.
Follow the steps given below:
- Open the
integration_cr.yaml
file from the Kubernetes project in WSO2 Integration Studio. - See that the integration details of the
jms-example
solution is updated. - Open a terminal, navigate to the location of your
integration_cr.yaml
file, and execute the following command to deploy the integration solution into the Kubernetes cluster:kubectl apply -f integration_cr.yaml
When the integration is successfully deployed, it should create the hello-world
integration, jms-example-deployment
, jms-example-service
, and ei-operator-ingress
as follows:
Tip
The ei-operator-ingress
will not be created if you have disabled the ingress controller.
kubectl get integration
NAME STATUS SERVICE-NAME AGE
jms-example Running hello-service 2m
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
jms-example-deployment 1/1 1 1 2m
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jms-example-service ClusterIP 10.101.107.154 <none> 8290/TCP 2m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d
k8s-ei-operator ClusterIP 10.98.78.238 <none> 443/TCP 1d
kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ei-operator-ingress wso2ei 10.0.2.15 80, 443 2m
This will create a new queue called queue in ActiveMQ.
Step 5: Test the deployment¶
Send a message to this queue. The proxy service you added in step 3 above will listen to this message and send that message to a new queue called secondQueue.
Top