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.hl7v3;
17  
18  import groovy.util.slurpersupport.GPathResult;
19  import lombok.extern.slf4j.Slf4j;
20  import org.apache.camel.Exchange;
21  import org.apache.cxf.jaxws.context.WebServiceContextImpl;
22  import org.apache.cxf.message.Message;
23  import org.apache.cxf.transport.http.AbstractHTTPDestination;
24  import org.apache.cxf.ws.addressing.AddressingProperties;
25  import org.apache.cxf.ws.addressing.JAXWSAConstants;
26  import org.openehealth.ipf.commons.audit.AuditContext;
27  import org.openehealth.ipf.commons.ihe.hl7v3.*;
28  import org.openehealth.ipf.commons.ihe.hl7v3.audit.Hl7v3AuditDataset;
29  import org.openehealth.ipf.commons.ihe.hl7v3.audit.Hl7v3AuditStrategy;
30  import org.openehealth.ipf.platform.camel.core.util.Exchanges;
31  import org.openehealth.ipf.platform.camel.ihe.ws.AbstractWebService;
32  
33  import javax.servlet.http.HttpServletRequest;
34  import javax.xml.ws.handler.MessageContext;
35  
36  import static java.util.Objects.requireNonNull;
37  
38  /**
39   * Generic Web Service implementation for HL7 v3-based transactions.
40   *
41   * @author Dmytro Rud
42   */
43  @Slf4j
44  abstract public class AbstractHl7v3WebService extends AbstractWebService {
45  
46      private final Hl7v3WsTransactionConfiguration wsTransactionConfiguration;
47  
48      public AbstractHl7v3WebService(Hl7v3InteractionId<? extends Hl7v3WsTransactionConfiguration> hl7v3InteractionId) {
49          this.wsTransactionConfiguration = requireNonNull(hl7v3InteractionId.getWsTransactionConfiguration(), "TransactionConfiguration is null");
50      }
51      
52      /**
53       * The proper message processing method.
54       * @param requestString
55       *      XML payload of the HL7 v3 request message.
56       * @return
57       *      XML payload of the HL7 v3 response message or an automatically generated NAK.
58       */
59      protected String doProcess(String requestString) {
60          Exchange result = process(requestString);
61          Exception exception = Exchanges.extractException(result);
62          if (exception != null) {
63              log.info("HL7 v3 service failed", exception);
64              return createNak(requestString, exception);
65          }
66          return Exchanges.resultMessage(result).getBody(String.class);
67      }
68  
69      /**
70       * Creates a transaction-specific NAK message.
71       */
72      protected String createNak(String requestString, Throwable throwable) {
73          return Hl7v3NakFactory.response(
74                  requestString,
75                  throwable,
76                  wsTransactionConfiguration.getNakRootElementName(),
77                  wsTransactionConfiguration.getControlActProcessCode(),
78                  false);
79      }
80  
81      /**
82       * Creates a transaction-specific NAK message.
83       */
84      protected String createNak(GPathResult request, Throwable throwable) {
85          return Hl7v3NakFactory.response(
86                  request, throwable,
87                  wsTransactionConfiguration.getNakRootElementName(),
88                  wsTransactionConfiguration.getControlActProcessCode(),
89                  false);
90      }
91  
92      public Hl7v3WsTransactionConfiguration getWsTransactionConfiguration() {
93          return wsTransactionConfiguration;
94      }
95  
96  
97      protected Hl7v3AuditDataset startAtnaAuditing(String requestString, Hl7v3AuditStrategy auditStrategy) {
98          Hl7v3AuditDataset auditDataset = null;
99          if (auditStrategy != null) {
100             try {
101                 auditDataset = auditStrategy.createAuditDataset();
102                 MessageContext messageContext = new WebServiceContextImpl().getMessageContext();
103                 HttpServletRequest servletRequest =
104                         (HttpServletRequest) messageContext.get(AbstractHTTPDestination.HTTP_REQUEST);
105                 if (servletRequest != null) {
106                     auditDataset.setRemoteAddress(servletRequest.getRemoteAddr());
107                 }
108 
109                 // The SOAP endpoint URL
110                 auditDataset.setDestinationUserId((String) messageContext.get(Message.REQUEST_URL));
111 
112                 AddressingProperties apropos = (AddressingProperties) messageContext.get(
113                                 JAXWSAConstants.ADDRESSING_PROPERTIES_INBOUND);
114                 if ((apropos != null) && (apropos.getReplyTo() != null) && (apropos.getReplyTo().getAddress() != null)) {
115                     auditDataset.setSourceUserId(apropos.getReplyTo().getAddress().getValue());
116                 }
117 
118                 if (auditDataset.getSourceUserId() == null) {
119                     auditDataset.setSourceUserId("unknown");
120                 }
121 
122                 if (wsTransactionConfiguration.isAuditRequestPayload()) {
123                     auditDataset.setRequestPayload(requestString);
124                 }
125 
126                 auditStrategy.enrichAuditDatasetFromRequest(auditDataset, requestString, null);
127             } catch (Exception e) {
128                 log.error("Phase 1 of server-side ATNA auditing failed", e);
129             }
130         }
131         return auditDataset;
132     }
133 
134 
135     protected void finalizeAtnaAuditing(
136             Object response,
137             Hl7v3AuditStrategy auditStrategy,
138             AuditContext auditContext,
139             Hl7v3AuditDataset auditDataset) {
140         if (auditStrategy != null) {
141             auditStrategy.enrichAuditDatasetFromResponse(auditDataset, response, auditContext);
142             auditStrategy.doAudit(auditContext, auditDataset);
143         }
144     }
145 
146 }