Monday, February 24, 2014

Dashboard - Gadget communication using pub/sub within WSO2 UES

What is pub/sub?

This is a messaging pattern where message senders named publishers and consumers named subscribers. In this architecture publishers are not directly sending messages to consumers but sending to a channel where interesting parties(subscribers) subscribe to this channel and consume messages.

In this blog-post, portal or my dashboard acts as the publisher where user triggers any event to publish and simple gadget acts as the subscriber.

My requirement is to have something similar to the following, When user triggers "Publish a random number" button, dashboard should publish a random number to a predefined channel.Subscriber gadget subscribes to this channel and print the published random number.


How can we create this type of a dashboard?

Refer WSO2-UES documentation on how to create a gadget and how to add gadgets to dashboards.

Note :- 
If you browse <UES_HOME>/repository/deployment/server/jaggeryapps/portal/dashboard-template/files/ directory this is where we store template files for your dashboards. You may update index.jag.hbs file according to your preference, but keep in mind hereafter every time you create a dashboard, these changes will reflect on the dashboard.

Since our requirement is to have this template for all my dashboards, lets update the index.jag.hbs file.

You can find the full updated source gist here[1].
Note I have added the following HTML snippet to get the user input and display the published value.
<input type="button" value="Publish a random number" onclick="publish()"/>
<div id="output"> </div>
Also I have introduced following script, in order to publish a random number to the defined channel.
<script>
function publish() {
               var message = Math.random();
               UESContainer.inlineClient.publish('my-channel', message);
               document.getElementById("output").innerHTML = "Number that is published to the channel : " + message;
        }
</script>
Lets move to the gadget, you may find the source for this sample subscriber gadget here[2] and refer "Subscriber Gadget" section from this blog post[3] if you need to build the subscriber gadget from the scratch.

Interested about inter-gadget communication within WSO2-UES? you may refer the same blog post[3] done by tanya.

[1]. https://gist.github.com/udarakr/d9ebe3c32b64ec4e1ba0
[2]. https://svn.wso2.org/repos/wso2/people/tanya/pub-sub/subscriber/
[3] http://tanyamadurapperuma.blogspot.com/2013/12/inter-gadget-communication-with-wso2-ues.html

Monday, February 17, 2014

Simple web-app with SSO capability which showcase CarbonContext usage

I'm going to use WSO2 Application Server 5.2.1[1] and WSO2 Identity Server 4.5.0[2] to deploy simple web-app with SSO capability to showcase CarbonContext[3] usage.

Without writing this webapp from the scratch I will use/modify the SSOAgentSample which can find here[4].

First let's checkout the source from this location[4] and modify it for our purpose.

a) Open travelocity.properties which can find under SSOAgentSample/src/main/resources/ directory,
vi src/main/resources/travelocity.properties
b) Update following properties, update the port from 8080 to 9764 and comment out AttributeConsumingServiceIndex property.
#The URL of the SAML 2.0 Assertion Consumer
SAML.ConsumerUrl=http://localhost:9764/travelocity.com/samlsso-home.jsp


#Identifier given for the Service Provider for SAML 2.0 attributes
#exchange
#SAML.AttributeConsumingServiceIndex=1701087467
 c) Run following command within SSOAgentSample directory to build the webapp.
mvn clean install
 We are done with the sample webapp for now, but I will update this to showcase CarbonContext usage and provide source in github.

d) Start WSO2 Identity Server, run following within Identity Server home.
sh bin/wso2server.sh
e) Lets register a new service provider in IS, browse Home> Manage> SAML SSO
and press  Register New Service Provider link.Provide following details and press Register.

Issuer : travelocity.com
Assertion Consumer URL:http://localhost:9764/travelocity.com/samlsso-home.jsp

Select other stuff according to your requirements, I'm going to select
Enable Response Signing, Enable Assertion Signing, Enable Single Logout and Enable Attribute Profile. 

Since I'm going to display roles, email address and given name of the logged in user within webapp I will select and add following three claims.

http://wso2.org/claims/role
http://wso2.org/claims/emailaddress
http://wso2.org/claims/givenname


f) Lets upload our webapp to AS and start using a port offset. Copy travelocity.com.war from SSOAgentSample/target to <AS_HOME>/repository/deployment/server/webapps/ directory.

In my local setup,
cp target/travelocity.com.war /home/udara/wso2/workspace/wso2as-5.2.1/repository/deployment/server/webapps
Since I'm starting Application Server in the same local machine which Identity Server instance resides, In-order to avoid port conflicts lets update port-offset within <AS_HOME>repository/conf/carbon.xml.
 <Offset>1</Offset>
g) Start WSO2 Application Server, run following within Application Server home.
sh bin/wso2server.sh
h) Browse http://localhost:9764/travelocity.com/ and select login with SAML from Identity Server and it will automatically redirects to the Identity Server login page.

 



Provide your username/password and Identity Server will automatically redirects you back to the http://localhost:9764/travelocity.com/samlsso-home.jsp with claims that we select in step e.

CarbonContext[3] usage

Lets update our webapp to list down all users within same tenant.

Add following import statements to the src/main/webapp/samlsso-home.jsp file along with current import statements.

