package be.error.wsproxy.core; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ws.context.MessageContext; import org.springframework.ws.server.endpoint.MessageEndpoint; import org.springframework.ws.server.endpoint.annotation.Endpoint; import org.springframework.ws.transport.context.TransportContextHolder; import org.springframework.ws.transport.http.HttpServletConnection; import be.error.wsproxy.interceptors.ServiceSpecificEndpointInterceptor; /** * This is the catch-all {@link Endpoint} which will forward requests to the target service using * {@link ForwardingClient}. If you need service specific actions on the inbound side, you can add them using * {@link ServiceSpecificEndpointInterceptor} for this endpoint. Remember, as being a proxy, this endpoint has two * purposes; it is both a Webservice (endpoint) but also a Webservice client for the actual target. Because of this * there are two filter chains involved, the ones defined on the endpoint itself (inbound) and the ones defined on * {@link ForwardingClient#setCustomClientInterceptors(java.util.Map)} (outbound). * <p> * If an error occurs during forwarding (ie. the response retrieved was not a valid SOAP message) a runtime exception * will be thrown and converted to a ({@link ForwardingEndpointTargetException}). The exception will include the HTTP * code & reason and the the body (if available) of the upstream response as exception message. This will result in a * SOAP fault being returned to the caller, containing the complete message. Doing this we offer an extra service to * callers making sure that in case of off-spec return values from upstream servers they still get a nice SOAP valid * reply: a SOAP fault. This also means that the handleFault of configured interceptors for this endpoint will be * triggered. * * @see ForwardingClient * @author Koen Serneels */ @Endpoint public class CatchAllEndpoint implements MessageEndpoint { private static final Logger LOG = Logger.getLogger(CatchAllEndpoint.class); @Autowired private ForwardingClient forwardingClient; @Override public void invoke(final MessageContext messageContext) { try { HttpServletRequest httpServletRequest = ((HttpServletConnection) TransportContextHolder .getTransportContext().getConnection()).getHttpServletRequest(); messageContext.setResponse(forwardingClient.forward( WebserviceIdentifierExtractorSupport.getWebServiceIdentifier(messageContext), messageContext.getRequest(), httpServletRequest)); } catch (RuntimeException runtimeException) { throw (createAndLogEndpointException(runtimeException, "Error communicating with upstream server.")); } } private RuntimeException createAndLogEndpointException(Throwable exception, String reason) { ForwardingEndpointTargetException forwardingEndpointTargetException = new ForwardingEndpointTargetException( reason + " Exception:[" + ExceptionUtils.getStackTrace(exception) + "]", exception); LOG.error("Had exception while forwarding request to target endpoint:" + forwardingEndpointTargetException); return forwardingEndpointTargetException; } }