openesb-components/ojc-core/httpsoapbc/httpsoapbcimpl/src/main/java/com/sun/jbi/httpsoapbc/OutboundMessageProcessor.java

2144 lines
103 KiB
Java
Executable File

/*
* BEGIN_HEADER - DO NOT EDIT
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* https://open-jbi-components.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* https://open-jbi-components.dev.java.net/public/CDDLv1.0.html.
* If applicable add the following below this CDDL HEADER,
* with the fields enclosed by brackets "[]" replaced with
* your own identifying information: Portions Copyright
* [year] [name of copyright owner]
*/
/*
* @(#)OutboundMessageProcessor.java
*
* Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
*
* END_HEADER - DO NOT EDIT
*/
package com.sun.jbi.httpsoapbc;
import com.sun.jbi.common.descriptor.EndpointInfo;
import com.sun.jbi.common.qos.messaging.MessagingChannel;
import com.sun.jbi.common.qos.redelivery.Redelivery;
import com.sun.jbi.common.qos.redelivery.RedeliveryConfig;
import com.sun.jbi.common.qos.redelivery.RedeliveryConfig.Failure;
import com.sun.jbi.common.qos.redelivery.RedeliveryStatus;
import com.sun.jbi.eManager.provider.EndpointStatus;
import com.sun.jbi.alerter.NotificationEvent;
import com.sun.jbi.httpsoapbc.async.AsyncRequestContext;
import com.sun.jbi.httpsoapbc.async.AsyncResponseDispatcher;
import com.sun.jbi.httpsoapbc.async.AsyncResponseHandler;
import com.sun.jbi.httpsoapbc.descriptors.HttpSoapHandler;
import com.sun.jbi.httpsoapbc.management.HTTPManagementMBean;
import com.sun.jbi.httpsoapbc.util.AlertsUtil;
import com.sun.jbi.httpsoapbc.util.DebugLog;
import com.sun.jbi.httpsoapbc.util.StringUtil;
import com.sun.jbi.httpsoapbc.util.TransactionsUtil;
import com.sun.jbi.httpsoapbc.util.TransformerPool;
import com.sun.jbi.httpsoapbc.util.LoggingMonitoringUtil;
import com.sun.jbi.httpsoapbc.util.Util;
import com.sun.jbi.httpsoapbc.util.WSDLUtilities;
import com.sun.jbi.internationalization.Messages;
import com.sun.jbi.nms.exchange.ExchangePattern;
import com.sun.jbi.nms.wsdl11wrapper.HelperFactory;
import com.sun.jbi.nms.wsdl11wrapper.WrapperParser;
import com.sun.jbi.nms.wsdl11wrapper.WrapperProcessingException;
import com.sun.xml.ws.developer.JAXWSProperties;
import java.io.File;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Map;
import javax.activation.DataSource;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.Fault;
import javax.jbi.messaging.InOnly;
import javax.jbi.messaging.InOut;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
import javax.jbi.servicedesc.ServiceEndpoint;
import javax.management.MBeanException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.transaction.Transaction;
import javax.transaction.SystemException;
import javax.xml.namespace.QName;
import javax.xml.soap.DetailEntry;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.ws.Dispatch;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.Service;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.SOAPFaultException;
import javax.wsdl.Message;
import javax.wsdl.Part;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import net.java.hulp.measure.Probe;
/**
* Process replies/requests received from the SE.
*/
public class OutboundMessageProcessor {
private static final Messages mMessages =
Messages.getMessages(OutboundMessageProcessor.class);
private static final Logger mLog =
Messages.getLogger(OutboundMessageProcessor.class);
private static final TransformerPool cTransformerPool =
new TransformerPool();
// The World Wide Web Consortium Recommendation states that UTF-8 should be used.
// Not doing so may introduce incompatibilities
// See http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLDecoder.html#decode(java.lang.String,%20java.lang.String)
private static final String URL_DECODE_ENCODING = "UTF-8";
private static final String COMPONENT_NAME = "sun-http-binding";
private Map mEndpoints;
private MessagingChannel mChannel;
private MessageFactory mSoapMessageFactory;
private SOAPConnectionFactory mConnFact;
private SOAPConnection mConn;
private SoapNormalizer mNormalizer;
private SoapDenormalizer mDenormalizer;
private Map mInboundExchanges;
private HTTPManagementMBean mManagementMBean;
private HttpNormalizer mHttpNormalizer;
private DocumentBuilderFactory mBuilderFactory;
private DocumentBuilder mBuilder;
// Disable HTTP/SOAP header propagation because of the lack of SE support at the moment, and the performance overhead.
private boolean mIsHeaderCopyEnabled = true; // TODO: may want to have a user configuration to enable/disable the copy
// measurements
private Probe mDCReceiveToSoapCallMeasurement = null;
// Message tracking
private boolean mMonitorEnabled = false;
private String mMode = LoggingMonitoringUtil.getMessageTrackingIDModeInbound();
public OutboundMessageProcessor(MessagingChannel chnl, Map endpoints, Map inboundExchanges, HTTPManagementMBean managementMBean) {
mChannel = chnl;
mEndpoints = endpoints;
mManagementMBean = managementMBean;
try {
mNormalizer = new SoapNormalizerImpl();
mDenormalizer = new SoapDenormalizerImpl();
} catch (Exception e) {
String text = mMessages.getString("HTTPBC-E00776.Failed_create_soap_normalizer");
AlertsUtil.getAlerter().critical(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
null,
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00776");
throw new IllegalStateException(text, e);
}
try {
mHttpNormalizer = new HttpNormalizer();
} catch (Exception e) {
String text = mMessages.getString("HTTPBC-E00777.Failed_create_http_normalizer");
AlertsUtil.getAlerter().critical(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
null,
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00777");
throw new IllegalStateException(text, e);
}
mInboundExchanges = inboundExchanges;
try {
mConnFact = SOAPConnectionFactory.newInstance();
mConn = mConnFact.createConnection();
mSoapMessageFactory = MessageFactory.newInstance();
mBuilderFactory = DocumentBuilderFactory.newInstance();
mBuilder = mBuilderFactory.newDocumentBuilder();
} catch (Exception e) {
String text = mMessages.getString("HTTPBC-E00778.Failed_create_outbound_processor");
AlertsUtil.getAlerter().critical(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
null,
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00778");
throw new IllegalStateException(text, e);
}
}
/**
* Process the message exchange
*/
public void processMessage(MessageExchange exchange) {
mDCReceiveToSoapCallMeasurement = Probe.fine(getClass(), "processMessageExchange");
String exchangeId = exchange.getExchangeId();
boolean inbound = exchange.getRole().equals(MessageExchange.Role.CONSUMER);
if (inbound) {
Long invocationTime = (Long) mInboundExchanges.remove(exchangeId);
if (mLog.isLoggable(Level.FINE) && invocationTime != null) {
long difference = System.currentTimeMillis() - invocationTime.longValue();
mLog.log(Level.FINE, "Response for exchange " + exchangeId + " received (" + Long.valueOf(difference) + " ms}");
}
}
URI pattern = exchange.getPattern();
if (mLog.isLoggable(Level.FINE)) {
if (inbound) {
mLog.log(Level.FINE, "Processing message exchange " + exchange.getExchangeId() + " as inbound; pattern is " + pattern.toString());
} else {
mLog.log(Level.FINE, "Processing message exchange " + exchange.getExchangeId() + " as outbound; pattern is " + pattern.toString());
}
}
switch (ExchangePattern.valueOf(exchange)) {
case IN_OUT:
if (inbound) {
processRequestReplyInbound((InOut) exchange);
} else {
processRequestReplyOutbound((InOut) exchange);
}
break;
case IN_ONLY:
if (inbound) {
processOneWayInbound((InOnly) exchange);
} else {
processOneWayOutbound((InOnly) exchange);
}
break;
case ROBUST_IN_ONLY: {
String msg = mMessages.getString("HTTPBC-E00751.MEP_robust_inonly_not_supported", exchange.getExchangeId());
mLog.log(Level.SEVERE, msg);
try {
setErrorUnsupportedExchangePattern(exchange, msg, null);
Endpoint epb = getInboundEndpoint(exchange);
mChannel.send(exchange);
if (epb != null) {
updateTallySends(epb, false);
}
} catch (MessagingException ex) {
String text = mMessages.getString("HTTPBC-E00775.Exception_during_exchange_processing", exchange.getExchangeId());
mLog.log(Level.SEVERE, text, ex);
Endpoint epb = getInboundEndpoint(exchange);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00775");
}
break;
}
default:
String msg = mMessages.getString("HTTPBC-E00752.Invalid_MEP", new Object[]{exchange.getExchangeId(), pattern.toString()});
mLog.log(Level.SEVERE, msg);
try {
setErrorUnsupportedExchangePattern(exchange, msg, null);
Endpoint epb = getInboundEndpoint(exchange);
mChannel.send(exchange);
if (epb != null) {
updateTallySends(epb, false);
}
} catch (MessagingException ex) {
String text = mMessages.getString("HTTPBC-E00775.Exception_during_exchange_processing", exchange.getExchangeId());
mLog.log(Level.SEVERE, text, ex);
Endpoint epb = getInboundEndpoint(exchange);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00775");
}
return;
}
}
/**
* Process the reply for a request/reply request originating from this BC.
*/
public void processRequestReplyInbound(InOut inout) {
boolean success = true;
//boolean isRetry = isRedeliveryConfigured(inout); // for some reason, QoS no longer returns Redelivery Status when retries are maxed out
boolean isRetry = isRedeliveryEnabled(inout);
Endpoint epb = getInboundEndpoint(inout);
NormalizedMessage inMsg = inout.getInMessage();
// message tracking
String trackingId = ((inMsg.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) != null) ? (String) inMsg.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) : "") +
((inMsg.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) != null) ? (String) inMsg.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) : "");
// If redelivery is configured and when a message exchange exhausts its redelivery attempts,
// redelivery library may re-route the exchange to a different endpoint.
// That means the endpoint associated with the exchange could be changed.
// We need to call Redelivery.getEndpoint(exchange) to get the original endpoint back.
// The following if block tries to locate the inbound endpoint using the above redelivery utility
// when the first attempt to get it based on the endpoint associated with the exchange fails.
if (isRetry && epb == null) {
epb = getInboundEndpoint(inout, true);
}
boolean ndcEnabled = LoggingMonitoringUtil.isNdcEnabled(epb);
if (ndcEnabled) {
// "Push" the NDC context based on the setting in the NDC properties file
Logger.getLogger("com.sun.EnterContext").log(Level.FINE, "{0}={1}", new Object[]{LoggingMonitoringUtil.SOLUTION_GROUP,
LoggingMonitoringUtil.getSolutionGroup(epb)});
}
if (inout.getOutMessage() != null) {
updateTallyReceivedReplies(epb);
// remove the redelivery listener handler - no retry needed.
if (isRetry) {
MessageExchangeSupport.removeRedeliveryListener(inout.getExchangeId());
}
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Processing-response-message", epb);
}
} else if (ExchangeStatus.ERROR.equals(inout.getStatus())) {
updateTallyReceives(epb, false);
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Handling-error-status", epb);
}
// send alerts
String errorMsg = (inout.getError() != null) ? inout.getError().getMessage() : null;
if (errorMsg != null) {
String msg = mMessages.getString("HTTPBC-E00720.Message_exchange_error",
new Object[]{
String.valueOf(epb.getServiceName()),
epb.getEndpointName(),
errorMsg
});
mLog.log(Level.SEVERE, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00720");
} else {
String msg = mMessages.getString("HTTPBC-E00721.Message_exchange_error_no_detail",
new Object[]{
String.valueOf(epb.getServiceName()),
epb.getEndpointName()
});
mLog.log(Level.SEVERE, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00721");
}
// let's redeliver if it is configured and max attempt count has not been exhausted
RedeliveryStatus retryStatus = Redelivery.getRedeliveryStatus(inout);
RedeliveryConfig retryConfig = epb.getRedeliveryConfiguration();
if (retryStatus != null && retryConfig != null) {
Failure onFailureOption = retryConfig.getFailure();
if (!retryStatus.hasFailed() && (onFailureOption == Failure.suspend || onFailureOption == Failure.error)) {
//handle redelivery
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Handling-redelivery", epb);
}
handleRedelivery(inout, epb);
return;
} else {
if (onFailureOption == Failure.suspend) {
// suspend the inbound endpoint
try {
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Suspending-endpoint", epb);
}
mManagementMBean.suspend(epb.getUniqueName());
// emit warning logs and send alerts
String msg = mMessages.getString("HTTPBC-E00806.About_to_suspend_endpoint",
new Object[]{
String.valueOf(epb.getServiceName()),
epb.getEndpointName()
});
mLog.log(Level.WARNING, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00806");
} catch (MBeanException e) {
errorMsg = e.getTargetException().getMessage();
if (errorMsg != null) {
String msg = mMessages.getString("HTTPBC-E00805.Failed_to_suspend_endpoint",
new Object[]{
String.valueOf(epb.getServiceName()),
epb.getEndpointName(),
errorMsg
});
mLog.log(Level.SEVERE, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00805");
}
}
}
}
}
}
try {
MessageExchangeSupport.notifyOfReply(inout);
} catch (Exception ex) {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E00759.Exception_during_reply_processing", ex.getLocalizedMessage());
mLog.log(Level.WARNING, text, ex);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00759");
}
success = false;
}
try {
if (inout.getStatus() == ExchangeStatus.ACTIVE) {
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Updating-exchange-reply-status", epb);
}
if (success) {
inout.setStatus(ExchangeStatus.DONE);
} else {
inout.setStatus(ExchangeStatus.ERROR);
}
mChannel.send(inout);
updateTallySends(epb, success);
}
} catch (MessagingException ex) {
String text = mMessages.getString("HTTPBC-E00759.Exception_during_reply_processing", ex.getLocalizedMessage());
mLog.log(Level.SEVERE, text, ex);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00759");
}
if (ndcEnabled) {
// "Pop" NDC context
Logger.getLogger("com.sun.ExitContext").log(Level.FINE, "{0}={1}", new Object[]{LoggingMonitoringUtil.SOLUTION_GROUP,
LoggingMonitoringUtil.getSolutionGroup(epb)});
}
}
/**
* Process the status reponse for a one-way request originating from this BC.
*/
public void processOneWayInbound(InOnly inonly) {
boolean replyAfterProcessing = true;
//boolean isRetry = isRedeliveryConfigured(inonly); // for some reason, QoS no longer returns Redelivery Status when retries are maxed out
boolean isRetry = isRedeliveryEnabled(inonly);
Endpoint epb = getInboundEndpoint(inonly);
NormalizedMessage inMsg = inonly.getInMessage();
String trackingId = ((inMsg.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) != null) ? (String) inMsg.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) : "") +
((inMsg.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) != null) ? (String) inMsg.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) : "");
// If redelivery is configured and when a message exchange exhausts its redelivery attempts,
// redelivery library may re-route the exchange to a different endpoint.
// That means the endpoint associated with the exchange could be changed.
// We need to call Redelivery.getEndpoint(exchange) to get the original endpoint back.
// The following if block tries to locate the inbound endpoint using the above redelivery utility
// when the first attempt to get it based on the endpoint associated with the exchange fails.
if (isRetry && epb == null) {
epb = getInboundEndpoint(inonly, true);
}
boolean ndcEnabled = LoggingMonitoringUtil.isNdcEnabled(epb);
if (ndcEnabled) {
// "Push" the NDC context based on the setting in the NDC properties file
Logger.getLogger("com.sun.EnterContext").log(Level.FINE, "{0}={1}", new Object[]{LoggingMonitoringUtil.SOLUTION_GROUP,
LoggingMonitoringUtil.getSolutionGroup(epb)});
}
if (ExchangeStatus.DONE.equals(inonly.getStatus())) {
updateTallyReceives(epb, true);
// remove the redelivery listener handler - no retry needed.
if (isRetry) {
MessageExchangeSupport.removeRedeliveryListener(inonly.getExchangeId());
}
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Processing-response-message", epb);
}
} else if (ExchangeStatus.ERROR.equals(inonly.getStatus())) {
updateTallyReceives(epb, false);
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Handling-error-status", epb);
}
// send alerts
String errorMsg = (inonly.getError() != null) ? inonly.getError().getMessage() : null;
if (errorMsg != null) {
String msg = mMessages.getString("HTTPBC-E00720.Message_exchange_error",
new Object[]{
String.valueOf(epb.getServiceName()),
epb.getEndpointName(),
errorMsg
});
mLog.log(Level.SEVERE, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00759");
} else {
String msg = mMessages.getString("HTTPBC-E00721.Message_exchange_error_no_detail",
new Object[]{
String.valueOf(epb.getServiceName()),
epb.getEndpointName()
});
mLog.log(Level.SEVERE, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00721");
}
// let's redeliver if it is configured and max attempt count has not been exhausted
RedeliveryStatus retryStatus = Redelivery.getRedeliveryStatus(inonly);
RedeliveryConfig retryConfig = epb.getRedeliveryConfiguration();
if (retryStatus != null && retryConfig != null) { // indicator that redelivery is configured
if (!retryStatus.hasFailed()) {
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Handling-redelivery", epb);
}
handleRedelivery(inonly, epb);
return;
} else {
Failure onFailureOption = retryConfig.getFailure(); // we know retryConfig cannot be null if we get this far
if (onFailureOption == Failure.suspend) {
// suspend the inbound endpoint
try {
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Suspending-endpoint", epb);
}
mManagementMBean.suspend(epb.getUniqueName());
// emit warning logs and send alerts
String msg = mMessages.getString("HTTPBC-E00806.About_to_suspend_endpoint",
new Object[]{
String.valueOf(epb.getServiceName()),
epb.getEndpointName()
});
mLog.log(Level.WARNING, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00806");
} catch (MBeanException e) {
errorMsg = e.getTargetException().getMessage();
if (errorMsg != null) {
String msg = mMessages.getString("HTTPBC-E00805.Failed_to_suspend_endpoint",
new Object[]{
String.valueOf(epb.getServiceName()),
epb.getEndpointName(),
errorMsg
});
mLog.log(Level.SEVERE, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00805");
}
}
}
}
}
}
Map nameToMeta = epb.getOperationNameToMetaData();
OperationMetaData meta = (OperationMetaData) nameToMeta.get(inonly.getOperation());
if (meta == null) {
// try again with operation LocalPart
meta = (OperationMetaData) nameToMeta.get(inonly.getOperation().getLocalPart());
if (meta == null) {
if (mLog.isLoggable(Level.WARNING)) {
String msg = mMessages.getString("HTTPBC-W00751.Operation_lookup_failed", inonly.getOperation().toString());
mLog.log(Level.WARNING, msg);
AlertsUtil.getAlerter().warning(msg,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-W00751");
}
}
}
if (meta != null) {
replyAfterProcessing = meta.getOneWayReplyAfterProcessing();
}
// If configured to wait for completion of request processing, only reply once SE completed processing request
if (replyAfterProcessing) {
try {
MessageExchangeSupport.notifyOfReply(inonly);
} catch (Exception ex) {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E00759.Exception_during_reply_processing", ex.getLocalizedMessage());
mLog.log(Level.WARNING, text, ex);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00759");
}
}
}
if (ndcEnabled) {
// "Pop" NDC context
Logger.getLogger("com.sun.ExitContext").log(Level.FINE, "{0}={1}", new Object[]{LoggingMonitoringUtil.SOLUTION_GROUP,
LoggingMonitoringUtil.getSolutionGroup(epb)});
}
}
/**
* Process the request for a request/reply sent to this BC and send back a reply.
* Also handle the processing of the completion status response
*/
public void processRequestReplyOutbound(InOut inout) {
Endpoint epb = null;
epb = getOutboundEndpoint(inout);
boolean ndcEnabled = LoggingMonitoringUtil.isNdcEnabled(epb);
NormalizedMessage inMsg = inout.getInMessage();
String trackingId = ((inMsg.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) != null) ? (String) inMsg.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) : "") +
((inMsg.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) != null) ? (String) inMsg.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) : "");
if (ndcEnabled) {
// "Push" the NDC context based on the setting in the NDC properties file
Logger.getLogger("com.sun.EnterContext").log(Level.FINE, "{0}={1}", new Object[]{LoggingMonitoringUtil.SOLUTION_GROUP,
LoggingMonitoringUtil.getSolutionGroup(epb)});
}
Transaction transaction = (Transaction) inout.getProperty(
MessageExchange.JTA_TRANSACTION_PROPERTY_NAME);
if (inout.getStatus() == ExchangeStatus.DONE) {
updateTallyReceives(epb, true);
} else if (inout.getStatus() == ExchangeStatus.ERROR) {
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Handling-error-status-from-inout-exchange", epb);
}
if (transaction != null) {
setTransactionRollbackOnly(transaction);
}
updateTallyReceives(epb, false);
} else {
Probe soapToDCSendMeasurement = Probe.fine(getClass(),
epb.getUniqueName(),
"soapToDCSend");
try {
updateTallyReceivedRequests(epb);
Map nameToMeta = epb.getOperationNameToMetaData();
if (inout.getOperation() == null) {
throw new MessagingException(mMessages.getString("HTTPBC-E00808.No_operation_defined_in_ME", inout.getExchangeId()));
}
OperationMetaData meta = (OperationMetaData) nameToMeta.get(inout.getOperation().getLocalPart());
if (meta == null) {
throw new MessagingException(mMessages.getString("HTTPBC-E00700.Operation_not_defined",
new Object[]{inout.getOperation(), inout.getExchangeId(), inout.getPattern().toString()}));
}
// Push the context
Logger.getLogger("com.sun.EnterContext").fine(epb.getServiceUnitID() + "-" + inout.getOperation());
if (epb instanceof HttpSoapEndpoint) {
dispatch((HttpSoapEndpoint) epb, inout, meta);
}
if (epb instanceof HttpEndpoint) {
dispatch((HttpEndpoint) epb, inout, meta);
}
} catch (Exception ex) {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E00759.Exception_during_reply_processing", ex.getLocalizedMessage());
mLog.log(Level.WARNING, text, ex);
}
try {
setErrorServerException(inout, ex, (String) null);
} catch (MessagingException e) {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E00759.Exception_during_reply_processing", ex.getLocalizedMessage());
mLog.log(Level.WARNING, text, ex);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00759");
}
}
if (transaction != null) {
setTransactionRollbackOnly(transaction);
}
} finally {
// Pop the context
Logger.getLogger("com.sun.ExitContext").fine(epb.getServiceUnitID() + "-" + inout.getOperation());
//mChannel.send(inout);
if (soapToDCSendMeasurement != null) {
soapToDCSendMeasurement.end();
}
//updateTallySentReplies(epb);
}
}
if (ndcEnabled) {
// "Pop" NDC context
Logger.getLogger("com.sun.ExitContext").log(Level.FINE, "{0}={1}", new Object[]{LoggingMonitoringUtil.SOLUTION_GROUP,
LoggingMonitoringUtil.getSolutionGroup(epb)});
}
}
/**
* Process the request for a one-way request sent to this BC and send back a completion status.
*/
public void processOneWayOutbound(InOnly inonly) {
Endpoint epb = null;
Transaction transaction = (Transaction) inonly.getProperty(
MessageExchange.JTA_TRANSACTION_PROPERTY_NAME);
epb = getOutboundEndpoint(inonly);
boolean ndcEnabled = LoggingMonitoringUtil.isNdcEnabled(epb);
NormalizedMessage inMsg = inonly.getInMessage();
String trackingId = ((inMsg.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) != null) ? (String) inMsg.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) : "") +
((inMsg.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) != null) ? (String) inMsg.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) : "");
try {
if (ndcEnabled) {
// "Push" the NDC context based on the setting in the NDC properties file
Logger.getLogger("com.sun.EnterContext").log(Level.FINE, "{0}={1}", new Object[]{LoggingMonitoringUtil.SOLUTION_GROUP,
LoggingMonitoringUtil.getSolutionGroup(epb)});
}
updateTallyReceivedRequests(epb);
if (epb instanceof HttpSoapEndpoint) {
if (inonly.getOperation() == null) {
throw new MessagingException(mMessages.getString("HTTPBC-E00808.No_operation_defined_in_ME", inonly.getExchangeId()));
}
Map nameToMeta = epb.getOperationNameToMetaData();
OperationMetaData meta = (OperationMetaData) nameToMeta.get(inonly.getOperation());
if (meta == null) {
// try again with operation LocalPart
meta = (OperationMetaData) nameToMeta.get(inonly.getOperation().getLocalPart());
if (meta == null) {
throw new MessagingException(mMessages.getString("HTTPBC-E00700.Operation_not_defined",
new Object[]{inonly.getOperation(), inonly.getExchangeId(), inonly.getPattern().toString()}));
}
}
if (mMonitorEnabled) {
LoggingMonitoringUtil.setCheckpoint(trackingId, "Processing-outbound-request", epb);
}
outboundCall(inonly.getInMessage(), meta, (HttpSoapEndpoint) epb, inonly);
}
} catch (MessagingException e) {
// Caused by parsing error (WrapperProcessingException, TransformerException, etc.)
// during denormalization
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-W00758.Exception_during_request_processing", e.getLocalizedMessage());
mLog.log(Level.WARNING, text, e);
}
try {
setErrorClientException(inonly, e, null);
} catch (MessagingException ex) {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-W00758.Exception_during_request_processing", ex.getLocalizedMessage());
mLog.log(Level.WARNING, text, ex);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00758");
}
}
if (transaction != null) {
setTransactionRollbackOnly(transaction);
}
} catch (SOAPException e) {
// Caused if SOAPMessage changes failed to save
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-W00758.Exception_during_request_processing", e.getLocalizedMessage());
mLog.log(Level.WARNING, text, e);
}
try {
setErrorClientException(inonly, e, null);
} catch (MessagingException ex) {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-W00758.Exception_during_request_processing", ex.getLocalizedMessage());
mLog.log(Level.WARNING, text, ex);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00758");
}
}
if (transaction != null) {
setTransactionRollbackOnly(transaction);
}
} catch (Exception e) {
// Fallback catch for all other exceptions (like runtime exceptions)
// Parser initialization exceptions caught here too.
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-W00758.Exception_during_request_processing", e.getLocalizedMessage());
mLog.log(Level.WARNING, text, e);
}
try {
setErrorServerException(inonly, e, (String) null);
} catch (MessagingException ex) {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-W00758.Exception_during_request_processing", e.getLocalizedMessage());
mLog.log(Level.WARNING, text, e);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00758");
}
}
if (transaction != null) {
setTransactionRollbackOnly(transaction);
}
} finally {
try {
if (inonly.getStatus() != ExchangeStatus.ERROR) {
inonly.setStatus(ExchangeStatus.DONE);
}
mChannel.send(inonly);
updateTallySends(epb, (inonly.getStatus() == ExchangeStatus.DONE));
} catch (MessagingException ex) {
String text = mMessages.getString("HTTPBC-E00780.Exception_set_status");
mLog.log(Level.SEVERE, text, ex);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E00780");
}
if (ndcEnabled) {
// "Pop" NDC context
Logger.getLogger("com.sun.ExitContext").log(Level.FINE, "{0}={1}", new Object[]{LoggingMonitoringUtil.SOLUTION_GROUP,
LoggingMonitoringUtil.getSolutionGroup(epb)});
}
}
}
/**
* Get the endpoint bean for the outbound service
* @param outboundExchange the message exchange to get the info for
* @return the endpoint bean corresponding to the outbound service for this
* message exchange
*/
Endpoint getOutboundEndpoint(MessageExchange outboundExchange) {
Endpoint epb = null;
ServiceEndpoint sep = outboundExchange.getEndpoint();
// check to see if we have here a dynamic endpoint first
if (sep instanceof HttpSoapDynamicEndpoint) {
// grab the Endpoint metadata from the dynamic SE implementation
epb = ((HttpSoapDynamicEndpoint) sep).getEndpointInfo();
} else {
String serviceName = outboundExchange.getEndpoint().getServiceName().toString();
String endpointName = outboundExchange.getEndpoint().getEndpointName();
if (mLog.isLoggable(Level.FINER)) {
mLog.log(Level.FINER, "Trying to locate the endpoint metadata for " + serviceName + " " + endpointName);
}
epb = (Endpoint) mEndpoints.get(AbstractEndpoint.getUniqueName(outboundExchange.getEndpoint().getServiceName().getNamespaceURI(),
outboundExchange.getEndpoint().getServiceName().getLocalPart(),
endpointName,
false));
}
return epb;
}
/**
* Get the endpoint bean for the inbound service
* @param inboundExchange the message exchange to get the info for
* @return the endpoint bean corresponding to the inbound service for this
* message exchange
*/
Endpoint getInboundEndpoint(MessageExchange inboundExchange) {
String serviceName = inboundExchange.getEndpoint().getServiceName().toString();
String endpointName = inboundExchange.getEndpoint().getEndpointName();
if (mLog.isLoggable(Level.FINER)) {
mLog.log(Level.FINER, "Getting inbound info for " + serviceName + " " + endpointName);
}
Endpoint epb = (Endpoint) mEndpoints.get(HttpSoapEndpoint.getUniqueName(inboundExchange.getEndpoint().getServiceName().getNamespaceURI(),
inboundExchange.getEndpoint().getServiceName().getLocalPart(),
endpointName,
true));
return epb;
}
/**
* Get the endpoint bean for the inbound service
* @param inboundExchange the message exchange to get the info for
* @param isRetry indicates if redelivery QoS is configured for the endpoint
* @return the endpoint bean corresponding to the inbound service for this
* message exchange
*/
Endpoint getInboundEndpoint(MessageExchange inboundExchange, boolean isRetry) {
if (isRetry) {
ServiceEndpoint actualEndpoint = Redelivery.getEndpoint(inboundExchange);
QName serviceName = actualEndpoint.getServiceName();
String endpointName = actualEndpoint.getEndpointName();
if (mLog.isLoggable(Level.FINER)) {
mLog.log(Level.FINER, "Getting inbound info for " + serviceName + " " + endpointName);
}
Endpoint epb = (Endpoint) mEndpoints.get(HttpSoapEndpoint.getUniqueName(serviceName.getNamespaceURI(),
serviceName.getLocalPart(),
endpointName,
true));
return epb;
}
return null;
}
/**
* Handle an outbound message exchange to invoke a webservice over HTTP/SOAP
* @param outMessage the message to send, still in JBI normalized format
* @param destinationURL the url of the webservice to invoke
* @param metadata the descriptions of the webservice methods
* @param epb endpoint meta-data
* @param outboundExchange the JBI outbound message exchange
* @return the reply soap message
*/
void outboundCall(NormalizedMessage normalizedMessage, OperationMetaData meta, HttpSoapEndpoint endpointMeta, MessageExchange outboundExchange)
throws SOAPException, MessagingException, Exception {
// message tracking
String trackingId = ((normalizedMessage.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) != null) ? (String) normalizedMessage.getProperty(NormalizedMessageProperties.NM_GROUP_ID_PROPERTY) : "") +
((normalizedMessage.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) != null) ? (String) normalizedMessage.getProperty(NormalizedMessageProperties.NM_MSG_ID_PROPERTY) : "");
if (mLog.isLoggable(Level.FINE)) {
DebugLog.debugLog(mLog, Level.FINE, "Normalized message content", normalizedMessage.getContent());
}
Probe denormalizationMeasurement = Probe.info(getClass(),
endpointMeta.getUniqueName(),
HttpSoapBindingLifeCycle.PERF_CAT_DENORMALIZATION);
SOAPMessage soapMsg = null;
try {
soapMsg = mDenormalizer.denormalize(normalizedMessage, outboundExchange, meta, mSoapMessageFactory, true);
if (mMonitorEnabled) {
try {
LoggingMonitoringUtil.setCheckpoint(endpointMeta, trackingId, "Processing-outbound-request", soapMsg.getSOAPPart().getEnvelope());
} catch (Exception e) {
if (mLog.isLoggable(Level.WARNING)) {
mLog.log(Level.WARNING, mMessages.getString("HTTPBC-W01310.Failed_to_get_soap_payload_for_checkpointing"));
}
}
}
} catch (MessagingException t) {
throw t; // do nothing, need to end instrumentation
} finally {
if (denormalizationMeasurement != null) {
denormalizationMeasurement.end();
}
}
soapMsg.saveChanges();
// Dispatch to external; make the soap call
if (mLog.isLoggable(Level.FINE)) {
DebugLog.debugLog(mLog, Level.FINE, "Sending SOAP envelope", soapMsg.getSOAPPart().getEnvelope());
}
Probe createDispatchMeasurement = Probe.fine(getClass(),
endpointMeta.getUniqueName(),
"createDispatch");
Transaction transaction = (Transaction) outboundExchange.getProperty(
MessageExchange.JTA_TRANSACTION_PROPERTY_NAME);
boolean txResumed = false;
boolean shouldSuspendTx = false;
if (transaction != null) {
if (mLog.isLoggable(Level.FINE)) {
mLog.log(Level.FINE, "Got transaction context from message exchange " + outboundExchange.getExchangeId() + ". About to resume transaction before the Dispatch call...");
}
if (mMonitorEnabled) {
try {
LoggingMonitoringUtil.setCheckpoint(endpointMeta, trackingId, "Resuming-transaction", soapMsg.getSOAPPart().getEnvelope());
} catch (Exception e) {
if (mLog.isLoggable(Level.WARNING)) {
mLog.log(Level.WARNING, mMessages.getString("HTTPBC-W01310.Failed_to_get_soap_payload_for_checkpointing"));
}
}
}
txResumed = TransactionsUtil.resumeTransaction(transaction);
}
Dispatch<SOAPMessage> dispatch = null;
try {
boolean isSSL = false;
// let's see if the NM property is set to overwrite the address URL
// and to prevent any kind of ClassCastException (you know, user errors)
String addrUrl = null;
Object urlProperty = normalizedMessage.getProperty(NormalizedMessageProperties.OUTBOUND_ADDRESS_URL);
if (urlProperty != null) {
if (urlProperty instanceof String) {
addrUrl = (String) urlProperty;
} else {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E01052.Invalid_url_nmproperty_type");
mLog.log(Level.WARNING, text);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
endpointMeta.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E01052");
}
}
}
if (addrUrl != null) { // a dynamic URL set as a NM property always takes precedence
// make sure it's a valid URL
try {
if (mLog.isLoggable(Level.FINE)) {
mLog.log(Level.FINE, "A dynamic URL with value '" + addrUrl + "' is assigned as a NM property (" + NormalizedMessageProperties.OUTBOUND_ADDRESS_URL + ")");
}
URL aUrl = new URL(addrUrl);
dispatch = endpointMeta.createDispatch(meta.getSoapActionURL(), addrUrl);
if (addrUrl.toLowerCase().startsWith("https")) {
isSSL = true;
}
} catch (Exception e) {
// Dispatch should not be created properly, but just in case...
dispatch = null;
// log a warning message, and send an alert for the invalid URL
// however, should proceed with normal processing
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E01050.Invalid_url_nmproperty", addrUrl);
mLog.log(Level.WARNING, text, e);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
endpointMeta.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E01050");
}
}
}
if (dispatch == null) { // either no address url property is defined, or it has a bad URL.
ServiceEndpoint sep = outboundExchange.getEndpoint();
if (sep instanceof HttpSoapDynamicEndpoint) {
dispatch = endpointMeta.createDispatch(meta.getSoapActionURL(), ((HttpSoapDynamicEndpoint) sep).getDynamicUrl());
if (((HttpSoapDynamicEndpoint) sep).getDynamicUrl().toLowerCase().startsWith("https")) {
isSSL = true;
}
} else {
dispatch = endpointMeta.createDispatch(meta.getSoapActionURL());
if (endpointMeta.getEndpointUrl().toString().toLowerCase().startsWith("https")) {
isSSL = true;
}
}
if (dispatch == null) {
if (mLog.isLoggable(Level.SEVERE)) {
String endpointName = endpointMeta.getServiceName().toString() + "," + endpointMeta.getEndpointName();
String deployedSAName = endpointMeta.getServiceUnitID().substring(0,
endpointMeta.getServiceUnitID().indexOf("-" + HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME));
String text = mMessages.getString("HTTPBC-E01051.Failed_to_create_Dispatch",
new Object[]{endpointName, endpointMeta.getOriginalWSDL().getName(), deployedSAName});
mLog.log(Level.SEVERE, text);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
endpointMeta.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E01051");
}
}
}
// add the JAX-WS handlers if any
enableJAXWSHandlers(endpointMeta, dispatch);
Map<String, Object> requestContext = dispatch.getRequestContext();
putBasicAuthCredential(requestContext, endpointMeta, normalizedMessage);
propagateCustomProperties(requestContext, normalizedMessage);
if (mIsHeaderCopyEnabled) {
setupHTTPHeaders(requestContext, normalizedMessage);
}
// set HostnameVerifier if necessary
HttpClientConnectionProperties clientConnProps = endpointMeta.getHttpClientConnectionProperties();
if (clientConnProps != null) {
if (isSSL && !clientConnProps.getHostnameVerification()) {
requestContext.put(JAXWSProperties.HOSTNAME_VERIFIER, new HttpsClientVerifier());
}
// set connect timeout if any
if (clientConnProps.getConnectTimeout() != null) {
int connectTimeoutInt = clientConnProps.getConnectTimeout().intValue();
requestContext.put(JAXWSProperties.CONNECT_TIMEOUT, connectTimeoutInt);
}
if (clientConnProps.getReadTimeout() != null) {
int readTimeoutInt = clientConnProps.getReadTimeout().intValue();
requestContext.put("com.sun.xml.ws.request.timeout", readTimeoutInt);
}
}
if (createDispatchMeasurement != null) {
createDispatchMeasurement.end();
}
// measuring time spent from receiving the ME and right before calling invoke()
if (mDCReceiveToSoapCallMeasurement != null) {
mDCReceiveToSoapCallMeasurement.end();
}
Probe callDispatchMeasurement = Probe.fine(getClass(),
endpointMeta.getUniqueName(),
"invokeDispatch");
if (outboundExchange instanceof InOnly) {
if (mMonitorEnabled) {
try {
LoggingMonitoringUtil.setCheckpoint(endpointMeta, trackingId, "Invoking-one-way-remote-service", soapMsg.getSOAPPart().getEnvelope());
} catch (Exception e) {
if (mLog.isLoggable(Level.WARNING)) {
mLog.log(Level.WARNING, mMessages.getString("HTTPBC-W01310.Failed_to_get_soap_payload_for_checkpointing"));
}
}
}
shouldSuspendTx = true;
dispatch.invokeOneWay(soapMsg);
} else {
if (mMonitorEnabled) {
try {
LoggingMonitoringUtil.setCheckpoint(endpointMeta, trackingId, "Invoking-inout-remote-service", soapMsg.getSOAPPart().getEnvelope());
} catch (Exception e) {
if (mLog.isLoggable(Level.WARNING)) {
mLog.log(Level.WARNING, mMessages.getString("HTTPBC-W01310.Failed_to_get_soap_payload_for_checkpointing"));
}
}
}
//replySoapMsg = dispatch.invoke(soapMsg);
AsyncRequestContext ctx = new AsyncRequestContext((InOut) outboundExchange, mChannel, meta, endpointMeta);
ctx.setProbe(callDispatchMeasurement);
AsyncResponseHandler<SOAPMessage> handler = AsyncResponseDispatcher.instance().getHandler(ctx);
dispatch.invokeAsync(soapMsg, handler);
shouldSuspendTx = true;
/*if (mMonitorEnabled) {
try {
LoggingMonitoringUtil.setCheckpoint(endpointMeta, trackingId, "Received-response-from-inout-remote-service", replySoapMsg.getSOAPPart().getEnvelope());
} catch (Exception e) {
if (mLog.isLoggable(Level.WARNING)) {
mLog.log(Level.WARNING, mMessages.getString("HTTPBC-W01310.Failed_to_get_soap_payload_for_checkpointing"));
}
}
}*/
}
/*if (callDispatchMeasurement != null) {
callDispatchMeasurement.end();
}
// TODO: allow disabling logging message contents and I18N
if (replySoapMsg != null && mLog.isLoggable(Level.FINE)) {
DebugLog.debugLog(mLog, Level.FINE, "Reply received", replySoapMsg.getSOAPPart().getEnvelope());
}
return replySoapMsg; */
} finally {
if (dispatch != null)
endpointMeta.releaseDispatch(dispatch);
if (txResumed && shouldSuspendTx) {
if (mLog.isLoggable(Level.FINE)) {
mLog.log(Level.FINE, "Transction was resumed before the Dispatch call. Successfully received a SOAP response. " +
"About to suspend the transaction before sending the reply in the message exchange...");
}
TransactionsUtil.suspendTransaction();
}
}
}
// Transmit the payload as a SOAPMessage.
private void dispatch(HttpSoapEndpoint endpoint, InOut inout, OperationMetaData opmetadata)
throws Exception {
//SOAPMessage response = null;
SOAPFault soapFault = null;
SOAPFaultException soapFaultException = null;
try {
//response =
outboundCall(inout.getInMessage(), opmetadata, endpoint, inout);
} catch (MessagingException e) {
// Caused by parsing error (WrapperProcessingException, TransformerException, etc.)
setErrorClientException(inout, e, null);
throw e;
} catch (SOAPException e) {
// Caused if SOAPMessage changes failed to save
setErrorClientException(inout, e, null);
throw e;
} catch (SOAPFaultException e) {
mLog.log(Level.FINE, "A fault occured, possibly a specified service fault.", e);
soapFaultException = e;
soapFault = e.getFault();
}
}
// Extracts from a normalized message all the parts that a message
// definition requires. The contents of the parts are returned as
// DOM nodes or string objects, depending on the value of the stringify
// argument.
private List extractPartsValueList(InOut inout, OperationMetaData opmetadata, boolean stringify)
throws Exception {
List partNameList = opmetadata.getCachedInputPartNameList();
List partValueList = new ArrayList();
if (!partNameList.isEmpty()) {
NormalizedMessage request = inout.getInMessage();
Document doc = (Document) Util.messageAsDom(request);
Element rootNode = doc.getDocumentElement();
if (mLog.isLoggable(Level.FINE)) {
mLog.log(Level.FINE, "Request: " + Util.toXml(rootNode, "UTF-8", false));
}
partValueList.addAll(createPartValueList(doc, opmetadata.getInputMessage(), stringify));
}
return partValueList;
}
// Generate the query-string for a HTTP request. The query-string is NOT
// the full GET URL, only the query portion.
//
// If http:urlEncoding is specified, we build an ampersand-delimited
// sequence of name-value pairs using the specified part name and part value
// lists.
// Example:
// parts lists have a part "foo" with the value "star"
// parts lists have a part "bar" with the value "jax"
// we instantiate the string "foo=star&bar=jax"
//
// If http:urlReplacement is specified, we take the specified urlContext
// argument as a 'pattern', and we instantiate from this pattern a
// string where the replacement points in the pattern are replaced by
// their corresponding part values from the specified list.
// Example:
// urlContext -> "/(foo)/(bar)/baz"
// parts lists have a part "foo" with the value "star"
// parts lists have a part "bar" with the value "jax"
// we instantiate the string "/star/jax/baz".
//
// NOTE: for http:urlEncoding case, we percent-encode as well. This is
// integral to the name-value pair scheme.
private String composeGetQueryString(
String urlContext,
String urlEncoding,
String httpOperationLocation,
List partNameList,
List partValueList)
throws Exception {
StringBuffer buffer = new StringBuffer();
if (OperationMetaData.HTTP_URL_ENCODING_ENCODED.equals(urlEncoding)) {
for (int i = 0; i < partNameList.size(); i++) {
String n = (String) partNameList.get(i);
buffer.append(URLEncoder.encode(n, URL_DECODE_ENCODING) + "=");
String v = (String) partValueList.get(i);
buffer.append(URLEncoder.encode(v, URL_DECODE_ENCODING));
if (i != partNameList.size() - 1) {
buffer.append("&");
}
}
} else if (OperationMetaData.HTTP_URL_ENCODING_REPLACEMENT.equals(urlEncoding)) {
String tempLocation = httpOperationLocation;
for (int i = 0; i < partNameList.size(); i++) {
String n = "(" + (String) partNameList.get(i) + ")";
String v = (String) partValueList.get(i);
tempLocation = StringUtil.replaceAll(tempLocation, n, v);
}
buffer.append(mergePath(new String[]{urlContext, tempLocation}));
} else {
throw new Exception(mMessages.getString("HTTPBC-E00747.Invalid_WSDL_HTTP_URL_encoding", urlEncoding));
}
return buffer.toString();
}
// Transmit the payload as a HTTP GET request with the payload
// represented as a query-string or path-info, depending on whether
// http:urlEncoded or http:urlReplacement representation type is specified.
private void dispatchHttpGet(HttpEndpoint endpoint, String queryString, InOut inout, OperationMetaData opmetadata)
throws Exception {
String httpAddressLocation = endpoint.getEndpointUrl().toString();
String httpBindingVerb = endpoint.getHttpBindingVerb();
String httpOperationLocation = opmetadata.getHttpOperationLocation();
String httpUrlEncoding = opmetadata.getHttpUrlEncoding();
//Service service = Service.create(endpoint.getServiceName());
QName portQName = new QName(endpoint.getServiceName().getNamespaceURI(), endpoint.getEndpointName());
String dynamicURL = getDynamicUrl(endpoint, inout);
// if the URL is specified using NMProperty or dynamic partnerLink, then
// the same get the precedence over the URL specified in the WSDL
String url = dynamicURL != null ? dynamicURL : httpAddressLocation;
if (httpOperationLocation != null && !"".equals(httpOperationLocation)) {
url = url.endsWith("/") ? url + httpOperationLocation : url + "/" + httpOperationLocation;
}
//service.addPort(portQName, HTTPBinding.HTTP_BINDING, url);
Dispatch<Source> dispatch = endpoint.createDispatch(url, Source.class);
//service.createDispatch(portQName, Source.class, Service.Mode.MESSAGE);
Map<String, Object> requestContext = dispatch.getRequestContext();
requestContext.put(MessageContext.HTTP_REQUEST_METHOD, httpBindingVerb);
putBasicAuthCredential(requestContext, endpoint, inout.getInMessage());
if (mIsHeaderCopyEnabled) {
setupHTTPHeaders(requestContext, inout.getInMessage());
}
HttpClientConnectionProperties clientConnectionProps = endpoint.getHttpClientConnectionProperties();
if (clientConnectionProps != null) {
if ((url.toLowerCase().startsWith("https")) && !clientConnectionProps.getHostnameVerification()) {
requestContext.put(JAXWSProperties.HOSTNAME_VERIFIER, new HttpsClientVerifier());
}
// set connect timeout if any
if (clientConnectionProps.getConnectTimeout() != null) {
int connectTimeoutInt = clientConnectionProps.getConnectTimeout().intValue();
requestContext.put(JAXWSProperties.CONNECT_TIMEOUT, connectTimeoutInt);
}
if (clientConnectionProps.getReadTimeout() != null) {
int readTimeoutInt = clientConnectionProps.getReadTimeout().intValue();
requestContext.put("com.sun.xml.ws.request.timeout", readTimeoutInt);
}
}
if (OperationMetaData.HTTP_URL_ENCODING_ENCODED.equals(httpUrlEncoding)) {
requestContext.put(MessageContext.QUERY_STRING, queryString);
} else if (OperationMetaData.HTTP_URL_ENCODING_REPLACEMENT.equals(httpUrlEncoding)) {
requestContext.put(MessageContext.PATH_INFO, queryString);
} else {
throw new Exception(mMessages.getString("HTTPBC-E00747.Invalid_WSDL_HTTP_URL_encoding", httpUrlEncoding));
}
try {
AsyncRequestContext ctx = new AsyncRequestContext(inout, mChannel, opmetadata, endpoint);
AsyncResponseHandler<Source> handler = AsyncResponseDispatcher.instance().getHandler(ctx);
//Source response = dispatch.invoke(null);
dispatch.invokeAsync(null, handler);
} catch (Exception e) {
String msg = mMessages.getString("HTTPBC-E00753.Message_dispatch_failed",
new Object[]{
httpBindingVerb,
url,
(OperationMetaData.HTTP_URL_ENCODING_ENCODED.equals(httpUrlEncoding) ? queryString : ""),
(OperationMetaData.HTTP_URL_ENCODING_REPLACEMENT.equals(httpUrlEncoding) ? queryString : ""),
portQName.toString(),
e.getLocalizedMessage()
});
throw new Exception(msg, e);
}
}
/**
* get the dynamic URL if the URL is specified using NMProperty or Dynamic PartnerLink
*
* @param endpoint HttpEndpoint
* @param inout MessageExchange
* @return dynamic URL
* @throws MalformedURLException
*/
private String getDynamicUrl(HttpEndpoint endpoint, InOut inout) throws MalformedURLException {
String addrUrl = null;
NormalizedMessage normalizedMessage = inout.getInMessage();
Object urlProperty = normalizedMessage.getProperty(NormalizedMessageProperties.OUTBOUND_ADDRESS_URL);
if (urlProperty != null) {
if (urlProperty instanceof String) {
addrUrl = (String) urlProperty;
} else {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E01052.Invalid_url_nmproperty_type");
mLog.log(Level.WARNING, text);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
endpoint.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E01052");
}
}
}
if (addrUrl == null) {
ServiceEndpoint sep = inout.getEndpoint();
if (sep != null && sep instanceof HttpSoapDynamicEndpoint) {
addrUrl = ((HttpSoapDynamicEndpoint) sep).getDynamicUrl();
mLog.log(Level.FINE, "A dynamic URL with value '" + addrUrl + "' is assigned using DynamicPartnerLink (" + NormalizedMessageProperties.OUTBOUND_ADDRESS_URL + ")");
}
} else {
mLog.log(Level.FINE, "A dynamic URL with value '" + addrUrl + "' is assigned as a NM property (" + NormalizedMessageProperties.OUTBOUND_ADDRESS_URL + ")");
}
if (addrUrl != null) {
URL u = new URL(addrUrl);
}
return addrUrl;
}
// Transmit the payload as a HTTP POST request. The payload is included as
// the request's entity-body.
private void dispatchHttpPost(HttpEndpoint endpoint, Object payload, InOut inout, OperationMetaData opmetadata)
throws Exception {
String httpAddressLocation = endpoint.getEndpointUrl().toString();
String httpBindingVerb = endpoint.getHttpBindingVerb();
String httpOperationLocation = opmetadata.getHttpOperationLocation();
String httpUrlEncoding = opmetadata.getHttpUrlEncoding();
//Service service = Service.create(endpoint.getServiceName());
QName portQName = new QName(endpoint.getServiceName().getNamespaceURI(), endpoint.getEndpointName());
String dynamicURL = getDynamicUrl(endpoint, inout);
// if the URL is specified using NMProperty or dynamic partnerLink, then
// the same get the precedence over the URL specified in the WSDL
String url = dynamicURL != null ? dynamicURL : httpAddressLocation;
if (httpOperationLocation != null && !"".equals(httpOperationLocation)) {
url = url.endsWith("/") ? url + httpOperationLocation : url + "/" + httpOperationLocation;
}
//service.addPort(portQName, HTTPBinding.HTTP_BINDING, url);
try {
if (payload == null) {
throw new Exception(mMessages.getString("HTTPBC-E01053.Invalid_http_post_payload"));
}
if (opmetadata.getInputMessage() == null || opmetadata.getInputMessage().getQName() == null) {
throw new Exception(mMessages.getString("HTTPBC-E01054.Invalid_http_post_input_message"));
}
Dispatch dispatch = null;
Object request = null;
if (payload instanceof Node){
dispatch = endpoint.createDispatch(url, Source.class);
request = new DOMSource((Node)payload);
}
else {
dispatch = endpoint.createDispatch(url, DataSource.class);
request = new StringDataSourceImpl(portQName,(String) payload);
}
Map<String, Object> requestContext = dispatch.getRequestContext();
requestContext.put(MessageContext.HTTP_REQUEST_METHOD, httpBindingVerb);
putBasicAuthCredential(requestContext, endpoint, inout.getInMessage());
if (mIsHeaderCopyEnabled) {
setupHTTPHeaders(requestContext, inout.getInMessage());
}
HttpClientConnectionProperties clientConnectionProps = endpoint.getHttpClientConnectionProperties();
if (clientConnectionProps != null) {
if ((url.toLowerCase().startsWith("https")) && !clientConnectionProps.getHostnameVerification()) {
requestContext.put(JAXWSProperties.HOSTNAME_VERIFIER, new HttpsClientVerifier());
}
// set connect timeout if any
if (clientConnectionProps.getConnectTimeout() != null) {
int connectTimeoutInt = clientConnectionProps.getConnectTimeout().intValue();
requestContext.put(JAXWSProperties.CONNECT_TIMEOUT, connectTimeoutInt);
}
if (clientConnectionProps.getReadTimeout() != null) {
int readTimeoutInt = clientConnectionProps.getReadTimeout().intValue();
requestContext.put("com.sun.xml.ws.request.timeout", readTimeoutInt);
}
}
// check if payload and input message type are valid
//DataSource response = dispatch.invoke(request);
AsyncRequestContext ctx = new AsyncRequestContext(inout, mChannel, opmetadata, endpoint);
AsyncResponseHandler handler = AsyncResponseDispatcher.instance().getHandler(ctx);
dispatch.invokeAsync(request, handler);
} catch (Exception e) {
String msg = mMessages.getString("HTTPBC-E00753.Message_dispatch_failed",
new Object[]{
httpBindingVerb,
url,
"", // no query string for POST
"", // no path_info for POST
portQName.toString(),
e.getLocalizedMessage()
});
throw new Exception(msg, e);
}
}
// Execute a HTTP request, GET or POST depending on the "verb" defined
// for the specified endpoint.
private void dispatch(HttpEndpoint endpoint, InOut inout, OperationMetaData opmetadata)
throws Exception {
String httpBindingVerb = endpoint.getHttpBindingVerb();
String httpUrlEncoding = opmetadata.getHttpUrlEncoding();
String httpOperationLocation = opmetadata.getHttpOperationLocation();
if (HttpEndpoint.HTTP_BINDING_VERB_GET.equals(httpBindingVerb)) {
// Extract parts from message exchange, and create the GET request
List partValueList = extractPartsValueList(inout, opmetadata, true);
List partNameList = opmetadata.getCachedInputPartNameList();
// Guard for the case when a message definition does not utilize
// all the parts available in the message exchange. We require
// complete congruence. If there is a part in the message that is
// not used by the message definition, or as a more
// serious offense, if there is a part the message definition needs
// but is not in the normalized message, then we reject the message.
if (partValueList.size() < partNameList.size()) {
String errMsg;
if (mLog.isLoggable(Level.FINE)) {
NormalizedMessage request = inout.getInMessage();
Document doc = (Document) Util.messageAsDom(request);
Element rootNode = doc.getDocumentElement();
errMsg = mMessages.getString("HTTPBC-E00781.Bad_content_detail", Util.toXml(rootNode, "UTF-8", false));
} else {
errMsg = mMessages.getString("HTTPBC-E00781.Bad_content");
}
Exception ex = new Exception(errMsg);
setErrorClientException(inout, ex, null);
throw ex;
}
String queryString = composeGetQueryString(endpoint.getUrlContext(),
httpUrlEncoding, httpOperationLocation, partNameList, partValueList);
// Send the query
dispatchHttpGet(endpoint, queryString, inout, opmetadata);
} else if (HttpEndpoint.HTTP_BINDING_VERB_POST.equals(httpBindingVerb)) {
// Extract parts from message exchange, and create the GET request
List partValueList = extractPartsValueList(inout, opmetadata, false);
// We do not allow input consisting of more than one part,
// because POST expects a blob (or document) to populate the
// HTTP request's entity-body, and in WSDL/XSD terms, that means
// one element-type part, or one simpleType part.
if (partValueList.size() > 1 || partValueList.size() == 0) {
String errMsg;
NormalizedMessage request = inout.getInMessage();
Document doc = (Document) Util.messageAsDom(request);
Element rootNode = doc.getDocumentElement();
if (partValueList.size() > 1) {
errMsg = mMessages.getString("HTTPBC-E00782.Multipart_POST_Unsupported_detail", Util.toXml(rootNode, "UTF-8", false));
} else {
errMsg = mMessages.getString("HTTPBC-E00781.Bad_content_detail", Util.toXml(rootNode, "UTF-8", false));
}
Exception ex = new Exception(errMsg);
setErrorClientException(inout, ex, null);
throw ex;
}
// Obtain a Node representation of the payload
Object value = partValueList.get(0);
Node msgNode = (value instanceof String
? Util.textAsDomWithXMLCheck((String) value)
: (value instanceof Document
? ((Document) value).getDocumentElement()
: null));
// Getting here means the payload part is of an unknown/unsupported
// type, or is a Document that yielded nothing as its document element.
if ((msgNode == null) && !(value instanceof String)) {
NormalizedMessage request = inout.getInMessage();
Document doc = (Document) Util.messageAsDom(request);
Element rootNode = doc.getDocumentElement();
String errMsg = mMessages.getString("HTTPBC-E00781.Bad_content_detail", Util.toXml(rootNode, "UTF-8", false));
Exception ex = new Exception(errMsg);
setErrorClientException(inout, ex, null);
throw ex;
}
// Send the query
dispatchHttpPost(endpoint, (msgNode != null ? msgNode : value), inout, opmetadata);
} else {
throw new Exception(mMessages.getString("HTTPBC-E00749.Invalid_HTTP_verb", httpBindingVerb));
}
}
private List createPartValueList(Document normalizedMsg, Message msgDef, boolean stringify)
throws WrapperProcessingException,
TransformerException,
UnsupportedEncodingException {
List partValueList = new ArrayList();
WrapperParser parser = null;
Transformer transformer = null;
try {
parser = HelperFactory.createParser();
parser.parse(normalizedMsg, msgDef);
transformer = cTransformerPool.retrieve();
String[] partNames = parser.getPartNames();
for (int i = 0; i < partNames.length; ++i) {
String partName = partNames[i];
if (isSimpleMessagePart(msgDef, partName)) {
StringBuffer contentBuffer = new StringBuffer();
NodeList nodeList = parser.getPartNodes(partName);
for (int n = 0, N = nodeList.getLength(); n < N; ++n) {
Node node = nodeList.item(n);
contentBuffer.append(node.getTextContent());
}
partValueList.add(contentBuffer.toString());
contentBuffer.delete(0, contentBuffer.length());
} else {
Document document = mBuilder.newDocument();
NodeList nodeList = parser.getPartNodes(partNames[i]);
for (int n = 0, N = nodeList.getLength(); n < N; ++n) {
Node node = nodeList.item(n);
if (node != null) {
copyNode(document, node);
}
}
if (stringify) {
StringWriter writer = new StringWriter();
StreamResult dest = new StreamResult(writer);
DOMSource source = new DOMSource(document);
transformer.transform(source, dest);
writer.flush();
partValueList.add(writer.toString());
} else {
partValueList.add(document);
}
}
}
} finally {
cTransformerPool.relinquish(transformer);
}
return partValueList;
}
private boolean isSimpleMessagePart(Message msgDef, String partName) {
Part p = msgDef.getPart(partName);
boolean isSimple = p.getElementName() == null && WSDLUtilities.isBuiltInType(p.getTypeName().getNamespaceURI());
return isSimple;
}
private void setErrorUnsupportedExchangePattern(MessageExchange exchange, String msg, String detail)
throws MessagingException {
// Do not modify an exchange whose status is already set to ERROR.
// The exchange may already have been previously initialized by an earlier setError... call.
if (exchange.getStatus() != ExchangeStatus.ERROR) {
if (detail == null) {
detail = "";
}
IllegalArgumentException ex = new IllegalArgumentException(msg);
exchange.setError(ex);
exchange.setStatus(ExchangeStatus.ERROR);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTCODE, "VersionMismatch");
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTSTRING, msg);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTACTOR, COMPONENT_NAME);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTDETAIL, detail);
}
}
private void setErrorServerException(MessageExchange exchange, Exception ex, String detail)
throws MessagingException {
// Do not modify an exchange whose status is already set to ERROR.
// The exchange may already have been previously initialized by an earlier setError... call.
if (exchange.getStatus() != ExchangeStatus.ERROR) {
if (detail == null) {
detail = "";
}
exchange.setError(ex);
exchange.setStatus(ExchangeStatus.ERROR);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTCODE, "Server");
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTSTRING, ex.getLocalizedMessage());
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTACTOR, COMPONENT_NAME);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTDETAIL, detail);
}
}
private void setErrorServerException(MessageExchange exchange, Exception ex, SOAPFault fault)
throws MessagingException {
// Do not modify an exchange whose status is already set to ERROR.
// The exchange may already have been previously initialized by an earlier setError... call.
if (exchange.getStatus() != ExchangeStatus.ERROR) {
String faultCode = fault.getFaultCode();
if (faultCode == null) {
faultCode = "Server";
}
String faultString = fault.getFaultString();
if (faultString == null) {
faultString = "";
}
String faultActor;
try {
faultActor = fault.getFaultActor();
if (faultActor == null) {
faultActor = "";
}
} catch (UnsupportedOperationException e) {
faultActor = "";
}
StringBuffer faultDetail = new StringBuffer();
javax.xml.soap.Detail details = fault.getDetail();
if (details != null) {
Iterator detailsIteration = details.getDetailEntries();
while (detailsIteration.hasNext()) {
DetailEntry detailEntry = (DetailEntry) detailsIteration.next();
try {
faultDetail.append(Util.toXml(detailEntry, "UTF-8", true));
} catch (Exception e) {
if (faultDetail.length() == 0) {
faultDetail.append(faultString);
}
break;
}
}
} else {
faultDetail.append(faultString);
}
exchange.setError(ex);
exchange.setStatus(ExchangeStatus.ERROR);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTCODE, faultCode);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTSTRING, faultString);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTACTOR, faultActor);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTDETAIL, faultDetail.toString());
}
}
private void setErrorClientException(MessageExchange exchange, Exception ex, String detail)
throws MessagingException {
// Do not modify an exchange whose status is already set to ERROR.
// The exchange may already have been previously initialized by an earlier setError... call.
if (exchange.getStatus() != ExchangeStatus.ERROR) {
if (detail == null) {
detail = "";
}
exchange.setError(ex);
exchange.setStatus(ExchangeStatus.ERROR);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTCODE, "Client");
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTSTRING, ex.getLocalizedMessage());
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTACTOR, COMPONENT_NAME);
exchange.setProperty(Denormalizer.PROPERTY_ERROR_FAULTDETAIL, detail);
}
}
private void copyNode(Document document, Node node) {
node = document.importNode(node, true);
document.appendChild(node);
NamedNodeMap attrs = node.getAttributes();
NamedNodeMap destAttrs = document.getAttributes();
if (attrs != null) {
for (int i = 0; i < attrs.getLength(); i++) {
Node attr = attrs.item(i);
Node n = document.importNode(attr, true);
if (destAttrs != null) {
destAttrs.setNamedItemNS(n);
}
}
}
}
private void updateTallyReceivedReplies(Endpoint e) {
if (e != null) {
EndpointStatus status = e.getEndpointStatus();
if (status != null) {
status.incrementReceivedReplies();
}
}
}
private void updateTallyReceivedRequests(Endpoint e) {
if (e != null) {
EndpointStatus status = e.getEndpointStatus();
if (status != null) {
status.incrementReceivedRequests();
}
}
}
private void updateTallySentReplies(Endpoint e) {
if (e != null) {
EndpointStatus status = e.getEndpointStatus();
if (status != null) {
status.incrementSentReplies();
}
}
}
private void updateTallySentRequests(Endpoint e) {
if (e != null) {
EndpointStatus status = e.getEndpointStatus();
if (status != null) {
status.incrementSentRequests();
}
}
}
private void updateTallyReceives(Endpoint e, boolean successfulReceive) {
if (e != null) {
EndpointStatus status = e.getEndpointStatus();
if (status != null) {
if (successfulReceive) {
status.incrementReceivedDones();
} else {
status.incrementReceivedErrors();
}
}
}
}
private void updateTallySends(Endpoint e, boolean successfulSend) {
if (e != null) {
EndpointStatus status = e.getEndpointStatus();
if (status != null) {
if (successfulSend) {
status.incrementSentDones();
} else {
status.incrementSentErrors();
}
}
}
}
private String mergePath(String[] segments) {
StringBuffer pathBuffer = new StringBuffer();
StringBuffer segBuffer = new StringBuffer();
for (String seg : segments) {
if (seg != null) {
segBuffer.append(seg);
while (segBuffer.length() > 0 && segBuffer.charAt(0) == '/') {
segBuffer.deleteCharAt(0);
}
while (segBuffer.length() > 0 && segBuffer.charAt(segBuffer.length() - 1) == '/') {
segBuffer.deleteCharAt(segBuffer.length() - 1);
}
pathBuffer.append(segBuffer).append("/");
segBuffer.delete(0, segBuffer.length());
}
}
return pathBuffer.substring(0, pathBuffer.length() - 1);
}
private void putBasicAuthCredential(Map<String, Object> requestContext, Endpoint endpoint, NormalizedMessage normalizedMessage) {
String dynamicUsername = (String) normalizedMessage.getProperty(NormalizedMessageProperties.OUTBOUND_BASIC_AUTH_USERNAME);
String dynamicPassword = (String) normalizedMessage.getProperty(NormalizedMessageProperties.OUTBOUND_BASIC_AUTH_PASSWORD);
if (dynamicUsername != null && !"".equals(dynamicUsername)) { // even if basic auth is not explicitly configured in the WSDL
requestContext.put(BindingProvider.USERNAME_PROPERTY, dynamicUsername);
} else {
if (endpoint.getBasicAuthCredential() != null &&
endpoint.getBasicAuthCredential().getName() != null &&
!"".equals(endpoint.getBasicAuthCredential().getName())) {
requestContext.put(BindingProvider.USERNAME_PROPERTY, endpoint.getBasicAuthCredential().getName());
}
}
if (dynamicPassword != null && !"".equals(dynamicPassword)) { // even if basic auth is not explicitly configured in the WSDL
requestContext.put(BindingProvider.PASSWORD_PROPERTY, dynamicPassword);
} else {
if (endpoint.getBasicAuthCredential() != null &&
endpoint.getBasicAuthCredential().getPassword() != null) {
requestContext.put(BindingProvider.PASSWORD_PROPERTY, new String(endpoint.getBasicAuthCredential().getPassword()));
}
}
}
private void propagateCustomProperties(Map<String, Object> requestContext, NormalizedMessage normalizedMessage) {
Map<String, Object> customProperties = (Map<String, Object>) normalizedMessage.getProperty(NormalizedMessageProperties.OUTBOUND_CUSTOM_PROPERTY);
if (customProperties != null) {
for (Map.Entry<String, Object> entry : customProperties.entrySet()) {
requestContext.put(entry.getKey(), entry.getValue());
}
}
}
private void setupHTTPHeaders(Map<String, Object> requestContext, NormalizedMessage normalizedMessage) {
Map<String, String> httpHeaderProperty =
(Map<String, String>) normalizedMessage.getProperty(NormalizedMessageProperties.OUTBOUND_HTTP_HEADERS_PROPERTY);
Map<String, List<String>> headers = new HashMap<String, List<String>>();
if (httpHeaderProperty != null) {
for (Map.Entry<String, String> entry : httpHeaderProperty.entrySet()) {
// make sure we do not propagate the "custom" client host/port entries
if (!NormalizedMessageProperties.HTTP_HEADER_ClIENT_HOST_NAME.equals(entry.getKey()) &&
!NormalizedMessageProperties.HTTP_HEADER_CLIENT_PORT_NUMBER.equals(entry.getKey())) {
headers.put(entry.getKey(), Collections.singletonList(entry.getValue()));
}
}
}
requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
}
private boolean isRedeliveryConfigured(MessageExchange exchange) {
RedeliveryStatus redeliveryStatus = Redelivery.getRedeliveryStatus(exchange);
return (redeliveryStatus != null);
}
private boolean isRedeliveryEnabled(MessageExchange exchange) {
boolean configured = false;
EndpointInfo info = new EndpointInfo(false,
exchange.getEndpoint().getEndpointName(),
null,
exchange.getEndpoint().getServiceName(),
null);
RedeliveryConfig retryConfig = mChannel.getServiceQuality(info, RedeliveryConfig.class);
if (retryConfig != null) {
configured = true;
} else {
// Well, try Redelivery.getEndpoint() API. It could be that the max redelivery
// attempts have been exhausted, and the ME was rerouted to a QoS endpoint
ServiceEndpoint actualEndpoint = Redelivery.getEndpoint(exchange);
QName serviceName = actualEndpoint.getServiceName();
String endpointName = actualEndpoint.getEndpointName();
Endpoint epb = (Endpoint) mEndpoints.get(HttpSoapEndpoint.getUniqueName(serviceName.getNamespaceURI(),
serviceName.getLocalPart(),
endpointName,
true));
if (epb != null) {
info = new EndpointInfo(false,
endpointName,
null,
serviceName,
null);
retryConfig = mChannel.getServiceQuality(info, RedeliveryConfig.class);
if (retryConfig != null) {
configured = true;
}
}
}
return configured;
}
private void handleRedelivery(MessageExchange exchange, Endpoint epb) {
try {
MessageExchangeSupport.notifyOfRedelivery(exchange);
} catch (Exception e) {
String groupId = (String) exchange.getProperty(SoapNormalizer.CRMP_GROUP_ID);
String messageId = (String) exchange.getProperty(SoapNormalizer.CRMP_MESSAGE_ID);
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E01036.Failed_to_process_redelivery", new Object[]{groupId, messageId});
mLog.log(Level.WARNING, text, e);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
epb.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E01036");
}
}
}
private void setTransactionRollbackOnly(Transaction transaction) {
boolean txResumed = false;
if (transaction != null) {
txResumed = TransactionsUtil.resumeTransaction(transaction);
}
if (txResumed) {
TransactionsUtil.setRollbackOnlyOnTransaction(transaction);
try {
TransactionsUtil.suspendTransaction();
} catch (SystemException se) {
// really no recourse for this as tx state is probably messed up
// Note - TransactionsUtil logs exception
}
}
}
private void enableJAXWSHandlers(Endpoint endpointMeta, Dispatch dispatch) throws Exception {
List handlerList = endpointMeta.getHandlers();
if (handlerList.size() == 0) {
return;
}
// load the handler jars
List handlerLibs = endpointMeta.getHandlerLibPaths();
URL[] handlerLibUrls = new URL[handlerLibs.size()];
int count = 0;
for (Iterator it = handlerLibs.iterator(); it.hasNext();) {
File libFile = (File) it.next();
if (libFile.exists()) {
handlerLibUrls[count] = libFile.toURL();
count++;
}
}
if (handlerLibUrls.length > 0) {
URLClassLoader handlerClassLoader = new URLClassLoader(handlerLibUrls, Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(handlerClassLoader);
}
// instantiate the handler instances
List handlers = new ArrayList();
for (Iterator it = handlerList.iterator(); it.hasNext();) {
// get the fully qualified handler class name
HttpSoapHandler handlerMeta = (HttpSoapHandler) it.next();
try {
Class handlerClass = Class.forName(handlerMeta.getHandlerClassName(), true, Thread.currentThread().getContextClassLoader());
// we require handler implementation to follow the Java Bean convention
handlers.add(handlerClass.newInstance());
} catch (Exception e) {
if (mLog.isLoggable(Level.WARNING)) {
String text = mMessages.getString("HTTPBC-E01055.Failed_to_instantiate_handler");
mLog.log(Level.WARNING, text, e);
AlertsUtil.getAlerter().warning(text,
HttpSoapBindingLifeCycle.SHORT_DISPLAY_NAME,
endpointMeta.getServiceUnitID(),
AlertsUtil.getServerType(),
AlertsUtil.COMPONENT_TYPE_BINDING,
NotificationEvent.OPERATIONAL_STATE_RUNNING,
NotificationEvent.EVENT_TYPE_ALERT,
"HTTPBC-E01055");
}
}
}
((BindingProvider) dispatch).getBinding().setHandlerChain(handlers);
}
// overide java default SSL HostnameVerifier to always return true
// when verification flag is turned off
private static class HttpsClientVerifier implements HostnameVerifier {
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
}