Tuesday, December 10, 2013

UES-Dashboard with WebSockets enable Gadgets

With the use of Websockets capability of Jaggery, you can create Websockets enabled gadgets within UES.

1. Create new directory for our gadget, name it dummy-chat.
2. Create your gadget XML file with the following content,
    <?xml version="1.0" encoding="UTF-8" ?>
    <Module>
        <ModulePrefs title="WS Dummy chat application"
                    height="350"
                    description="This is a dummy sample gadget to showcase Web socket capability"
                    tags="chat">
           <Require feature="dynamic-height"/>
        </ModulePrefs>
        <Content type="html">
           <![CDATA[
           <script src="/portal/gadgets/dummy-chat/js/dummy-chat.js" type="text/javascript"></script>
           <div id="gadget-wrapper">
                   <div id="msg-content"></div>
                   <div id="gadget-area-div">
                   <textarea rows="4" cols="50" id="msg"></textarea><br/>
                   <button type="button" onclick="send()">Send Me!</button>
                   </div>
           </div>
           ]]>
        </Content>
    </Module>

Name this XML file dummy-chat.xml and save the content inside our gadget directory.

3. Create directory to store JavaScript files of our gadget, name it js.
4. Create dummy-chat.js file with following content inside js directory.
    var url,ws;
    window.onload = function WindowLoad(event) {
       url = 'wss://localhost:9443/ws-chat/server.jag';
       ws = new WebSocket(url);
       //event handler for the message event in the case of text frames
       ws.onopen = function() {
       console.log("web Socket onopen. ");
       };

       ws.onmessage = function(event) {
       console.log("web Socket Onmessage from Server. " + event.data);
       var reply = document.getElementById('msg-content');
       reply.innerHTML = reply.innerHTML + '<br/>' + event.data;
       };

       ws.onclose = function() {
       console.log("web Socket onclose. ");

       };
    }

    //send msg to the server
    function send(){
       var msg = document.getElementById('msg');
       ws.send(msg.value);
       console.log("Client message "+msg.value);
       msg.value = '';
    }

5. If you wish to have eye-catching thumbnail and banner for your gadget, you can store them inside dummy-chat directory.Find our directory structure here,

.
├── banner.jpg
├── dummy-chat.xml
├── js
│   └── dummy-chat.js
└── thumbnail.jpg

We are done with the Websocket client implementation. Client application here provides a text field and button to send messages, and provides a place where messages from the server printed.

Lets move to the server implementation, This dummy server acknowledges all messages and will print the same message with some dummy text.

I’m using the same server implementation from jaggey Websocket doc[1] with a small modification.

1. Create a new jaggery app and name it ws-chat.

2. Create server.jag with following content inside ws-chat directory.
    <%
    var log = new Log();
    webSocket.ontext = function (data) {
        log.info('Client Sent : ' + data);
        var ws = this;
        setTimeout(function () {
           var currentDate = new Date();
           ws.send("message received !!");
           ws.send(currentDate+" : "+data);
        }, 1000);
    };
    
    webSocket.onbinary = function (stream) {
        log.info('Client Streamed : ' + stream.toString());

    };
    %>
Server will send “message received !!”  and the received message with timestamp to the client.

Lets move to the deployment of this gadget client and the server,

1. Copy ws-chat jaggery application and host it inside <UES_HOME>/repository/deployment/server/jaggeryapps/
2. Move dummy-chat gadget to <UES_HOME>/repository/deployment/server/jaggeryapps/portal/gadgets/
3. Start UES instance by running ./wso2server.sh from <UES_HOME>/bin directory.

You can verify availability of the new gadget by browsing, http://localhost:9763/store/assets/gadget/
Lets bookmark this gadget and create our dashboard from dummy-chat gadget.Sign-in to the portal from http://localhost:9763/portal and follow creating a dashboard guide from here[2].
Browse https://localhost:9443/<DASHBOARD_NAME>/ while logged into the UES and you can use dummy-chat gadget within the dashboard.

[1] http://jaggeryjs.org/apidocs/websocket.jag
[2] http://docs.wso2.org/display/UES100/Creating+a+Dashboard

Wednesday, December 4, 2013

Overcome "class path is too long" error while executing WSO2 ciper tool in windows

The cipher tool is there to encrypt and decrypt simple texts and by default bundled with all WSO2 products. You can simply use this tool by running either the shell script or batch script inside <PRODUCT_HOME>/bin directory according to your environment.

