001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.camel.component.spring.ws; 018 019 import java.util.HashMap; 020 import java.util.Iterator; 021 import java.util.Map; 022 import javax.xml.namespace.QName; 023 import javax.xml.transform.Source; 024 025 import org.apache.camel.Endpoint; 026 import org.apache.camel.Exchange; 027 import org.apache.camel.ExchangePattern; 028 import org.apache.camel.Message; 029 import org.apache.camel.Processor; 030 import org.apache.camel.converter.jaxp.XmlConverter; 031 import org.apache.camel.impl.DefaultConsumer; 032 import org.apache.camel.impl.DefaultExchange; 033 import org.springframework.ws.WebServiceMessage; 034 import org.springframework.ws.context.MessageContext; 035 import org.springframework.ws.server.endpoint.MessageEndpoint; 036 import org.springframework.ws.soap.SoapHeader; 037 import org.springframework.ws.soap.SoapHeaderElement; 038 import org.springframework.ws.soap.SoapMessage; 039 040 public class SpringWebserviceConsumer extends DefaultConsumer implements MessageEndpoint { 041 042 private SpringWebserviceEndpoint endpoint; 043 private SpringWebserviceConfiguration configuration; 044 045 public SpringWebserviceConsumer(Endpoint endpoint, Processor processor) { 046 super(endpoint, processor); 047 this.endpoint = (SpringWebserviceEndpoint) endpoint; 048 this.configuration = this.endpoint.getConfiguration(); 049 } 050 051 /** 052 * Invoked by Spring-WS when a {@link WebServiceMessage} is received 053 */ 054 public void invoke(MessageContext messageContext) throws Exception { 055 Exchange exchange = new DefaultExchange(endpoint.getCamelContext(), ExchangePattern.InOptionalOut); 056 populateExchangeFromMessageContext(messageContext, exchange); 057 058 // start message processing 059 getProcessor().process(exchange); 060 061 // create webservice response from output body 062 if (exchange.getPattern().isOutCapable()) { 063 Message responseMessage = exchange.getOut(Message.class); 064 if (responseMessage != null) { 065 Source responseBody = responseMessage.getBody(Source.class); 066 WebServiceMessage response = messageContext.getResponse(); 067 XmlConverter xmlConverter = configuration.getXmlConverter(); 068 xmlConverter.toResult(responseBody, response.getPayloadResult()); 069 } 070 } 071 } 072 073 private void populateExchangeFromMessageContext(MessageContext messageContext, Exchange exchange) { 074 populateExchangeWithPropertiesFromMessageContext(messageContext, exchange); 075 076 // create inbound message 077 WebServiceMessage request = messageContext.getRequest(); 078 SpringWebserviceMessage inMessage = new SpringWebserviceMessage(request); 079 inMessage.setHeaders(extractSoapHeadersFromWebServiceMessage(request)); 080 exchange.setIn(inMessage); 081 } 082 083 private void populateExchangeWithPropertiesFromMessageContext(MessageContext messageContext, Exchange exchange) { 084 // convert WebserviceMessage properties (added through interceptors) to 085 // Camel exchange properties 086 String[] propertyNames = messageContext.getPropertyNames(); 087 if (propertyNames != null) { 088 for (String propertyName : propertyNames) { 089 exchange.setProperty(propertyName, messageContext.getProperty(propertyName)); 090 } 091 } 092 } 093 094 private Map<String, Object> extractSoapHeadersFromWebServiceMessage(WebServiceMessage request) { 095 Map<String, Object> headers = new HashMap<String, Object>(); 096 if (request instanceof SoapMessage) { 097 SoapMessage soapMessage = (SoapMessage) request; 098 SoapHeader soapHeader = soapMessage.getSoapHeader(); 099 if (soapHeader != null) { 100 Iterator<?> attibutesIterator = soapHeader.getAllAttributes(); 101 while (attibutesIterator.hasNext()) { 102 QName name = (QName) attibutesIterator.next(); 103 headers.put(name.toString(), soapHeader.getAttributeValue(name)); 104 } 105 Iterator<?> elementIter = soapHeader.examineAllHeaderElements(); 106 while (elementIter.hasNext()) { 107 Object element = elementIter.next(); 108 if (element instanceof SoapHeaderElement) { 109 QName name = ((SoapHeaderElement) element).getName(); 110 headers.put(name.toString(), element); 111 } 112 } 113 } 114 } 115 return headers; 116 } 117 118 @Override 119 protected void doStop() throws Exception { 120 if (configuration.getEndpointMapping() != null) { 121 configuration.getEndpointMapping().removeConsumer(configuration.getEndpointMappingKey()); 122 } 123 super.doStop(); 124 } 125 126 @Override 127 protected void doStart() throws Exception { 128 if (configuration.getEndpointMapping() != null) { 129 configuration.getEndpointMapping().addConsumer(configuration.getEndpointMappingKey(), this); 130 } 131 super.doStart(); 132 } 133 134 }