📄 soaphandler.java
字号:
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as
* published by JBoss Inc.; either version 1.0 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.
*/
package org.jbpm.bpel.integration.server;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.wsdl.Operation;
import javax.wsdl.OperationType;
import javax.wsdl.Part;
import javax.xml.namespace.QName;
import javax.xml.rpc.JAXRPCException;
import javax.xml.rpc.handler.Handler;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.rpc.server.ServletEndpointContext;
import javax.xml.rpc.soap.SOAPFaultException;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.bpel.BpelException;
import org.jbpm.bpel.db.IntegrationSession;
import org.jbpm.bpel.graph.def.BpelDefinition;
import org.jbpm.bpel.graph.exe.BpelFaultException;
import org.jbpm.bpel.integration.def.PartnerLinkDefinition;
import org.jbpm.bpel.integration.jms.IntegrationConstants;
import org.jbpm.bpel.integration.jms.IntegrationControl;
import org.jbpm.bpel.integration.jms.PartnerLinkEntry;
import org.jbpm.bpel.integration.jms.RequestListener;
import org.jbpm.bpel.sublang.def.Query;
import org.jbpm.bpel.variable.def.MessageType;
import org.jbpm.bpel.wsdl.PropertyAlias;
import org.jbpm.bpel.xml.BpelConstants;
import org.jbpm.bpel.xml.util.DatatypeUtil;
import org.jbpm.bpel.xml.util.XmlUtil;
/**
* @author Alejandro Gu韟ar
* @version $Revision: 1.8 $ $Date: 2007/01/18 12:58:28 $
*/
public class SoapHandler implements Handler {
private QName[] headers;
private String partnerLinkHandle;
private long responseTimeout;
private long oneWayTimeout;
private static final Log log = LogFactory.getLog(SoapHandler.class);
private static final SoapFaultWriter faultWriter = createSoapFaultWriter();
/** Name of the partner link. */
public static final String PARTNER_LINK_HANDLE_PARAM = "partnerLinkHandle";
/** Time to wait for response messages, in milliseconds. */
public static final String RESPONSE_TIMEOUT_PARAM = "responseTimeout";
/** Time to expire one-way messages, in milliseconds. */
public static final String ONE_WAY_TIMEOUT_PARAM = "oneWayTimeout";
/** The fault code for client-side faults */
public static final QName CLIENT_FAULTCODE = new QName(
SOAPConstants.URI_NS_SOAP_ENVELOPE, "Client");
/** The fault code for server-side faults */
public static final QName SERVER_FAULTCODE = new QName(
SOAPConstants.URI_NS_SOAP_ENVELOPE, "Server");
/** The fault string for response timeouts. */
public static final String TIMEOUT_FAULTSTRING = "The service is not in "
+ "an appropiate state for the requested operation";
/** The fault string for faults returned from the business process. */
public static final String BUSINESS_FAULTSTRING = "Business logic fault";
/** Message context property for the message parts */
static final String MESSAGE_PROP = "jbpm.bpel.message";
/** Message context property for the SOAP fault exception */
static final String FAULT_PROP = "jbpm.bpel.fault";
/** Servlet context attribute for the integration control instance */
static final String INTEGRATION_CONTROL_ATTR = "jbpm.bpel.integrationControl";
/**
* Allocates a new handler for JAX-RPC use.
*/
public SoapHandler() {
}
/**
* Allocates a new handler for test purposes.
*/
SoapHandler(String partnerLinkHandle) {
this.partnerLinkHandle = partnerLinkHandle;
}
public void init(HandlerInfo handlerInfo) throws JAXRPCException {
// save headers
headers = handlerInfo.getHeaders();
// get the configuration
Map handlerConfig = handlerInfo.getHandlerConfig();
// partner link handle parameter
partnerLinkHandle = (String) handlerConfig.get(PARTNER_LINK_HANDLE_PARAM);
if (partnerLinkHandle == null) {
throw new JAXRPCException("Parameter '"
+ PARTNER_LINK_HANDLE_PARAM
+ "' is mandatory in the handler configuration");
}
// response timeout parameter
String receiveTimeoutText = (String) handlerConfig.get(RESPONSE_TIMEOUT_PARAM);
if (receiveTimeoutText != null) {
try {
responseTimeout = Long.parseLong(receiveTimeoutText);
}
catch (NumberFormatException e) {
throw new JAXRPCException("Parameter '"
+ RESPONSE_TIMEOUT_PARAM
+ "' does not contain a parsable long", e);
}
}
// one-way timeout parameter
String oneWayTimeoutText = (String) handlerConfig.get(ONE_WAY_TIMEOUT_PARAM);
if (oneWayTimeoutText != null) {
try {
oneWayTimeout = Long.parseLong(oneWayTimeoutText);
}
catch (NumberFormatException e) {
throw new JAXRPCException("Parameter '"
+ ONE_WAY_TIMEOUT_PARAM
+ "' does not contain a parsable long", e);
}
}
}
public void destroy() {
}
public QName[] getHeaders() {
return headers;
}
public boolean handleRequest(MessageContext messageContext)
throws JAXRPCException, SOAPFaultException {
JbpmContext jbpmContext = JbpmConfiguration.getInstance()
.createJbpmContext();
try {
IntegrationControl integrationControl = findIntegrationControl(messageContext);
Session jmsSession = integrationControl.getJmsConnection().createSession(
false, Session.CLIENT_ACKNOWLEDGE);
try {
SOAPMessage soapMessage = ((SOAPMessageContext) messageContext).getMessage();
ObjectMessage jmsRequest = sendRequest(soapMessage, jmsSession,
jbpmContext, integrationControl);
TemporaryQueue replyTo = (TemporaryQueue) jmsRequest.getJMSReplyTo();
if (replyTo != null) {
try {
ObjectMessage jmsResponse = receiveResponse(jmsSession, replyTo);
// store the output parts for handling response
Map outputParts = (Map) jmsResponse.getObject();
messageContext.setProperty(MESSAGE_PROP, outputParts);
String faultName = jmsResponse.getStringProperty(IntegrationConstants.FAULT_NAME_PROP);
// is the outcome a fault?
if (faultName != null) {
throw new SOAPFaultException(CLIENT_FAULTCODE,
BUSINESS_FAULTSTRING, null, null);
}
}
finally {
replyTo.delete();
}
}
}
finally {
jmsSession.close();
}
}
/*
* NO need to set jbpm context as rollback only for any exception, since
* operations in try-block only read definitions from database
*/
catch (SOAPFaultException e) {
log.debug("request caused a fault", e);
messageContext.setProperty(FAULT_PROP, e);
}
catch (SOAPException e) {
log.debug("incoming soap message carries invalid content", e);
messageContext.setProperty(FAULT_PROP, new SOAPFaultException(
CLIENT_FAULTCODE, e.getMessage(), null, null));
}
catch (JMSException e) {
throw new JAXRPCException("message delivery failed", e);
}
finally {
jbpmContext.close();
}
return true;
}
public boolean handleResponse(MessageContext messageContext)
throws JAXRPCException {
Map messageParts = (Map) messageContext.getProperty(MESSAGE_PROP);
SOAPFaultException faultException = (SOAPFaultException) messageContext.getProperty(FAULT_PROP);
// absence of both parts and exception means no response to handle
if (messageParts == null && faultException == null)
return true;
SOAPMessage soapMessage = ((SOAPMessageContext) messageContext).getMessage();
JbpmContext jbpmContext = JbpmConfiguration.getInstance()
.createJbpmContext();
try {
if (faultException != null) {
writeFault(soapMessage, messageParts, faultException);
}
else {
writeResponse(soapMessage, messageParts, jbpmContext,
findIntegrationControl(messageContext));
}
}
/*
* NO need to set jbpm context as rollback only for any exception, since
* operations in try-block only read definitions from database
*/
catch (SOAPException e) {
throw new JAXRPCException("could not compose outbound soap message", e);
}
finally {
jbpmContext.close();
}
return true;
}
public boolean handleFault(MessageContext messageContext)
throws JAXRPCException {
return true;
}
public long getResponseTimeout() {
return responseTimeout;
}
public long getOneWayTimeout() {
return oneWayTimeout;
}
private static IntegrationControl findIntegrationControl(
MessageContext messageContext) {
return (IntegrationControl) findServletContext(messageContext).getAttribute(
INTEGRATION_CONTROL_ATTR);
}
private static ServletContext findServletContext(MessageContext messageContext) {
Iterator propertyNameIt = messageContext.getPropertyNames();
while (propertyNameIt.hasNext()) {
String propertyName = (String) propertyNameIt.next();
Object property = messageContext.getProperty(propertyName);
if (property instanceof ServletContext) {
log.debug("found servlet context property: " + propertyName);
return (ServletContext) property;
}
else if (property instanceof HttpSession) {
log.debug("found http session property: " + propertyName);
return ((HttpSession) property).getServletContext();
}
else if (property instanceof ServletEndpointContext) {
log.debug("found servlet endpoint context property: " + propertyName);
return ((ServletEndpointContext) property).getServletContext();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -