Showing posts with label WSO2 APIM. Show all posts
Showing posts with label WSO2 APIM. Show all posts

Sunday, July 22, 2018

Configure Tibco EMS JMS Transport Scenario for WSO2 API Manager with WSO2 ESB


This post describes how to configure WSO2 APIM 2.1.0 as a JMS Producer and gets a response back as a complete JMS story, using Tibco EMS and WSO2 ESB 5.0.0.

  • WSO2 APIM hosts the API, that a client (i.e. cURL) would invoke.
  • Tibco EMS acts as the JMS server
  • WSO2 APIM 2.1.0 acts as a JMS Producer and once the API in API Manager is invoked by a client, it sends a JMS message to a JMS Queue (in Tibco EMS). We will call this JMS queue as 'Sender Queue- SMSStore'.  
  • WSO2 ESB 5.0.0 act as the JMS consumer when subscribed and listening to Sender JMS queue.
  • WSO2 ESB hosts a proxy service which routes the message to a backend service and send the response from backend service back to a JMS reciever queue.
  • WSO2 ESB also acts as JMS a producer when sending back the response recieved from Backend service to a destination JMS queue.
  • The backend service we use is a sample service deployed in WSO2 ESB (SimpleStockQuoteService) and it is deployed in the sample Axis2Server embeded within WSO2 ESB.

                                          Figure: Design and Message flow of the setup

Configure and setup APIM


1) Configure JMSSender  in <APIM_HOME>/repository/conf/axis2.xml


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender">
   <parameter locked="false" name="QueueConnectionFactoryAPIM">
      <parameter locked="false" name="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</parameter>
      <parameter name="java.naming.provider.url">tcp://tibco.server.host.one:7222,tcp://tibco.server.host.two:7222</parameter>
      <parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactoryAPIM</parameter>
      <parameter locked="false" name="transport.jms.JMSSpecVersion">1.0.2b</parameter>
      <parameter name="transport.jms.MaxJMSConnections">5</parameter>
      <!-- By default, Axis2 spawns a new thread to handle each outgoing message. To change this behavior, you need to remove the ClientApiNonBlocking property from the message.Removal of this property can be vital when queuing transports like JMS are involved. -->
      <property action="remove" name="ClientApiNonBlocking" scope="axis2" />
      <parameter locked="false" name="transport.jms.ConnectionFactoryType">queue</parameter>
      <parameter name="transport.jms.DefaultReplyDestinationType" locked="true">queue</parameter>
      <parameter name="transport.jms.DestinationType" locked="true">queue</parameter>
      <parameter locked="false" name="transport.jms.UserName">apimuser</parameter>
      <parameter locked="false" name="transport.jms.Password">12345</parameter>
      <parameter locked="false" name="transport.jms.CacheLevel">connection</parameter>
   </parameter>
</transportSender>


2) Copy below Tibco JMS client related jars into <APIM_HOME>/repository/components/extensions/ directory

  1. jms-2.0.jar
  2. tibemsd_sec.jar
  3. tibjms.jar
  4. tibjmsadmin.jar
  5. tibjmsapps.jar
  6. tibjmsufo.jar
  7. tibrvjms.jar


3) Start the APIM server and create an API, Publish and subscribe to it with an Application. When creating the API, the endpoint of the API should be given as a JMS endpoint which actually points to the JMS queue (i.e. SMSStore), we will be creating later.

JMS endpoint :
"jms:/SMSStore?transport.jms.ConnectionFactory=QueueConnectionFactoryAPIM&amp;transport.jms.ReplyDestination=SMSReceiveNotificationStore"
Note the below properties given in that endpoint address.
  • (JMSQueue name): SMSStore D
    • Direct endpoint JMS queue of the JMS message. It recieves the JMS messages.
  • transport.jms.ConnectionFactory=QueueConnectionFactoryAPIM
    • Queue ConnectionFactory which is used to create a QueueConnection between API Manager and Tibco EMS server.
  • transport.jms.ReplyDestination=SMSReceiveNotificationStore
    • JMS Queue, which recieves the response related to this request
