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.commons.ihe.ws.cxf.audit;
17  
18  import org.apache.cxf.binding.soap.SoapMessage;
19  import org.apache.cxf.headers.Header;
20  import org.apache.cxf.message.Message;
21  import org.apache.cxf.phase.Phase;
22  import org.apache.cxf.ws.addressing.AddressingProperties;
23  import org.apache.cxf.ws.addressing.JAXWSAConstants;
24  import org.apache.cxf.ws.addressing.Names;
25  import org.openehealth.ipf.commons.audit.AuditContext;
26  import org.openehealth.ipf.commons.ihe.core.atna.AuditStrategy;
27  import org.openehealth.ipf.commons.ihe.ws.WsTransactionConfiguration;
28  import org.openehealth.ipf.commons.ihe.ws.correlation.AsynchronyCorrelator;
29  import org.openehealth.ipf.commons.ihe.ws.cxf.payload.OutPayloadExtractorInterceptor;
30  import org.openehealth.ipf.commons.ihe.ws.cxf.payload.StringPayloadHolder;
31  
32  /**
33   * CXF interceptor for ATNA auditing in WS-based IHE transactions with
34   * WSA asynchrony support.  Handles <b>outgoing</b> requests
35   * on <b>producer</b> side.
36   *
37   * @author Dmytro Rud
38   */
39  public class AuditOutRequestInterceptor<T extends WsAuditDataset> extends AbstractAuditInterceptor<T> {
40      private final AsynchronyCorrelator<T> correlator;
41      private final WsTransactionConfiguration<T> wsTransactionConfiguration;
42  
43      /**
44       * Constructor.
45       */
46      public AuditOutRequestInterceptor(
47              AuditStrategy<T> auditStrategy,
48              AuditContext auditContext,
49              AsynchronyCorrelator<T> correlator,
50              WsTransactionConfiguration<T> wsTransactionConfiguration)
51      {
52          super(Phase.PRE_PROTOCOL_ENDING, auditStrategy, auditContext);
53          addAfter(OutPayloadExtractorInterceptor.class.getName());
54          this.correlator = correlator;
55          this.wsTransactionConfiguration = wsTransactionConfiguration;
56      }
57  
58      
59      @Override
60      protected void process(SoapMessage message) {
61          if (isGET(message)) {
62              return;
63          }
64  
65          T auditDataset = getAuditDataset(message);
66          auditDataset.setRemoteAddress((String) message.get(Message.ENDPOINT_ADDRESS));
67          auditDataset.setDestinationUserId((String) message.get(Message.ENDPOINT_ADDRESS));
68          extractXuaUserNameFromSaml2Assertion(message, Header.Direction.DIRECTION_OUT, auditDataset);
69  
70          Object request = extractPojo(message);
71  
72          // Get request payload, handle different variants thereby:
73          //   a) for HL7v3-based transactions, payload corresponds to the "main" message;
74          //   b) for ebXML-based transactions, rely on the {@link OutPayloadExtractorInterceptor}.
75          if (wsTransactionConfiguration.isAuditRequestPayload()) {
76              if (request instanceof String) {
77                  auditDataset.setRequestPayload((String) request);
78              } else {
79                  auditDataset.setRequestPayload(message.getContent(StringPayloadHolder.class));
80              }
81          }
82  
83          getAuditStrategy().enrichAuditDatasetFromRequest(auditDataset, request, message);
84  
85          // when the invocation is asynchronous: store audit dataset into the correlator
86          AddressingProperties props = (AddressingProperties) message.get(JAXWSAConstants.ADDRESSING_PROPERTIES_OUTBOUND);
87          if (props != null && (Boolean.TRUE.equals(message.getContextualProperty(AsynchronyCorrelator.FORCE_CORRELATION)) ||
88              ! Names.WSA_ANONYMOUS_ADDRESS.equals(props.getReplyTo().getAddress().getValue())))
89          {
90              correlator.storeAuditDataset(props.getMessageID().getValue(), auditDataset);
91          }
92      }
93  
94  }