Package org.wso2.carbon.bam.core.receivers

Source Code of org.wso2.carbon.bam.core.receivers.StatisticsEventingMessageReceiver$EventData

/*
* Copyright (c) 2005-2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package org.wso2.carbon.bam.core.receivers;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.receivers.AbstractMessageReceiver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.bam.common.dataobjects.common.EventingServerDO;
import org.wso2.carbon.bam.common.dataobjects.service.*;
import org.wso2.carbon.bam.core.admin.BAMDataServiceAdmin;
import org.wso2.carbon.bam.core.persistence.BAMPersistenceManager;
import org.wso2.carbon.bam.core.util.BAMUtil;
import org.wso2.carbon.bam.util.BAMConstants;
import org.wso2.carbon.bam.util.BAMException;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

/**
* Statistics Eventing MessageReceiver can process the messages fired by the BAM service statistics
* data publisher. It is capable of picking up, sytem, service and operation level stat data from
* the messages received. Expected message format:
* <p/>
* (01) <statdata:Event xmlns:statdata="http://wso2.org/ns/2009/09/bam/service/statistics/data">
* (02)     <statdata:ServiceStatisticsData>
* (03)         <statdata:ServerName>http://127.0.0.1:9763</statdata:ServerName>
* (04)          <statdata:TenantID>10</statdata:TenantID>
* (05)          <statdata:AverageResponseTime>16.4</statdata:AveageResponseTime>
* (06)          <statdata:MinimumResponseTime>0</statdata:MinimumResponseTime>
* (07)          <statdata:MaximumResponseTime>109</statdata:MaximumResponseTime>
* (08)          <statdata:RequestCount>21</statdata:RequestCount>
* (09)          <statdata:ResponseCount>20</statdata:ResponseCount>
* (10)          <statdata:FaultCount>0</statdata:FaultCount>
* (11)          <statdata:ServiceName>HelloService</statdata:ServiceName>
* (12)          <statdata:OperationName>greet</statdata:OperationName>
* (13)      </statdata:ServiceStatisticsData>
* (13) </statdata:Event>
* <p/>
* Note that ServiceName element MUST be present if the message represents service specific data. If
* the message is about operation specific data, then both ServiceName element and OperationName
* element MUST be present. If it is system level data, neither the ServiceName nor the OperationName
* are expected in the message.
* <p/>
* Schema for message format:
* <p/>
* <?xml version="1.0" encoding="utf-8" ?>
* <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://wso2.org/ns/2009/09/bam/service/statistics/data"
* tns="http://wso2.org/ns/2009/09/bam/service/statistics/data">
* <p/>
* <xsd:element name="Event">
* <xsd:complexType>
* <xsd:sequence>
* <xsd:element name="ServiceStatisticsData">
* <xsd:complexType>
* <xsd:sequence>
* <xsd:element name="ServerName" type="xsd:string"/>
* <xsd:element name="AverageResponseTime" type="xsd:decimal"/>
* <xsd:element name="MinimumResponseTime" type="xsd:long"/>
* <xsd:element name="MaximumResponseTime" type="xsd:long"/>
* <xsd:element name="RequestCount" type="xsd:integer"/>
* <xsd:element name="ResponseCount" type="xsd:integer"/>
* <xsd:element name="FaultCount" type="xsd:integer"/>
* <xsd:element name="ServiceName" type="xsd:string" minOccurs="0"/>
* <xsd:element name="OperationName" type="xsd:string" minOccurs="0"/>
* </xsd:sequence>
* </xsd:complexType>
* </xsd:element>
* </xsd:sequence>
* </xsd:complexType>
* </xsd:element>
* </xsd:schema>
*/
public class StatisticsEventingMessageReceiver extends AbstractMessageReceiver {

    private static final Log log = LogFactory.getLog(StatisticsEventingMessageReceiver.class);

    public static final String STATISTICS_DATA_NS_URI = "http://wso2.org/ns/2009/09/bam/service/statistics/data";