Below I have mentioned a section of synapse API file created. ( related API resource that has our 
JMS endpoint )

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8"?>
<resource methods="POST" url-mapping="/b" faultSequence="fault">
   <inSequence>
      <property name="api.ut.backendRequestTime" expression="get-property('SYSTEM_TIME')" />
      <filter source="$ctx:AM_KEY_TYPE" regex="PRODUCTION">
         <then>
            <send>
               <endpoint name="admin--test_APIproductionEndpoint_1">
                  <http uri-template="jms:/SMSStore?transport.jms.ConnectionFactory=QueueConnectionFactoryAPIM&amp;transport.jms.ReplyDestination=SMSReceiveNotificationStore">
                     <timeout>
                        <duration>60000</duration>
                        <responseAction>fault</responseAction>
                     </timeout>
                  </http>
                  <property name="ENDPOINT_ADDRESS" value="jms:/SMSStore?transport.jms.ConnectionFactory=QueueConnectionFactoryAPIM&amp;transport.jms.ReplyDestination=SMSReceiveNotificationStore" />
               </endpoint>
            </send>
         </then>
         <else>
            <sequence key="_sandbox_key_error_" />
         </else>
      </filter>
   </inSequence>
   <outSequence>
      <class name="org.wso2.carbon.apimgt.gateway.handlers.analytics.APIMgtResponseHandler" />
      <send />
   </outSequence>
</resource>


Configure and setup ESB


1) Configure JMSListener and JMSSender in ESB - axis2.xml
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
      <parameter locked="false" name="QueueConnectionFactoryESB">
         <parameter locked="false" name="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</parameter>
         <parameter name="java.naming.provider.url">tcp://tibco.server.host.one:7222,tcp://tibco.server.host.two:7222</parameter>
         <parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactoryESB</parameter>
         <parameter locked="false" name="transport.jms.JMSSpecVersion">1.0.2b</parameter>
         <parameter locked="false" name="transport.jms.ConnectionFactoryType">queue</parameter>
         <parameter locked="false" name="transport.jms.UserName">esbuser</parameter> 
         <parameter locked="false" name="transport.jms.Password">12345</parameter>
         <parameter name="transport.jms.MaxJMSConnections">5</parameter>
      </parameter>
   </transportReceiver>
   <transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender">
      <parameter locked="false" name="QueueConnectionFactoryESB">
         <parameter locked="false" name="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</parameter>
         <parameter name="java.naming.provider.url">tcp://tibco.server.host.one:7222,tcp://tibco.server.host.two:7222</parameter>
         <parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactoryESB</parameter>
         <parameter locked="false" name="transport.jms.JMSSpecVersion">1.0.2b</parameter>
         <parameter locked="false" name="transport.jms.ConnectionFactoryType">queue</parameter>
         <parameter name="transport.jms.DefaultReplyDestinationType" locked="true">queue</parameter>
         <parameter name="transport.jms.DestinationType" locked="true">queue</parameter>
         <parameter locked="false" name="transport.jms.UserName">esbuser</parameter>
         <parameter locked="false" name="transport.jms.Password">12345</parameter>
         <parameter name="transport.jms.MaxJMSConnections">5</parameter>
         <parameter locked="false" name="transport.jms.CacheLevel">connection</parameter>
      </parameter>
   </transportSender>


Above are all the configurations required for this setup.

2) Other than that, copy below Tibco JMS client related jars into <ESB_HOME>/repository/components/extensions/ directory
  • jms-2.0.jar
  • tibemsd_sec.jar
  • tibjms.jar
  • tibjmsadmin.jar
  • tibjmsapps.jar
  • tibjmsufo.jar
  • tibrvjms.jar

You can get them from the tibco installation directory.
i.e. /home/samithac/tibco/ems/8.4/lib

3) Deploy the Proxy service required in ESB. For that copy the below SMSForwardProxy.xml into <ESB_HOME>/repository/deployment/server/synapse-configs/default/proxy-services



1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="SMSForwardProxy" transports="jms" startOnLoad="true">
   <description />
   <target>
      <inSequence>
         <send>
            <endpoint>
               <address uri="http://localhost:9000/services/SimpleStockQuoteService" />
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send />
      </outSequence>
   </target>
   <parameter name="transport.jms.DestinationType">queue</parameter>
   <!-- listnening to this queue-->
   <parameter name="transport.jms.Destination">SMSStore</parameter>
   <parameter name="transport.jms.ContentType">
      <rules xmlns="">
         <jmsProperty>contentType</jmsProperty>
         <default>text/xml</default>
      </rules>
   </parameter>
   <parameter name="transport.jms.ConnectionFactory">QueueConnectionFactoryESB</parameter>
</proxy>



