APIM manage workflow with multiple roles APIM 3.0.0 per API based subscription workflow Logging internal HTTP requests Log APIM analytics events to a file Monetization and sample with WSO2 API Manager 2.6.0 Share application and subscription among a set of specific groups or roles WSO2 APIM Correlating analytics event with correlationID APIM analytics distinguish production and sandbox traffic APIM 2.x.x analytics internal and analytics tuneup Configure APIM(Next release) Key Manager User stores APIM(Next release) working with key manager DAS 3.x Parse system variables to Spark Context Revoke OAuth application In APIM 2.1.0 Next WSO2 APIM powered by WSO2 Ballerina Configure WSO2 APIM Analytics on Cluster environment Configure WSO2 DAS 3.1.0 for WSO2 APIM 2.0.0 Analytics WSO2 APIM publishing custom statistics WSO2 APIM Error codes Working with WSO2 message tracer Use DAS admin service to query using Spark SQL Configure WSO2 APIM Analytics using XML WSO2 APIM Generating and Retrieving Custom Statistics Understanding WSO2 APIM Statistics Model Publishing WSO2 APIM 1.10.x Runtime Statistics to DAS with RDBMS Publishing_APIM_1100_Runtime_Statistics_to_DAS Aggregate functions with WSO2 DAS REST API Create a cApp for WSO2 DAS Debugging WSO2 Products using OSGI console. Publishing APIM Runtime Statistics to DAS Deploy cApp on WSO2 DAS How to configure and start the Accumulo minicluster How to setup DNS server on Ubuntu and Ubuntu server How to use Java Reflection how to install apache web server on ubuntu and ubuntu server How to install Mail server on Ubuntu and Ubuntu server How to install squirrelmail webmail client on Ubuntu and Ubuntu Server Pass and return String value to JNI method Pass and return numeric value to JNI method Calling a C Function from the Java Programming Language using JNI AXIS 2 Sample web service Client with maven and eclipse How to setup AXIS 2 with Apache Tomcat AXIS 2 Sample web service with maven and eclipse Robot framework Sample with Selenium Robot framework Custom Library Sample Behaviour-Driven Development with JBehave and Eclipse Play Audio with Netbeans and linking with LibVLC Implement LibVLC based player with QT-part2 Simple Audio playing sample with LibVLC How to install LibVLC on Ubuntu Implement LibVLC based player with QT-part1
WSO2 APIM publishing custom statistics
  1. Introduction

    In this blog, I will explain the possible approach to take, extend the runtime statistics in the APIM to DAS. Custom event publishing is important when you want to publish a custom event which is not provided apim by default. Also, it will help to handle more advanced business requirements like message body based analytics which is also not proved by the APIM by default.

  2. Using Class mediator

    Class mediator[1] is another approach to extend the APIM runtime statistics as an event. You can create a java class with DAS data publisher which will publisher the event when Class mediator gets invoke. Here the sample java class for the class mediator. Before start implement makes sure to import all the required java dependencies to the project. For that please check the sample section for the source code.

    package com.rukspot.sample.eventpublisher;
    
    import org.apache.synapse.MessageContext;
    import org.apache.synapse.mediators.AbstractMediator;
    import org.apache.synapse.rest.RESTConstants;
    import org.wso2.carbon.apimgt.gateway.APIMgtGatewayConstants;
    import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityUtils;
    import org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationContext;
    import org.wso2.carbon.apimgt.impl.utils.APIUtil;
    import org.wso2.carbon.databridge.agent.DataPublisher;
    
    public class SimpleClassMediator extends AbstractMediator {
    
    
        public boolean mediate(MessageContext mc) {
    
            String context = (String) mc.getProperty(RESTConstants.REST_API_CONTEXT);
            String apiPublisher = (String) mc.getProperty(APIMgtGatewayConstants.API_PUBLISHER);
            String apiVersion = (String) mc.getProperty(RESTConstants.SYNAPSE_REST_API);
            String api = APIUtil.getAPINamefromRESTAPI(apiVersion);
    
            AuthenticationContext authContext = APISecurityUtils.getAuthenticationContext(mc);
            String username = "";
            String applicationName = "";
            if (authContext != null) {
                username = authContext.getUsername();
                applicationName = authContext.getApplicationName();
            }
            System.out.println(api);
            try {
                DataPublisher publisher = EventPublisher.getPublisher();
                String id = "org.wso2.apimgt.statistics.custom:1.0.0";
                Object[] payload= new Object[]{api,applicationName,username};
                publisher.publish(id, null, null, payload);
            } catch (Exception e) {
                System.out.println("error Sending event " + e.getMessage());
            }
            return true;
        }
    }
    
  3. Using handler

    Another way is to implement the data publisher in a synapse handler[2]. It is similar to the class mediator but it is implemented as a handler and place in the handler section in the API synapse. Here the sample handler class.

    package com.rukspot.sample.eventpublisher;
    
    import org.apache.synapse.MessageContext;
    import org.apache.synapse.rest.AbstractHandler;
    import org.apache.synapse.rest.RESTConstants;
    import org.wso2.carbon.apimgt.gateway.APIMgtGatewayConstants;
    import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityUtils;
    import org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationContext;
    import org.wso2.carbon.apimgt.impl.utils.APIUtil;
    import org.wso2.carbon.databridge.agent.DataPublisher;
    
    public class SimpleEventPublisherHandler extends AbstractHandler {
        public boolean handleRequest(MessageContext mc) {
            String context = (String) mc.getProperty(RESTConstants.REST_API_CONTEXT);
            String apiPublisher = (String) mc.getProperty(APIMgtGatewayConstants.API_PUBLISHER);
            String apiVersion = (String) mc.getProperty(RESTConstants.SYNAPSE_REST_API);
            String api = APIUtil.getAPINamefromRESTAPI(apiVersion);
    
            AuthenticationContext authContext = APISecurityUtils.getAuthenticationContext(mc);
            String username = "";
            String applicationName = "";
            if (authContext != null) {
                username = authContext.getUsername();
                applicationName = authContext.getApplicationName();
            }
            System.out.println(api);
            try {
                DataPublisher publisher = EventPublisher.getPublisher();
                String id = "org.wso2.apimgt.statistics.custom:1.0.0";
                Object[] payload= new Object[]{api,applicationName,username};
                publisher.publish(id, null, null, payload);
            } catch (Exception e) {
                System.out.println("error Sending event " + e.getMessage());
            }
            return true;
        }
    
        public boolean handleResponse(MessageContext messageContext) {
            return true;
        }
    }
    
  4. Using Event mediator
      • Event mediator[3] is one of the ways to integrate to your mediation flow as a mediator. A mediator is a simple way to add a custom event stream without touching any java level codes.
      • APIM 2.0.0 is not shipped with Event mediator by default. But it is possible to install feature in APIM 2.0.0 and configure.
      • To install feature first add the relevant feature repository to the APIM according to this[4].
      • Then find the PublishEvent Mediator Aggregate:4.6.1 feature and restart after done.
      • To configure event publishing you need to configure the EventSink configuration and EventPublisher mediator.
      • EventSink[5] configuration is to define the DAS connection-related information and sample configuration is as follow. The configuration is need to deploy in the /home/rukshan/apim/2.0.0/test/wso2am-2.0.0/repository/deployment/server/event-sinks/ directory with name testSink.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <eventSink>
        <receiverUrl>tcp://localhost:7612</receiverUrl>
        <authenticatorUrl/>
        <username>admin</username>
        <password>admin</password>
    </eventSink>
    
      • Next, we need to define the event mediator in the Synapse API as follow.
    <?xml version="1.0" encoding="UTF-8"?>
    <api xmlns="http://ws.apache.org/ns/synapse"
         name="admin--sample"
         context="/sample/1.0.0"
         version="1.0.0"
         version-type="context">
       <resource methods="GET" url-mapping="/one" faultSequence="fault">
          <inSequence>
             <property name="api.ut.backendRequestTime"
                       expression="get-property('SYSTEM_TIME')"/>
             <filter source="$ctx:AM_KEY_TYPE" regex="PRODUCTION">
                <then>
    
            <publishEvent>
                <eventSink>testSink</eventSink>
                <streamName>test</streamName>
                <streamVersion>1.0.0</streamVersion>
                <attributes>
                   <meta/>
                   <correlation/>
                   <payload>
                      <attribute name="atr1" type="STRING" defaultValue="" value="testValue"/>
                      <attribute name="atr2" type="STRING" defaultValue="" value="Test Region"/>
                   </payload>
                   <arbitrary/>
                </attributes>
             </publishEvent>
    
                   <send>
                      <endpoint name="admin--sample_APIproductionEndpoint_0">
                         <http uri-template="http://localhost:8080/simple-service-webapp/webapi/myresource"/>
                         <property name="ENDPOINT_ADDRESS"
                                   value="http://localhost:8080/simple-service-webapp/webapi/myresource"/>
                      </endpoint>
                   </send>
                </then>
                <else>
                   <sequence key="_sandbox_key_error_"/>
                </else>
             </filter>
          </inSequence>
          <outSequence>
             <class name="org.wso2.carbon.apimgt.usage.publisher.APIMgtResponseHandler"/>
             <send/>
          </outSequence>
       </resource>
       <resource methods="GET" url-mapping="/two" 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--sample_APIproductionEndpoint_1">
                         <http uri-template="http://localhost:8080/simple-service-webapp/webapi/myresource"/>
                         <property name="ENDPOINT_ADDRESS"
                                   value="http://localhost:8080/simple-service-webapp/webapi/myresource"/>
                      </endpoint>
                   </send>
                </then>
                <else>
                   <sequence key="_sandbox_key_error_"/>
                </else>
             </filter>
          </inSequence>
          <outSequence>
             <class name="org.wso2.carbon.apimgt.usage.publisher.APIMgtResponseHandler"/>
             <send/>
          </outSequence>
       </resource>
       <handlers>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.common.APIMgtLatencyStatsHandler"/>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.security.CORSRequestHandler">
             <property name="apiImplementationType" value="ENDPOINT"/>
          </handler>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler"/>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.throttling.ThrottleHandler">
             <property name="productionMaxCount" value="2"/>
          </handler>
          <handler class="org.wso2.carbon.apimgt.usage.publisher.APIMgtUsageHandler"/>
          <handler class="org.wso2.carbon.apimgt.usage.publisher.APIMgtGoogleAnalyticsTrackingHandler">
             <property name="configKey" value="gov:/apimgt/statistics/ga-config.xml"/>
          </handler>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerExtensionHandler"/>
       </handlers>
    </api>
    
  5. Using Bam mediator
      • Bam mediator[6] is similar to the Event Mediator but it is now deprecated. But it will be useful if you are using an older version of APIM. An older version of APIM supports BAM mediator by default.
      • To configure event publisher here also there is two component to configure. First, we need to define the bam server profile[7].In server profile, we define the connection setting as well as stream definition. Once you define these definitions we can directly refer them in the mediator to send the event
      • To configure mediator, open your synapse API file and define the mediator in a proper place.
    <bam xmlns="http://ws.apache.org/ns/synapse">
       <serverProfile name="test-bam-profile">
          <streamConfig name="org.wso2.apimgt.statistics.custom" version="1.0.0"></streamConfig>
       </serverProfile>
    </bam>>
    
      • And complete synapse file would be like this.
    <?xml version="1.0" encoding="UTF-8"?>
    <api xmlns="http://ws.apache.org/ns/synapse"
         name="admin--sample"
         context="/sample/1.0.0"
         version="1.0.0"
         version-type="context">
       <resource methods="GET" url-mapping="/*" faultSequence="fault">
          <inSequence>
             <filter source="$ctx:AM_KEY_TYPE" regex="PRODUCTION">
                <then>
                   <property name="api.ut.backendRequestTime"
                             expression="get-property('SYSTEM_TIME')"/>
    
    <bam xmlns="http://ws.apache.org/ns/synapse">
       <serverProfile name="test-bam-profile">
          <streamConfig name="org.wso2.apimgt.statistics.custom" version="1.0.0"></streamConfig>
       </serverProfile>
    </bam>
    
                   <send>
                      <endpoint name="admin--sample_APIproductionEndpoint_0">
                         <http uri-template="http://localhost:8080/simple-service-webapp/webapi/myresource"/>
                      </endpoint>
                   </send>
                </then>
                <else>
                   <sequence key="_sandbox_key_error_"/>
                </else>
             </filter>
          </inSequence>
          <outSequence>
             <class name="org.wso2.carbon.apimgt.usage.publisher.APIMgtResponseHandler"/>
             <send/>
          </outSequence>
       </resource>
       <handlers>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.security.CORSRequestHandler">
             <property name="apiImplementationType" value="ENDPOINT"/>
          </handler>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler"/>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.throttling.APIThrottleHandler">
             <property name="id" value="A"/>
             <property name="policyKeyResource"
                       value="gov:/apimgt/applicationdata/res-tiers.xml"/>
             <property name="policyKey" value="gov:/apimgt/applicationdata/tiers.xml"/>
             <property name="policyKeyApplication"
                       value="gov:/apimgt/applicationdata/app-tiers.xml"/>
          </handler>
          <handler class="org.wso2.carbon.apimgt.usage.publisher.APIMgtUsageHandler"/>
          <handler class="org.wso2.carbon.apimgt.usage.publisher.APIMgtGoogleAnalyticsTrackingHandler">
             <property name="configKey" value="gov:/apimgt/statistics/ga-config.xml"/>
          </handler>
          <handler class="org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerExtensionHandler"/>
       </handlers>
    </api>
    
  6. Sample

    Here you can find the above-mentioned sample. Class mediator and Handler implementation can be found on the jar inside the zip. Download the sample from here. Please find the readme for more about the configuration.

  7. References
    1. https://docs.wso2.com/display/ESB490/Class+Mediator
    2. https://docs.wso2.com/display/ESB490/Writing+a+Synapse+Handler
    3. https://docs.wso2.com/display/ESB490/Publish+Event+Mediator
    4. https://docs.wso2.com/display/ADMIN44x/Installing+Features+via+the+UI
    5. https://docs.wso2.com/display/ESB490/Working+with+Event+Sinks
    6. https://docs.wso2.com/display/ESB481/BAM+Mediator
    7. https://docs.wso2.com/display/ESB481/Configuring+a+Server+Profile

Add Comment

* Required information
1000
Powered by Commentics

Comments (0)

No comments yet. Be the first!