Thursday, December 12, 2013

Flot - Get Your Ticks Rotated With Flot-Tickrotor

Once again this blog post is some simple but useful feature that I came across while playing out with Flot.

Problem
Have you ever got into trouble by your x-axis ticks overlapping on each other as you have many to be occupied within a small place-holder or because ticks are too long? It will make your chart look like a mess. 

Solution
As a workaround you can increase the width of your place-holder. But you will face into trouble if your place-holder has already occupied the full length of your page or your place-holder size is fixed and you don't have control over it.

Best possible solution
Probably you might have thought of rotating them in some angle to get this solved so that the visibility of the ticks get improved. Yes, that is the best possible solution that one can think of. Rotate the x-axis ticks !!!

So in this blog post I will explain how you can rotate your ticks or in other words display your ticks in some preferred angle.

It is just simple three step process.

1. Clone Flot-Tickrotor from here and place the jquery.flot.tickrotor.js along with other flot plugins.
2. Import the script file in your chart file as follows. 

   
     <script language="javascript" src="lib/jquery.flot.tickrotor.js" type="text/javascript"></script>

          
IMPORTANT :
If you are using jquery.flot.axislabels.js then make sure that you place your jquery.flot.tickrotor.js before the jquery.flot.axislabels.js. Because jquery.flot.tickrotor.js completely redefines X-axis label height and then jquery.flot.axislabels.js modifies it.

3. In the options section of the xaxis specify the angle that you need to get your ticks rotated as rotateTicks.


                xaxis: {
                        axisLabel: 'Application',
                          ticks: ticks,
                        -------------------------
                        < your other x-axis options goes here >
                        -------------------------
                        rotateTicks: 135
               }



We are ready to go !!! Now our x-axis ticks have rotated with an angle of 135 degrees.


IMPORTANT :
You need to use the jquery.flot.js file from the flot-branch master as there is some bug fixed done in the master, related to ticks rotation.

If not, you will end up with your ticks getting repeated as shown in the below image.


You can find the full sample code of the above graph here .

Acknowledgement
- Thanks Mark Cote for the flot plugin to get the ticks rotated.


Inter Gadget Communication with WSO2 UES

The main objective of this blog post is to explain how to implement inter-gadget communication with WSO2 User Engagement Server (UES). 


Inter - Gadget Communication
Inter-gadget communication that we are talking here is the capability of one gadget to talk with some other gadget. In simple words "is Gadget A capable of sending some data to Gadget B" and "is Gadget B capable of updating itself with the received data". The message paradigm that is used underneath is the publisher - subscriber model.


Publisher - Subscriber Model
As shown in the image given below, publisher publishes the message to a channel and subscribers listen to that channel. Upon a new message in the channel by the publisher, subscribers fetch the message and update their selves accordingly.



In a complex scenario, there can be one publisher publishing to multiple channels and also number of subscribers listening to multiple channels. 

The role of WSO2 User Engagement Server is to act as the Message Broker in this paradigm.

Implementation
I will explain the implementation of this publisher - subscriber (pub-sub) model with a simple example scenario.

Let's say publisher-gadget publishes a random number to a channel and that random number will be shown up in the subscriber-gadget each time that publisher-gadget will publish.

Gadgets usually communicate with the gadget-container via features and those features are declared in the the ModulPrefs section of gadget.xml file.

Gadgets convey their interest to either publish or subscribe to a channel via the gadgets.Hub.* API. Therefore the feature titled "pubsub-2" needs to be imported in-order to load the necessary API fragments . As I mentioned earlier this feature can be declared in the ModulePrefs section of our gadget.

OK. Now let's make our hands dirty with the sample that I described earlier.

Hint : Once we are done with the implementation we will have two gadgets with the following folder/file structure.



Publisher Gadget
Let's see how we can declare this in the publisher - gadget.xml file.


       <Require feature="pubsub-2">
                <Param name="topics">
                          <![CDATA[
                               <Topic title="randomNumber name="my-channel" publish="true"/>
                          ]]>
               </Param>
      </Require>


Pay attention to the sections I have marked in red in the above code snippet.  Feature that we have to import is pubsub-2. And my-channel is the channel that the publisher wishes to publish into. To indicate that this is the publisher gadget we have set publish="true".

In the sample that I'm going to describe in this post, when somebody clicks the button named "Publish a random number" in the publisher gadget, a random number will be published to my-channel. So let's have a button declared in our gadget.xml file.


         <div>
              <input type="button" value="Publish a random number" onclick="publish()"/>
         </div>


