Package org.jboss.soa.esb.services.jbpm.actionhandlers

Source Code of org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler

/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.soa.esb.services.jbpm.actionhandlers;

import static org.jboss.soa.esb.services.jbpm.actionhandlers.ActionUtil.*;
import org.apache.log4j.Logger;
import org.dom4j.tree.DefaultElement;
import org.jboss.internal.soa.esb.addressing.helpers.EPRHelper;
import org.jboss.internal.soa.esb.util.LRUCache;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.addressing.EPR;
import org.jboss.soa.esb.addressing.PortReference;
import org.jboss.soa.esb.addressing.eprs.LogicalEPR;
import org.jboss.soa.esb.client.ServiceInvoker;
import org.jboss.soa.esb.couriers.Courier;
import org.jboss.soa.esb.couriers.CourierFactory;
import org.jboss.soa.esb.couriers.CourierUtil;
import org.jboss.soa.esb.listeners.message.MessageDeliverException;
import org.jboss.soa.esb.message.Message;
import org.jboss.soa.esb.services.jbpm.Constants;
import org.jboss.soa.esb.services.jbpm.JBpmObjectMapper;
import org.jboss.soa.esb.services.jbpm.actions.JBpmCallback;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.Token;
/**
*
* Send messages to ESB services from jBPM applications, and leaves the node
* in a wait state, waiting for a call back.
*
* <li/>esbCategoryName - for ESB registry lookup
* <li/>esbServiceName - for ESB registry lookup
* <li>millisToWaitForResponse - deprecated, please use a jBPM Timer </li>
*
* @author <a href="mailto:schifest@heuristica.com.ar">Esteban</a>
* @author <a href="mailto:kstam@jboss.com">Kurt T Stam</a>
*/
public class EsbActionHandler implements ActionHandler
{
    private static final long serialVersionUID = 2L;

    public String esbCategoryName;

    public String esbServiceName;

    public Integer millisToWaitForResponse;

    public Boolean globalProcessScope;

    public DefaultElement bpmToEsbVars;

    public DefaultElement esbToBpmVars;
   
    public String exceptionTransition;

    public String replyToOriginator;
   
    private transient Logger logger = Logger.getLogger(getClass());
   
    private static transient LRUCache<String, ServiceInvoker> siCache = new LRUCache<String, ServiceInvoker>(20);

    public void execute (ExecutionContext executionContext) throws Exception
    {
        //validation
        if (replyToOriginator != null) {
            if (!(Constants.EPR_REPLY.equals(replyToOriginator) || Constants.EPR_FAULT.equals(replyToOriginator))) {
                throw new ConfigurationException("EPR type (replyToOriginator) must be \"" + Constants.EPR_REPLY + "\" or \"" + Constants.EPR_FAULT + "\"");
            }
        } else {
            if (null == esbCategoryName)
                throw new ConfigurationException(
                    "Service category (esbCategoryName element) must not be null");
            if (null == esbServiceName)
                throw new ConfigurationException(
                    "Service name (esbServiceName element) must not be null");
        }
        if (millisToWaitForResponse !=null) {
            logger.info("millisToWaitForResponse is no longer a valid element, please use a " +
                    "jBPM timer for this node instead.");
        }
        //Create the ESB Message
        JBpmObjectMapper mapper = new JBpmObjectMapper();
      Message message = mapper.mapFromJBpmToEsbMessage(bpmToEsbVars, globalProcessScope, executionContext);
        //Set the replyTo to the JBpmCallback Service
        String esbToBpmVarsXml=null;
        if (esbToBpmVars!=null) {
            esbToBpmVarsXml = esbToBpmVars.asXML();
        }
        EPR replyTo = createReplyTo(esbToBpmVarsXml, globalProcessScope, executionContext);
        message.getHeader().getCall().setReplyTo(replyTo);
        if (exceptionTransition!=null) {
//          Set the replyTo to the JBpmCallback Service
            EPR faultTo = createFaultTo(esbToBpmVarsXml, globalProcessScope, executionContext);
            message.getHeader().getCall().setFaultTo(faultTo);
        }
       
        final ContextInstance contextInstance = executionContext.getContextInstance() ;
       
        if (isReplyToOrFaultToSet(contextInstance))
        {
            setRelatesToMessageId(contextInstance, message);
        }
       
        //Sending the message on its way
        if (logger.isDebugEnabled()) logger.debug("Created ESB message=" + message);
       
        if (replyToOriginator != null) {
            final EPR epr ;
            final Object replyToEPR = contextInstance.getVariable(Constants.REPLY_TO);
            final Object faultToEPR = contextInstance.getVariable(Constants.FAULT_TO);

            if (Constants.EPR_FAULT.equals(replyToOriginator) && (faultToEPR != null)) {
                epr = EPRHelper.fromXMLString(faultToEPR.toString()) ;
            } else if (replyToEPR != null) {
                epr = EPRHelper.fromXMLString(replyToEPR.toString()) ;
            } else {
                throw new ConfigurationException("No EPR present in process instance") ;
            }
           
           
            if(epr instanceof LogicalEPR) {
                final ServiceInvoker invoker = ((LogicalEPR)epr).getServiceInvoker();
                invoker.deliverAsync(message);
            } else {
                final Courier courier = CourierFactory.getCourier(epr);
                try {
                    courier.deliver(message);
                } finally {
                    CourierUtil.cleanCourier(courier);
                }
            }
        } else {
            getServiceInvoker().deliverAsync(message);
        }
        logger.debug("Message send successfully");
    }
   
