Thursday, August 27, 2015

MQTT retain message flow in WSO2 MB





This article will explain basics of retain feature as it's defined in MQTT 3.1specification[1], Simple use case of retain feature and high level architecture of how MQTT retain messages handled in WSO2 message broker 3.0.0[2].

What is MQTT retain ?


MQTT retain is a method to keep certain messages (retain flagged) within broker so future subscribers for same topic can receive these messages. According to MQTT 3.1 specification[1] following are the main attributes of retain feature in MQTT.

  • Publishing client decides if a particular message should kept in broker for future subscribers. (set retain flag upon publishing the message)
  • When a new subscriber subscribed for given topic if there is a retained message for that topic it should be delivered to subscriber upon subscription.
  • Retain message should remove from broker if an empty payload received for a given topic with retain flag set to true.

All retain messages will honor QOS and other basic MQTT rules defined in specification[1].


Simple use-case for MQTT retain


MQTT is a light weight messaging protocol which mainly focused on IoT (Internet of things) developments. There can be instances where network connections or even sensors itself not available in practical scenarios. By using MQTT retain feature it's possible to keep a last known good value for future subscribers upon subscribing.

For example, Smart temperature monitor can check if the temperature outside operational range and send warnings with retain flag enabled (temporary warning message). Any newly joined equipment (subscriber) can take precautions to handle the situation even if the  temperature monitor is offline/ broken at the time of subscribing since it'll receive the retained warning message.

Once parameters are within desired range it can remove the retain enabled message from broker (Remove the warning) by sending empty payload message with retain enabled. This will remove the retain message and future subscribers won't receive it.


High level architecture of MQTT retain implementation in WSO2 MB 3.0.0


There are two paths in retain feature.  Namely there are as follows.
  • Retain Publish Path (Message flow path when MQTT message received with retain flag set by the broker)
  • Retain Delivery Path (Message flow path where retain message delivered to MQTT topic subscriber upon subscription)

Retain Publish Path


Following diagram shows start to end message flow path when a retain message hit on broker. 



Retain Publish Path

When a MQTT message received to the broker retain state will pass through disruptor before processing it.

In PersistenceStoreConnector MQTT message metadata will be converted to andes message metadata and retain state will be preserved in andes metadata for further processing.

Inside disruptor, onUpdateEvent retain message will put to the event list. Message writer will write to data stores once message writer event triggered.

After onUpdateEvent triggered messageWriter Event will be triggered. This event will call MessagingEngine to write retained messages to datasource.

MessagingEngine will call store retain messages methods in MessageStore interface and call relevant data source implementation to store retain messages. Unlike normal MQTT/AMQP messages, retain messages will be stored on separate retain specific table on MB message store. (MB_RETAINED_CONTENT, MB_RETAINED_METADATA)


Retain Delivery Path


Following diagram shows start to end message delivery path when a subscriber subscribe to a topic and that particular topic has retained messages stored on broker side.


Retain Delivery Path



Retain delivery path triggers when a MQTT subscriber subscribed to a topic. On state change event updateState() in AndesInboundStateEvent will call handleOpenSubscriptionEvent().
OpenSubscriptionEvent() will check if subscription instance is a MQTT and if it's MQTT check for retained messages for subscribed topic.

