Wednesday, June 29, 2016

How to configure WSO2 App Manager with MySQL ?

All WSO2 products comes with H2 internal database/s by default. Any of these product can be configured with different databases other than the H2 DB. App Manager product contains several databases unique only to App Manager that is not common with other WSO2 products. If you are familiar with changing default database of any of WSO2 product, concept is similar for App Manager as well.  Anyway, here I'm explaining step by step, what each of these database in App Manager is doing and how we can configure them to use MySQL.

We have following five datasources defined in the {AppM_Home}/repository/conf/datasources/master-datasources.xml file.

[1] <name>jdbc/WSO2CarbonDB</name> - Use for registry data storage, user store, permission store
[2] <name>jdbc/WSO2AM_DB</name> - Use to store App details that created from App Manager
[3] <name>jdbc/WSO2AM_STATS_DB</name> - Stats storage. Needed only when Data Analytic Server is configured
[4] <name>jdbc/ES_Storage</name> - Use to store thumbnail/banner images of apps
[5] <name>jdbc/WSO2SocialDB</name> - Use to store comments and ratings added for apps by store users


This guide explains configuring App Manager standalone instance with MySQL DB. If it is a cluster deployment, there are some additional configurations required other than explains in this post.

Step 0: Login to the MySQL server and create 4 databases.
mysql> create database appm_regdb;
Query OK, 1 row affected (0.01 sec)

mysql> create database appm_appdb;
Query OK, 1 row affected (0.00 sec)

mysql> create database appm_esdb;
Query OK, 1 row affected (0.00 sec)

mysql> create database appm_socialdb;
Query OK, 1 row affected (0.00 sec)


Step 1: Change  datasources mentioned previously (other than the STATS_DB) as follows by pointing to above created MySQL databases. You need to replace the config with  valid database username/password.
Note that <defaultAutoCommit>false</defaultAutoCommit> property is mandatory for "jdbc/WSO2AM_DB" datasource.

File location: {AppM_Home}/repository/conf/datasources/master-datasources.xml

     <datasource>
            <name>WSO2_CARBON_DB</name>
            <description>The datasource used for registry and user manager</description>
            <jndiConfig>
                <name>jdbc/WSO2CarbonDB</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                   <url>jdbc:mysql://localhost:3306/appm_regdb</url>
                  <username>root</username>
                   <password>root</password>
                   <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>

        <datasource>
            <name>WSO2AM_DB</name>
            <description>The datasource used for APP Manager database</description>
            <jndiConfig>
                <name>jdbc/WSO2AM_DB</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                    <url>jdbc:mysql://localhost:3306/appm_appdb</url>
                    <username>root</username>
                    <password>root</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <defaultAutoCommit>false</defaultAutoCommit>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>

<datasource>
           <name>JAGH2</name>
           <description>The datasource used for by the Jaggery Storage Manager</description>
           <jndiConfig>
               <name>jdbc/ES_Storage</name>
           </jndiConfig>
           <definition type="RDBMS">
               <configuration>
                   <url>jdbc:mysql://localhost:3306/appm_esdb</url>
                   <username>root</username>
                   <password>root</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                   <maxActive>50</maxActive>
                   <maxWait>60000</maxWait>
               </configuration>
           </definition>
       </datasource>

<datasource>
            <name>WSO2_SOCIAL_DB</name>
            <description>The datasource used for social framework</description>
            <jndiConfig>
                <name>jdbc/WSO2SocialDB</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                    <url>jdbc:mysql://localhost:3306/appm_socialdb</url>
                    <username>root</username>
                    <password>root</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>

Step 2: Copy MySQL jdbc driver to {AppM_Home}/repository/components/lib directory

Step 3: Start the server with -Dsetup option. This will create the required tables in above four databases.
sh wso2server.sh -Dsetup

That's all.

Tuesday, April 26, 2016

How to use App Manager Business Owner functionality ?

WSO2 App Manager new release (1.2.0) has introduced capability to define business owner for each application. (AppM-1.2.0  is yet to be released by the time this blog post is writing and you could download nightly build from here and tryout until the release is done.)