The function call that will be triggered by this button click is publish() and we define it in the js file of our publisher - gadget. (in publisher-gadget.js)


          function publish() {
               var message = Math.random();
               gadgets.Hub.publish("my-channel", message);
               document.getElementById("output").innerHTML = "Number that is published to the channel : " + message;
        }


Once again pay your attention to the red line which says publish the random number to my-channel which we declared in the ModulePrefs section.

Subscriber Gadget
As we did in the publisher gadget, we need to import the pubsub-2 feature and declare this gadget as a subscriber gadget in the subscriber-gadget.xml file.


          <Require feature="pubsub-2">
            <Param name="topics">
                <![CDATA[
<Topic title="randomNumber" name="my-channel"
description="Subscribes to random number channel" type="object"
subscribe="true"/>
]]>
            </Param>
        </Require>


And then let's have a simple div in the subscriber-gadget.xml file which we can use to set the fetched value from the publisher's channel.


          <div id="output"> </div>


After that we need to add the following snippet in the subscriber-gadget.js to activate the subscription to "my-channel" channel.


         gadgets.HubSettings.onConnect = function () {
                     gadgets.Hub.subscribe("my-channel", callback);
         };


The function that we want to invoke in the subscriber end, upon a message publishing by the publisher is written in the javascript callback function as follows which is also in the subscriber-gadget.js file.


         function callback(topic, obj, subscriberData) {
               document.getElementById("output").innerHTML = "Number that is fetched from the channel : " + obj;
         }


OK. We are done with the pub-sub implementation.

Finally what we need to do is add these two gadgets to a WSO2 UES dashboard and check out the functionality.

For that you can follow WSO2 UES documentation on how to create a gadget and how to add gadgets to dashboards.

Or else there is a bit hacky way also ;) (Not recommended. But if you want to check whether your two gadgets working fine, you can try this out.)

1. Copy your two gadgets in UES_HOME/repository/deployment/server/jaggeryapps/portal/gadgets/
2. Then create a dashboard (let's say our dashboard is pub-sub) using any two of the existing gadgets (NOT our two gadgets) in UES dashboard.
3. Open up UES_HOME/repository/deployment/server/jaggeryapps/pub-sub and open up the index.jag
4. Search for word .xml and you will find two of them.
5. Replace those two urls with the following and save the index.jag file.
             http://localhost:9763/portal/gadgets/publisher/publisher-gadget.xml
             http://localhost:9763/portal/gadgets/subscriber/subscriber-gadget.xml

So your index.jag will have two snippets as follows.



     <li class="layout_block " data-sizey="2" data-sizex="2" data-col="1" data-row="2" 
                data-url="http://localhost:9763/portal/gadgets/publisher/publisher-gadget.xml
                data-wid="5" data-prefs="{}" data-title="">




     <li class="layout_block " data-sizey="2" data-sizex="2" data-col="3" data-row="2"
                data-url="http://localhost:9763/portal/gadgets/subscriber/subscriber-gadget.xml
                data-wid="6" data-prefs="{}" data-title="">


6. And then access the dashboard as https://localhost:9443/pub-sub/
7. You'll see a dashboard as given in the below image.


8. Click on "Publish a random number" button in the publisher gadget and observe that the same number getting printed in the subscriber gadget as well.



9. Try clicking on the same button several times and observe the subscriber gadget updating its content accordingly.

You can download the complete code of the above two gadget from here.

Real World Scenario
Let's say we have a time slider as the publsiher gadget. Upon a time period selection on the slider, we need to display the number of builds per apps within that period in a seperate gadget. So the later gadget acts as the subscriber by listening to the time slider gadget's channel.

You can do whole lot of things with WSO2 UES pub-sub model :)
Enjoy !!!

Acknowledgement
- Thanks to the WSO2 Gadget Server ( currently deprecated )  documentation on pub-sub model.


Monday, December 9, 2013

How to Get Axis Labels in Flot Charts