    // OM element names
    public static final String STATISTICS_DATA_ELEMENT_NAME_EVENT = "Event";
    public static final String STATISTICS_DATA_ELEMENT_NAME_SERVICE_STATISTICS_DATA = "ServiceStatisticsData";
    public static final String STATISTICS_DATA_ELEMENT_NAME_TENANT_ID = "TenantID";
    public static final String STATISTICS_DATA_ELEMENT_NAME_SERVER_NAME = "ServerName";
    public static final String STATISTICS_DATA_ELEMENT_NAME_AVG_RESPONSE_TIME = "AverageResponseTime";
    public static final String STATISTICS_DATA_ELEMENT_NAME_MIN_RESPONSE_TIME = "MinimumResponseTime";
    public static final String STATISTICS_DATA_ELEMENT_NAME_MAX_RESPONSE_TIME = "MaximumResponseTime";
    public static final String STATISTICS_DATA_ELEMENT_NAME_REQUEST_COUNT = "RequestCount";
    public static final String STATISTICS_DATA_ELEMENT_NAME_RESPONSE_COUNT = "ResponseCount";
    public static final String STATISTICS_DATA_ELEMENT_NAME_FAULT_COUNT = "FaultCount";
    public static final String STATISTICS_DATA_ELEMENT_NAME_SERVICE_NAME = "ServiceName";
    public static final String STATISTICS_DATA_ELEMENT_NAME_OPERATION_NAME = "OperationName";

    public final void invokeBusinessLogic(MessageContext mc) throws AxisFault {

        BAMDataServiceAdmin dsAdmin = new BAMDataServiceAdmin();
        EventData[] eventData;
        try {
            eventData = getEventDataArray(mc.getEnvelope().getBody());
        } catch (BAMException e) {
            log.error("BAM Statistics MessageReceiver invokeBusinessLogic " +
                    e.getLocalizedMessage() + "\n" + "BAM MR invokeBusinessLogic SOAP Envelope causing the problem" +
                    mc.getEnvelope().toString(), e);
            return;
        }
        for (EventData data : eventData) {
            storeData(data, dsAdmin);
        }

        if (log.isDebugEnabled()) {
            log.debug("BAM MR invokeBusinessLogic SOAP Envelope " + mc.getEnvelope().toString());
        }
    }

    private EventData[] getEventDataArray(OMElement rootElement) throws BAMException {

        Iterator serviceStatisticsDataIterator;
        OMElement eventElement = rootElement.getFirstChildWithName(
                new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_EVENT));

        if (eventElement == null) {
            throw new BAMException("Event element not found in the message");
        }