I'm not going to explain in detail about this tool, but you can find out more information from here[1].

In this blog post I'm going to explain a workaround to get rid of the error "The class path is too long for the windows shell to handle it" when you try to run ciphertools.bat -Dconfigure" command within windows environment.

Before continue further just take a back-up of the <PRODUCT_HOME>/bin/cipertools.bat file.

What you have to do is update line no 73 to 77 with,
call ant -buildfile "%CARBON_HOME%\bin\build.xml" -q
set CARBON_CLASSPATH=.\conf
FOR %%c in ("%CARBON_HOME%\lib\*.jar") DO set CARBON_CLASSPATH=!CARBON_CLASSPATH!;".\lib\%%~nc%%~xc"
FOR %%C in ("%CARBON_HOME%\repository\lib\*.jar") DO set CARBON_CLASSPATH=!CARBON_CLASSPATH!;".\repository\lib\%%~nC%%~xC"
This snippet will only add dependent jar files to the class_path and you can get rid of the above mentioned issue.


[1] http://docs.wso2.org/display/Carbon420/Encrypting+and+Decrypting+Simple+Texts

Tuesday, December 3, 2013

Access WSO2 Carbon admin Webservice using SoapUI

For the purpose of writing this blog post I'm going to use WSO2 GREG, SoapUI 4.5.1 on a linux environment.

In my previous blog post I explained how to explore a WSO2 Carbon admin Webservice, here I'm going to access an admin web service by providing authentication details.

I assume you are in the 3rd step of my previous example and able to list all admin services using OSGI console command listAdminServices.

If you able to access https://localhost:9443/services/UserAdmin?wsdl you are good to move further in this post.

1. Open new SoapUI project, lets name it UserAdmin provide above URL as the initial WSDL and press ok.


You will see all available SOAP requests under "UserAdmin" webservice.

2. Lets run getAllRolesNames, expand it and click on the Request1 link.


You will get the SOAP request generated by SoapUI with the use of provided WSDL.

3. Click on the Aut button under the request tab select authorization type as preemptive.

4. Provide admin username and password of your carbon instance.

5. Send SOAP request.

If you have done everything right you will get the list of available roles in your carbon server.



Further I will explain how to use the already generated Set-Cookie: JSESSIONID to authenticate next requests rather than providing username & password again.

Lets view raw response in our previous step, by pressing raw tab inside response window.You will see HTTP header details,
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=D9A45BE1CCD7616F88FDF4E0FF85C213; Path=/; Secure; HttpOnly
Content-Type: text/xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 03 Dec 2013 10:40:15 GMT
Server: WSO2 Carbon Server
I'm going to send a getRolesOfUser SOAP request with the use of available Cookie: JSESSIONID=D9A45BE1CCD7616F88FDF4E0FF85C213.

Click Headers tab under the request window and enter "Header" name as Cookie and "Value" as JSESSIONID=D9A45BE1CCD7616F88FDF4E0FF85C213.
Refer following screen-shot,


Here I'm trying to list down all available roles for the given user, in my case it's me "udara" ;) .

You will see some similar response,



WSO2 ESB Web-service based remote registry mount

Since WSO2 products are based on Carbon stack, you don't have to store your collections and resources within the same server itself.You can store those across multiple locations.

In this blog post I'm using WSO2 GREG and WSO2 ESB to explain this topic further.

There are multiple methods to mount remote registry in-to the ESB,

1. JDBC based remote configuration
2. Atom based remote configuration
3. Webservice based remote configuration

1st method is the WSO2 recommended approach in production environments as other two methods are not supporting transactions.But there might be scenarios where you can't directly connect to your registry database due to security restrictions.

I'm going to explain the 3rd method further in this blog post.
Before moving forward, lets download and setup Greg and ESB products in my local machine.

1. Start WSO2 Greg by running ./wso2server.sh within <Greg_HOME>/bin directory.

by default all WSO2 products bind to following ports,
HTTPS port  : 9443
HTTP port    : 9763

Since I'm running both products on the same machine for the purpose of writing this blog post I have to start WSO2-ESB with a port offset.

2. Open <ESB_HOME>/repository/conf/carbon.xml and change the offset a,
<Offset>1</Offset>
Lets configure our remote registry instance now, using Webservice configuration.