Retained message metadata will be retrieved(if there's any) from messagingEngine by calling getRetainedMessageByTopic method. This method will check if there's any wildcard matches[1] for subscribed topic as well.

If there's any retained message metadata found for subscribed topic contents of that message will send to the subscriber directly.

This concludes life cycle of a retained message once subscriber receives the message.



References

[1] http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/MQTT_V3.1_Protocol_Specific.pdf
[2] http://wso2.com/products/message-broker/

Monday, January 19, 2015

WSO2 Carbon : Remote debug wso2 carbon components using Intellij Idea IDE






In this brief tutorial I'll explain how to remote debug a carbon component. Since all wso2 products are based on  carbon components, this simple tutorial will help you to debug any wso2 product.

Please note that first section explains how to install carbon component using p2 repository as a feature. You can skip first section if you have a component already installed.

Prerequisites :

WSO2 carbon binary [download] [1]
Sample carbon component [git repo] [2]
Intllij Idea IDE

Install Carbon Component

First we have to install carbon component to a carbon instance. This step is needed since we are going to remote debug installed component. If you have already installed/build the component you wants to debug skip this section and start with 'Remote Debugging'.

1. Download and extract wso2 carbon zip file.
Run wso2server.sh in {wso2_carbon_base}/wso2carbon-4.2.0/bin directory using CLI as follows.
sh wso2server.sh

If carbon instance successfully initiated it should promote a url for carbon console in CLI.
pumudus-MacBook-Pro:bin pumudu$ sh wso2server.sh
JAVA_HOME environment variable is set to /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
CARBON_HOME environment variable is set to /Users/pumudu/Documents/carbon/wso2carbon-4.2.0
[2015-01-19 13:28:03,617]  INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} -  Starting WSO2 Carbon...
[2015-01-19 13:28:03,620]  INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} -  Operating System : Mac OS X 10.9.4, x86_64
[2015-01-19 13:28:03,620]  INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} -  Java Home        : /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
[2015-01-19 13:28:03,620]  INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} -  Java Version     : 1.6.0_65
[2015-01-19 13:28:03,620]  INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} -  Java VM          : Java HotSpot(TM) 64-Bit Server VM 20.65-b04-462,Apple Inc.
[2015-01-19 13:28:03,620]  INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} -  Carbon Home      : /Users/pumudu/Documents/carbon/wso2carbon-4.2.0
[2015-01-19 13:28:03,621]  INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} -  Java Temp Dir    : /Users/pumudu/Documents/carbon/wso2carbon-4.2.0/tmp
[2015-01-19 13:28:03,621]  INFO {org.wso2.carbon.core.internal.CarbonCoreActivator} -  User             : pumudu, en-US, Asia/Colombo
[2015-01-19 13:28:03,670]  WARN {org.wso2.carbon.core.bootup.validator.util.ValidationResultPrinter} -  The default keystore (wso2carbon.jks) is currently being used. To maximize security when deploying to a production environment, configure a new keystore with a unique password in the production server profile.
[2015-01-19 13:28:04,568]  INFO {org.wso2.carbon.registry.core.jdbc.EmbeddedRegistryService} -  Configured Registry in 50ms
[2015-01-19 13:28:04,660]  INFO {org.wso2.carbon.registry.core.internal.RegistryCoreServiceComponent} -  Registry Mode    : READ-WRITE
[2015-01-19 13:28:04,718]  INFO {org.wso2.carbon.user.core.internal.UserStoreMgtDSComponent} -  Carbon UserStoreMgtDSComponent activated successfully.
[2015-01-19 13:28:07,726]  INFO {org.apache.catalina.startup.TaglibUriRule} -  TLD skipped. URI: http://tiles.apache.org/tags-tiles is already defined
[2015-01-19 13:28:08,704]  INFO {org.wso2.carbon.core.deployment.DeploymentInterceptor} -  Deploying Axis2 service: echo {super-tenant}
[2015-01-19 13:28:08,872]  INFO {org.wso2.carbon.core.deployment.DeploymentInterceptor} -  Deploying Axis2 service: Version {super-tenant}
[2015-01-19 13:28:08,964]  INFO {org.wso2.carbon.core.deployment.DeploymentInterceptor} -  Deploying Axis2 service: echo {super-tenant}
[2015-01-19 13:28:09,022]  INFO {org.wso2.carbon.core.deployment.DeploymentInterceptor} -  Deploying Axis2 service: Version {super-tenant}
[2015-01-19 13:28:09,503]  INFO {org.wso2.carbon.core.init.CarbonServerManager} -  Repository       : /Users/pumudu/Documents/carbon/wso2carbon-4.2.0/repository/deployment/server/
[2015-01-19 13:28:09,518]  INFO {org.wso2.carbon.core.internal.permission.update.PermissionUpdater} -  Permission cache updated for tenant -1234
[2015-01-19 13:28:09,537]  INFO {org.wso2.carbon.core.transports.http.HttpsTransportListener} -  HTTPS port       : 9443
[2015-01-19 13:28:09,537]  INFO {org.wso2.carbon.core.transports.http.HttpTransportListener} -  HTTP port        : 9763
[2015-01-19 13:28:09,548]  INFO {org.apache.tomcat.util.net.NioSelectorPool} -  Using a shared selector for servlet write/read
[2015-01-19 13:28:09,669]  INFO {org.apache.tomcat.util.net.NioSelectorPool} -  Using a shared selector for servlet write/read
[2015-01-19 13:28:09,878]  INFO {org.wso2.carbon.core.init.JMXServerManager} -  JMX Service URL  : service:jmx:rmi://localhost:11111/jndi/rmi://localhost:9999/jmxrmi
[2015-01-19 13:28:09,879]  INFO {org.wso2.carbon.core.internal.StartupFinalizerServiceComponent} -  Server           :  WSO2 Carbon-4.2.0
[2015-01-19 13:28:09,879]  INFO {org.wso2.carbon.core.internal.StartupFinalizerServiceComponent} -  WSO2 Carbon started in 8 sec
[2015-01-19 13:28:10,004]  INFO {org.wso2.carbon.ui.internal.CarbonUIServiceComponent} -  Mgt Console URL  : https://10.106.3.125:9443/carbon/