1. How to define business owners ?

Login as a admin user to admin-dashboard by accessing following URL.
https://localhost:9443/admin-dashboard

This will give you UI similar to bellow where you can define new business owners.


Click on "Add Business Owner" option to add new business owners.


All created business owners are listed in UI as follows, which allows you to edit or delete from the list.




2. How to associate business owner to application ?

You can login to Publisher by accessing the following URL to create new app.
https://localhost:9443/publisher 

In the add new web app UI, you should be able to see page similar to following, where you can type and select the business owner for the app.



Once the required data is filled and app is ready to publish to store, change the app life-cycle state to 'published' to publish app into app store.



Once the app is published, users could access app through the App Store by accessing the following URL.
https://localhost:9443/store

App users can find the business owner details in the App Overview page as shown bellow.





If you are using REST APIs to create and publish the apps, following sample command would help.

These APIs are protected with OAuth and you need to generate a oauth token before invoking APIs.

Register a OAuth app and generates consumer key and secret key
Request:
curl -X POST -H "Content-Type: application/json" -H "Authorization: Basic YWRtaW46YWRtaW4=" -d  '{"clientName": "Demo_App", "grantType": "password refresh_token"}'  http://localhost:9763/api/appm/oauth/v1.0/register

Note: Authorization header should pass base64encoded(username:password) as the value in above request.

Response:
{"clientId":"1kaMrCWFr9NeT1VCfTxacI_Pu0sa","clientName":"Demo_App","callBackURL":null,"clientSecret":"YNkRA_30pwOZ6kNTIZC9B54p7LEa"}

Generate access token using above consumer/secret keys
Request:
curl -k -X POST -H "Authorization: Basic MWthTXJDV0ZyOU5lVDFWQ2ZUeGFjSV9QdTBzYTpZTmtSQV8zMHB3T1o2a05USVpDOUI1NHA3TEVh" -H "Content-Type: application/x-www-form-urlencoded" -d 'username=admin&password=admin&grant_type=password&scope=appm:read appm:administration appm:create appm:publish'  https://localhost:9443/oauth2/token

Note: Authorization header should pass base64encoded(clientId:clientSecret) as the value in above request.

Response:
{"access_token":"cc78ea5a2fa491ed23c05288f539b5f5","refresh_token":"3b203c859346a513bd3f94fc6bf202e4","scope":"appm:administration appm:create appm:publish appm:read","token_type":"Bearer","expires_in":3600}


Add new business owner
Request:
curl -X POST -H "Authorization: Bearer cc78ea5a2fa491ed23c05288f539b5f5" -H "Content-Type: application/json" -d '{"site": "http://wso2.com", "email": "beth@gmail.com", "description": "this is a test description", "name": "Beth", "properties": [{"isVisible": true,"value": "0112345678","key": "telephone"}]}' http://localhost:9763/api/appm/publisher/v1.1/administration/businessowner

Response:
{"id":1}


Create new App and define business owner as previously added business owner
curl -X POST -H "Authorization: Bearer cc78ea5a2fa491ed23c05288f539b5f5" -H "Content-Type: application/json" http://localhost:9763/api/appm/publisher/v1.1/apps/webapp -d '{
  "name": "TravelBooking",
  "version": "1.0.0",
  "isDefaultVersion":true,
  "displayName": "Travel Booking",
  "description": "description",
  "businessOwnerId":"1",
  "isSite": "false",
  "context": "/travel",
  "appUrL": "http://www.google.lk",
  "acsUrl": "",
  "transport": "http",
  "policyGroups": [
    {
      "policyGroupName": "policy1",
      "description": "Policy 1",
      "throttlingTier": "Unlimited",
      "userRoles": [
        "role1"
      ],
      "allowAnonymousAccess": "false"
    },
    {
      "policyGroupName": "policy2",
      "description": "Policy 2",
      "throttlingTier": "Gold",
      "userRoles": [
        "role2"
      ],
      "allowAnonymousAccess": "false"
    },
    {
      "policyGroupName": "policy3",
      "description": "Policy 3",
      "throttlingTier": "Unlimited",
      "userRoles": [
        "role3"
      ],
      "allowAnonymousAccess": "false"
    }
  ],
  "uriTemplates": [
    {
      "urlPattern": "/*",
      "httpVerb": "GET",
      "policyGroupName": "policy1"
    },
    {
      "urlPattern": "/*",
      "httpVerb": "POST",
      "policyGroupName": "policy2"
    },
    {
      "urlPattern": "/pattern1",
      "httpVerb": "POST",
      "policyGroupName": "policy3"
    }
  ]
}'