3. Open <ESB_HOME>/repository/conf/registry.xml and add the following configuration.
<remoteInstance url="https://10.100.0.128:9443/registry">
   <id>instanceid</id>
   <username>admin</username>
   <password>admin</password>
   <type>ws</type>
</remoteInstance>

<mount path="/_system/governance" overwrite="true">
   <instanceId>instanceid</instanceId>
   <targetPath>/_system/governance</targetPath>
</mount>
<mount path="/_system/config" overwrite="true">
   <instanceId>instanceid</instanceId>
   <targetPath>/_system/config</targetPath>
</mount>
Use correct "remoteInstance url" (only have to update the IP address) according to your environment. "instanceid" is the remote registry instance ID(no need to update this value)."username and password" values are to login to the remote registry instance.

In my sample I'm using two mount configurations. "mount path" describes the path where you want to mount. Overwrite variable describes whether you overwrite existing resource or not.It can be any value from true, false, virtual or simply nothing as this parameter is optional. Keep the "instanceId" value as same as in the "id" of remoteInstance configuration above."targetPath" is the path inside remote registry which we are going to mount.

Above configuration I'm going to overwrite both governance and config collections inside ESB from the remote registry collections.

 4. Start WSO2 ESB by running ./wso2server.sh within <ESB_HOME>/bin directory.

Verify the status of WS remote registry mount by,
  i)  Log in to the ESB server's carbon console
  ii) Browse the Registry. Now you should see the config and governance collections(WS remote mounted using my sample registry.xml) are updated with arrow icons.


NOTE-

I en-counted following error while working with WSO2 ESB 4.5.1 and WSO2 GREG 4.5.2, you better try the above sample with latest version of WSO2 Greg and WSO2 ESB.

[2013-12-03 11:42:05,929] ERROR - FIXTransportServiceComponent Error while activating FIX transport management bundle
java.lang.NullPointerException
    at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:89)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.getTransportElement(TransportPersistenceManager.java:127)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.saveTransportConfiguration(TransportPersistenceManager.java:285)
    at org.wso2.carbon.transport.fix.internal.FIXTransportServiceComponent.activate(FIXTransportServiceComponent.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:252)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:346)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:588)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:196)
    at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:328)
    at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:221)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:513)
    at org.wso2.carbon.core.init.CarbonServerManager.removePendingItem(CarbonServerManager.java:290)
    at org.wso2.carbon.core.init.PreAxis2ConfigItemListener.bundleChanged(PreAxis2ConfigItemListener.java:118)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
[2013-12-03 11:42:05,944] ERROR - JMSTransportServiceComponent Error while activating JMS transport management bundle
java.lang.NullPointerException
    at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:89)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.getTransportElement(TransportPersistenceManager.java:127)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.saveTransportConfiguration(TransportPersistenceManager.java:285)
    at org.wso2.carbon.transport.jms.internal.JMSTransportServiceComponent.activate(JMSTransportServiceComponent.java:69)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:252)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:346)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:588)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:196)
    at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:328)
    at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:221)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:513)
    at org.wso2.carbon.core.init.CarbonServerManager.removePendingItem(CarbonServerManager.java:290)
    at org.wso2.carbon.core.init.PreAxis2ConfigItemListener.bundleChanged(PreAxis2ConfigItemListener.java:118)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
[2013-12-03 11:42:05,952] ERROR - MailTransportServiceComponent Error while activating the mail transport management bundle
java.lang.NullPointerException
    at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:89)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.getTransportElement(TransportPersistenceManager.java:127)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.saveTransportConfiguration(TransportPersistenceManager.java:285)
    at org.wso2.carbon.transport.mail.internal.MailTransportServiceComponent.activate(MailTransportServiceComponent.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:252)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:346)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:588)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:196)
    at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:328)
    at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:221)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:513)
    at org.wso2.carbon.core.init.CarbonServerManager.removePendingItem(CarbonServerManager.java:290)
    at org.wso2.carbon.core.init.PreAxis2ConfigItemListener.bundleChanged(PreAxis2ConfigItemListener.java:118)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