2. Log into carbon management console using Mgt console URL : https://10.106.3.125:9443/carbon/
Default credentials username : admin Password : admin

3. From given simple carbon component git repository[2] get the source code of carbon component.

4. After logged into carbon management console goto
Configure -> Features -> Feature Management -> Repository Management -> Add Repository.
Then copy paste P-2 repository path from target directory.
{base_carbon_component}/order-manager/order-manager-repository/target/p2-repo/



5. Install "Order Manager Aggregate" carbon component using Available Features tab.



6. If everything went smoothly it'll ask you to restart the server. Using CLI or using web console restart the wso2 server.



7. Once restarted the server and logged into management console order management ui should appear  under main tab.
  


It's a very simple CRUD system. Feel free to add few entries and understand the functionality of this component. Now we can start debug this order management component using intellij IDE.

Remote Debugging


1. Start carbon server with debug enabled using following command.
sh wso2server.sh -debug 5005


2. Open carbon component project[2] using Intellij IDE. We'll debug addOrder and deleteOrder methods in back end. Similarly we can debug front end as well.
Add two break points in line number 49 and 79 in OrderService.java as follows.
order-manager/order-manager-components/org.wso2.carbon.order.mgt/src/main/java/org/wso2/carbon/order/mgt/OrderService.java 


3. Goto Run-> Debug.. It'll open debug dialog box. first select Remote and then click on plus sign on upper left corner.



4. Give appropriate name for debug session instead of "unnamed" and click on debug. Make sure Host is localhost and Port has set to 5005.

5. Once carbon server successfully boot up log in as admin in carbon management console and try to add a new order entry.


Click on resume program in debugger panel or press F9 to resume. Make sure you resume once you done with a break point before interacting with the management console again.

6. Similarly try to delete a record and it'll trigger the break point in line number 79.



This is how you can remote debug any carbon related product / component by intellij idea.
Happy debugging..!!! good luck..!!!




Reference :
[1] http://wso2.com/products/carbon/
[2] https://github.com/pumudu88/SimpleCarbonComponent


Monday, January 12, 2015

WSO2 Carbon : What's WSO2 Carbon ?






What's Carbon (The Definition)

WSO2 Carbon platform is the base framework for all WSO2 products and Cloud services. It's based on java OSGi(Open Service Gateway initiative) and it's 100% open source. WSO2 Carbon is lean, consistent, modular, componentized middleware platform for enterprise softwares. The Carbon platform consists of a powerful core set of components and numerous product-specific components that are plugged together to provide a unique set of products.

One of the main characteristic of carbon components is that they can be easily decoupled. Carbon components can be added or removed from any given carbon instance easily because of this decoupling characteristic.  




WSO2 carbon platform diagram

Why we need Carbon like platform ?

Following are some major advantages in carbon platform.
  • High scalability.
  • Easy to extend functionality.
  • Well defined approaches to create carbon components.
  • StratosLive consistent management and operations.
  • Adding new servers and functions smoothly without downtime.


Following are some features in Carbon platform
  • Manages the packaging of OSGi bundles into features.
  • Supports deploying, un-deploying, checkpoints.
  • Advanced features included shared repositories