I will post another blog post to describe how wso2 ESB Proxy works..be patient :-)

4) Deploy sample backend service (SimpleStockQuoteService) in to the Axis2 server. Open a command prompt (or a shell in Linux) and go to the required sample folder.  <ESB_HOME>/samples/axis2Server/src/SecureStockQuoteService . Then give the 'ant' command to build the sample and deploy.











                                                                                                                                                                            
5) Then start the axis2server within WSO2 ESB. For that, go o to <ESB_HOME>/samples/axis2Server/ directory and give run the axis2server.sh script to start the server.


Configure and setup Tibco EMS JMS server


1) Go to the tibco installation directory's bin directory and start the Server using below command.
./tibemsd64 -config ~/TIBCO_HOME/tibco/cfgmgmt/ems/data/tibemsd.conf


This startup command will load the configurations from ~/TIBCO_HOME/tibco/cfgmgmt/ems/data/tibemsd.conf



You can use the  TIBCO Enterprise Message Service Administration Tool to manage/view the connections, factories, etc. You can start it with ./tibemsadmin64 command.




2) Create 2 queues in JMS server 

I have created two queues with below names.
  • SMSStore - Queue into which the APIM send the JMS message. ESB server also consumes JMS messages from this queue.
  • SMSReceiveNotificationStore - Queue into which the ESB sends the response JMS message.


Sample command:

create queue SMSReceiveNotificationStore

3) Create 2 ConnectionFactories in JMS server

I have below two JMS connection factories been created already.

  • QueueConnectionFactoryAPIM
  • QueueConnectionFactoryESB


Sample command:

create factory QueueConnectionFactoryAPIM queue url=tcp://localhost:7222 reconnect_attempt_delay=100000 reconnect_attempt_count=3

You can see the Connection Factories been created in

/home/samithac/TIBCO_HOME/tibco/cfgmgmt/ems/data/factories.conf file as below. You can create the Connection Factories by manually adding into the above file too.

[QueueConnectionFactoryESB]
  type                     = queue
  url                      = tcp://tibco.server.host.one:7222
  connect_attempt_count = 3
  connect_attempt_delay = 15000
  connect_attempt_timeout = 10000
  reconnect_attempt_count = 1
  reconnect_attempt_delay = 1
  reconnect_attempt_timeout = 5000

[QueueConnectionFactoryAPIM]
  type                     = queue
  url                      = tcp://tibco.server.host.one:7222
  connect_attempt_count = 3
  connect_attempt_delay = 15000
  connect_attempt_timeout = 10000
  reconnect_attempt_count = 1
  reconnect_attempt_delay = 1
  reconnect_attempt_timeout = 5000


Ok. Now you are ready. Tou can invoke the API and get a response back. Below is how I invokded the API via cURL client and got the expected response back. The payload used is saved in a xml file named payload.xml and placed at the directory where the curl command is given.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
 <soapenv:Header/>
 <soapenv:Body>
  <ser:getQuote>
  <!--Optional:-->
   <ser:request>
   <!--Optional:-->
    <xsd:symbol>message</xsd:symbol>
   </ser:request>
  </ser:getQuote>
 </soapenv:Body>
</soapenv:Envelope>

Sample cURL command:

curl -X POST --header 'Content-Type: application/xml' --header 'Accept: application/xml' --header 'Authorization: Bearer 9b17298d-6404-338e-9036-271bb7a239f3' -d @payload.xml 'https://10.100.7.124:8243/test/1.0.0/b' -k



That's it. Cheers...!

References:

http://blog.samisa.org/2014/01/jms-usecases-tutorial-with-wso2-esb.html
https://docs.wso2.com/display/ESB500/ESB+as+Both+a+JMS+Producer+and+Consumer

Saturday, December 30, 2017

Configuring SSL Termination with WSO2 API Manager

When you are setting up WSO2 API manager fronted with a load balancer, you have the option of terminating SSL for HTTPS requests. So the load balancer will be decrypting incoming HTTPS messages and forwarding them to the Carbon servers as HTTP. So basically the APIM should be working with HTTP requests, after surpassing the load balancer. This is useful when you want to reduce the load on your Carbon servers due to encryption. To achieve this, the load balancer should be configured with TLS termination and the Tomcat RemoteIpValve should be enabled for Carbon servers.

I am going to describe the steps you have to follow for your exact requirement, from the beginning so that you can follow.

In these steps, note the below facts.