[2013-12-03 11:42:05,960] ERROR - VFSTransportServiceComponent Error while initializing VFS transport management bundle
java.lang.NullPointerException
    at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:89)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.getTransportElement(TransportPersistenceManager.java:127)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.saveTransportConfiguration(TransportPersistenceManager.java:285)
    at org.wso2.carbon.transport.vfs.internal.VFSTransportServiceComponent.activate(VFSTransportServiceComponent.java:66)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:252)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:346)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:588)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:196)
    at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:328)
    at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:221)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:513)
    at org.wso2.carbon.core.init.CarbonServerManager.removePendingItem(CarbonServerManager.java:290)
    at org.wso2.carbon.core.init.PreAxis2ConfigItemListener.bundleChanged(PreAxis2ConfigItemListener.java:118)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340) 


You can find out official WSO2 documentation for this topic at [1].


[1] http://docs.wso2.org/display/ESB460/Remote+Registry+Instance+Configuration#RemoteRegistryInstanceConfiguration-WebService-BasedRemoteInstanceConfiguration

Wednesday, November 27, 2013

Explore WSO2 Carbon admin Web services

The Carbon Management console is popular among WSO2 Product users.Without making any file level configuration changes, one can use web based admin console to interact with the Carbon installation.

As a Carbon developer one can ask, "Is there any other way to access those admin services rather than using the management console?"

Yes you can, Management functionalities inside the console UI communicate with back end web-services which you can use directly. All these web services are secured, you can access them with either HTTP Basic Authentication or session based authentication.

1. First you need to change the visibility of  admin web service WSDLs.
Open CARBON_HOME/repository/conf/carbon.xml and search for the HideAdminServiceWSDLs property.

Change the value of HideAdminServiceWSDLs property as follows,
<HideAdminServiceWSDLs>false</HideAdminServiceWSDLs>
2. Start Carbon server with –DosgiConsole parameter.
CARBON_HOME/bin$ sh wso2server.sh -DosgiConsole
3. Once server started in OSGI-Console mode just run listAdminServices command.
osgi> listAdminServices
Above command will list down all available admin services in your Carbon server.

I'm taking TenantMgtAdminService located at https://10.100.0.128:9443/admin/services/TenantMgtAdminService/ as a sample and explore this service within SoupUI.

4. Browse https://10.100.0.128:9443/admin/services/TenantMgtAdminService?wsdl

You can simply import this WSDL to SoapUI and check for all available services.

Create new soapui project with a name you want and https://10.100.0.128:9443/admin/services/TenantMgtAdminService?wsdl as the initial WSDL.



Happy Exploring !!!



Thursday, November 21, 2013

Deploy your own Enterprise Store [part 3]

I will discuss about few UI modifications you can do to make your own Music Store(or whatever) from what you have deployed, using WSO2 ES while following previous blog posts.You can find previous posts from [1] and [2].

At the moment we have our own mp3 asset type plus few other default asset types (gadget, site, e-book) in the ES.


First I'm going to hide all default asset types from the Store UI, there are number of ways to accomplish this task.

1. Get a fresh WSO2-ES pack and remove all default asset rxt's , asset types from store-tenant.json, publisher-tenant.json files while adding our new mp3 asset.

2. By modifying  /_system/config/store/configs/store.json in our registry. You can find this under Resources > Browse > _system > config >store > configs in our management console https://localhost:9443/admin/carbon/admin/login.jsp.

Under content menu you can update store.json with the following content by pressing Edit as text. We are going to remove all default asset types from the config.
{
  "assets": [
    "mp3"
  ],
  "assetsPageSize": 12,
  "commentsPageSize": 10,
  "userSpace": "\/_system\/governance\/users",
  "roles": {
    "Internal\/store": {
      "\/permission\/admin\/login": [
        "ui.execute"
      ]
    }
  },
  "userRoles": [
    "Internal\/store"
  ],
  "permissions": {
    "login": {
      "\/permission\/admin\/login": [
        "ui.execute"
      ]
    }
  },
  "paths": {
    "RXT_EXTENSION_PATH": "\/config\/ext\/"
  }
}
Just save it and browse our store http://localhost:9763/store/



You can update the icon-sprite.png resides under repository/deployment/server/jaggeryapps/store/extensions/assets/mp3/resources/  with a suitable one for our MP3 store.

Without writing a single line of code we can configure our simple digital asset store by using WSO2 ES :)

[1]. http://udarakr.blogspot.com/2013/11/deploy-your-own-enterprise-store-part-1.html
[2]. http://udarakr.blogspot.com/2013/11/deploy-your-own-enterprise-store-part-2.html

Wednesday, November 20, 2013

Deploy your own Enterprise Store [part 2]