Have you tried adding axis labels in to any type of Flot chart ? By default Flot does not support axis labels. But it is very easy to get the axis labels with the aid of a simple plugin. So let's see how we can get it done in 3 steps !!!

  1. Git clone this repository and place the jquery.flot.axislabels.js inside the folder where you have other Flot related libraries or plugins.
                          git clone https://github.com/xuanluo/flot-axislabels.git

    2.  Import the script file in the Flot chart file as follows.

      <script language="javascript" type="text/javascript" src="../../jquery.flot.axislabels.js"></script>

    3. Pass the axis names and their formatting in the options section along with the other options of X-axis and Y-axis as in the below snippet.


                       xaxis: {
                     axisLabel: 'X',
                      axisLabelUseCanvas: true,
                      axisLabelFontSizePixels: 12,
        axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
        axisLabelPadding: 5

                 },
            yaxis: {
axisLabel: 'Sin(X)',
        axisLabelUseCanvas: true,
        axisLabelFontSizePixels: 12,
        axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
        axisLabelPadding: 5

               },

Now you can see the axis labels appearing in your chart as shown in the below image. 


We are done :) It is simple as that.

Have a look at the README section of the cloned repository  for more details. (Although I said a repository, it is just a single file )

You can refer the full sample code given below in-case if anything was unclear.



 
 Flot Axis Labels
 
 
 
 
 
 



 
Acknowledgement
[1] https://github.com/xuanluo/flot-axislabels


Wednesday, December 4, 2013

WSO2 ESB - Get-rid of Scientific Representation of Large Numbers When Message Transformed Through a XSLT Mediator

In this blog post I'm going to explain how to get-rid of the scientific representation ( ex: 2.2908408306E44 ) and get the non-scientific representation of the number when large numbers are mediated through the XSLT mediator. 

Problem

Following diagram explains the problem that I'm going to explain. Note that the large number that is sent across the mediator is derived from defined xpath and do some mediation logic to that particular number. (in this example multiplied by 55 ) The non-scientific number that we sent across the mediator has been converted in to a scientific number.


 When is this problematic ?

Assume that the number that is sent across the mediator is a customer ID. And the mediated customer ID will be sent through some other mediation logic or will be sent to a login portal. But that end will be expecting a non-scientific representation of the customer ID and this will result in a failure in that end.

Why is the large number represented in a scientific format ?

If you have used WSO2 ESB versions earlier to ESB 4.5.0, you might have noticed that this conversion does not happen. Reason behind this representation is from ESB 4.5.0 on-wards the XSLT engine that does the XSLT mediation has been replaced from xalan 2.7.0 to saxon. So saxon converts large numbers in to scientific representation.

How to reproduce the above scenario ?

I will explain how you can reproduce the above scenario using a sample proxy configuration with a sample XSLT style-sheet.

1. Start WSO2 ESB (tested in ESB 4.7.0) and create a proxy service using the following synapse configuration.


          

         
         
      
      
         
      
   
   
2. Go to Browse under Registry in the left pane and navigate to /_system/config/users/ and Click on Add Resource to add the given XSLT style-sheet (Add it as transform.xslt) and Save.

 
  
     

      
               
                
          

 

3. Go to back to Services list under Manage in the left pane and click on Try this service under testXSLT. (Our transoformation proxy service is testXSLT)

4. Use the following sample request to test out the behavior. And then click on Send.

<body>
   <customerDetail>
      <name>Tanya Madurapperuma</name>
      <id>416516514654651634984</id>
   </customerDetail>
</body>

5. Go and observe the logs that get printed on the ESB console. (Please note that in the given sample proxy configuration I have paid attention only to the message that is sent through the XSLT mediator and the message that is returned from the mediator but not about what is sent out from the out-sequence as this is just for reproducing the issue. )

In the sample proxy configuration I have set to log the message before it is sent through the mediator and the message after it is mediated by XSLT mediator.

Following are the logs that got printed in my console. Note I have marked the important parts of the log in red.

[2013-12-04 06:24:00,252]  INFO - LogMediator To: /services/testXSLT.testXSLTHttpSoap12Endpoint, WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:61a7932a-1852-421b-b6f2-fbea95117e95, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><customerDetail><name>Tanya Madurapperuma</name><id>416516514654651634984</id></customerDetail></soapenv:Body></soapenv:Envelope>

[2013-12-04 06:24:00,383]  INFO - LogMediator To: /services/testXSLT.testXSLTHttpSoap12Endpoint, WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:61a7932a-1852-421b-b6f2-fbea95117e95, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><id xmlns:cus="http://test.com" CUSTOMER_ID="2.2908408306005837E22"/></soapenv:Body></soapenv:Envelope>

Observe that id which was originally in non-scientific format is converted in to the scientific format once it is sent through the XSLT mediator.