Response:
{"AppId": "78012b68-719d-4e14-a8b8-a899d41dc712"}


Change app lifecycle state to 'Published'
curl -X POST -H "Authorization: Bearer cc78ea5a2fa491ed23c05288f539b5f5" -H "Content-Type: application/json" http://localhost:9763/api/appm/publisher/v1.1/apps/webapp/change-lifecycle?appId=78012b68-719d-4e14-a8b8-a899d41dc712&action=Submit%20for%20Review

curl -X POST -H "Authorization: Bearer cc78ea5a2fa491ed23c05288f539b5f5" -H "Content-Type: application/json" http://localhost:9763/api/appm/publisher/v1.1/apps/webapp/change-lifecycle?appId=78012b68-719d-4e14-a8b8-a899d41dc712&action=Approve

curl -X POST -H "Authorization: Bearer cc78ea5a2fa491ed23c05288f539b5f5" -H "Content-Type: application/json" http://localhost:9763/api/appm/publisher/v1.1/apps/webapp/change-lifecycle?appId=78012b68-719d-4e14-a8b8-a899d41dc712&action=Publish

Retrieve App info in store
Request:
curl -X GET -H "Authorization: Bearer cc78ea5a2fa491ed23c05288f539b5f5" -H "Content-Type: application/json" http://localhost:9763/api/appm/store/v1.1/apps/webapp/id/78012b68-719d-4e14-a8b8-a899d41dc712

Response:
{"businessOwnerId":"1","isSite":"false","isDefaultVersion":true,"screenshots":[],"customProperties":[],"tags":[],"rating":0.0,"transport":["http"],"lifecycle":"WebAppLifeCycle","lifecycleState":"PUBLISHED","description":"description","version":"1.0.0","provider":"admin","name":"TravelBooking1","context":"/travel1","id":"78012b68-719d-4e14-a8b8-a899d41dc712","type":"webapp","displayName":"Travel Booking"}

Retrieve business owner details
Request:
curl -X GET -H "Authorization: Bearer cc78ea5a2fa491ed23c05288f539b5f5" -H "Content-Type: application/json" http://localhost:9763/api/appm/store/v1.1/businessowner/1

Response:
{"site":"http://wso2.com","email":"beth@gmail.com","description":"this is a test description","name":"Beth","properties":[{"isVisible":true,"value":"0112345678","key":"telephone"}],"id":1}

Tuesday, June 2, 2015

WSO2 App Manager 1.0.0 released

WSO2 App Manager is the very latest product added to WSO2 product stack.

App Manager can work as a Apps Store for web apps and mobile apps while providing whole set of other features.


  • Single sign on/ Single sign out between web apps
  • Role/permission based access control for web apps
  • Capability to configure federated authentication for web apps
  • Subscription maintenance in App Store
  • Commenting, Rating capabilities in App Store
  • Statistic monitoring for apps usage 

Above are the core features comes with App Manager. Have a look at App Manager product page to get an idea about whole other features and its capabilities.

http://wso2.com/products/app-manager/

Saturday, November 15, 2014

How to enable login to WSO2 API Manager Store using Facebook credentials

WSO2 Identity Server 5.0.0 release has provided several default federated authenticators like Google, Facebook, Yahoo. Even it's possible to write custom authenticator as well, in addition to default authenticators provided.

In this post we are going to demonstrate, how we can configure WSO2 API Manager with WSO2 Identity Server, so that users comes to API Store can use their Facebook account as well to login to API Store.