I have explained how to install WSO2 ES with bundled default assets in the previous blog post.In this post I will explain how to introduce your own digital asset type to the ES.

Before going though those steps we need to understand a bit about WSO2 Governance Registry. WSO2 GREG enables storing meta-data of our digital assets and assets themselves. You can find more information about WSO2 GREG from here.

Make sure you have WSO2 ES up and running for now,
Browse following URL and sign-in to the management console with the use of given user credentials(default).
Management Console : https://localhost:9443/admin/carbon/admin/login.jsp
Username :admin
Password :admin 
If you browse through following, Main>Resources > Browse> _system> governance > sites > admin > Facebook you will see something similar to the following screen-shot.


This is exactly where all information of Facebook (site-asset) stored. If you select the version 1.0.0 you can see meta-data as well as the properties of this asset.


Lets move to the publisher for a second, browse https://localhost:9443/publisher/asset/site and you will get,


If you compare form fields of add-site form with the properties of above Facebook site-asset, you can clearly understand the relationship between them.

Lets add our own asset type to the ES now. Make sure you proceed with a fresh WSO2 ES pack now on, just unzip already downloaded zip to a different location.

All the resources you need to create are available @ mp3-store git repo.
You can either replace existing files or update as explain in following steps.

1. Introduce meta-data model(rxt file)
If you browse repository/resources/rxts/ directory inside ES distribution, you can see number of .rxt files there. Open site.rxt file using your favorite text editor.

(Yeah !! now you know exactly where all those add-site form fields came from.)

You may create your own meta-data model now.
Create mp3.rxt (Yes im going to create a Music Store) with the following content.
<?xml version="1.0"?>
<artifactType type="application/vnd.wso2-mp3+xml" shortName="mp3" singularLabel="MP3" pluralLabel="MP3s"
              hasNamespace="false" iconSet="10">
    <storagePath>/mp3s/@{overview_provider}/@{overview_name}/@{overview_version}</storagePath>
    <nameAttribute>overview_name</nameAttribute>
    <ui>
        <list>
            <column name="Provider">
                <data type="path" value="overview_provider" href="@{storagePath}"/>
            </column>
            <column name="Name">
                <data type="path" value="overview_name" href="@{storagePath}"/>
            </column>
            <column name="Version">
                <data type="path" value="overview_version" href="@{storagePath}"/>
            </column>
        </list>
    </ui>
    <content>
        <table name="Overview">
            <field type="text" required="true">
                <name>Provider</name>
            </field>
            <field type="text" required="true">
                <name>Name</name>
            </field>
            <field type="text" required="true">
                <name>Version</name>
            </field>
            <field type="text">
                <name>Createdtime</name>
            </field>
        <field type="options">
                <name label="Category">Category</name>
                <values>
                    <value>Country</value>
                    <value>Pop</value>
                    <value>Rock</value>
                </values>
            </field>
        <field type="text" url="true">
                <name>URL</name>
            </field>
        <field type="text" required="true">
                <name>Artists</name>
            </field>
            <field type="text-area">
                <name>Description</name>
            </field>
        </table>
        <table name="Images">
            <field type="text" required="true">
                <name>Thumbnail</name>
            </field>
            <field type="text" required="true">
                <name>Banner</name>
            </field>
        </table>
    </content>

</artifactType>

2. Introduce new asset type to the store.
Go to the repository/deployment/server/jaggeryapps/store/config/ directory inside youe ES distribution.
Open store-tenant.json file and update following line with the new asset type.
"assets": ["gadget", "site", "ebook","mp3"],
3. Go to repository/deployment/server/jaggeryapps/store/extensions/assets directory inside youe ES distribution.
Create a directory called mp3 inside assets directory and copy/paste content from already existing asset type.You can update the content if you wish to do so.

Create mp3.json inside repository/deployment/server/jaggeryapps/store/config/ext/ directory with the following content. You can refer existing default artifact json while creating this.

Sample