How to get-rid of the scientific representation ?

Now let's look at how we can avoid our number getting converted to a scientific representation. There are two approaches that we can take in order to get this done.

Approach No 1
Change your XSLT style-sheet to get the number formatted back to non-scientific representation as in the following manner.

format-number($customerId * 55, "#")

You can edit your style-sheet as follows. Go to Browse under Registry and navigate to  /_system/config/users/transform.xslt and click on Edit as text and modify your XSLT style-sheet.

So at the end of the day your complete style-sheet will look as below.


 
 
     

      
               
               
          


Approach No 2
Replace the XSLT engine saxon with xalan.

Although this is not a recommended approach, you can get back the non-scientific representation by replacing the XSLT engine in WSO2 ESB with xalan.

For that download a WSO2 ESB version prior to 4.5.0. Then follow the below steps.

1. Go to ESB_HOME_4.7.0/lib/endorsed/ and back up saxon9he.jar and delete it.
2. Go to ESB_HOME_Prior_to_4.5.0/lib/endorsed/ and copy xalan-2.7.0.wso2v1.jar and paste in ESB_HOME_4.7.0/lib/endorsed/

And then try the transformation proxy with the same sample request.

So you logs will look like as follows once you have taken any of the above suggested approaches.

[2013-12-04 11:15:37,167]  INFO - LogMediator To: /services/testXSLT.testXSLTHttpSoap12Endpoint, WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:5a9fbd26-b905-4e4e-894d-325e5881c50d, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><customerDetail><name>Megan Aguilar</name><id>416516514654651634984</id></customerDetail></soapenv:Body></soapenv:Envelope>

[2013-12-04 11:15:37,171]  INFO - LogMediator To: /services/testXSLT.testXSLTHttpSoap12Endpoint, WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:5a9fbd26-b905-4e4e-894d-325e5881c50d, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><id xmlns:cus="http://test.com" CUSTOMER_ID="22908408306005836824576"/></soapenv:Body></soapenv:Envelope>

Observe that the number is back in non-scientific format !!!


Saturday, October 26, 2013

Flot Multi Bar Chart with Text based X-axis Ticks

Flot is a javascript plotting library for jquery which has some nice, interactive and easy to use features. Also unlike some other plotting libraries, almost all browsers supports flot graphs.

In this blog post I'm going to explain how to create a multi-bar chart using flot which has text based tick values in X axis. If you have ever played with Flot, you may know why I emphasize the phrase "text based tick values". Because flot normally supports only number based tick values in X-axis. As you read ahead the post, I'll show up the way how to get your texty ticks in X-axis.

As you can see in the above graph, I'm going to explain a multi bar chart drawn in order to display the number of successful and failed builds per each application. I will explain the code step by step in drawing the chart.


    
    
    
    

The first script tag contains the excanvas which is needed for support Internet Explorer versions below 9.

Flot placeholder is a jquery object and therefore you need to add the jquery.js. And then comes the file that is responsible for drawing all these flot charts which is jquery.flot.js. All the flot related library files can be checked out from the flot github location. (Note: To draw this graph we do not need all those files, but you might need them when trying with other types of graphs or other flot features.)

By default Flot doesn't come with the support for axis labels. The file jquery.flot.axislabels.js is included to make it possible to mark the axis names of the graph. In the above graph X-axis is named as App and Y-axis is named as No of builds. You can download that flot plugin from here.

In order to get the multi bar chart to work, we will have to include a plugin called jquery.flot.orderBars.js underneath the above files.  You can download the jquery.flot.orderBars.js from here.

Below given is the initial data set which I need to get a flot multi bar chart.



Now let's look at the format of the data that needs to be passed in to the flot graph.

The format of our initial data will be different from the data that is passed to the flot graph. As I have mentioned above, one reason for that is X-axis of the graph contains text based tick values such as "app4", "app5" and etc. But flot accepts only integer type ticks for the X-axis. So what we do is we come up with some integer mapping to represent each X-axis tick which is text based.

[1, "app4"],
[2, "app5"],
[3, "app6"],
[4, "app7"],
[5, "app8"]

So we map "app4", "app5" and etc with the integer we selected according to the above mapping.(instead of "app4" we put 1, for "app5" we put 2 and so on ) Hence the data that we will be passing to flot will take the following format.

var build_pass_data = [
                [1, 4],
                [2, 1],
                [3, 1],
                [4, 4],
                [5, 3]
            ];
