/* * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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.mediator.publishevent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.MessageContext; import org.apache.synapse.SynapseException; import org.apache.synapse.core.axis2.Axis2MessageContext; import java.util.Map; import java.util.TreeMap; /** * Set the Activity ID to the Transport Header and the Synapse Context. */ public class ActivityIDSetter { private static final String MSG_CONTEXT_ACTIVITY_ID = "activity_id"; private static final String ACTIVITY_ID = "activityID"; private static final Log log = LogFactory.getLog(ActivityIDSetter.class); /** * Sets a unique Activity ID to the transport header and synapse context. * This is useful when tracking the message when it passes through different systems. * If either synapse context or transport header already had activity id set, that is reused. * If both synapse context and transport header had activity id set, transport header activity id get precedence * If non of either synapse context or transport header had activity id set, new unique id is generated * * @param messageContext message context of message * @throws SynapseException */ public static void setActivityIdInTransportHeader(MessageContext messageContext) throws SynapseException { try { //get the unique ID used for correlating messages for BAM activity monitoring String idString = getUniqueId(); //Get activity ID form message context, if available. Object idFromContext = messageContext.getProperty(MSG_CONTEXT_ACTIVITY_ID); Axis2MessageContext axis2smc = (Axis2MessageContext) messageContext; org.apache.axis2.context.MessageContext axis2MessageContext = axis2smc.getAxis2MessageContext(); Map headers = (Map) axis2MessageContext .getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS); if (headers != null) { String idFromHeader = (String) (headers).get(ACTIVITY_ID); if (idFromHeader == null || idFromHeader.equals("")) { if (idFromContext != null) { //case 1 - activity ID present in synapse context but absent elsewhere (transport headers exist) //Use the ID present String inID = String.valueOf(idFromContext); if (!(inID.equals(""))) { idString = inID; if (log.isDebugEnabled()) { log.debug("Incoming message had no activity ID, using the ID '" + inID + "' from the Synapse context instead."); } } } else { //case 2 - no activity ID present anywhere, but transport headers exist //Add generated activity ID to Synapse context for later use if needed messageContext.setProperty(MSG_CONTEXT_ACTIVITY_ID, idString); if (log.isDebugEnabled()) { log.debug("no activity ID present anywhere, but transport headers exist."); } } //Add the recovered (case1) or generated (case2) activity ID to the transport header headers.put(ACTIVITY_ID, idString); } else { //case 3 - activity ID is present in the transport header //Just propagate this ID rather than use the generated ID, and expose it to the synapse context idString = idFromHeader; messageContext.setProperty(MSG_CONTEXT_ACTIVITY_ID, idString); if (log.isDebugEnabled()) { log.debug("Propagating activity ID found in transport header: " + idFromHeader); } } } else { if (idFromContext != null) { String inID = String.valueOf(idFromContext); if (!(inID.equals(""))) { //case 4 - transport headers do not exist but activity ID present in synapse context //Use the ID from the context to replace the generated activity ID idString = inID; if (log.isDebugEnabled()) { log.debug("Using activity ID '" + inID + "' from synapse context, transport headers do not exist"); } } } else { if (log.isDebugEnabled()) { log.info("Activity ID not found anywhere, creating new."); } } //case 5 - no activity ID found anywhere and transport headers do not exist //Propagate the generated ID and add it to the synapse context headers = new TreeMap<String, String>(); headers.put(ACTIVITY_ID, idString); axis2MessageContext.setProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS, headers); messageContext.setProperty(MSG_CONTEXT_ACTIVITY_ID, idString); } } catch (Exception e) { String errorMsg = "Error while setting Activity ID in Header "; log.error(errorMsg, e); throw new SynapseException(errorMsg, e); } } //Generate unique ID (cheaper than generating a UUID) private static String getUniqueId() { return (String.valueOf(System.nanoTime()) + Math.round(Math.random() * 123456789)); } }