1. Configuring Load balancer

 

I am using nginx as the load balancer. As we are not competent with the F5 which you use as the load balancer, we will not be able to provide guidance/scripts to configure F5. I am providing the following guide with Nginx so that you can have the basic understanding on what has to be done via the load balancer for this task. You may use this knowledge to configure F5.
Configure the /etc/nginx/sites-enabled/default file as below.

server {
       listen 443;
       ssl on;
       ssl_certificate /etc/nginx/ssl/nginx.crt;
       ssl_certificate_key /etc/nginx/ssl/nginx.key;
       location /apimanager/carbon {
           index index.html;
           proxy_set_header X-Forwarded-Host $host;
           proxy_set_header X-Forwarded-Server $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-Proto $scheme;
           proxy_pass http://localhost:9763/carbon;
           proxy_redirect  http://localhost:9763/carbon  https://localhost/apimanager/carbon;
           proxy_cookie_path / /apimanager/carbon/;
       }
 
       location ~ ^/apimanager/store/(.*)registry/resource/_system/governance/apimgt/applicationdata/icons/(.*)$ {
           index index.html;
           proxy_set_header X-Forwarded-Host $host;
           proxy_set_header X-Forwarded-Server $host;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
               proxy_pass http://localhost:9763/$1registry/resource/_system/governance/apimgt/applicationdata/icons/$2;
       }
 
 
       location ~ ^/apimanager/publisher/(.*)registry/resource/_system/governance/apimgt/applicationdata/icons/(.*)$ {
           index index.html;
           proxy_set_header X-Forwarded-Host $host;
           proxy_set_header X-Forwarded-Server $host;
       proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
           proxy_pass http://localhost:9763/$1registry/resource/_system/governance/apimgt/applicationdata/icons/$2;       
      }
 
       location /apimanager/publisher {
          index index.html;
          proxy_set_header X-Forwarded-Host $host;
          proxy_set_header X-Forwarded-Server $host;
         proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_pass http://localhost:9763/publisher;
          proxy_redirect  http://localhost:9763/publisher  https://localhost/apimanager/publisher;
          proxy_cookie_path /publisher /apimanager/publisher;
      }
 
      location /apimanager/store {
          index index.html;
          proxy_set_header X-Forwarded-Host $host;
          proxy_set_header X-Forwarded-Server $host;
         proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_pass http://localhost:9763/store;
          proxy_redirect http://localhost:9763/store https://localhost/apimanager/store;
          proxy_cookie_path /store /apimanager/store;
       }

       location / {
              proxy_pass http://localhost:8280;
       }
}

Certificate generation for nginx has to be done. Follow https://docs.wso2.com/display/AM210/Adding+a+Reverse+Proxy+Serve for it.
And then start nginx server.

Next file configurations are related to configuring WSO2 API Manager.

2. tomcat/catalina-server.xml file configuration 

 

Do the following configs in <CARBON_HOME>/repository/conf/tomcat/catalina-server.xml

a) Enabling RemoteIpValve for Carbon servers

Configure RemoteIPValve in <CARBON_HOME>/repository/conf/tomcat/catalina-server.xml as below.
<Valve className="org.apache.catalina.valves.RemoteIpValve" 
remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" />
 b) Set proxy port and hostname

 <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
              port="9443"
             proxyPort="443"
               hostname="localhost"
              bindOnInit="false"
              sslProtocol="TLS"
---
--
/> 

3. carbon.xml configuration


Configure <APIM-HOME>/repository/conf/carbon.xml file as below.
  • Uncomment following element, 
        <HttpAdminServices>*</HttpAdminServices>
  • Set,  
        <EnableHTTPAdminConsole>true</EnableHTTPAdminConsole>

  • Set hostname,
        <HostName>localhost</HostName>
        <MgtHostName>localhost</MgtHostName>

4. site.json files of web apps

a)
  • Edit the <APIM_HOME>/repository/deployment/server/jaggeryapps/store/site/conf/site.json file with the context and request URL as shown below.
  • This is done to configure the reverse proxy server for WSO2 API Store, so that you can route the requests that come to the store through a proxy server.
"reverseProxy" : {
        "enabled" : true, 
        "host" : "localhost", // If the reverse proxy does not have a domain name use the IP
        "context":"/apimanager/store",
        "regContext":"" // Use this only if a different path is used for the registry
    }