var build_fail_data = [
                [1, 2],
                [2, 3],
                [3, 3],
                [4, 3],
                [5, 6]
            ];

var data = [
            {label: "PASS", data: build_pass_data, bars: {fillColor: "#336600"}, color: "#336600"},
            {label: "FAIL", data: build_fail_data, bars: {fillColor: "#E41B17"}, color: "#E41B17"}
           ]

Along with the data we will pass the fill color and the border color of the bars as well.

Then we have to tell the flot about the above mapping we used. That information is passed to the flot options. So our options section is as follows.

var options = {
                xaxis: {
                    min: 0,
                    max: 7,
                    mode: null,
                    ticks: [
                        [1, "app4"],
                        [2, "app5"],
                        [3, "app6"],
                        [4, "app7"],
                        [5, "app8"]
                    ],
                    tickLength: 0,
                    axisLabel: "App",
                    axisLabelUseCanvas: true,
                    axisLabelFontSizePixels: 12,
                    axisLabelFontFamily: "Verdana, Arial, Helvetica, Tahoma, sans-serif",
                    axisLabelPadding: 5
                }, yaxis: {
                    axisLabel: "No of builds",
                    tickDecimals: 0,
                    axisLabelUseCanvas: true,
                    axisLabelFontSizePixels: 12,
                    axisLabelFontFamily: "Verdana, Arial, Helvetica, Tahoma, sans-serif",
                    axisLabelPadding: 5
                }, grid: {
                    hoverable: true,
                    clickable: false,
                    borderWidth: 1
                }, legend: {
                    labelBoxBorderColor: "none", 
                    position: "right"
                }, series: {
                    shadowSize: 1, 
                    bars: {
                        show: true, 
                        barWidth: 0.13, 
                        order: 1
                    }
                }
            };


You might notice that under the "ticks" of xaxis we have placed our mapping. Also note how we have mentioned the X-axis name and the Y-axis name and their formatting.

Finally we need to pass the data and the options to the flot placeholder.

$.plot($("#placeholder"), data, options);

Additionally we have to specify the css of the placeholder,legend and etc for the better look and feels of the graph.

Now we are done with the Flot Multi-bar chart !!!

I have given the complete code below in-case you need any reference. (enclosed the following code within two html tags.)

Enjoy plotting with flot :)



    
    Flot Multi Bar Chart

    

    
    
    
    
    

    




Sunday, October 20, 2013

Tricky way to modify the userName SCIM claim in WSO2 Identity Server ( IS )

SCIM is an open standard for Identity Provisioning. In simple words SCIM is designed to create, maintain (read,update) and deactivate (delete) user accounts and related identities which reside in one or more systems/applications.

In this blog post, I'm going to explain a tricky way to modify the userName claim. Why I said a tricky way is because you will not be able to simply update it via a curl command as userName claim in carbon user stores is immutable. If you have ever tried updating the userName claim, you might have ended up with an error like this.

{"Errors":[{"description":"User name is immutable in carbon user store.","code":"500"}]}

In order to test this, start a WSO2 IS (tested with IS 4.5.0) connected to Active Directory as back-end data store. (You can do it by modifying the user-mgt.xml to connect to a AD instance.)

And then go to Configure --> Claim Management and select urn:scim:schemas:core:1.0

Now we have to map the SCIM claims to the existing attributes of the Active Directory. Because when we add a user via SCIM, apart from the userName SCIM claim there are four other SCIM attributes that is being added behind the scene.
( Make sure that you map String type attributes from the AD with the SCIM claims. You can find the AD attributes here. )

CLAIM URIAD Attribute
urn:scim:schemas:core:1.0:userName mail
urn:scim:schemas:core:1.0:meta.location streetAddress
urn:scim:schemas:core:1.0:meta.created homePhone
urn:scim:schemas:core:1.0:meta.lastModified pager
urn:scim:schemas:core:1.0:id homePostalAddress

Apart from the above mapping add the following mappings as well. (This is for better explanation of this post.)

CLAIM URIAD Attribute
urn:scim:schemas:core:1.0:name.givenName givenName
urn:scim:schemas:core:1.0:name.familyName company

First of all let's Create a user via SCIM. 

curl -v -k --user username:password --data "{"schemas":[],"name":{"familyName":"Madurapperuma", "givenName":"Tani"},"userName":"tanya@wso2.com","password":"testing123@"}" --header "Content-Type:application/json" https://localhost:9443/wso2/scim/Users

