We are often required to share data between multiple applications. We find ourselves in a situation where we need data to persist for later retrieval and sharing across multiple applications.
One of the ways is using the option of a database shared across multiple applications. In Mule, the other way (and the easiest way) we can do this is by using the Object Store.
Mule uses the Object Store in various filters, routers, and other message processors that need to store their state between messages. Most of the time, Mule manages the Object Store automatically and no user configuration is required. It’s very easy to use the Object Store in Mule for storing data and sharing, which we will explore now in our demonstration.
In this article, we will simply demonstrate using the Object Store and sharing the data between different Mule applications.
Let’s consider we have created two different applications, app1 and app2, which need to share the data between them. We will keep both the application be under a domain called MyDomain.
The graphical representation is as follows:
Here, we will be demonstrating the sharing of data between two different Mule applications, app1 and app2, under the same domain called MyDomain.
Let’s start by creating a domain application from the domain project. Name the domain project MyDomain. The domain project MyDomain will have the following configuration:
<?xml version="1.0" encoding="UTF-8"?> <mule-domain xmlns="http://www.mulesoft.org/schema/mule/domain" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:spring="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/domain http://www.mulesoft.org/schema/mule/domain/current/mule-domain.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd"> <http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081"/> <spring:beans> <spring:bean id="myListableObjectStore" class="org.mule.util.store.SimpleMemoryObjectStore" /> </spring:beans> </mule-domain>
We can see above that the domain project defines the Object Store and an HTTP listener connector, which will be shared across all the applications under this domain.
The next step will be creating app1 and app2 under MyDomain.
Adding Data From App1
In app1, we will create a flow that will store data into the Object Store. We will store the data in the Object Store by adding a key which will increment by one whenever adding a new data to the Object Store:
<flow name="storeDataFlow"> <http:listener config-ref="HTTP_Listener_Configuration1" path="/set" doc:name="HTTP" /> <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object" /> <set-variable variableName="objectStoreSize" value="#[app.registry.ObjectStore.allKeys().size()]" doc:name="Set count" /> <objectstore:store config-ref="ObjectStore" key="#[new java.lang.Integer(flowVars['objectStoreSize']+1)]" value-ref="#[payload]" doc:name="AddToObjectStore" /> <set-payload value="Payload set in ObjectStore !!!!" doc:name="Set Payload" /> <object-to-byte-array-transformer doc:name="Object to Byte Array" /> </flow>
Here, we can see that we are using tag <objectstore:store/> to store data with a key that will increment each time we add data into it.
Retrieving Values in App2
In app2, we will be creating the following flows to retrieve all the values of the data that are inserted into Object Store by app1:
<flow name="retrieveAllValuesFlow"> <http:listener config-ref="HTTP_Listener_Configuration1" path="/getvalues" doc:name="HTTP" /> <set-variable variableName="AllValues" value="#[new java.util.ArrayList()]" doc:name="Create all message arraylist"/> <foreach collection="#[app.registry.ObjectStore.allKeys()]" doc:name="For Each" counterVariableName="i"> <objectstore:retrieve config-ref="ObjectStore" key="#[new java.lang.Integer(i)]" doc:name="Retrieve message"/> <object-to-string-transformer doc:name="Object to String" /> <logger message="Values #[new java.lang.Integer(i)] :- #[message.payload]" level="INFO" doc:name="Logger" /> <expression-component doc:name="Add message to all messages"><![CDATA[flowVars['AllValues'].add(payload)]]> </expression-component> </foreach> <set-payload doc:name="Set Payload" value="All the Values #[flowVars['AllValues']] "/> </flow>
Here, with the above flow, we will be getting all the data stored by app1 by iterating all the keys associated with the data.
Time to Test Our Applications
So, all set! Now, we are going to deploy both of the applications under MyDomain and start sharing the data between these two.
Since app1 and app2 are under the same domain, if we deploy MyDomain, both applications will automatically get deployed under the Mule server:
To start with, let’s add some data to the Object Store from app1 by posting the payload to the API.
Here, we are sending the JSON payload with id=01 and name=Anirban:
Let’s add some more data from app1. Again, we will hit the service and send the JSON payload with id=003 and name=Mike:
We will repeat the process one more time, hit the service, and send the JSON payload with id=027 and name=David. Now, we have added some data to our Object Store from app1.
Once done, we have successfully inserted data into the Object Store.
Next, from app2, we will retrieve the entire data value with the help of the keys associated with each data from the Object Store of all the data that we inserted into it from app1.
We have used the tag <objectstore:all-keys/> in app2 to retrieve all the keys of the data inserted from the app1 application.
When we hit http://localhost:8085/getvalues, all the data values associated with the keys will display in the response. Here, we can see that there will be three values inserted into the Object Store:
As we can see with the above example, it’s very easy to share data across any number of applications in Mule. Here, the data from app1 is accessed by app2. We can extend and modify these applications to do read and write operations on data and vice versa.
We can also perform other operations on the data such as writing the data from one application and deleting the data from other, retrieving all the keys associated with the data in the Object Store, removing a particular key associated with a data in the Object Store by an application, etc.
With this approach, it becomes easy for us to share our data between applications at runtime without having a database or a file system shared between them.