Introduction
Integrating applications with event brokers is a common requirement in modern integration projects. In this article, we’ll walk through how to connect WSO2 Micro Integrator 4.5.0 with Solace PubSub+ Event Broker and exchange messages using JMS 2.0.
The goal is to show how WSO2 Micro Integrator can publish messages to Solace and consume messages from it. We’ll also look at what happens behind the scenes when a message travels from WSO2 MI to the Solace broker.
At a high level, WSO2 Micro Integrator communicates through the JMS 2.0 API. The Solace JMS provider implements this API and internally uses JCSMP, Solace’s native Java API. JCSMP then converts the message into SMF, Solace’s wire protocol, before the broker receives, processes, and routes it.
This guide is practical and implementation-focused. We’ll start by running a local Solace broker for development, then configure both Solace and WSO2 Micro Integrator for publishing and consuming messages.
In this article, we’ll cover:
- Setting up Solace PubSub+ Event Broker for development
- Understanding the message flow from WSO2 Micro Integrator to Solace
- Configuring Solace PubSub+ through the management console
- Setting up WSO2 Micro Integrator as a message publisher
- Setting up WSO2 Micro Integrator as a message consumer
Before we move into the use cases, we’ll first start a Solace broker instance and configure it for development. This gives us a working environment that we can use throughout the rest of the article.
1. Setting up the Solace Broker
The easiest way to start a Solace instance for development is by using the Docker image. Simply run the command below, and it will spin up an instance. In this article, I’m using the Mac version.
docker run -d \
--name=solace \
-p 8080:8080 \ # PubSub+ Console (Web UI)
-p 55554:55555 \ # SMF (Solace Message Format)
-p 55443:55443 \ # SMFs (SMF over TLS)
-p 8008:8008 \ # REST
-p 1883:1883 \ # MQTT
-p 5672:5672 \ # AMQP
-p 9000:9000 \ # REST (Web Transport)
-p 2222:2222 \ # CLI (SSH)
--shm-size=2g \ # Shared memory for message spool
--env username_admin_globalaccesslevel=admin \
--env username_admin_password=admin \
--restart=unless-stopped \
solace/solace-pubsub-standard:latest
docker run -d --name=solace -p 8080:8080 -p 55554:55555 -p 55443:55443 -p 8008:8008 -p 1883:1883 -p 5672:5672 -p 9000:9000 -p 2223:2222 --shm-size=2g --env username_admin_globalaccesslevel=admin --env username_admin_password=admin --restart=unless-stopped solace/solace-pubsub-standard:latest On a successful startup, you can view the container status using Docker Desktop.
Figure-01: Docker Desktop Container Status
More details on the port information can be found in the Solace documentation. The table below is extracted from the official documentation for the Software Broker. For other types of brokers, the ports are different. Refer to it here: Default Port Numbers
| Port | Service Description | Type of Traffic |
| 2222 | Solace Event Broker CLI (SSH/SFTP) | Management |
| 8080 | Access to Broker Manager, SEMP, and SolAdmin | Management |
| 1943 | Broker Manager (HTTPS), SEMP over TLS, SolAdmin over TLS | Management |
| 5550 | Health Check Listen Port | Data |
| 5553 | Health Check Listen Port (TLS) | Data |
| 55555 | Solace Message Format (SMF) | Data |
| 55003 | SMF Compressed | Data |
| 55556 | SMF Routing | Data |
| 55443 | SMF TLS / SSL (with or without compression) | Data |
| 8008 | Web Transport (WebSockets, Comet, etc.) | Data |
| 1443 | Web Transport TLS / SSL | Data |
| 5671 | AMQP TLS / SSL (default VPN; unique ports needed per VPN) | Data |
| 5672 | AMQP (default VPN; unique ports needed per VPN) | Data |
| 1883 | MQTT (default VPN; unique ports needed per VPN) | Data |
| 8883 | MQTT TLS / SSL (default VPN; unique ports needed per VPN) | Data |
| 8000 | MQTT over WebSockets (default VPN; unique ports needed per VPN) | Data |
| 8443 | MQTT over WebSockets TLS / SSL (default VPN; unique ports needed per VPN) | Data |
| 9000 | REST (default VPN; unique ports needed per VPN) | Data |
| 9443 | REST TLS / SSL (default VPN; unique ports needed per VPN) | Data |
| 8741 | High-Availability (HA) Mate Link | HA |
| 8300 | HA Configuration Synchronization | HA |
| 8301 | HA Configuration Synchronization | HA |
| 8302 | HA Configuration Synchronization | HA |
By using http://localhost:8080/, you can log in to the Solace Console with admin/admin as the username and password.
Figure-02: Solace Console
2. How the Message Flow Works in the Solace Broker
Before starting the implementation, it’s important to understand how the message flow works between WSO2 Micro Integrator and Solace, as this will help us configure it correctly.
Figure-2.1: Message Flow
- The flow is initiated through the Axis2 JMS Transport in WSO2 Micro Integrator.
- WSO2 Micro Integrator is exposed via the standard Java JMS 2.0 interface.
- Solace JMS implements the javax.jms interfaces using Solace-specific logic, translating JMS operations into JCSMP calls.
- Solace JCSMP handles the underlying network communication, including managing TCP connections, using the SMF (Solace Message Format) protocol, and supporting reconnection, flow control, as well as message encoding and decoding.
- Once the message reaches the Solace Broker, TLS termination happens first at the SMF Listener.
- After TLS termination, message routing happens based on the Message VPN that comes with the username (console-vp-username@console-vpn) or a separate parameter from JMS.
parameter.Solace_JMS_VPN = "console-vpn" - Authentication is performed based on the configured method, such as Basic Authentication, Client Certificate, OAuth 2.0, or Kerberos.
- Once authenticated, the Client Profile associated with the username is applied to determine the permitted operations, such as sending or receiving messages.
- The ACL (Access Control List) profile is then used to define which topics or queues the client is authorized to access.
- Additionally, since JMS JNDI is being used, the required JNDI objects must be created to enable clients to perform lookups and connect to the appropriate topics or queues.
3. Configuring Solace through the Console
3.1 Create the Message VPN
- Log in to http://localhost:8080 with admin / admin
- Click Message VPNs in the left navigator
- Click + Create Message VPN
Figure-03: Create Message VPN
On the next screen, you’ll see a default user configuration. When a Message VPN is created in Solace, it automatically includes a built-in client username called default within that VPN. During the creation process, the console asks you to set a password for this user. If a client connects to the VPN using a username that doesn’t match any explicitly configured client usernames, Solace will automatically fall back to this default user.
Figure-04: Create Default User Configuration
Figure-05: View after successful Message VPN creation
3.2 Create the Client Profile
The Client Profile defines what the client can do (send, receive, guaranteed messaging, etc.).
- Navigate to console-vpn -> Access Control -> Client Profiles
- Click + Create Client Profile
Figure-06: Creating the Client Profile
Figure-07: Enabling Needed Configurations
Figure-08: Successful Creation
3.3 Create the ACL Profile
The ACL Profile controls where the client can publish and subscribe (topic/queue-level access).
Figure-09: Create ACL Profile
Figure-10: Allow ACL Profiles
By default, the action is set to Disallow. In a production environment, you would typically keep this setting as Disallow and explicitly add exceptions to allow specific access. For this guide, however, we’ll leave it open.
Double-click the Disallow option, and it will enable the drop-down so you can change it to Allow.
Here, Client Connect, Publish Topic, and Subscribe Topic have been allowed.
3.4 Create the Client Username (Basic Authentication)
Figure-11: Adding Client Username
Figure-12: Adding Client Username
Figure-13: Adding Client Username
3.5 Create the Queue for Guaranteed Messaging and Add It to a Topic Subscription
Figure-14: Creating the Queue for Guaranteed Delivery
Figure-15: Created Queue
Now we need to add the topic subscription.
Figure-16: Adding Topic Subscription
Figure-17: Added Subscription
3.6 Create the JNDI Objects
Even though we are using the Solace libraries for the connection setup, what happens under the hood is:
WSO2 -> JMS 2.0 API -> Solace JMS Implementation -> Solace JCSMP Implementation -> Solace Broker.
Since WSO2 uses the JMS API, and the JMS API obtains ConnectionFactory and Destination objects through JNDI lookups, JNDI objects are needed on the broker.
3.6.1 Enable JNDI on the Message VPN
- Navigate to console-vpn -> Settings
- Under JNDI, enable JNDI Enabled
- Click Apply
Figure-18: Enable JNDI
3.6.2 Create a JNDI Connection Factory
- Navigate to console-vpn -> JNDI -> Connection Factories
- Click + Create Connection Factory
- Set:
- Name: /jndi/cf/console-connection-factory
- Messaging Properties:
- Publisher Messages Delivery Mode: Persistent (for guaranteed) or Non-Persistent (for direct)
- Transport: SMF
- Click Create
Figure-19: Adding JNDI Connection Factory
Figure-20: Adding JNDI Connection Factory
3.6.3 Create a JNDI Queue Object
- Navigate to console-vpn -> JNDI -> Queues
- Click + Create Queue
- Set:
- JNDI Name: /jndi/queue/console-queue
- Physical Name: console-queue
- Click Create
Figure-21: Adding JNDI Queue
Figure-22: Adding JNDI Queue
Figure-23: Adding JNDI Queue
3.6.4 Create a JNDI for the Physical Topic
Figure-24: Physical Topic
Figure-25: Physical Topic
A summary of what we have done so far is depicted in the flow diagram below.
Figure-26: Implementation Summary
4. Publisher Implementation
Now we can set up WSO2 Micro Integrator to publish to a topic and consume it from the queue.
4.1 Download the Required JARs
Download the JARs below, which we need to add to MI_HOME/lib:
- sol-jcsmp-10.22.0.jar
- sol-jms-10.22.0.jar
Note that version 10.23 onwards does not work with WSO2 due to the Netty dependencies. Because of that, this guide uses the latest version that supports WSO2 MI 4.5.0.
4.2 Configure deployment.toml for the Sender
[[transport.jms.sender]]
name = "solaceTopicSender"
parameter.initial_naming_factory = "com.solacesystems.jndi.SolJNDIInitialContextFactory"
parameter.provider_url = "smf://console-vpn-username:batticaloa@localhost:55554"
parameter.connection_factory_name = "/jndi/cf/console-connection-factory"
parameter.connection_factory_type = "topic"
parameter.Solace_JMS_VPN = "console-vpn"4.3 Create a CAR File with an API to Publish Messages to the Topic
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse" name="SolacePublisherAPI" context="/solace">
<resource methods="POST" uri-template="/publish">
<inSequence>
<!-- 1. Message Received at API -->
<log level="full">
<property name="MESSAGE" value="Received request to publish to Solace"/>
</log>
<!-- 2. Set the properties out only and force sc accpeted to send back 202 -->
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="OUT_ONLY" value="true"/>
<!-- 3. Send to Solace topic via JMS -->
<send>
<endpoint>
<address uri="jms:/console-vpn-sub/messages/order?transport.jms.ConnectionFactory=solaceTopicSender&transport.jms.DestinationType=topic"/>
</endpoint>
</send>
</inSequence>
</resource>
</api>4.4 Send an API Call
curl --request POST \
--url http://localhost:8290/solace/publish \
--header 'Content-Type: application/json' \
--data '{"Name":"Test 3"}'4.5 Check the Messages at the Solace Broker Console
Figure-27: Message Queued
That’s it; we are done with the Message Sender implementation. Now we can move to the consumer implementation.
5. Consumer Implementation
5.1 Configure deployment.toml for the Consumer
[[transport.jms.listener]]
name = "solaceQueueListener"
parameter.initial_naming_factory = "com.solacesystems.jndi.SolJNDIInitialContextFactory"
parameter.provider_url = "smf://console-vpn-username:batticaloa@localhost:55554"
parameter.connection_factory_name = "/jndi/cf/console-connection-factory"
parameter.connection_factory_type = "queue"
parameter.Solace_JMS_VPN = "console-vpn"
parameter.session_transaction = trueSince session transaction is enabled, we need to disable the direct transport.
Figure-28: Disable Direct Transport
5.2 Create a JMS Proxy
Create a JMS Proxy like the one below. This is a sample configuration, and based on the need, you can add additional properties or parameters for the listeners.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="SolaceQueueListener" transports="jms" startOnLoad="true">
<target>
<inSequence>
<log level="full">
<property name="SolaceQueueListener" value="Received message from Solace queue"/>
</log>
</inSequence>
<faultSequence>
<property name="SET_ROLLBACK_ONLY" value="true" scope="axis2"/>
<log level="custom">
<property name="SolaceQueueListener" value="Transaction Rollbacked"/>
</log>
</faultSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/json</default>
</rules>
</parameter>
<parameter name="transport.jms.Destination">/jndi/queue/console-queue</parameter>
<parameter name="transport.jms.ConnectionFactory">solaceQueueListener</parameter>
</proxy>5.3 Verify the Listener Logs
Based on the logs, we can observe that the listener worked and consumed the message.
INFO {LogMediator} - {api:SolacePublisherAPI} To: /solace/publish, MessageID: urn:uuid:1ad6f8ba-93a8-4d17-bd6a-3e56664622e6, correlation_id: 1ad6f8ba-93a8-4d17-bd6a-3e56664622e6, Direction: request, MESSAGE = Received request to publish to Solace, Payload: {"Name":"Test 8"}
INFO {TcpClientChannel} - Client-10: Connecting to host 'orig=tcp://localhost:55554, scheme=tcp://, host=localhost, port=55554' (host 1 of 1, smfclient 10, attempt 1 of 1, this_host_attempt: 1 of 1)
INFO {JCSMPBasicSession} - Client-10: AdCtrl version changes: 2->4
INFO {TcpClientChannel} - Client-10: Connected to host 'orig=tcp://localhost:55554, scheme=tcp://, host=localhost, port=55554' (smfclient 10)
INFO {TcpClientChannel} - Client-10: Channel Closed (smfclient 10)
[2026-04-07 16:01:54,987] INFO {TcpClientChannel} - Client-11: Connecting to host 'orig=tcp://localhost:55554, scheme=tcp://, host=localhost, port=55554' (host 1 of 1, smfclient 11, attempt 1 of 1, this_host_attempt: 1 of 1)
INFO {JCSMPBasicSession} - Client-11: AdCtrl version changes: 2->4
INFO {TcpClientChannel} - Client-11: Connected to host 'orig=tcp://localhost:55554, scheme=tcp://, host=localhost, port=55554' (smfclient 11)
INFO {LogMediator} - {proxy:SolaceQueueListener} To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:192.168.2.16e59119d683fc4cb0:1, Direction: request, SolaceQueueListener = Received message from Solace queue, Payload: {"Name":"Test 8"}6. Conclusion
This brings us to the end of this guide on integrating WSO2 Micro Integrator 4.5.0 with Solace PubSub+ Event Broker.
We explored how messages flow between WSO2 Micro Integrator and Solace, including the role of JMS 2.0, the Solace JMS provider, JCSMP, and the SMF protocol. We also walked through how to configure Solace, set up WSO2 Micro Integrator as a publisher, and consume messages using WSO2 Micro Integrator APIs and a Proxy Service.
With this setup in place, you now have a practical foundation for building event-driven integrations between WSO2 Micro Integrator and Solace PubSub+. From here, you can extend the example further with more advanced routing, error handling, message persistence, and real-world integration scenarios.
FAQ
Yes. WSO2 Micro Integrator 4.5.0 can connect to Solace PubSub+ Event Broker using JMS 2.0. This allows WSO2 MI to publish messages to Solace topics and consume messages from Solace queues.
WSO2 Micro Integrator integrates with Solace PubSub+ through the JMS transport. Solace provides a JMS implementation that connects to the Solace broker using JCSMP and the SMF protocol.
To connect WSO2 MI with Solace PubSub+, you need a running Solace broker, a Message VPN, client username, ACL profile, client profile, JNDI connection factory, JNDI queue or topic objects, and the required Solace JMS libraries in WSO2 MI.
Yes. WSO2 MI can publish messages to a Solace topic by configuring a JMS sender and using a JMS endpoint in an API or integration flow.
Yes. WSO2 MI can consume messages from a Solace queue by configuring a JMS listener and creating a JMS proxy service that listens to the Solace queue.
Solace PubSub+ helps WSO2 Micro Integrator support real-time, asynchronous, and event-driven integrations. It is useful when applications need reliable message delivery, decoupled communication, and scalable event routing.
JMS acts as the standard messaging API between WSO2 MI and Solace. WSO2 MI uses JMS transport configurations, while the Solace JMS provider handles communication with the Solace broker.
JNDI is used to look up JMS connection factories, queues, and topics. When integrating WSO2 MI with Solace, the required JNDI objects must be created in Solace so WSO2 MI can connect to the correct destinations.
For this setup, the required libraries are sol-jcsmp-10.22.0.jar and sol-jms-10.22.0.jar. These libraries allow WSO2 MI to communicate with Solace using JMS.
Yes. WSO2 MI can work with Solace guaranteed messaging by publishing to topics that are subscribed to queues and by consuming from Solace queues using JMS listeners.
A Message VPN is a logical messaging environment inside Solace PubSub+. It separates clients, queues, topics, authentication, and access control settings.
A topic is typically used for publish-subscribe messaging, while a queue is used for guaranteed message delivery. In this integration, WSO2 MI can publish to a topic and consume from a queue.
Yes. Solace PubSub+ can be run locally using Docker, making it suitable for development and testing WSO2 Micro Integrator integrations.
WSO2 MI connects to Solace using the SMF port. In the article’s Docker setup, the internal Solace SMF port 55555 is mapped to local port 55554.
Yes. WSO2 MI and Solace PubSub+ can be used together to build event-driven integrations where applications communicate asynchronously through topics and queues.