You will get a response payload as follows.

{"id":"5c05a64c-4f9b-44c7-9092-27cd4dc15640","schemas":["urn:scim:schemas:core:1.0"],"name":{"familyName":"Madurapperuma","givenName":"Tani"},"userName":"tanya@wso2.com","meta":{"lastModified":"2013-10-20T09:47:35","location":"https://localhost:9443/wso2/scim/Users/5c05a64c-4f9b-44c7-9092-27cd4dc15640","created":"2013-10-20T09:47:35"}}

As I have mentioned above, you will not be able to update the userName SCIM claim after the creation of the user since the userName claim is immutable in carbon user store.

So with this tricky method you will be able to modify it.
Map the AD attribute that you have mapped to the userName claim to another SCIM claim and try modifying the newly mapped claim

In our case we have mapped AD attribute "mail" to SCIM claim "userName". So we will map it to SCIM claim "Emails" as well.

Now we have the following additional mapping as well.

CLAIM URI
AD Attribute
urn:scim:schemas:core:1.0:emails
mail

Now let's try updating SCIM claim "emails".

curl -v -k --user username:password -X PUT -d "{"schemas":[],"userName":"tanya@wso2.com", "emails":"tani@wso2.com"}" --header "Content-Type:application/json" https://localhost:9443/wso2/scim/Users/5c05a64c-4f9b-44c7-9092-27cd4dc15640

At this point, you might be worrying that it did not work seeing the response payload. Wait !!! The response payload that I got is as follows. 

{"id":"5c05a64c-4f9b-44c7-9092-27cd4dc15640","schemas":["urn:scim:schemas:core:1.0"],"userName":"tanya@wso2.com","emails":"tani@wso2.com","meta":{"lastModified":"2013-10-20T09:54:20","location":"https://localhost:9443/wso2/scim/Users/5c05a64c-4f9b-44c7-9092-27cd4dc15640","created":"2013-10-20T09:47:35"}} 

So hasn't the trick worked ? 

Let's get the updated user and see what has happenned.

curl -v -k --user username:password https://localhost:9443/wso2/scim/Users/5c05a64c-4f9b-44c7-9092-27cd4dc15640

Response payload is as follows. 

{"id":"5c05a64c-4f9b-44c7-9092-27cd4dc15640","schemas":["urn:scim:schemas:core:1.0"],"name":{"familyName":"Madurapperuma","givenName":"Tani"},"userName":"tani@wso2.com","emails":["tani@wso2.com"],"phoneNumbers":[{"value":"2013-10-01T09:54:20","type":"pager"},{"value":"2013-10-01T09:47:35","type":"home"}],"addresses":[{"value":"https://localhost:9443/wso2/scim/Users/5c05a64c-4f9b-44c7-9092-27cd4dc15640","type":"streetAddress"}],"meta":{"lastModified":"2013-10-20T09:54:20","created":"2013-10-20T09:47:35","location":"https://localhost:9443/wso2/scim/Users/5c05a64c-4f9b-44c7-9092-27cd4dc15640"}}

No more worries :) It has worked. You may notice that it is the same user that we created a while ago. See the familyName and the giveName values if you are not sure. 

So in summing up, all you have to do is just map the AD attribute that you mapped to SCIM claim userName to another AD attribute that is mutable.


Acknlowlegement
  • Venura and Ishara at WSO2 
  • Two blog posts by Hasini and Suresh

Saturday, October 5, 2013

Localizing WSO2 Carbon Products - Part 2

How to generate language fragment bundles to localize Carbon products


In this last blog post, I explained what is localizing, why we need to localize and also why we go ahead with the fragment bundle approach when it comes to localizing WSO2 carbon products.

So as I promised in the last post, will explain how to generate language fragment bundles. 
  1. First find out the ui bundles in CARBON_HOME/repository/components/plugins/ that contain Resources.properties files which you need to localize.
  2. And then pack resource files in the folder structure with the proper naming conventions. See the example below.




IMPORTANT: Note that folder names (such as org.wso2.carbon.claim.mgt.ui_4.2.0 ) should be named with the original bundle name and the version. ( I will explain later why you need to do so. )

  3. Once you have created the  resource files packed in the correct folder structure, place them in the           CARBON_HOME/resources folder. 

   4.  And navigate to the CARBON_HOME/bin and run the following command.