{
    "applyTo": "mp3",


    "import": [
        "/modules/rxt/ext/scripts/form.overview.exporter.js",
        "/modules/rxt/ext/scripts/form.exporter.js"],

    "fieldPropertyRules": [
        "overview.name:order=1",
        "overview.provider:order=2",
        "overview.description:order=3",
        "overview.version:order=4"
    ],

    "tables": [

        {
            "name": "*"
        }

    ],

    "fieldProperties": [

        {
            "field": "*",
            "name": "order",
            "value": ""
        },
        {
            "field": "*",
            "name": "hidden",
            "value": "false"
        },
        {
            "field": "*",
            "name": "visible",
            "value": "true"
        },
        {
            "field": "overview.*",
            "name": "save",
            "value": "default"
        },
        {
            "field": "overview.*",
            "name": "editable",
            "value": true
        },
         {
            "field": "images.*",
            "name": "editable",
            "value": true
        },
        {
            "field": "*.lifeCycle",
            "name": "save",
            "value": "asset.lifecycle.action.save"
        },
        {
            "field": "overview.provider",
            "name": "readOnly",
            "value": "true"
        },
         {
            "field":"overview.provider",
            "name":"editable",
            "value":false
        },
         {
            "field":"overview.name",
            "name":"editable",
            "value":false
        },
        {
            "field": "overview.createdtime",
            "name": "hidden",
            "value": "true"
        },
        {
            "field":"overview.version",
            "name":"editable",
            "value":false
        },

    ],

    "fields": [
        {
            "name": "lifeCycle",
            "table": "*",
            "label": "Life Cycle",
            "value": "SampleLifeCycle2"

        } ,
        {
            "name": "banner",
            "table": "images",
            "type": "file"
        },
        {
            "name": "thumbnail",
            "table": "images",
            "type": "file"
        },
        {
            "name": "url",
            "table": "overview",
            "type": "file"
        },
        {
            "name": "description",
            "table": "overview",
            "value": "The provider has not given a description."
        }

    ],

    "permissions": {
        "created": ["Internal/private_{overview_provider}"],
        "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
        "published": ["Internal/private_{overview_provider}"],
        "unpublished": ["Internal/private_{overview_provider}"]
    },


    "storage": {

        "images_banner": {

            "lifecycle": {
                "created": ["Internal/private_{overview_provider}"],
                "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
                "published": ["Internal/everyone", "Internal/private_{overview_provider}", "Internal/reviewer"],
                "unpublished": ["Internal/private_{overview_provider}"]
            }
        },

        "images_thumbnail": {

            "lifecycle": {
                "created": ["Internal/private_{overview_provider}"],
                "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
                "published": ["Internal/everyone", "Internal/private_{overview_provider}", "Internal/reviewer"],
                "unpublished": ["Internal/private_{overview_provider}"]
            }
        }

    }
}



4.  Introduce new asset type to the publisher.
Go to the  repository/deployment/server/jaggeryapps/publisher/config/ directory inside youe ES distribution.
 Open publisher-tenant.json file and update following line with the new asset type.
"collections": ["gadgets", "sites", "ebooks","mp3s"],


5. Go to the repository/deployment/server/jaggeryapps/publisher/config/ext/ directory inside youe ES distribution. create mp3.json file with the following content.


{
    "applyTo": "mp3",
    "import": [
        "/modules/ext/scripts/rxt.importer.js",
        "/modules/ext/scripts/form.exporter.js"],
    "fieldPropertyRules": [
        "overview.name:order=1",
        "overview.provider:order=2",
        "overview.description:order=3",
        "overview.version:order=4"
    ],
    "tables": [
        {
            "name": "*"
        }
    ],
    "fieldProperties": [
        {
            "field": "*",
            "name": "order",
            "value": ""
        },
        {
            "field": "*",
            "name": "hidden",
            "value": "false"
        },
        {
            "field": "*",
            "name": "visible",
            "value": "true"
        },
        {
            "field": "overview.*",
            "name": "save",
            "value": "default"
        },
        {
            "field": "overview.*",
            "name": "editable",
            "value": true
        },
         {
            "field": "images.*",
            "name": "editable",
            "value": true
        },
        {
            "field": "*.lifeCycle",
            "name": "save",
            "value": "asset.lifecycle.action.save"
        },
        {
            "field": "overview.provider",
            "name": "readOnly",
            "value": "true"
        },
         {
            "field":"overview.provider",
            "name":"editable",
            "value":false
        },
         {
            "field":"overview.name",
            "name":"editable",
            "value":false
        },
        {
            "field": "overview.createdtime",
            "name": "hidden",
            "value": "true"
        },
        {
            "field":"overview.version",
            "name":"editable",
            "value":false
        },

    ],
    "fields": [
        {
            "name": "lifeCycle",
            "table": "*",
            "label": "Life Cycle",
            "value": "SampleLifeCycle2"
        } ,
        {
            "name": "banner",
            "table": "images",
            "type": "file"
        },
        {
            "name": "thumbnail",
            "table": "images",
            "type": "file"
        },
        {
            "name": "url",
            "table": "overview",
            "type": "file"
        },
        {
            "name": "description",
            "table": "overview",
            "value": "The provider has not given a description."
        }
    ],
    "permissions": {
        "created": ["Internal/private_{overview_provider}"],
        "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
        "published": ["Internal/private_{overview_provider}"],
        "unpublished": ["Internal/private_{overview_provider}"]
    },
    "storage": {
        "images_banner": {
            "lifecycle": {
                "created": ["Internal/private_{overview_provider}"],
                "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
                "published": ["Internal/everyone", "Internal/private_{overview_provider}", "Internal/reviewer"],
                "unpublished": ["Internal/private_{overview_provider}"]
            }
        },
        "images_thumbnail": {
            "lifecycle": {
                "created": ["Internal/private_{overview_provider}"],
                "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
                "published": ["Internal/everyone", "Internal/private_{overview_provider}", "Internal/reviewer"],
                "unpublished": ["Internal/private_{overview_provider}"]
            }
        }

    }
}
Now you can test the set-up by publishing a mp3.