        QName serviceStatisticsDataQName =
                new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_SERVICE_STATISTICS_DATA);
        serviceStatisticsDataIterator = eventElement.getChildrenWithName(serviceStatisticsDataQName);

        List<EventData> eventDataList = new ArrayList<EventData>();

        while (serviceStatisticsDataIterator.hasNext()) {
            EventData eventData = new EventData();
            OMElement serviceStatisticsDataElement;

            serviceStatisticsDataElement = (OMElement) serviceStatisticsDataIterator.next();

            if (serviceStatisticsDataElement == null) {
                throw new BAMException("ServiceStatisticsData element not found in the message");
            }

            int tenantID = getIntDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_TENANT_ID), serviceStatisticsDataElement);
            if (tenantID == -1) {
                tenantID = CarbonConstants.SUPER_TENANT_ID;
            }

            String serverName = getStringDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_SERVER_NAME), serviceStatisticsDataElement);
            if (serverName == null) {
                throw new BAMException("ServerName element not found in the message");
            }

            double avgResTime = getDoubleDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_AVG_RESPONSE_TIME), serviceStatisticsDataElement);
            long minResTime = getLongDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_MIN_RESPONSE_TIME), serviceStatisticsDataElement);
            long maxResTime = getLongDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_MAX_RESPONSE_TIME), serviceStatisticsDataElement);
            int requestCount = getIntDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_REQUEST_COUNT), serviceStatisticsDataElement);
            int responseCount = getIntDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_RESPONSE_COUNT), serviceStatisticsDataElement);
            int faultCount = getIntDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_FAULT_COUNT), serviceStatisticsDataElement);
            String serviceName = getStringDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_SERVICE_NAME), serviceStatisticsDataElement);
            String operationName = getStringDataValueWithQName(
                    new QName(STATISTICS_DATA_NS_URI, STATISTICS_DATA_ELEMENT_NAME_OPERATION_NAME), serviceStatisticsDataElement);

            eventData.setTenantID(tenantID);
            eventData.setServerName(serverName);
            eventData.setAvgResTime(avgResTime);
            eventData.setMinResTime(minResTime);
            eventData.setMaxResTime(maxResTime);
            eventData.setRequestCount(requestCount);
            eventData.setResponseCount(responseCount);
            eventData.setFaultCount(faultCount);
            eventData.setServiceName(serviceName);
            eventData.setOperationName(operationName);

            eventDataList.add(eventData);

        }
        return eventDataList.toArray(new EventData[eventDataList.size()]);
    }

    private void storeData(EventData data, BAMDataServiceAdmin dsAdmin) {

        if (data.operationName != null) {
            storeOperationData(data, dsAdmin);
        } else if (data.serviceName != null) {
            storeServiceData(data, dsAdmin);
        } else {
            storeServerData(data, dsAdmin);
        }
    }

    private void storeOperationData(EventData data, BAMDataServiceAdmin dsAdmin) {

        if (data.operationName != null && !"".equals(data.operationName)) {

            OperationStatisticsDO operationStatisticsDO = new OperationStatisticsDO(
                    data.serverName, Calendar.getInstance(), data.avgResTime, data.maxResTime,
                    data.minResTime, data.requestCount, data.responseCount, data.faultCount,
                    data.serviceName, data.operationName);
            try {

                /**
                 * set the server ID, service ID and operation ID for stats object, as in eventing case,
                 * we oly know the server name, service name and operation name
                 */
                ServerDO monitoringServer = dsAdmin.getServer(data.serverName, data.tenantID,
                        BAMConstants.SERVER_TYPE_EVENTING, BAMConstants.SERVICE_STAT_TYPE);
                //TODO:check whether this is needed
                if (monitoringServer == null) {
                    if (data.serverName != null) {
                        ServerDO server = new EventingServerDO();
                        server.setTenantID(data.tenantID);
                        server.setServerURL(data.serverName);
                        server.setServerType(BAMConstants.SERVER_TYPE_EVENTING);
                        server.setCategory(BAMConstants.SERVICE_STAT_TYPE);
                        BAMPersistenceManager.getPersistenceManager(BAMUtil.getRegistry())
                                .addMonitoredServer(server);
                    }
                }
                operationStatisticsDO.setServerID(monitoringServer.getId());
                //TODO: SHOULD CACHE THIS TO AVOID UNWANTED DB CALLS FOR GETTING SERVICE ID FOR EACH EVENT
                ServiceDO service = dsAdmin.getService(operationStatisticsDO.getServerID(), data.serviceName);
                if (service != null) {

                    /**
                     * NOTE: If service is null, it is the first time that the data for that service is
                     * being added. In that case, we will not have an ID for the service yet, and the
                     * BAM persistance manager will make sure to add the service to the DB.
                     * We come into this block, only if the service is already in the DB
                     */
                    operationStatisticsDO.setServiceID(service.getId());
                }
                org.wso2.carbon.bam.common.dataobjects.service.OperationDO operation = dsAdmin.getOperation(
                        operationStatisticsDO.getServiceID(), data.operationName);
                if (operation != null) {

                    /**
                     * NOTE: If operation is null, it is the first time that the data for that operation is
                     * being added. In that case, we will not have an ID for the operation yet, and the
                     * BAM persistance manager will make sure to add the operation to the DB.
                     * We come into this block, only if the operation is already in the DB
                     */
                    operationStatisticsDO.setOperationID(operation.getOperationID());
                }
                // now add the operation stats
                dsAdmin.addOperationStatistics(operationStatisticsDO);
            } catch (Exception e) {
                log.error("Error updating operation statistics data for server " + data.serverName +
                        " service " + data.serviceName + " operation " + data.operationName +
                        " from eventing message receiver \n" + e.getLocalizedMessage(), e);
            }
        }
    }

    private void storeServiceData(EventData data, BAMDataServiceAdmin dsAdmin) {

        ServiceStatisticsDO serviceStatisticsDO =
                new ServiceStatisticsDO(data.serverName, Calendar.getInstance(), data.avgResTime,
                        data.maxResTime, data.minResTime, data.requestCount,
                        data.responseCount, data.faultCount, data.serviceName);

        try {

            /**
             * set both the server ID and service ID for stats object, as in eventing case, we only
             * know the server name and service name check whether server is already in DB else
             * add it(dsAdmin side BAM)
             */
            ServerDO monitoringServer = dsAdmin.getServer(data.serverName, data.tenantID,
                    BAMConstants.SERVER_TYPE_EVENTING, BAMConstants.SERVICE_STAT_TYPE);
            if (monitoringServer == null) {
                if (data.serverName != null) {
                    ServerDO server = new ServerDO();
                    server.setTenantID(data.tenantID);
                    server.setServerURL(data.serverName);
                    server.setServerType(BAMConstants.SERVER_TYPE_EVENTING);
                    server.setCategory(BAMConstants.SERVICE_STAT_TYPE);
                    BAMPersistenceManager.getPersistenceManager(BAMUtil.getRegistry())
                            .addMonitoredServer(server);
                    monitoringServer = dsAdmin.getServer(data.serverName, data.tenantID,
                    BAMConstants.SERVER_TYPE_EVENTING, BAMConstants.SERVICE_STAT_TYPE);
                }
            }
            serviceStatisticsDO.setServerID(monitoringServer.getId());
            ServiceDO service = dsAdmin.getService(serviceStatisticsDO.getServerID(), data.serviceName);
            if (service != null) {

                /**
                 * NOTE: If service is null, it is the first time that the data for that service is
                 * being added. In that case, we will not have an ID for the service yet, and the
                 * BAM persistence manager will make sure to add the service to the DB.
                 * We come into this block, only if the service is already in the DB
                 */
                serviceStatisticsDO.setServiceID(service.getId());
            }
            // now add the service stats
            dsAdmin.addServiceStatistics(serviceStatisticsDO);
        } catch (Exception e) {
            log.error("Error updating service statistics data for server " + data.serverName + " service "
                    + data.serviceName + " from eventing message receiver " + e.getLocalizedMessage(), e);
        }
    }

    private void storeServerData(EventData data, BAMDataServiceAdmin dsAdmin) {

        ServerStatisticsDO serverStatisticsDO =
                new ServerStatisticsDO(data.serverName, Calendar.getInstance(), data.avgResTime,
                        data.maxResTime, data.minResTime, data.requestCount,
                        data.responseCount, data.faultCount);

        try {

            /**
             * set the ID for stats object, as in eventing case, we oly know the server name, hence
             * we need to pick up the corresponding ID from data service
             */
            ServerDO monitoringServer = dsAdmin.getServer(data.serverName, data.tenantID,
                    BAMConstants.SERVER_TYPE_EVENTING, BAMConstants.SERVICE_STAT_TYPE);
            // server is not present, let's add a generic server
            if (monitoringServer == null) {
                if (data.serverName != null) {
                    ServerDO server = new ServerDO();
                    server.setTenantID(data.tenantID);
                    server.setServerURL(data.serverName);
                    server.setServerType(BAMConstants.SERVER_TYPE_EVENTING);
                    server.setCategory(BAMConstants.SERVICE_STAT_TYPE);
                    BAMPersistenceManager.getPersistenceManager(BAMUtil.getRegistry())
                            .addMonitoredServer(server);
                }
                monitoringServer = dsAdmin.getServer(data.serverName, data.tenantID,
                    BAMConstants.SERVER_TYPE_EVENTING, BAMConstants.SERVICE_STAT_TYPE);
            }
            int id = monitoringServer.getId();
            serverStatisticsDO.setServerID(id);
            // now, add the stats with that ID
            dsAdmin.addServerData(serverStatisticsDO);
        } catch (Exception e) {
            log.error("Error updating system level service statistics data for server " +
                    data.serverName + " from eventing message receiver " + e.getMessage(), e);
        }
    }


    /**
     * Encapsulates the data extraction logic from a received event
     */

    class EventData {

        // Event attributes
        String serverName;
        int tenantID;
        long minResTime;
        double avgResTime;
        long maxResTime;
        int requestCount;
        int responseCount;
        int faultCount;
        String serviceName;
        String operationName;

        public String getOperationName() {
            return operationName;
        }

        public void setOperationName(String operationName) {
            this.operationName = operationName;
        }

        public String getServiceName() {
            return serviceName;
        }

        public void setServiceName(String serviceName) {
            this.serviceName = serviceName;
        }

        public int getFaultCount() {
            return faultCount;
        }

        public void setFaultCount(int faultCount) {
            this.faultCount = faultCount;
        }

        public int getResponseCount() {
            return responseCount;
        }

        public void setResponseCount(int responseCount) {
            this.responseCount = responseCount;
        }

        public int getRequestCount() {
            return requestCount;
        }

        public void setRequestCount(int requestCount) {
            this.requestCount = requestCount;
        }

        public long getMaxResTime() {
            return maxResTime;
        }

        public void setMaxResTime(long maxResTime) {
            this.maxResTime = maxResTime;
        }

        public double getAvgResTime() {
            return avgResTime;
        }

        public void setAvgResTime(double avgResTime) {
            this.avgResTime = avgResTime;
        }

        public long getMinResTime() {
            return minResTime;
        }

        public void setMinResTime(long minResTime) {
            this.minResTime = minResTime;
        }

        public int getTenantID() {
            return tenantID;
        }

        public void setTenantID(int tenantID) {
            this.tenantID = tenantID;
        }

        public String getServerName() {
            return serverName;
        }

        public void setServerName(String serverName) {
            this.serverName = serverName;
        }
    }

    private int getIntDataValueWithQName(QName qName, OMElement serviceStatisticsDataElement) {
        OMElement element = serviceStatisticsDataElement.getFirstChildWithName(qName);
        int value = -1;

        if (element != null) {
            try {
                value = Integer.parseInt(element.getText().trim());
            } catch (Exception ignore) {
                log.info("Data not in required format (Integer) for data field: " +
                        qName.getLocalPart(), ignore);
            }
        }

        return value;
    }

    private long getLongDataValueWithQName(QName qName, OMElement serviceStatisticsDataElement) {
        OMElement element = serviceStatisticsDataElement.getFirstChildWithName(qName);
        long value = -1;

        if (element != null) {
            try {
                value = Long.parseLong(element.getText().trim());
            } catch (Exception ignore) {
                log.info("Data not in required format (Long) for data field: " +
                        qName.getLocalPart(), ignore);
            }
        }

        return value;
    }

    private Double getDoubleDataValueWithQName(QName qName, OMElement serviceStatisticsDataElement) {
        OMElement element = serviceStatisticsDataElement.getFirstChildWithName(qName);
        double value = -1;

        if (element != null) {
            try {
                value = Double.parseDouble(element.getText().trim());
            } catch (Exception ignore) {
                log.info("Data not in required format (Double) for data field: " +
                        qName.getLocalPart(), ignore);
            }
        }

        return value;
    }

    private String getStringDataValueWithQName(QName qName, OMElement serviceStatisticsDataElement) {
        OMElement element = serviceStatisticsDataElement.getFirstChildWithName(qName);
        String value = null;

        if (element != null) {
            value = element.getText().trim();
        }

        return value;
    }

}
TOP

Related Classes of org.wso2.carbon.bam.core.receivers.StatisticsEventingMessageReceiver$EventData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.