b)
  • Edit the <APIM_HOME>/repository/deployment/server/jaggeryapps/publisher/site/conf/site.json file with the context and host as shown below.
  • This is done to configure the reverse proxy server for WSO2 API Publisher, so that you can route the requests that come to the publisher through a proxy server. 
"reverseProxy" : {
        "enabled" : true, 
        "host" : "localhost",//If the reverse proxy does not have a domain name use the IP
        "context":"/apimanager/publisher",
        "regContext":"" // Use this only if a different path is used for the registry
    } 

5. Configuring api-manager.xml file.

  • Change the value of KeyValidatorClientType to WSClient in the <APIM_HOME>/repository/conf/api-manager.xml file.
  • You need to make this change when you change the value of the host, because requests that are made to the Key Manager will also start getting routed through the reverse proxy; therefore, this needs to be over HTTP instead of TCP, which is Thrifts underlying protocol.
        <KeyValidatorClientType>WSClient</KeyValidatorClientType>
  • Change gateway endpoint urls displayed on store,
         <GatewayEndpoint>http://localhost,https://localhost</GatewayEndpoint>  
    
    
  • Set Store URL to be linked and from publisher,
         <APIStore>
                <URL>https://localhost/apimanager/store</URL>
         ---
         </APIStore>
    This is it..!
  •   
 
 

Sunday, May 28, 2017

Performance Testing-Monitoring-Analyzing for WSO2 Products

Performance testing is the process of determining the speed or effectiveness of a computer, network, software program or device [1]. Performance of a software application/product/service can be measured/tested via load tests.

Performance of WSO2 products application systems too are widely tested via these load tests. Other than the performance tests, the JVM heap, CPU performance too can be monitored to determine the causes for certain performance issues of a system/application/product.

In this post I will discuss important facts related to these, basically on the below 2 aspects.

  1. Load Tests and result analysis. 
  2. Using Oracle JMC for performance monitoring.

Load Tests and Result Analysis


I will take WSO2 API Manager for examples to describe this topic. In the case of WSO2 API Manager, the performance can be elaborated using the factors such as below.
  1. Transactions Per Second (TPS)
  2. Response time (minimum/average/maximum)
  3. Error rate
Basically if the TPS is very low or if the average response time is very high,  or if the maximum response time is very high, or if the error rate is high, there is obviously an issue with the system, may be in the configurations in the APIM product or may be in the other systems interacting with APIM.


JMeter is a very convenient tool to generate a load to perform load tests. We can write JMeter scripts to run long running performance tests. In the case of WSO2 APIM, what we basically do is writing test scripts to call APIs published in the API Store.

Following is a simple JMeter test script, composed to test an API in the Store of WSO2 API Manager.

APIMSimpleTest.jmx



You can simply download this file and rename it to APIMSimpleTest.jmx and open it with JMeter if you want to play around with it.

Following are the basic items in this test script.
  1. Thread Group - "API Calling Thread Group"
    Following items exist within this test group.
    1. HTTP Request - "Get Menu"
    2. View Results Tree
    3. Summary Report
  2. HTTP Header Manager

Thread Group - "API Calling Thread Group"



 

  • Number of Threads (Users) : 2000
  • Ramp-up Period(in seconds) : 100
  • Scheduler configuration - Duration : 3600
This test runs for an hour (3600 seconds), with 2000 threads (simulates 2000 users). Ramp up period defines how long does it take to reach the defined thread count.



HTTP Request - "Get Menu"




The HTTP request made to call the API is defined by this. (HTTP Request Method & Path, Web Server Protocol, Server, Port number )



HTTP Header Manager




This sets the 2 headers  to the API call.



Analyzing JMeter test results


"View Results Tree" and "Summary Report" items under Thread group are added to view and analyze the test results. These are called "listeners" and they can be added to a thread group by Right Click on thread group> Add> Listner>

"View Results Tree" item facilitates viewing all the http requests made during the test and their responses. If you provide an empty file (with .jtl extension) to the "Write results to file/ Read from File>Filename" field, all the basic information on the http/https request will be written and saved into that file during the test.

"Summary Report" listener displays a summary of the test including Samples count, min/max/average response times, Error %, throughput, etc.

Note that you can use more listeners to analyze JMeter test results using .jtl file generated as mentioned above. 

It is not required to have these listeners in the test script run time to make analyzing reports. You can just add any listener later after the test and provide the .jtl file and generate an analysis graph, table, etc.

