View Javadoc
1   /*
2    * Copyright 2009 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *     
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.openehealth.ipf.platform.camel.ihe.ws;
17  
18  import lombok.extern.slf4j.Slf4j;
19  import org.apache.camel.Exchange;
20  import org.apache.camel.ExchangePattern;
21  import org.apache.camel.Message;
22  import org.apache.cxf.binding.soap.SoapFault;
23  import org.apache.cxf.jaxws.context.WebServiceContextImpl;
24  import org.openehealth.ipf.platform.camel.core.util.Exchanges;
25  
26  import javax.xml.ws.handler.MessageContext;
27  import java.util.Map;
28  
29  import static java.util.Objects.requireNonNull;
30  import static org.openehealth.ipf.platform.camel.ihe.ws.HeaderUtils.processIncomingHeaders;
31  import static org.openehealth.ipf.platform.camel.ihe.ws.HeaderUtils.processUserDefinedOutgoingHeaders;
32  
33  /**
34   * Base class for web services that are aware of a {@link DefaultWsConsumer}.
35   *
36   * @author Jens Riemschneider
37   */
38  @Slf4j
39  abstract public class AbstractWebService {
40      private DefaultWsConsumer consumer;
41  
42      /**
43       * Calls the consumer for processing via Camel.
44       *
45       * @param body
46       *          contents of the in-message body to be processed.
47       * @param additionalHeaders
48       *          additional in-message headers (can be <code>null</code>).
49       * @param exchangePattern
50       *          pattern of the exchange put into the route.
51       * @return the resulting exchange.
52       */
53      protected Exchange process(
54              Object body, 
55              Map<String, Object> additionalHeaders,
56              ExchangePattern exchangePattern) {
57          requireNonNull(consumer);
58          MessageContext messageContext = new WebServiceContextImpl().getMessageContext();
59          Exchange exchange = consumer.getEndpoint().createExchange(exchangePattern);
60          
61          // prepare input message & headers
62          Message inputMessage = exchange.getIn();
63          inputMessage.setBody(body);
64          processIncomingHeaders(messageContext, inputMessage);
65          if (additionalHeaders != null) {
66              inputMessage.getHeaders().putAll(additionalHeaders);
67          }
68  
69          // set Camel exchange property based on request encoding
70          exchange.setProperty(Exchange.CHARSET_NAME,
71                  messageContext.get(org.apache.cxf.message.Message.ENCODING));
72  
73          // process
74          consumer.process(exchange);
75  
76          Exception exception = Exchanges.extractException(exchange, false);
77          if (exception instanceof SoapFault) {
78              log.debug("Rethrowing SOAP fault occurred in the route", exception);
79              throw (SoapFault) exception;
80          }
81  
82          // handle resulting message and headers
83          Message resultMessage = Exchanges.resultMessage(exchange);
84          processUserDefinedOutgoingHeaders(messageContext, resultMessage, false);
85  
86          // set response encoding based on Camel exchange property
87          String responseEncoding = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
88          if (responseEncoding != null) {
89              messageContext.put(org.apache.cxf.message.Message.ENCODING, responseEncoding);
90          }
91          return exchange;
92      }
93  
94      /**
95       * Calls the consumer for synchronous (InOut) processing via Camel
96       * without additional in-message headers.
97       *
98       * @param body
99       *          contents of the in-message body to be processed.
100      * @return the resulting exchange.
101      */
102     protected Exchange process(Object body) {
103         return process(body, null, ExchangePattern.InOut);
104     }
105     
106     /**
107      * Sets the consumer to be used to process exchanges
108      * @param consumer
109      *          the consumer to be used
110      */
111     public void setConsumer(DefaultWsConsumer consumer) {
112         this.consumer = requireNonNull(consumer, "consumer");
113     }
114 
115     /**
116      * Returns the configured ITI consumer instance.
117      */
118     protected DefaultWsConsumer getConsumer() {
119         return consumer;
120     }
121 
122 }