ant localize
    5. Now go to the CARBON_HOME/repository/components/dropins/. You will see the generated language bundles that you can use to localize.

NOTE: In case if you want to change the location of your resource files or stored location you can change it by passing those as parameters to the ant command.
ant localize -Dresources.directory=/data/blog/wso2is-4.5.0/myResources/ -Ddropins.directory=/data/blog/wso2is-4.5.0/myDrpoins/
But regardless your resource file location, after the generation of fragment bundles, you need to place them in the CARBON_HOME/repository/components/dropins/ directory.

   6. Now you change the locale through browser setting or pass as a query param to the url. And you will observe your page is being localized. Switch between locales and observe that the product getting changed with the new language.

Story behind ant task

In what ever the product you choose to localize, open the build.xml file at CARBON_HOME/bin. Bit down there in that file, there is an ant task called localize.

If you go through this ant task closely, you may note that the folder name of the resources files are spitted and assigned as fragment host and version.

 
      
       
      
      
       
       
      
       
       
      
      
      
      
      

Also note that default locations of resources directory is set to CARBON_HOME/resources while dropins directory is set to CARBON_HOME/repository/components/dropins/



Acknowledgement
My thanks goes to Sumedha at WSO2 for his tremendous support given during this task.


Friday, October 4, 2013

Localizing WSO2 Carbon Products - Part 1

Introduction to Localization of Carbon products 


WSO2 products are used all over the world and it's users may need to translate a product into different languages when adapting that particular product into their country or region. This process of translating the product into different languages is known as Localization.

If you open up any WSO2 product and go inside CARBON_HOME/repository/components/plugins, you will see number of jar files. Among those jars the ones that have their names end with ui_<version>.jar are usually the bundles that contains the resources files that needs to localization.

For an example, let's take WSO2 Identity Server 4.5.0 and go to repository/components/plugins. From that let's select org.wso2.carbon.claim.mgt.ui_4.2.0.jar. Open up the jar using an archive manager or in any preferred way. You may observe folder structure similar to this.



The file you see at the very end; Resources.properties file is the one which the page in the UI used to read string values from. If you open the Resources.properties file you'll observe that it contains some name value pairs as below.

claim.mgt=Claim Management

claim.add=Add

add=Add

cancel=Cancel

claim.management=Claim Management

new.claim.details=New Claim Details
First make a copy of this file and name it with the code of the locale of your preferred language. For an example if you want to localize to French, name of your file should look like Resources_fr.properties. And then you need to change the value of the name value pairs to go with your language. For an example you might change the first pair as follows.

claim.mgt=Gestion des réclamations
In order to localize the whole product, you need to add a resource file for each ui bundle with your desired language.

NOTE:
You can have any number of resource files inside one jar as follows. ( So that you can switch between different languages very easily.)











After that go ahead and change the locale either through browser settings or passing the locale through a url parameter ( as locale=fr ). Now if you refresh the page you will see the page being localized in your preferred language.

But the problem with this approach is that if you happen to patch any of these jars, you will have to update the Resources.properties file of your preferred language every time that you do so.

So the recommended approach is to localize through fragment bundles which gets attached to the specified host. In my next post I will be explaining how to generate the fragment bundles to localize WSO2 carbon products.

Monday, September 30, 2013

Configure WSO2 Identity Server SAML2 IDP with Oracle Weblogic as Service Provider

This blog post explains How to configure WSO2 Identity Server as SAML2 IDP and Oracle Weblogic as Service Provider.

You might already know that there are two parties engaged in a single sign on system.
  1. Identity Providers (IDP)
  2. Service Providers (SP)
So there should be a mechanism for the identity provider to know that this is an authentic service provider and at the same time service provider needs to know that authentication response came from a trusted identity provider. This secure transaction between IDP and SP is ensured by sharing metadata files of the two parties.

First let's see How can we configure Weblogic as a Service Provider.

First you need to download and install Weblogic server. You can download it from here and follow the README.txt for the installation. 

NOTE: Make sure you configure a new domain if you do not have one already.

Start a browser and log in to Oracle weblogic server administration console at http://localhost:7001/console

We will be using appB as the sample test application which you can download from here

Deploy appB in the Weblogic server. 
  1. Go to Deployments under <mydomain> and click install.
  2. Click upload your file(s) and browse appB.
  3. Keep all the default options and finish deployment.