JMeter ships with very few listeners and if you want to add more listeners you can add them to the JMeter as plugins.

Many important plugins can be downloaded from here.

Links for some useful plugins are listed below.

After adding these plugins, you may see them under the Add> Listner list of listeners.

Quick Analysis report Generation can be done using a .jtl file. This will generate a complete analysis report (with graphs/tables) as an .html web page file. This is a very important and convenient feature in JMeter.

To generate a report, just run following single jmeter command.

./jmeter -g  <.jtl file> -o <output_dir_to_create_reports> 

This will display many graphs/tables including the below.
  1. Test and Report informations
  2. APDEX (Application Performance Index)
  3. Requests Summary
  4. Statistics per each thread - (average,min,max response times/throughput, error rates)
  5. Details descriptions on the errors occured
  6. Over Time based Charts
  7. Throughput related graphs
  8. Response times related graphs

Using Oracle Java Mission Control for performance monitoring


When we analyze the performance of a WSO2 product, it is important to analyze on the CPU functionality, Java Heap Memory, Threads, etc. Oracle Java Mission Control (JMC) is an ideal tool for this, which is shipped with Oracle Java.

Oracle Java Mission Control is a tool suite for managing, monitoring, profiling, and troubleshooting your Java applications. Oracle Java Mission Control has been included in standard Java SDK since version 7u40. JMC consists of the JMX Console and the Java Flight Recorder. [2]

If you start JMC in machine that a WSO2 product runs, you can find tremendous amount of information on its performance and functionality.

1. Using JMX Console


Java Mission Control (JMC) uses Java Management Extensions (JMX) to communicate with remote Java processes and the JMX Console is a tool in JMC for monitoring and managing a running JVM instance.

This tool presents live data about memory and CPU usage, garbage collections, thread activity, and more.

To use this to monitor WSO2 product's JVM start the JMC on the computer in which the product is running.  Under the JVM browser, you have to select the related JVM, "[1.x.x_xx]org.wso2.carbon.bootstrap.Bootstrap(xxxxx)".

Then right click on it and select "Start JMX console"


Now you can see the graphs, dashboards on Java heap memory, JVM CPU usage, etc. under the overview section.

The JMX console also consists of a live MBean browser, by which you can monitor and manage the MBeans related to the respective JVM.

In the case of WSO2 APIM, org.apache.synapse MBean will be useful to monitor the statistics related to API endpoints. Under the MBean tree org.apache.synapse>PassThroughLatencyView>nio_https_https, you can view average backend latency, average latency and many other feature attributes.


2. Using Java Flight Recorder


Java Flight Recorder is a profiling and event collection framework built into the Oracle JDK. This can be used to collect recordings and save into a file for later analysis.

Run JFR for a WSO2 product instance via JMC

To run JFR for a WSO2 product instance via JMC, for a fixed time period, follow the below steps.

  • Select the related JVM, "[1.x.x_xx]org.wso2.carbon.bootstrap.Bootstrap(xxxxx)".
  • Then right click on it and select "Start Flight Recording". You will be prompted whether to enable Java commercial features and click "Yes" for it.
  • Then provide a file name and location to dump the recording file.
  • Select "Time Fixed Recording" and provide the recording time you want and click "Finish".



  • After the provided time, the recording .jfr file will be saved in the given location. You can open it in JMC anytime to analyze the recordings.

Running JFR from Command Line

To run JFR for a WSO2 product instance via command line, execute the following commands in the computer where the instance is running.

>jcmd carbon VM.unlock_commercial_features

This will unlock commercial features for the WSO2 carbon JVM, that will enable running JFR. Note that this name "carbon" here can be replaced by any word part separated by period in the related jvm-representation name "org.wso2.carbon.bootstrap.Bootstrap"

>jcmd carbon JFR.start settings=profile duration=3600s name=FullPerfTest filename=recording-1.jfr

This command will start the JFR for the WSO2 product JVM for a duration of 3600 seconds, and the recording file will be dumped to the <WSO2_PRODUCT_HOME> with the name recording-1.jfr at the end of the provided time duration.

You can refer this[3] blog post to learn on JFR in detail.


References
[1] - http://searchsoftwarequality.techtarget.com/definition/performance-testing
[2] - https://www.prosysopc.com/blog/using-java-mission-control-for-performance-monitoring/
[3] - https://medium.com/@chrishantha/using-java-flight-recorder-2367c01deacf