<%@page import="org.wso2.carbon.context.CarbonContext" %>
<%@page import="org.wso2.carbon.user.api.UserRealm" %>
Add following highlighted snippet to obtain the reference to the user-realm from the CarbonContext and print user list.

        </table>
        <a href="index.jsp">Go to Login page</a>
        <hr/>
        <!--Start of The user list-->
        <p><b>The user list</b></p>
            <%
                CarbonContext context = CarbonContext.getCurrentContext();
                UserRealm realm = context.getUserRealm();
                String[] names = realm.getUserStoreManager().listUsers("*", 100);
                    for (String name : names) {
                       %><%=name%><br/><%
                    }
            %>
            <!--End of The user list-->

        <form action="logout">
        <input type="submit" value="Logout">


i) Build(Step c) and re-deploy your webapp.
j) Browse http://localhost:9764/travelocity.com/samlsso-home.jsp and you will get,



I have created a repo to provide the updated source, you can find related repo here[5].


[1]. http://wso2.com/products/application-server/
[2]. http://wso2.com/products/identity-server/
[3]. http://docs.wso2.org/display/Carbon420/CarbonContext+API
[4]. https://svn.wso2.org/repos/wso2/carbon/platform/branches/turing/products/is/4.5.0/modules/samples/sso/SSOAgentSample/
[5]. https://github.com/udarakr/SSOAgentSample-1.0

Tuesday, February 11, 2014

Creating RabbitMQ Proxy Service in WSO2 ESB with different exchange types

You can follow documentation for RabbitMQ AMQP Transport here[1] if you wish to use exchange type as direct.According to the following implementation
if you don't specify the exchange type it will set to direct by default.

String exchangerType = properties.get(RabbitMQConstants.EXCHANGE_TYPE);
if (exchangerType != null) {
     String durable = properties.get(RabbitMQConstants.EXCHANGE_DURABLE);
         if (durable != null) {
              channel.exchangeDeclare(exchangeName, exchangerType, Boolean.parseBoolean(durable));
         } else {
              channel.exchangeDeclare(exchangeName, exchangerType, true);
         }
 } else {
      channel.exchangeDeclare(exchangeName, "direct", true);
 }

So how to use other exchange types such as topic, headers, x-consistent-hash etc...

Simple solution is to introduce the property "rabbitmq.exchange.type" to your proxy end-point URI.

Default sample proxy,

<proxy xmlns="http://ws.apache.org/ns/synapse" name="AMQPProxy" transports="rabbitmq" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <log level="full"/>
         <property name="OUT_ONLY" value="true"/>
         <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
      </inSequence>
      <endpoint>
         <address
         uri="rabbitmq:/AMQPProxy?rabbitmq.server.host.name=localhost&rabbitmq.server.port=5672&rabbitmq.server.user.name=guest&rabbitmq.server.password=guest&rabbitmq.queue.name=queue2&rabbitmq.exchange.name=exchange2"/>
      </endpoint>
   </target>
   <parameter name="rabbitmq.queue.name">queue1</parameter>
   <parameter name="rabbitmq.exchange.name">exchange1</parameter>
   <parameter name="rabbitmq.connection.factory">AMQPConnectionFactory</parameter>
   <description></description>
</proxy>

Following is my updated end-point, which is going to use x-consistent-hash as the exchange type.

<endpoint>
         <address
         uri="rabbitmq:/AMQPProxy?rabbitmq.server.host.name=localhost&rabbitmq.server.port=5672&rabbitmq.server.user.name=guest&rabbitmq.server.password=guest&rabbitmq.queue.name=queue2&rabbitmq.exchange.type=x-consistent-hash&rabbitmq.exchange.name=exchange2"/>
      </endpoint>

[1]. http://docs.wso2.org/display/ESB460/RabbitMQ+AMQP+Transport

RabbitMQ Management and Configuration

While creating a RabbitMQ proxy service with WSO2 ESB, I googled a bit about management aspects of RabbitMQ and complied this post as a future reference.

I took the easiest way to install RabbitMQ by using a .deb downloaded from here[1]. Found that there are two main configuration files in RabbitMQ, rabbitmq-env.conf is to set up environment related details and rabbitmq.config to configure RabbitMQ core application, Erlang services and RabbitMQ plug-ins.But the most important fact to keep in mind is that these configuration files are not created by default.

For my purpose of moving from default port 5672 to 8080, I have created /etc/rabbitmq/rabbitmq.config file with the following content.
[ {rabbit, [{tcp_listeners, [8080]}]} ].
Then start/restart RabbitMQ server with the following command.
sudo service rabbitmq-server start
Since I haven't change any environment specific configurations yet, I can use the default RabbitMQ startup log to monitor startup process with following command.
tail -f /var/log/rabbitmq/startup_log
For easy management and configuration RabbitMQ do have a nice web UI. But you have to activate rabbitmq_management plugin in-order-to access it.
rabbitmq-plugins enable rabbitmq_management
Then,browse http://localhost:15672/#/ or if you have already changed the port same as me http://localhost:18080/#/.

For more information you can find out official documentation here[2].
 
[1]. http://www.rabbitmq.com/releases/rabbitmq-server/v3.0.2/
[2]. https://www.rabbitmq.com/