{"id":44592,"date":"2015-09-29T22:01:48","date_gmt":"2015-09-29T19:01:48","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=44592"},"modified":"2023-12-13T11:57:39","modified_gmt":"2023-12-13T09:57:39","slug":"monitoring-and-management","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html","title":{"rendered":"Monitoring and Management"},"content":{"rendered":"<p><em>This article is part of our Academy Course titled <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/spring-integration-for-eai\/\">Spring Integration for EAI<\/a>.<\/p>\n<p>In this course, you are introduced to Enterprise Application Integration patterns and how Spring Integration addresses them. Next, you delve into the fundamentals of Spring Integration, like channels, transformers and adapters. Check it out <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/spring-integration-for-eai\/\">here<\/a>!<\/em><\/p>\n<div class=\"toc\">\n<h4>Table Of Contents<\/h4>\n<dl>\n<dt><a href=\"#introduction\">1. Introduction<\/a><\/dt>\n<dt><a href=\"#jmx-notifications\">2. Publishing and receiving JMX notifications<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#publish-notification\">2.1. Publishing a JMX notification<\/a><\/dt>\n<dt><a href=\"#receive-notification\">2.2. Receiving a JMX notification<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#polling\">3. Polling managed attributes from an MBean<\/a><\/dt>\n<dt><a href=\"#operations\">4. Invoking MBean operations<\/a><\/dt>\n<dt><a href=\"#export\">5. Exporting components as MBeans<\/a><\/dt>\n<dt><a href=\"#history\">6. Trailing a message path<\/a><\/dt>\n<dt><a href=\"#msg-store\">7. Persisting buffered messages<\/a><\/dt>\n<dt><a href=\"#metadata\">8. Implementing idempotent components<\/a><\/dt>\n<dt><a href=\"#control-bus\">9. Sending operation invocation requests<\/a><\/dt>\n<\/dl>\n<\/div>\n<h2><a name=\"introduction\"><\/a>1. Introduction<\/h2>\n<p>After having experimented with the main components provided by Spring Integration and seen how it integrates well with other systems like JMS queues or web services, this chapter finishes the course by showing different mechanisms of monitoring or gathering more information about what is going on within the messaging system.<\/p>\n<p>Some of these mechanisms consist of managing or monitoring the application through MBeans, which are part of the JMX specification. We will also learn how to monitor messages to see which components were involved during the messaging flow and how to persist messages for components that have the capability to buffer messages.<\/p>\n<p>Another mechanism discussed in this chapter is how we will implement the EIP idempotent receiver pattern using a metadata store.<\/p>\n<p>Finally, the last mechanism described is the control bus. This will let us send messages that will invoke operations on components in the application context.<\/p>\n<h2><a name=\"jmx-notifications\"><\/a>2. Publishing and receiving JMX notifications<\/h2>\n<p>The JMX specification defines a mechanism that allows MBeans to publish notifications that will be sent to other MBeans or to the management application. The Oracle <a href=\"http:\/\/docs.oracle.com\/javase\/tutorial\/jmx\/notifs\/index.html\">documentation<\/a> explains how to implement this mechanism.<\/p>\n<p>Spring Integration supports this feature by providing channel adapters that are both able to publish and receive JMX notifications. We are going to see an example that uses both channel adapters:<\/p>\n<ul>\n<li>A notification listening channel adapter<\/li>\n<li>A notification publishing channel adapter<\/li>\n<\/ul>\n<h3><a name=\"publish-notification\"><\/a>2.1. Publishing a JMX notification<\/h3>\n<p>In the first part of the example, the messaging system receives a String message (a message with a payload of type String) through its entry gateway. It then uses a service activator (notification handler) to build a <code><a href=\"http:\/\/docs.oracle.com\/javase\/7\/docs\/api\/javax\/management\/Notification.html\">javax.management.Notification<\/a><\/code> and sends it to the notification publishing channel adapter, which will publish the JMX notification.<\/p>\n<p>The flow of this first part is shown below:<\/p>\n<p><figure id=\"attachment_4486\" aria-describedby=\"caption-attachment-4486\" style=\"width: 1024px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic1.png\"><img decoding=\"async\" class=\"size-large wp-image-4486\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic1-1024x166.png\" alt=\"Figure 1\" width=\"1024\" height=\"166\" \/><\/a><figcaption id=\"caption-attachment-4486\" class=\"wp-caption-text\">Figure 1<\/figcaption><\/figure><\/p>\n<p>The xml configuration equivalent to the previous graphic:<\/p>\n<pre class=\"brush:xml\">\n&lt;context:component-scan base-package=\"xpadro.spring.integration.jmx.notification\"\/&gt;\n    \n&lt;context:mbean-export\/&gt;\n&lt;context:mbean-server\/&gt;\n\n&lt;!-- Sending Notifications --&gt;\n&lt;int:gateway service-interface=\"xpadro.spring.integration.jmx.notification.JmxNotificationGateway\" default-request-channel=\"entryChannel\"\/&gt;\n\n&lt;int:channel id=\"entryChannel\"\/&gt;\n\n&lt;int:service-activator input-channel=\"entryChannel\" output-channel=\"sendNotificationChannel\" \n    ref=\"notificationHandler\" method=\"buildNotification\"\/&gt;\n\n&lt;int:channel id=\"sendNotificationChannel\"\/&gt;\n\n&lt;int-jmx:notification-publishing-channel-adapter channel=\"sendNotificationChannel\" \n    object-name=\"xpadro.spring.integration.jmx.adapter:type=integrationMBean,name=integrationMbean\"\/&gt;\n<\/pre>\n<p>The gateway is as simple as in previous examples. Remember that the <code>@Gateway<\/code> annotation is not necessary if you have just one method:<\/p>\n<pre class=\"brush:java\">\npublic interface JmxNotificationGateway {\n\n    public void send(String type);\n}\n<\/pre>\n<p>A <code>Message<\/code> will reach the service activator, which will build the message with the JMX notification:<\/p>\n<pre class=\"brush:java\">\n@Component(\"notificationHandler\")\npublic class NotificationHandler {\n    private Logger logger = LoggerFactory.getLogger(this.getClass());\n    private static final String NOTIFICATION_TYPE_HEADER = \"jmx_notificationType\";\n    \n    public void receive(Message&lt;Notification&gt; msg) {\n        logger.info(\"Notification received: {}\", msg.getPayload().getType());\n    }\n    \n    public Message&lt;Notification&gt; buildNotification(Message&lt;String&gt; msg) {\n        Notification notification = new Notification(msg.getPayload(), this, 0);\n        \n        return MessageBuilder.withPayload(notification)\n                .copyHeadersIfAbsent(msg.getHeaders()).setHeader(NOTIFICATION_TYPE_HEADER, \"myJmxNotification\").build();\n    }\n}\n<\/pre>\n<p>Notice that we have set a new header. This is necessary to provide the notification type or the JMX adapter will throw an <code>IllegalArgumentException<\/code> with the message \u201cNo notification type header is available, and no default has been provided\u201d.<\/p>\n<p>Finally, we just need to return the message in order to be sent to the publishing adapter. The rest is handled by Spring Integration.<\/p>\n<h3><a name=\"receive-notification\"><\/a>2.2. Receiving a JMX notification<\/h3>\n<p>The second part of the flow consists in a notification listening channel adapter that will receive our previously published notification.<\/p>\n<p><figure id=\"attachment_4487\" aria-describedby=\"caption-attachment-4487\" style=\"width: 661px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic2.png\"><img decoding=\"async\" class=\"size-full wp-image-4487\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic2.png\" alt=\"Figure 2\" width=\"661\" height=\"182\" \/><\/a><figcaption id=\"caption-attachment-4487\" class=\"wp-caption-text\">Figure 2<\/figcaption><\/figure><\/p>\n<p>The xml configuration:<\/p>\n<pre class=\"brush:xml\">\n&lt;!-- Receiving Notifications --&gt;\n&lt;int-jmx:notification-listening-channel-adapter channel=\"receiveNotificationChannel\" \n    object-name=\"xpadro.spring.integration.jmx.adapter:type=integrationMBean,name=integrationMbean\"\/&gt;\n\n&lt;int:channel id=\"receiveNotificationChannel\"\/&gt;\n\n&lt;int:service-activator input-channel=\"receiveNotificationChannel\" \n    ref=\"notificationHandler\" method=\"receive\"\/&gt;\n<\/pre>\n<p>We will just receive the notification and log it:<\/p>\n<pre class=\"brush:java\">\npublic void receive(Message&lt;Notification&gt; msg) {\n    logger.info(\"Notification received: {}\", msg.getPayload().getType());\n}\n<\/pre>\n<p>The application that runs the example:<\/p>\n<pre class=\"brush:java\">\npublic class NotificationApp {\n    public static void main(String[] args) throws InterruptedException {\n        AbstractApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:xpadro\/spring\/integration\/jmx\/config\/int-notification-config.xml\");\n        \n        JmxNotificationGateway gateway = context.getBean(JmxNotificationGateway.class);\n        gateway.send(\"gatewayNotification\");\n        Thread.sleep(1000);\n        context.close();\n    }\n}\n<\/pre>\n<h2><a name=\"polling\"><\/a>3. Polling managed attributes from an MBean<\/h2>\n<p>Imagine we have an <code>MBean<\/code> that is monitoring some feature. With the attribute polling channel adapter, your application will be able to poll the <code>MBean<\/code> and receive the updated data.<\/p>\n<p>I have implemented an <code>MBean<\/code> that generates a random number every time is asked. Not the most vital feature but will serve us to see an example:<\/p>\n<pre class=\"brush:java\">\n@Component(\"pollingMbean\")\n@ManagedResource\npublic class JmxPollingMBean {\n    \n    @ManagedAttribute\n    public int getNumber() {\n        Random rnd = new Random();\n        int randomNum = rnd.nextInt(100);\n        return randomNum;\n    }\n}\n<\/pre>\n<p>The flow couldn\u2019t be simpler; we need an attribute polling channel adapter specifying the type and name of our <code>MBean<\/code>. The adapter will poll the <code>MBean<\/code> and place the result in the result channel. Each result polled will be shown on console through the stream stdout channel adapter:<\/p>\n<pre class=\"brush:xml\">\n&lt;context:component-scan base-package=\"xpadro.spring.integration.jmx.polling\"\/&gt;\n\n&lt;context:mbean-export\/&gt;\n&lt;context:mbean-server\/&gt;\n\n&lt;!-- Polling --&gt;\n&lt;int-jmx:attribute-polling-channel-adapter channel=\"resultChannel\"\n        object-name=\"xpadro.spring.integration.jmx.polling:type=JmxPollingMBean,name=pollingMbean\"\n        attribute-name=\"Number\"&gt;\n    &lt;int:poller max-messages-per-poll=\"1\" fixed-delay=\"1000\"\/&gt;\n&lt;\/int-jmx:attribute-polling-channel-adapter&gt;\n\n&lt;int:channel id=\"resultChannel\"\/&gt;\n\n&lt;int-stream:stdout-channel-adapter channel=\"resultChannel\" append-newline=\"true\"\/&gt;\n<\/pre>\n<p>The application that runs the example:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush:java\">\npublic class PollingApp {\n    public static void main(String[] args) throws InterruptedException {\n        AbstractApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:xpadro\/spring\/integration\/jmx\/config\/int-polling-config.xml\");\n        context.registerShutdownHook();\n        Thread.sleep(5000);\n        context.close();\n    }\n}\n<\/pre>\n<p>And the console output:<\/p>\n<pre class=\"brush:bash\">2014-04-16 16:23:43,867|AbstractEndpoint|started org.springframework.integration.config.ConsumerEndpointFactoryBean#0\n82\n72\n20\n47\n21\n2014-04-16 16:23:48,878|AbstractApplicationContext|Closing org.springframework.context.support.ClassPathXmlApplicationContext@7283922\n<\/pre>\n<h2><a name=\"operations\"><\/a>4. Invoking MBean operations<\/h2>\n<p>The next mechanism allows us to invoke an operation of an <code>MBean<\/code>. We are going to implement another bean that contains a single operation, our old friend hello world:<\/p>\n<pre class=\"brush:java\">\n@Component(\"operationMbean\")\n@ManagedResource\npublic class JmxOperationMBean {\n    \n    @ManagedOperation\n    public String hello(String name) {\n        return \"Hello \" + name;\n    }\n}\n<\/pre>\n<p>Now, we can use a channel adapter if the operation does not return a result, or a gateway if so. With the following xml configuration, we export the <code>MBean<\/code> and use the gateway to invoke the operation and wait for the result:<\/p>\n<pre class=\"brush:xml\">\n&lt;context:component-scan base-package=\"xpadro.spring.integration.jmx.operation\"\/&gt;\n    \n&lt;context:mbean-export\/&gt;\n&lt;context:mbean-server\/&gt;\n\n&lt;int:gateway service-interface=\"xpadro.spring.integration.jmx.operation.JmxOperationGateway\" default-request-channel=\"entryChannel\"\/&gt;\n\n&lt;int-jmx:operation-invoking-outbound-gateway request-channel=\"entryChannel\" reply-channel=\"replyChannel\"\n    object-name=\"xpadro.spring.integration.jmx.operation:type=JmxOperationMBean,name=operationMbean\" \n    operation-name=\"hello\"\/&gt;\n\n&lt;int:channel id=\"replyChannel\"\/&gt;\n\n&lt;int-stream:stdout-channel-adapter channel=\"replyChannel\" append-newline=\"true\"\/&gt;\n<\/pre>\n<p>In order to work, we have to specify the type and name of the <code>MBean<\/code>, and the operation we want to invoke. The result will be sent to the stream channel adapter in order to be shown on the console.<\/p>\n<p>The application that runs the example:<\/p>\n<pre class=\"brush:java\">\npublic class OperationApp {\n    public static void main(String[] args) throws InterruptedException {\n        AbstractApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:xpadro\/spring\/integration\/jmx\/config\/int-operation-config.xml\");\n        \n        JmxOperationGateway gateway = context.getBean(JmxOperationGateway.class);\n        gateway.hello(\"World\");\n        Thread.sleep(1000);\n        context.close();\n    }\n}\n<\/pre>\n<h2><a name=\"export\"><\/a>5. Exporting components as MBeans<\/h2>\n<p>This component is used to export message channels, message handlers and message endpoints as MBeans so you can monitor them.<\/p>\n<p>You need to put the following configuration into your application:<\/p>\n<pre class=\"brush:xml\">\n&lt;int-jmx:mbean-export id=\"integrationMBeanExporter\"\n    default-domain=\"xpadro.integration.exporter\" server=\"mbeanServer\"\/&gt;\n\n&lt;bean id=\"mbeanServer\" class=\"org.springframework.jmx.support.MBeanServerFactoryBean\"&gt;\n    &lt;property name=\"locateExistingServerIfPossible\" value=\"true\"\/&gt;\n&lt;\/bean&gt;\n<\/pre>\n<p>And set the following VM arguments as explained in the Spring <a href=\"http:\/\/docs.spring.io\/spring-integration\/docs\/3.0.2.RELEASE\/reference\/html\/system-management-chapter.html#jmx-mbean-exporter\">documentation<\/a>:<\/p>\n<pre class=\"brush:bash\">-Dcom.sun.management.jmxremote\n-Dcom.sun.management.jmxremote.port=6969\n-Dcom.sun.management.jmxremote.ssl=false\n-Dcom.sun.management.jmxremote.authenticate=false\n<\/pre>\n<p>The application that runs the example sends three messages:<\/p>\n<pre class=\"brush:java\">\npublic class ExporterApp {\n    public static void main(String[] args) throws InterruptedException {\n        AbstractApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:xpadro\/spring\/integration\/jmx\/config\/int-exporter-config.xml\");\n        context.registerShutdownHook();\n        \n        JmxExporterGateway gateway = context.getBean(JmxExporterGateway.class);\n        gateway.sendMessage(\"message 1\");\n        Thread.sleep(500);\n        gateway.sendMessage(\"message 2\");\n        Thread.sleep(500);\n        gateway.sendMessage(\"message 3\");\n    }\n}\n<\/pre>\n<p>Once the application is running, you can see information about the components. The following screenshot is made on the JConsole:<\/p>\n<p><figure id=\"attachment_4488\" aria-describedby=\"caption-attachment-4488\" style=\"width: 871px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic3.png\"><img decoding=\"async\" class=\"size-full wp-image-4488\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic3.png\" alt=\"Figure 3\" width=\"871\" height=\"270\" \/><\/a><figcaption id=\"caption-attachment-4488\" class=\"wp-caption-text\">Figure 3<\/figcaption><\/figure><\/p>\n<p>You can notice that the <code>sendCount<\/code> attribute of the entry channel has the value 3, because we have sent three messages in our example.<\/p>\n<h2><a name=\"history\"><\/a>6. Trailing a message path<\/h2>\n<p>In a messaging system, components are loosely coupled. This means that the sending component does not need to know who will receive the message. And the other way round, the receiver is just interested in the message received, not who sent it. This benefit can be not so good when we need to debug the application.<\/p>\n<p>The <a href=\"http:\/\/www.eaipatterns.com\/MessageHistory.html\">message history<\/a> consists in attaching to the message, the list of all components the message passed through.<\/p>\n<p>The following application will test this feature by sending a message through several components:<\/p>\n<p><figure id=\"attachment_4489\" aria-describedby=\"caption-attachment-4489\" style=\"width: 1024px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic4.png\"><img decoding=\"async\" class=\"size-large wp-image-4489\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic4-1024x143.png\" alt=\"Figure 4\" width=\"1024\" height=\"143\" \/><\/a><figcaption id=\"caption-attachment-4489\" class=\"wp-caption-text\">Figure 4<\/figcaption><\/figure><\/p>\n<p>The key element of the configuration is not visible in the previous graphic: the <code>message-history<\/code> element:<\/p>\n<pre class=\"brush:xml\">\n&lt;context:component-scan base-package=\"xpadro.spring.integration.msg.history\"\/&gt;\n\n&lt;int:message-history\/&gt;\n\n&lt;int:gateway id=\"historyGateway\" service-interface=\"xpadro.spring.integration.msg.history.HistoryGateway\" \n    default-request-channel=\"entryChannel\"\/&gt;\n\n&lt;int:channel id=\"entryChannel\"\/&gt;\n\n&lt;int:transformer id=\"msgTransformer\" input-channel=\"entryChannel\" \n    expression=\"payload + 'transformed'\" output-channel=\"transformedChannel\"\/&gt;\n\n&lt;int:channel id=\"transformedChannel\"\/&gt;\n\n&lt;int:service-activator input-channel=\"transformedChannel\" ref=\"historyActivator\"\/&gt;\n<\/pre>\n<p>With this configuration set, the service activator at the end of the messaging flow will be able to retrieve the list of visited components by looking at the header of the message:<\/p>\n<pre class=\"brush:java\">\n@Component(\"historyActivator\")\npublic class HistoryActivator {\n    private Logger logger = LoggerFactory.getLogger(this.getClass());\n\n    public void handle(Message&lt;String&gt; msg) {\n        MessageHistory msgHistory = msg.getHeaders().get(MessageHistory.HEADER_NAME, MessageHistory.class);\n        if (msgHistory != null) {\n            logger.info(\"Components visited: {}\", msgHistory.toString());\n        }\n    }\n}\n<\/pre>\n<p>The application running this example:<\/p>\n<pre class=\"brush:java\">\npublic class MsgHistoryApp {\n    public static void main(String[] args) throws InterruptedException {\n        AbstractApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:xpadro\/spring\/integration\/msg\/history\/config\/int-msg-history-config.xml\");\n        \n        HistoryGateway gateway = context.getBean(HistoryGateway.class);\n        gateway.send(\"myTest\");\n        Thread.sleep(1000);\n        context.close();\n    }\n}\n<\/pre>\n<p>The result will be shown on the console:<\/p>\n<pre class=\"brush:bash\">2014-04-16 17:34:52,551|HistoryActivator|Components visited: historyGateway,entryChannel,msgTransformer,transformedChannel<\/pre>\n<h2><a name=\"msg-store\"><\/a>7. Persisting buffered messages<\/h2>\n<p>Some of the components in Spring Integration can buffer messages. For example, a queue channel will buffer messages until consumers retrieve them from it. Another example is the aggregator endpoint; as seen in the second tutorial, this endpoint will gather messages until the group is complete basing its decision on the release strategy.<\/p>\n<p>These integration patterns imply that if a failure occurs, buffered messages can be lost. To prevent this, we can persist these messages, for example storing them into a database. By default, Spring Integration stores these messages in memory. We are going to change this using a <a href=\"http:\/\/www.eaipatterns.com\/MessageStore.html\">message store<\/a>.<\/p>\n<p>For our example, we will store these messages into a <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a> database. In order to do that, we just need the following configuration:<\/p>\n<pre class=\"brush:xml\">\n&lt;bean id=\"mongoDbFactory\" class=\"org.springframework.data.mongodb.core.SimpleMongoDbFactory\"&gt;\n    &lt;constructor-arg&gt;\n        &lt;bean class=\"com.mongodb.Mongo\"\/&gt;\n    &lt;\/constructor-arg&gt;\n    &lt;constructor-arg value=\"jcgdb\"\/&gt;\n&lt;\/bean&gt;\n\n&lt;bean id=\"mongoDbMessageStore\" class=\"org.springframework.integration.mongodb.store.ConfigurableMongoDbMessageStore\"&gt;\n    &lt;constructor-arg ref=\"mongoDbFactory\"\/&gt;\n&lt;\/bean&gt;\n<\/pre>\n<p>Now, we are going to create an application to test this feature. I have implemented a flow that receives through a gateway, a message with a String payload. This message is sent by the gateway to a queue channel that will buffer the messages until the service activator <code>msgStoreActivator<\/code> retrieves it from the queue. The service activator will poll messages every five seconds:<\/p>\n<pre class=\"brush:xml\">\n&lt;context:component-scan base-package=\"xpadro.spring.integration.msg.store\"\/&gt;\n\n&lt;import resource=\"mongodb-config.xml\"\/&gt;\n\n&lt;int:gateway id=\"storeGateway\" service-interface=\"xpadro.spring.integration.msg.store.MsgStoreGateway\" \n    default-request-channel=\"entryChannel\"\/&gt;\n\n&lt;int:channel id=\"entryChannel\"&gt;\n    &lt;int:queue message-store=\"myMessageStore\"\/&gt;\n&lt;\/int:channel&gt;\n\n&lt;int:service-activator input-channel=\"entryChannel\" ref=\"msgStoreActivator\"&gt;\n    &lt;int:poller fixed-rate=\"5000\"\/&gt;\n&lt;\/int:service-activator&gt;\n<\/pre>\n<p>Maybe you have noticed the <code>myMessageStore<\/code> bean. In order to see how the persisting messages mechanism works, I have extended the <code><a href=\"http:\/\/docs.spring.io\/spring-integration\/docs\/3.0.2.RELEASE\/api\/org\/springframework\/integration\/mongodb\/store\/ConfigurableMongoDbMessageStore.html\">ConfigurableMongoDBMessageStore<\/a><\/code> class to put logs in it and debug the result. If you want to try this, you can delete the MongoDB messageStore bean in <code>mongodb-config.xml<\/code> since we are no longer using it.<br \/>\n[ulp id=&#8217;DdINgEqoOovgkhhk-2&#8242;]<br \/>\n&nbsp;<br \/>\nI have overwritten two methods:<\/p>\n<pre class=\"brush:java\">\n@Component(\"myMessageStore\")\npublic class MyMessageStore extends ConfigurableMongoDbMessageStore {\n    private Logger logger = LoggerFactory.getLogger(this.getClass());\n    private static final String STORE_COLLECTION_NAME = \"messageStoreCollection\";\n\n    @Autowired\n    public MyMessageStore(MongoDbFactory mongoDbFactory) {\n        super(mongoDbFactory, STORE_COLLECTION_NAME);\n        logger.info(\"Creating message store '{}'\", STORE_COLLECTION_NAME);\n    }\n    \n    @Override\n    public MessageGroup addMessageToGroup(Object groupId, Message&lt;?&gt; message) {\n        logger.info(\"Adding message '{}' to group '{}'\", message.getPayload(), groupId);\n        return super.addMessageToGroup(groupId, message);\n    }\n\n    @Override\n    public Message&lt;?&gt; pollMessageFromGroup(Object groupId) {\n        Message&lt;?&gt; msg = super.pollMessageFromGroup(groupId);\n        if (msg != null) {\n            logger.info(\"polling message '{}' from group '{}'\", msg.getPayload(), groupId);\n        }\n        else {\n            logger.info(\"Polling null message from group {}\", groupId);\n        }\n        \n        return msg;\n    }\n}\n<\/pre>\n<p>This mechanism works as follows:<\/p>\n<ol>\n<li>When a message reaches the queue channel, which have our message store configured, it will invoke the \u2018addMessageToGroup\u2019 method. This method will insert a document with the payload to the MongoDB collection specified in the constructor. This is done by using a <code><a href=\"http:\/\/docs.spring.io\/spring-data\/mongodb\/docs\/1.4.x\/api\/org\/springframework\/data\/mongodb\/core\/MongoTemplate.html\">MongoTemplate<\/a><\/code>.<\/li>\n<li>When the consumer polls the message, the <code>pollMessageFromGroup<\/code> will be invoked, retrieving the document from the collection.<\/li>\n<\/ol>\n<p>Let\u2019s see how it works by debugging the code. We will stop just before polling the message to see how it is stored in the database:<\/p>\n<p><figure id=\"attachment_4490\" aria-describedby=\"caption-attachment-4490\" style=\"width: 424px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic5.png\"><img decoding=\"async\" class=\"size-full wp-image-4490\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic5.png\" alt=\"Figure 5\" width=\"424\" height=\"91\" \/><\/a><figcaption id=\"caption-attachment-4490\" class=\"wp-caption-text\">Figure 5<\/figcaption><\/figure><\/p>\n<p>At this moment, we can take a look at the database:<\/p>\n<p><figure id=\"attachment_4491\" aria-describedby=\"caption-attachment-4491\" style=\"width: 638px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic6.png\"><img decoding=\"async\" class=\"size-full wp-image-4491\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic6.png\" alt=\"Figure 6\" width=\"638\" height=\"271\" \/><\/a><figcaption id=\"caption-attachment-4491\" class=\"wp-caption-text\">Figure 6<\/figcaption><\/figure><\/p>\n<p>Once resumed, the message is polled from the collection:<\/p>\n<p><figure id=\"attachment_4492\" aria-describedby=\"caption-attachment-4492\" style=\"width: 354px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic7.png\"><img decoding=\"async\" class=\"size-full wp-image-4492\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/ch6_pic7.png\" alt=\"Figure 7\" width=\"354\" height=\"28\" \/><\/a><figcaption id=\"caption-attachment-4492\" class=\"wp-caption-text\">Figure 7<\/figcaption><\/figure><\/p>\n<p>The application that runs the example:<\/p>\n<pre class=\"brush:java\">\npublic class MsgStoreApp {\n    public static void main(String[] args) throws InterruptedException {\n        AbstractApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:xpadro\/spring\/integration\/msg\/store\/config\/int-msg-store-config.xml\");\n        \n        MsgStoreGateway gateway = context.getBean(MsgStoreGateway.class);\n        \n        gateway.send(\"myMessage\");\n        Thread.sleep(30000);\n        context.close();\n    }\n}\n<\/pre>\n<h2><a name=\"metadata\"><\/a>8. Implementing idempotent components<\/h2>\n<p>If our application needs to avoid duplicate messages, Spring Integration provides this mechanism by implementing the <a href=\"http:\/\/eaipatterns.com\/IdempotentReceiver.html\">idempotent receiver<\/a> pattern. The responsible of detecting duplicate messages is the metadata store component. This component consists in storing key-value pairs. The framework provides two implementations of the interface <code><a href=\"http:\/\/docs.spring.io\/spring-integration\/docs\/3.0.2.RELEASE\/api\/org\/springframework\/integration\/metadata\/MetadataStore.html\">MetadataStore<\/a><\/code>:<\/p>\n<ul>\n<li><a href=\"http:\/\/docs.spring.io\/spring-integration\/docs\/3.0.2.RELEASE\/api\/org\/springframework\/integration\/metadata\/SimpleMetadataStore.html\">SimpleMetadataStore<\/a>: Default implementation. It stores the information using an in-memory <a href=\"http:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/Map.html\">map<\/a>.<\/li>\n<li><a href=\"http:\/\/docs.spring.io\/spring-integration\/docs\/3.0.2.RELEASE\/api\/org\/springframework\/integration\/metadata\/PropertiesPersistingMetadataStore.html\">PropertiesPersistingMetadataStore<\/a>: Useful if you need to persist the data. It uses a properties file. We are going to use this implementation in our example.<\/li>\n<\/ul>\n<p>OK, let\u2019s start with the configuration file:<\/p>\n<pre class=\"brush:xml\">\n&lt;context:component-scan base-package=\"xpadro.spring.integration.msg.metadata\"\/&gt;\n\n&lt;bean id=\"metadataStore\"\nclass=\"org.springframework.integration.metadata.PropertiesPersistingMetadataStore\"\/&gt;\n\n&lt;int:gateway id=\"metadataGateway\" service-interface=\"xpadro.spring.integration.msg.metadata.MetadataGateway\"\n    default-request-channel=\"entryChannel\"\/&gt;\n\n&lt;int:channel id=\"entryChannel\"\/&gt;\n\n&lt;int:filter input-channel=\"entryChannel\" output-channel=\"processChannel\"\n    discard-channel=\"discardChannel\" expression=\"@metadataStore.get(headers.messageId) == null\"\/&gt;\n\n\n&lt;!-- Process message --&gt;            \n&lt;int:publish-subscribe-channel id=\"processChannel\"\/&gt;\n\n&lt;int:outbound-channel-adapter channel=\"processChannel\" expression=\"@metadataStore.put(headers.messageId, '')\"\/&gt;\n\n&lt;int:service-activator input-channel=\"processChannel\" ref=\"metadataActivator\" method=\"process\"\/&gt;\n\n\n&lt;!-- Duplicated message - discard it --&gt;\n&lt;int:channel id=\"discardChannel\"\/&gt;\n\n&lt;int:service-activator input-channel=\"discardChannel\" ref=\"metadataActivator\" method=\"discard\"\/&gt;\n<\/pre>\n<p>We have defined a \u201cmetadataStore\u201d in order to use our properties metadata store instead of the default in-memory implementation.<\/p>\n<p>The flow is explained here:<\/p>\n<ol>\n<li>A message is sent to the gateway.<\/li>\n<li>The filter will send the message to the process channel since it is the first time it is sent.<\/li>\n<li>There are two subscribers to the process channel: the service activator that processes the message and an outbound channel adapter. The channel adapter will send the value of the message header <code>messagId<\/code> to the metadata store.<\/li>\n<li>The metadata store stores the value in the properties file.<\/li>\n<li>Next time the same message is sent; the filter will find the value and discard the message.<\/li>\n<\/ol>\n<p>The metadata store creates a properties file in the file system. If you are using Windows, you will see a metadata-store.properties file in the \u2018C:\\Users\\username\\AppData\\Local\\Temp\\spring-integration\u2019 folder<\/p>\n<p>The example uses a service activator to log if the message has been processed:<\/p>\n<pre class=\"brush:java\">\n@Component(\"metadataActivator\")\npublic class MetadataActivator {\n    private Logger logger = LoggerFactory.getLogger(this.getClass());\n\n    public void process(Message&lt;String&gt; msg) {\n        logger.info(\"Message processed: {}\", msg.getPayload());\n    }\n    \n    public void discard(Message&lt;String&gt; msg) {\n        logger.info(\"Message discarded: {}\", msg.getPayload());\n    }\n}\n<\/pre>\n<p>The application will run the example:<\/p>\n<pre class=\"brush:java\">\npublic class MetadataApp {\n    private static final String MESSAGE_STORE_HEADER = \"messageId\";\n    \n    public static void main(String[] args) throws InterruptedException {\n        AbstractApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:xpadro\/spring\/integration\/msg\/metadata\/config\/int-msg-metadata-config.xml\");\n        \n        MetadataGateway gateway = context.getBean(MetadataGateway.class);\n        \n        Map&lt;String,String&gt; headers = new HashMap&lt;&gt;();\n        headers.put(MESSAGE_STORE_HEADER, \"msg1\");\n        Message&lt;String&gt; msg1 = MessageBuilder.withPayload(\"msg1\").copyHeaders(headers).build();\n        \n        headers = new HashMap&lt;&gt;();\n        headers.put(MESSAGE_STORE_HEADER, \"msg2\");\n        Message&lt;String&gt; msg2 = MessageBuilder.withPayload(\"msg2\").copyHeaders(headers).build();\n        \n        gateway.sendMessage(msg1);\n        Thread.sleep(500);\n        gateway.sendMessage(msg1);\n        Thread.sleep(500);\n        gateway.sendMessage(msg2);\n        \n        Thread.sleep(3000);\n        context.close();\n    }\n}\n<\/pre>\n<p>The first invocation will result in the following output on the console:<\/p>\n<pre class=\"brush:bash\">2014-04-17 13:00:08,223|MetadataActivator|Message processed: msg1\n2014-04-17 13:00:08,726|MetadataActivator|Message discarded: msg1\n2014-04-17 13:00:09,229|MetadataActivator|Message processed: msg2\n<\/pre>\n<p>Now remember that the PropertiesPersistingMetadataStore stores the data in a properties file. This means that the data will survive ApplicationContext restarts. So, if we don\u2019t delete the properties file and we run the example again, the result will be different:<\/p>\n<pre class=\"brush:bash\">2014-04-17 13:02:27,117|MetadataActivator|Message discarded: msg1\n2014-04-17 13:02:27,620|MetadataActivator|Message discarded: msg1\n2014-04-17 13:02:28,123|MetadataActivator|Message discarded: msg2\n<\/pre>\n<h2><a name=\"control-bus\"><\/a>9. Sending operation invocation requests<\/h2>\n<p>The last mechanism discussed on this tutorial is the <a href=\"http:\/\/eaipatterns.com\/ControlBus.html\">control bus<\/a>. The control bus will let you manage the system the same way it is done by the application. The message will be executed as a Spring Expression Language. To be executable from the control bus, the method needs to use the @ManagedAttribute or @ManagedOperation annotation.<\/p>\n<p>This section\u2019s example uses a control bus to invoke a method on a bean:<\/p>\n<pre class=\"brush:xml\">\n&lt;context:component-scan base-package=\"xpadro.spring.integration.control.bus\"\/&gt;\n\n&lt;int:channel id=\"entryChannel\"\/&gt;\n\n&lt;int:control-bus input-channel=\"entryChannel\" output-channel=\"resultChannel\"\/&gt;\n\n&lt;int:channel id=\"resultChannel\"\/&gt;\n\n&lt;int:service-activator input-channel=\"resultChannel\" ref=\"controlbusActivator\"\/&gt;\n<\/pre>\n<p>The operation that will be invoked is as follows:<\/p>\n<pre class=\"brush:java\">\n@Component(\"controlbusBean\")\npublic class ControlBusBean {\n\n    @ManagedOperation\n    public String greet(String name) {\n        return \"Hello \" + name;\n    }\n}\n<\/pre>\n<p>The application that runs the example sends a message with the expression to be executed:<\/p>\n<pre class=\"brush:java\">\npublic class ControlBusApp {\n    public static void main(String[] args) throws InterruptedException {\n        AbstractApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:xpadro\/spring\/integration\/control\/bus\/config\/int-control-bus-config.xml\");\n        MessageChannel channel = context.getBean(\"entryChannel\", MessageChannel.class);\n        \n        Message&lt;String&gt; msg = MessageBuilder.withPayload(\"@controlbusBean.greet('World!')\").build();\n        channel.send(msg);\n        \n        Thread.sleep(3000);\n        context.close();\n    }\n}\n<\/pre>\n<p>The result is shown on the console:<\/p>\n<pre class=\"brush:bash\">2014-04-17 13:21:42,910|ControlBusActivator|Message received: Hello World!<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This article is part of our Academy Course titled Spring Integration for EAI. In this course, you are introduced to Enterprise Application Integration patterns and how Spring Integration addresses them. Next, you delve into the fundamentals of Spring Integration, like channels, transformers and adapters. Check it out here! Table Of Contents 1. Introduction 2. Publishing &hellip;<\/p>\n","protected":false},"author":533,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[30,410],"class_list":["post-44592","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-spring","tag-spring-integration"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Monitoring and Management - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"This article is part of our Academy Course titled Spring Integration for EAI. In this course, you are introduced to Enterprise Application Integration\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Monitoring and Management - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"This article is part of our Academy Course titled Spring Integration for EAI. In this course, you are introduced to Enterprise Application Integration\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-29T19:01:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-13T09:57:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Xavier Padro\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/xavips\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Xavier Padro\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html\"},\"author\":{\"name\":\"Xavier Padro\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/5443fbc8fb815652f181942d4622090d\"},\"headline\":\"Monitoring and Management\",\"datePublished\":\"2015-09-29T19:01:48+00:00\",\"dateModified\":\"2023-12-13T09:57:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html\"},\"wordCount\":1855,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Spring\",\"Spring Integration\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html\",\"name\":\"Monitoring and Management - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2015-09-29T19:01:48+00:00\",\"dateModified\":\"2023-12-13T09:57:39+00:00\",\"description\":\"This article is part of our Academy Course titled Spring Integration for EAI. In this course, you are introduced to Enterprise Application Integration\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/monitoring-and-management.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Monitoring and Management\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/5443fbc8fb815652f181942d4622090d\",\"name\":\"Xavier Padro\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbf0579a188773b88762d54dadc779b2cd17ddb261d809956ed55d8569bd7ca2?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbf0579a188773b88762d54dadc779b2cd17ddb261d809956ed55d8569bd7ca2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbf0579a188773b88762d54dadc779b2cd17ddb261d809956ed55d8569bd7ca2?s=96&d=mm&r=g\",\"caption\":\"Xavier Padro\"},\"description\":\"Xavier is a software developer working in a consulting firm based in Barcelona. He is specialized in web application development with experience in both frontend and backend. He is interested in everything related to Java and the Spring framework.\",\"sameAs\":[\"http:\\\/\\\/xpadro.blogspot.gr\\\/\",\"http:\\\/\\\/linkedin.com\\\/pub\\\/xavier-padro-sobrepera\\\/1a\\\/64\\\/3\\\/en\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/xavips\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/xavier-padro\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Monitoring and Management - Java Code Geeks","description":"This article is part of our Academy Course titled Spring Integration for EAI. In this course, you are introduced to Enterprise Application Integration","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html","og_locale":"en_US","og_type":"article","og_title":"Monitoring and Management - Java Code Geeks","og_description":"This article is part of our Academy Course titled Spring Integration for EAI. In this course, you are introduced to Enterprise Application Integration","og_url":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2015-09-29T19:01:48+00:00","article_modified_time":"2023-12-13T09:57:39+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Xavier Padro","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/xavips","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Xavier Padro","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html"},"author":{"name":"Xavier Padro","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/5443fbc8fb815652f181942d4622090d"},"headline":"Monitoring and Management","datePublished":"2015-09-29T19:01:48+00:00","dateModified":"2023-12-13T09:57:39+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html"},"wordCount":1855,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Spring","Spring Integration"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html","url":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html","name":"Monitoring and Management - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2015-09-29T19:01:48+00:00","dateModified":"2023-12-13T09:57:39+00:00","description":"This article is part of our Academy Course titled Spring Integration for EAI. In this course, you are introduced to Enterprise Application Integration","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/monitoring-and-management.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Monitoring and Management"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/5443fbc8fb815652f181942d4622090d","name":"Xavier Padro","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/bbf0579a188773b88762d54dadc779b2cd17ddb261d809956ed55d8569bd7ca2?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/bbf0579a188773b88762d54dadc779b2cd17ddb261d809956ed55d8569bd7ca2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bbf0579a188773b88762d54dadc779b2cd17ddb261d809956ed55d8569bd7ca2?s=96&d=mm&r=g","caption":"Xavier Padro"},"description":"Xavier is a software developer working in a consulting firm based in Barcelona. He is specialized in web application development with experience in both frontend and backend. He is interested in everything related to Java and the Spring framework.","sameAs":["http:\/\/xpadro.blogspot.gr\/","http:\/\/linkedin.com\/pub\/xavier-padro-sobrepera\/1a\/64\/3\/en","https:\/\/x.com\/https:\/\/twitter.com\/xavips"],"url":"https:\/\/www.javacodegeeks.com\/author\/xavier-padro"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/44592","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/533"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=44592"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/44592\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=44592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=44592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=44592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}