/* * Copyright 2004,2005 The Apache Software Foundation. * * Licensed 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.das.messageflow.data.publisher.publish; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.Output; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.aspects.flow.statistics.publishing.PublishingFlow; import org.apache.synapse.aspects.flow.statistics.publishing.PublishingPayload; import org.apache.synapse.aspects.flow.statistics.publishing.PublishingPayloadEvent; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.das.data.publisher.util.PublisherUtil; import org.wso2.carbon.das.messageflow.data.publisher.internal.MessageFlowDataPublisherDataHolder; import org.wso2.carbon.das.messageflow.data.publisher.util.MediationDataPublisherConstants; import org.wso2.carbon.databridge.commons.Event; import org.wso2.carbon.databridge.commons.utils.DataBridgeCommonsUtils; import javax.xml.bind.DatatypeConverter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.zip.GZIPOutputStream; public class StatisticsPublisher { private static Log log = LogFactory.getLog(StatisticsPublisher.class); private static String streamId = DataBridgeCommonsUtils.generateStreamId(MediationDataPublisherConstants.STREAM_NAME, MediationDataPublisherConstants.STREAM_VERSION); private static ThreadLocal<Kryo> kryoTL = new ThreadLocal<Kryo>() { @Override protected Kryo initialValue() { Kryo kryo = new Kryo(); /** * When registering classes use for serialization, the numbering order should be preserved and * SHOULD follow the same convention from Analytic Server as well. Otherwise deserialization fails. */ kryo.register(HashMap.class, 111); kryo.register(ArrayList.class, 222); kryo.register(PublishingPayload.class, 333); kryo.register(PublishingPayloadEvent.class, 444); return kryo; } }; public static void process(PublishingFlow publishingFlow, int tenantId) { Object[] metaData = new Object[2]; Object[] eventData = new Object[2]; addMetaData(metaData, tenantId); addEventData(eventData, publishingFlow); if (log.isDebugEnabled()) { log.debug("Before sending to analytic server ------"); /* Logs to print data sending to analytics server. Use log4j.properties to enable this logs */ for (int i = 0; i < eventData.length; i++) { log.debug("Section-" + i + " -> " + eventData[i]); } } publishToAgent(eventData, metaData); if (log.isDebugEnabled()) { log.debug("------ After sending to analytic server"); } } private static void addMetaData(Object[] metaDataValueList, int tenantId) { /* [0] -> compressed */ metaDataValueList[0] = true; // payload-data is in compressed form /* [1] -> tenantId */ metaDataValueList[1] = tenantId; } private static void addEventData(Object[] eventData, PublishingFlow publishingFlow) { /* [0] -> messageId */ eventData[0] = publishingFlow.getMessageFlowId(); Map<String, Object> mapping = publishingFlow.getObjectAsMap(); String host = null; String port = null; host = PublisherUtil.getHostAddress(); mapping.put("host", host); // Adding host if (port != null) { mapping.put("port", port); } ByteArrayOutputStream out = new ByteArrayOutputStream(); Output output = new Output(out); kryoTL.get().writeObject(output, mapping); output.flush(); /* [1] -> flowData */ eventData[1] = compress(out.toByteArray()); if (log.isDebugEnabled()) { ObjectMapper mapper = new ObjectMapper(); String jsonString = null; try { jsonString = mapper.writeValueAsString(mapping); } catch (JsonProcessingException e) { log.error("Unable to convert", e); } log.debug("Uncompressed data :"); log.debug(jsonString); } } private static void publishToAgent(Object[] eventData, Object[] metaData) { // Creating Event Event event = new Event(streamId, System.currentTimeMillis(), metaData, null, eventData); // Has to use try-publish for asynchronous publishing MessageFlowDataPublisherDataHolder.getInstance().getPublisherService().publish(event); } /** * Compress the payload * * @param str * @return */ private static String compress(byte[] str) { if (str == null || str.length == 0) { return null; } ByteArrayOutputStream out = new ByteArrayOutputStream(); try { GZIPOutputStream gzip = new GZIPOutputStream(out); gzip.write(str); gzip.close(); return DatatypeConverter.printBase64Binary(out.toByteArray()); } catch (IOException e) { log.error("Unable to compress data", e); } return null; } }