    /**
     * Caches the most recently used ServiceInvokers.
     *
     * @return a ServiceInvoker for the current esbService and esbCategoryName.
     * @throws MessageDeliverException
     */
    private ServiceInvoker getServiceInvoker() throws MessageDeliverException
    {
        String key = esbCategoryName + esbServiceName;
        final ServiceInvoker origInvoker = siCache.get(key) ;
        if (origInvoker != null) {
            return origInvoker;
        } else {
            ServiceInvoker invoker = new ServiceInvoker(esbCategoryName,  esbServiceName);
            siCache.put(key, invoker);
            return invoker;
        }
    }
   
    /**
     * Setup the replyTo for the CallBack Service.
     *
     * Creates or increments a process-node-version-counter whose name is related to
     * the current node ID. The name of the counter is jbpmProcessNodeVersionCounter<NodeId>.
     * The counter is added to the ProcessVariable Map (global to the ProcessInstance)
     * on the jBPM side The same variable should be added to the
     * EsbMessage before it is passed onto the ESB. Other parameters added
     * are the returnVariable mapping, the nodeId and the tokenId.
     *
     * @param returnVars - XML fragment from the processdefinition.xml describing
     * the mapping of ESB Message objects to the jBPM variableMap.
     * @param executionContext of the currently invoked EsbActionHandler.
     * @return the replyTo EPR of the JBpmCallbackService.
     */
    protected EPR createReplyTo(String esbToJBpmXml, Boolean globalProcessScope, ExecutionContext executionContext)
    {
        EPR replyTo = new LogicalEPR(ServiceInvoker.INTERNAL_SERVICE_CATEGORY, JBpmCallback.JBPM_CALL_BACK_SERVICE_NAME);
        PortReference portReference = replyTo.getAddr();
        if (globalProcessScope!=null) {
            portReference.addExtension(Constants.PROCESS_SCOPE_ATTR, globalProcessScope.toString());
        }
        final Token token = executionContext.getToken() ;
        final long tokenId = token.getId();
        portReference.addExtension(Constants.TOKEN_ID, String.valueOf(tokenId));
        String nodeId = "";
        if (executionContext.getNode()!=null) {
            nodeId = String.valueOf(executionContext.getNode().getId());
            portReference.addExtension(Constants.NODE_ID, nodeId);
           
        }
        portReference.addExtension(Constants.PROCESS_INSTANCE_ID, String.valueOf(executionContext.getProcessInstance().getId()));
       
        String counterName = Constants.PROCESS_NODE_VERSION_COUNTER  + nodeId + '_' + tokenId;
        Long counter = Long.getLong(String.valueOf(executionContext.getVariable(counterName)));
        if (counter!=null) {
            counter = counter + 1;
        } else {
            counter = 0l;
        }
        //Adding to the jBPM variableMap
        executionContext.getContextInstance().setVariableLocally(counterName, counter.toString(), token);
        //Adding same value to the message
        portReference.addExtension(counterName, counter.toString());
        return replyTo;
    }
    /**
     * Sets the faultTo EPR. This way jBPM can handle a failure in the ESB service by taking a
     * exception (faultTo) transition.
     * @param returnVars - XML fragment from the processdefinition.xml describing
     * the mapping of ESB Message objects to the jBPM variableMap.
     * @param executionContext of the currently invoked EsbActionHandler.
     * @return the faultTo EPR of the JBpmCallbackService.
     */
    protected EPR createFaultTo(String esbToJBpmXml, Boolean globalProcessScope, ExecutionContext executionContext)
    {
        EPR faultTo = createReplyTo(esbToJBpmXml, globalProcessScope, executionContext);
        if (!exceptionTransition.equals("condition")) {
            PortReference portReference = faultTo.getAddr();
            portReference.addExtension(Constants.TRANSITION_NAME, exceptionTransition);
        }
        return faultTo;
    }

   
}
TOP

Related Classes of org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler

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.