Step 1 : Configure SSO between API Store and API Publisher

First you need to configure SSO between publisher and store as mentioned in this document.

Step 2 : You need to have App Id and App secret key pair generated for a application registered in facebook developers site. This can be done by login to facebook developer site and creating a new app.

Step 3 :  Login to the Identity Server and register a IdP with Facebook authenticator

This can be done by navigating to Main -> Identity Providers -> Add. This will prompt the following window. In the "Federated Authenticators" section expand the "Facebook Configuration" and provide the details.

App Id and App Secrete generated in the step two maps to Client Id and Client Secret values asked in the form.



Step 4 : Go to the two service providers created in step-1 and associate the above created IdP to it.

This configuration is available under "Local & Outbound Authentication Configuration" section of the SP.


Step 5 : If you try to access store url (i.e: https://localhost:9443/store) , it should redirect to the facebook login page.

Step 6: In order to store users to capable in using their facebook account as a login, they need to follow this step and associate their facebook account to their user account in the API Store.

Identity Server has provided a dashboard which gives multiple features for users in maintaining their user accounts. Associating a social login for their account is a one option provided in this dashboard.

This dashboard can be accessed in the following url .
https://<IS_HOST>:<IS_PORT>/dashboard

eg: https://localhost:9444/dashboard

Note: If you are running Identiry Server with port offset, you need to do changes mentioned here, in order to get this dashboard working.

Login to the dashboard with API Store user account. It will give you a dashboard like follows.


Click on the "View details" button provided in "Social Login" gadget. In the prompt window, there is a option to "Associate Social Login".  Click on this and give your Facebook account id as follows.


Once account is registered, it will list down as follows.


That's all we have to configure . This user should be able to login to API Store using his facebook account now.

Note: This post explained , when there is already a user account is exist in the API Store , how these users can associate their facebook account to authenticate to API Store. If someone needs to enable API Store login for all facebook accounts without having user account in API Store, that should be done though a custom authenticator added to Identity Server. i.e Provision this user using JIT (Just In Time Provisioning) functionality provided in IdP and using custom authenticator associate "subscriber" role to this provisioned user.

Sunday, October 26, 2014

Exposing a SOAP service as a REST API using WSO2 API Manager

This post explains how we can publish an existing SOAP service as a  REST API using WSO2 API Manager.

We will be using a sample data-service called "OrderSvc"as the SOAP service which can be deployed as a SOAP service in WSO2 Data Services Server. But this could be any of SOAP service.

1. Service Description of ‘OrderSvc’ SOAP Backend Service

This “orderSvc” service provides WSDL with 3 operations (“submitOrder”, “cancelOrder”, “getOrderStatus”). 


submitOrder operation takes ProductCode and Quantity as parameters.
Sample request :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dat="http://ws.wso2.org/dataservice">
  <soapenv:Header/>
  <soapenv:Body>
     <dat:submitOrder>
        <dat:ProductCode>AA_1</dat:ProductCode>
        <dat:Quantity>4</dat:Quantity>
     </dat:submitOrder>
  </soapenv:Body>

</soapenv:Envelope>

cancelOrder operation takes OrderId as parameter and does an immediate cancellation and returns a confirmation code.
Sample request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dat="http://ws.wso2.org/dataservice">
  <soapenv:Header/>
  <soapenv:Body>
     <dat:cancelOrder>
        <dat:OrderId>16</dat:OrderId>
     </dat:cancelOrder>
  </soapenv:Body>
</soapenv:Envelope>

orderStatus operaioin takes the orderId as parameter and return the order status as response.
Sample request :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dat="http://ws.wso2.org/dataservice">
  <soapenv:Header/>
  <soapenv:Body>
     <dat:orderStatus>
        <dat:OrderId>16</dat:OrderId>
     </dat:orderStatus>
  </soapenv:Body>
</soapenv:Envelope>


We need to expose this "OrderSvc" SOAP service as a REST API using API Manager. And once we exposed this as a REST API, “submitOrder”, “cancelOrder”, “getOrderStatus” operations should map to REST resources as bellow which takes the user parameters as query parameters.

“/submitOrder” (POST) => request does not contain order id or date; response is the full order payload.

“/cancelOrder/{id}” (GET) => does an immediate cancellation and returns a confirmation code.

“/orderStatus/{id}” (GET) => response is the order header (i.e., payload excluding line items).


Deploying the Data-Service :

1. Login to the MySQL and create a database called “demo_service_db” . (This database name can be anything , we need to update the data-service (.dbs file) accordingly).

mysql> create database demo_service_db;
mysql> demo_service_db;

2. Execute the dbscript given here on the above created database. This will create two tables ‘CustomerOrder’, ‘OrderStatus’ and one stored procedure ‘submitOrder’. Also it will insert some sample data into two tables.

3. Include mysql jdbc driver into DSS_HOME/repository/components/lib directory.


4. Download the data-service file given here. Before deploy this .dbs file, we need to modify the data source section defined in it. i.e in the downloaded orderSvc.dbs file, change the following properties by providing correct jdbcUrl ( need to point to the database that you created in step 1)  and change the userName/ Pwd of mysql connection, if those are different than the one defined here.


<config id="ds1">
     <property name="driverClassName">com.mysql.jdbc.Driver</property>
     <property name="url">jdbc:mysql://localhost:3306/demo_service_db</property>
     <property name="username">root</property>
     <property name="password">root</property>
  </config>


5. Deploy the orderSvc.dbs file in Data services server by copying this file into “wso2dss-3.2.1/repository/deployment/server/dataservices” directory. Start the server.


6. Before expose through API Manager, check whether all three operations works as expected using try-it tool or SOAP-UI.


submitOrder
Sample request :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dat="http://ws.wso2.org/dataservice">
  <soapenv:Header/>
  <soapenv:Body>
     <dat:submitOrder>
        <dat:ProductCode>AA_1</dat:ProductCode>
        <dat:Quantity>4</dat:Quantity>
     </dat:submitOrder>
  </soapenv:Body>
</soapenv:Envelope>


Response :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
     <submitOrderResponse xmlns="http://ws.wso2.org/dataservice">
        <OrderId>16</OrderId>
        <ProductCode>AA_1</ProductCode>
        <Quantity>4</Quantity>
     </submitOrderResponse>
  </soapenv:Body>
</soapenv:Envelope>


cancelOrder
Sample request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dat="http://ws.wso2.org/dataservice">
  <soapenv:Header/>
  <soapenv:Body>
     <dat:cancelOrder>
        <dat:OrderId>16</dat:OrderId>
     </dat:cancelOrder>
  </soapenv:Body>
</soapenv:Envelope>


Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
     <axis2ns1:REQUEST_STATUS xmlns:axis2ns1="http://ws.wso2.org/dataservice">SUCCESSFUL</axis2ns1:REQUEST_STATUS>
  </soapenv:Body>
</soapenv:Envelope>


orderStatus
Sample request :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dat="http://ws.wso2.org/dataservice">
  <soapenv:Header/>
  <soapenv:Body>
     <dat:orderStatus>
        <dat:OrderId>16</dat:OrderId>
     </dat:orderStatus>
  </soapenv:Body>
</soapenv:Envelope>


Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
     <OrderStatus xmlns="http://ws.wso2.org/dataservice">
        <OrderStatus>CANCELED</OrderStatus>
     </OrderStatus>
  </soapenv:Body>

</soapenv:Envelope>



2. Configuring API Manager

1. Download the custom sequence given here and save it to the APIM registry location “/_system/governance/apimgt/customsequences/in/”.  This can be done by login to the API Manager carbon management console. 

In the left menu section, expand the Resources -> Browse -> Go to "/_system/governance/apimgt/customsequences/in" -> Click in "Add Resource" -> Browse the file system and upload the "orderSvc_supporting_sequence.xml" sequence that downloaded above. Then click "Add". This step will save the downloaded sequence into registry.


4. Create orderSvc API by wrapping orderSvc SOAP service.

Login to the API Publisher and create a API with following info.

Name: orderSvc
Context: ordersvc
Version: v1

Resource definition1
URL Pattern: submitOrder
Method: POST

Resource definition2
URL Pattern: cancelOrder/{id}
Method: GET

Resource definition3
URL Pattern: orderStatus/{id}
Method: GET


Endpoint Type:* : Select the endpoint type as Address endpoint. And go to the “Advanced Options” and select the message format as “SOAP 1.1”.
Production Endpoint:https://localhost:9446/services/orderSvc/ (Give the OrderSvc service endpoint)

Tier Availability : Unlimited

Sequences : Click on the Sequences checkbox and selected the previously saved custom sequence under “In Flow”.


Publish the API into gateway.

We are done with the API creation.

Functionality of the custom sequence "orderSvc_supporting_sequence.xml"

OrderSvc backend service expecting a SOAP request while user invoking API by sending parameters as query parameters (i.e cancelOrder/{id}, orderStatus/{id}).

This custom sequence will take care of building SOAP payload required for cancelOrder, orderStatus operations by looking at the incoming request URI and the query parameters.

Using a switch mediator, it read the request path . i.e 

<switch xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:ns3="http://org.apache.synapse/xsd" source="get-property('REST_SUB_REQUEST_PATH')">

Then check the value of request path using a regular expression and construct the payload either for cancelOrder or orderStatus according to the matched resource. i.e

<case regex="/cancelOrder.*">
    <payloadFactory media-type="xml">
        <format>
            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <soapenv:Header/>
                <soapenv:Body xmlns:dat="http://ws.wso2.org/dataservice">
                    <dat:cancelOrder>
                        <dat:OrderId>$1</dat:OrderId>
                    </dat:cancelOrder>
                </soapenv:Body>
            </soapenv:Envelope>
        </format>
        <args>
            <arg evaluator="xml" expression="get-property('uri.var.id')"/>
        </args>
    </payloadFactory>
    <header name="Action" scope="default" value="urn:cancelOrder"/>
</case>

<case regex="/orderStatus.*">
    <payloadFactory media-type="xml">
        <format>
            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <soapenv:Header/>
                <soapenv:Body xmlns:dat="http://ws.wso2.org/dataservice">
                    <dat:orderStatus>
                        <dat:OrderId>$1</dat:OrderId>
                    </dat:orderStatus>
                </soapenv:Body>
            </soapenv:Envelope>
        </format>
        <args>
            <arg evaluator="xml" expression="get-property('uri.var.id')"/>
        </args>
    </payloadFactory>
    <header name="Action" scope="default" value="urn:orderStatus"/>
</case>


Test OrderSvc API published in API Manager

Login to the API Store and subscribe to the OrderSvc API and generate a access token. Invoke the orderStatus resource as given bellow. This will call to OrderSvc SOAP service and give you the response.

curl -v -H "Authorization: Bearer  _smfAGO3U6mhzFLro4bXVEl71Gga" http://localhost:8280/order/v1/orderStatus/3

Saturday, March 1, 2014

How to get a JSON response with WSO2 Data Services Server (wso2dss) ?

Latest version of DSS can be downloaded from here. (At the moment it's wso2dss-3.1.1).

Data Services Server support for both XML and JSON outputs. In order to get a JSON output, you need to change following configurations.

Add following parameter to 'axis2.xml' and in 'axis2_client.xml'. (In axis2_client.xml this parameter is already there, but its default value is set to false. These two files are located in '{DSS_HOME}/repository/conf/axis2/' directory).

'<parameter name="httpContentNegotiation">true</parameter>'

Note that if you are using tenant, then the above parameter need to be set in 'tenant-axis2.xml' as well.

Restart the server. We are done.

We need to use content-negotiation when doing the requests. i.e We need to pass 'Accept' header with the request. Example request done for customersInBoston operation in the RDBMSSample is given bellow. (This sample 'RDBMSSample' service is deployed in server by default).

curl -v -H "Accept:application/json" http://localhost:9783/services/samples/RDBMSSample/customersInBoston

Response
{"customers":{"customer":[{"customer-name":"Gifts4AllAges.com","contact-last-name":"Yoshido","contact-first-name":"Juri","phone":"6175559555","city":"Boston","country":"USA"},{"customer-name":"Diecast Collectables","contact-last-name":"Franco","contact-first-name":"Valarie","phone":"6175552555","city":"Boston","country":"USA"}]}}

Sunday, December 29, 2013

Message Tracing with WSO2 API Manager

The latest version of WSO2 API Manager can be downloaded from here. We could deploy API Manager in a distributed manner by separating Gateway, KeyManager, Publisher and Store servers. All the API requests are first comes to the gateway server. Then gateway calls to the key-validation server to validate the key. Only if key validation is successful, gateway allows for the back-end call.


It's important to have message details logging capability in gateway and key-manager servers, so that we can track the request and response key validation details for all requests. And it should have a same activity_id for a particular message in the key-manager and gateway servers. So that we can co-relate the same message at the key-manager and gateway nodes when doing the analysis.

Message tracing feature has been included in the API-Manager-1.6.0 release. How this message tracing feature track the same message in different servers is, when the request comes into a particular server, it adds a http header called "activityID" if this header is already not there in the request. Same is doing for the outgoing response message as well.  It checks the incoming message context and if the "activityID" header is available, then same activityID is added to the outgoing message as well. So that the messages can be co-relate using this activityID header. This feature can be used in any product to track the message. As an example say message flow is ESB -> Application-Server -> Data-Services-Server, then we can install this feature into each server and track the message.

Coming back to the API-Manager scenario, with this message tracing feature, you could log the message info in gateway and key-manager servers and/or publish the message tracing info into Business Activity Monitoring server (BAM) as streams. Once you published message info into BAM server, those streams are saved in to Cassandra keyspace and we could use them for analysis.

How to enable message tracing to log details in gateway and key-manager servers ?

1. Login to the Management Console of Gateway server. ( eg: https://localhost:9443/carbon )
Go to "Configure -> Message Tracing". This will give you the configuration UI as shown in bellow and Select the "Enable Message Tracing" option.


2. Now go to the "Configure -> Logging". In the prompt UI, give the "APIManagerExtensionHandler" as input value to "Filter Loggers by" field and click on "Contains" button. This will give you the following filter result and change the "org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerExtensionHandler" log level to "DEBUG" as shown.


3. Same way, go to the Management console of Key-Manager server and enable the "Massage Tracing" as we did in the step-1. Now go to the "Configure -> Logging" and set the log level to "DEBUG" for class "org.wso2.carbon.apimgt.keymgt.service.APIKeyValidationService" as we did in step-2.


Now, in each request call, we can see the message tracing logs in gateway and key-manager servers as shown bellow.

Gateway Server Logs:


Key-Manager Server Logs:


Note that same transaction_id has been printed in both gateway and key-manager servers for a given request.

We are done with logging. Further, if you need we could publish these tracing info in to BAM server as well.

How to configure message tracing to publish info into Business Activity Monitoring Server?

We need to have a remote BAM server running. You can download the latest version of BAM sever from here. Login to the management console of Gateway and Key-Manager severs and go to "Configure -> Message Tracing" and enable "Enable BAM Event Publishing" option and provide the BAM server details as shown bellow. (The following configuration is provided when BAM server is running with port offset 3).


Now, there will be streams publish by the gateway and key-manager servers to BAM server in each request. You can connect to the Cassandra server and check the published message info. Login to the management console of BAM server and go to "Tools > Cassandra Explorer > Connect to Cluster".


 Once you connect to the Cassandra server as mentioned above, you can see that there is a column family called "BAM_MESSAGE_TRACE" has been created. This column family contains all the message tracing data.


You can click on the "BAM_MESSAGE_TRACE" and explore the column family data.

Also, we can use "Activity Dashboard" comes with BAM server to analyse the data. Using this dashboard, we can filter the messages using certain criteria and it will group the messages that having same activity_id. This document describes how we can use the "Activity Dashboard".