Create a user in security realms.
  1. Go to Security Realms --> myrealm
  2. Select Users and Groups tab and Add a New user. (If you are using above appB, create your user as ssouser, because in weblogic.xml file of appB <principal-name> is defined as ssouser.)
Create SAML2 Identity Asserter.
  1. Go to Security Realms --> myrealm
  2. Providers tab --> Authentication tab and select New.
  3. Create an Identity Asserter choosing the type as SAML2IdentityAsserter
  4. Click on the just created SAML2IdentityAsserter and select Management tab. (You need to restart the admin server before this step to get the changes affected.)

  5. Click on New and select New Web Single Sign-On Identity Provider Partner.
  6. Browse and give the metadata file of WSO2 Identity Server. (NOTE : At the moment with IS 4.5.0 , it is not possible to auto generate the metadata file. The below given metadata file is one I created manually following the spec. )
    
       
           
             
                
                   MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJVUzELMAkGA1UE
    CAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoMBFdTTzIxEjAQBgNVBAMMCWxv
    Y2FsaG9zdDAeFw0xMDAyMTkwNzAyMjZaFw0zNTAyMTMwNzAyMjZaMFUxCzAJBgNVBAYTAlVTMQsw
    CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzENMAsGA1UECgwEV1NPMjESMBAGA1UE
    AwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTou
    sMzOM4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe0hseUdN5
    HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXnRS4HrKGJTzxaCcU7OQID
    AQABoxIwEDAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADgYEAW5wPR7cr1LAdq+IrR44i
    QlRG5ITCZXY9hI0PygLP2rHANh+PYfTmxbuOnykNGyhM6FjFLbW2uZHQTY1jMrPprjOrmyK5sjJR
    O4d1DeGHT/YnIjs9JogRKv4XHECwLtIVdAbIdWHEtVZJyMSktcyysFcvuhPQK8Qc/E/Wq8uHSCo=
                
             
          
         
    
         
    
         
    
    
    
    
    
  7. Click on the just created Identity Provider Partner and fill the details, tick the options as below and Click Save.
  8. Verify whether your metadata file has parsed correctly by navigating to Single Sign-On Signing Certificate tab and Single Sign-On Service Endpoints tab.
Configure at server level.
  1. Go to Environment --> Servers and Click on myserver(admin).
  2. Tick the SSL Listen Port Enabled option and Save.
NOTE: We will be using the demo Keystore and if you need you can have your own custom keystore.

SAML2 General Tab configurations.
  1. Go to Federation Services tab --> SAML 2.0 General tab. 
  2. Fill the fields with relevant information as shown below and Save.
SAML2 Service Provider Tab configurations.
  1. Go to Federation Services tab --> SAML 2.0 Service Provider tab.
  2. Enable it and Save.
Publish Metadata. (Incase your IDP requires a metadata file from Weblogic server.)
  1. Go back to SAML2 General tab and Click on Publish Meta Data.
  2. Provide a location to save the Weblogic metadata file.
Create SAML Authentication Provider.
  1. Go to Security Realms --> myrealm
  2. Providers tab --> Authentication tab and select New.
  3. Create SAML Authenticator choosing the type as SAMLAuthenticator
  4. Click on the just created SAMLAuthenticator.
  5. Go to Configuration tab --> Common tab and select Control Flag as Sufficient.

Go to DefaultAuthenticator and select Control Flag as Sufficient as well.

Now we have done with configuring Weblogic server as the service provider.


Let's have a look how can we configure WSO2 IS to serve as the Identity provider.

Start WSO2 Identity server (tested in IS 4.5.0) and login as admin.

Create the same user you created in Weblogic server in Identity Server.
  1. Go to Configure tab and click on Users.
  2. Click on Add New User and add the same user.
  3. Give Login permission to that user.

Register new Service Provider.
  1. Go to Main tab and select SAML SSO under Manage.
  2. Click on Register New Service Provider.
  3. Fill the data as below and click Register.
Now we have done with configuring both IDP and SP and it's the time to test the SAML2 Application.

Restart the weblogic server + WSO2 IS and go to http://localhost:7001/appB/admin/services.jsp  and you will be redirected to WSO2 Identity server SAML sso page.

Log in with the created user ( in our case ssouser )

If you see the below page, Congratulations !!! You have configured WSO2 IS as SAML2 IDP and Weblogic as SP.

Acknowledgement
  • My thanks goes to Prabath and Dulanja at WSO2.
  • Gilles for this excellent blog post.