Start your fresh ES with above changes and browse our mp3 asset type using, https://localhost:9443/publisher/asset/mp3. Yes!! you will get something similar to the following screen-shot.


Just fill those form fields with your own values and create the first mp3 asset on ES :)

You will redirect to a page, where you can see something similar to this.
(Here I'm using the same Thumbnail and Banner created for the CNN site)


You can select your mp3, browse life-cycle and change its state to In-review -> published from created state.( If you do not have permission to run above step just log-in as admin to the ES)


Lets, log-in to the store and browse our newly added asset type using following URL http://localhost:9763/store/assets/mp3


And if you select already published MP3,in my case skyfall :). You will see something similar to the following where you can download, comment and rate the asset.


Now, you are good to go with your own asset (mp3) store.

Deploy your own Enterprise Store [part 1]

Why enterprise store?

We are living in a digital-era where we create and use thousands of digital assets. There are number of tools around us to create assets, but very few resources we have to store, publish, maintain which bring immense value addition to our digital assets. This is the enterprise wide problem solved by the WSO2 Enterprise Store. Organize your assets at one place, access from everywhere !!

ES powered by two major apps, store and publisher. Lets talk about the publisher first. As the back office of the store, publisher is the platform which create, manage life-cycle and monitor statistics of assets. You can provision those published assets though the store front-end.

Lets dive in-to the ES world by running the product, first download the WSO2 ES product from here and unzip the product.You can find following directory structure inside the ES.

├── bin
├── dbscripts
├── INSTALL.txt
├── lib
├── LICENSE.txt
├── modules
├── README.txt
├── release-notes.html
├── repository
├── resources
├── tmp
└── webapp-mode
Here I'm working in a linux environment, you can follow official installation guide here if you are using/familiar with any other environment.

Navigate to the bin directory and start the server using following commands within your terminal window.
cd bin/
sh wso2server.sh 
Once the server started you can browse,

Store URL : http://localhost:9763/store
Publisher URL : http://localhost:9763/publisher
Mgt Console URL  : https://localhost:9443/admin/carbon/


Use the following default user credentials to login, or else you can create your own user.

username : admin
password : admin

By default ES 1.0.0 shipped with provision for gadgets, websites and eBooks, you can browse, search, download or bookmark, manage life-cycle, view stats of those default digital assets in this ES installation.

Few screen-shots from the ES 1.0.0.

Store home

Site-Asset home


Sample- FaceBook asset page

In the following screen-shot you can find out some interesting social features of the WSO2 ES such as commenting, rating and tagging of assets.



Store-My items page

This is where you can see all assets that you have either download or bookmark from the store.


Publisher home

Asset Statistics

This is where you one can get a insight of his/her assets.
Number of bookmarks/downloads per asset, number of bookmarks/downloads during given period of time etc.


Asset Life-cycle management

Add new asset(gadget asset type)

Lets talk about how to install your own digital asset(rather than using gadgets,sites and e-books) in coming blog post.

If you wish to contribute to the WSO2 Enterprise-Store Product, yes its on github. You can clone ES from here and play/contribute with/to the source.