View Javadoc
1   /*
2    * Copyright 2014 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.mllp.core;
17  
18  import org.apache.camel.api.management.ManagedAttribute;
19  import org.apache.camel.component.mina2.Mina2Endpoint;
20  import org.openehealth.ipf.commons.audit.AuditContext;
21  import org.openehealth.ipf.commons.ihe.core.atna.AuditStrategy;
22  import org.openehealth.ipf.commons.ihe.hl7v2.audit.MllpAuditDataset;
23  import org.openehealth.ipf.commons.ihe.hl7v2.storage.InteractiveContinuationStorage;
24  import org.openehealth.ipf.commons.ihe.hl7v2.storage.UnsolicitedFragmentationStorage;
25  import org.openehealth.ipf.platform.camel.ihe.atna.AuditableEndpoint;
26  import org.openehealth.ipf.platform.camel.ihe.core.Interceptor;
27  import org.openehealth.ipf.platform.camel.ihe.hl7v2.intercept.consumer.*;
28  import org.openehealth.ipf.platform.camel.ihe.hl7v2.intercept.producer.ProducerAdaptingInterceptor;
29  import org.openehealth.ipf.platform.camel.ihe.hl7v2.intercept.producer.ProducerMarshalInterceptor;
30  import org.openehealth.ipf.platform.camel.ihe.hl7v2.intercept.producer.ProducerRequestAcceptanceInterceptor;
31  import org.openehealth.ipf.platform.camel.ihe.hl7v2.intercept.producer.ProducerResponseAcceptanceInterceptor;
32  import org.openehealth.ipf.platform.camel.ihe.mllp.core.intercept.consumer.*;
33  import org.openehealth.ipf.platform.camel.ihe.mllp.core.intercept.producer.ProducerAuditInterceptor;
34  import org.openehealth.ipf.platform.camel.ihe.mllp.core.intercept.producer.ProducerMarshalAndInteractiveResponseReceiverInterceptor;
35  import org.openehealth.ipf.platform.camel.ihe.mllp.core.intercept.producer.ProducerRequestFragmenterInterceptor;
36  import org.openehealth.ipf.platform.camel.ihe.mllp.core.intercept.producer.ProducerStringProcessingInterceptor;
37  
38  import java.util.ArrayList;
39  import java.util.List;
40  
41  /**
42   * Camel endpoint for MLLP-based eHealth transactions (like IHE PIX, PDQ, XAD-PID, etc.).
43   *
44   * @author Dmytro Rud
45   */
46  public class MllpTransactionEndpoint<AuditDatasetType extends MllpAuditDataset>
47          extends MllpEndpoint<MllpTransactionEndpointConfiguration, AuditDatasetType, MllpTransactionComponent<AuditDatasetType>>
48          implements AuditableEndpoint<AuditDatasetType> {
49  
50      /**
51       * Constructor.
52       *
53       * @param mllpComponent   MLLP Component instance which is creating this endpoint.
54       * @param wrappedEndpoint The original camel-mina endpoint instance.
55       * @param config          Configuration parameters.
56       */
57      public MllpTransactionEndpoint(
58              MllpTransactionComponent<AuditDatasetType> mllpComponent,
59              Mina2Endpoint wrappedEndpoint,
60              MllpTransactionEndpointConfiguration config) {
61          super(mllpComponent, wrappedEndpoint, config);
62      }
63  
64  
65      @Override
66      public List<Interceptor> createInitialConsumerInterceptorChain() {
67          List<Interceptor> initialChain = new ArrayList<>();
68          initialChain.add(new ConsumerRequestInteractionSetterInterceptor());
69          initialChain.add(new ConsumerStringProcessingInterceptor());
70          if (isSupportUnsolicitedFragmentation()) {
71              initialChain.add(new ConsumerRequestDefragmenterInterceptor());
72          }
73          initialChain.add(new ConsumerMarshalInterceptor());
74          initialChain.add(new ConsumerRequestAcceptanceInterceptor());
75          if (isSupportInteractiveContinuation()) {
76              initialChain.add(new ConsumerInteractiveResponseSenderInterceptor());
77          }
78          if (isAudit()) {
79              initialChain.add(new ConsumerAuditInterceptor<AuditDatasetType>(getAuditContext()));
80          }
81          initialChain.add(new ConsumerResponseAcceptanceInterceptor());
82          initialChain.add(new ConsumerAdaptingInterceptor(getCharsetName()));
83          if (isAudit()) {
84              initialChain.add(new ConsumerAuthenticationFailureInterceptor(getAuditContext()));
85          }
86          return initialChain;
87      }
88  
89  
90      @Override
91      public List<Interceptor> createInitialProducerInterceptorChain() {
92          List<Interceptor> initialChain = new ArrayList<>();
93          initialChain.add(new ProducerStringProcessingInterceptor());
94          if (isSupportUnsolicitedFragmentation()) {
95              initialChain.add(new ProducerRequestFragmenterInterceptor());
96          }
97          initialChain.add(isSupportInteractiveContinuation()
98                  ? new ProducerMarshalAndInteractiveResponseReceiverInterceptor()
99                  : new ProducerMarshalInterceptor());
100         initialChain.add(new ProducerResponseAcceptanceInterceptor());
101         if (isAudit()) {
102             initialChain.add(new ProducerAuditInterceptor<AuditDatasetType>(getAuditContext()));
103         }
104         initialChain.add(new ProducerRequestAcceptanceInterceptor());
105         initialChain.add(new ProducerAdaptingInterceptor());
106         return initialChain;
107     }
108 
109     @Override
110     public AuditContext getAuditContext() {
111         return getConfig().getAuditContext();
112     }
113 
114     /**
115      * Returns <tt>true</tt> when ATNA auditing should be performed.
116      */
117     @Override
118     @ManagedAttribute(description = "Audit Enabled")
119     public boolean isAudit() {
120         return getAuditContext().isAuditEnabled();
121     }
122 
123     @Override
124     public AuditStrategy<AuditDatasetType> getClientAuditStrategy() {
125         return getMllpComponent().getClientAuditStrategy();
126     }
127 
128     @Override
129     public AuditStrategy<AuditDatasetType> getServerAuditStrategy() {
130         return getMllpComponent().getServerAuditStrategy();
131     }
132 
133     /**
134      * Returns <code>true</code> if this endpoint supports unsolicited message fragmentation.
135      */
136     @ManagedAttribute(description = "Support Unsolicited Fragmentation Enabled")
137     public boolean isSupportUnsolicitedFragmentation() {
138         return getConfig().isSupportUnsolicitedFragmentation();
139     }
140 
141     /**
142      * Returns threshold for unsolicited message fragmentation
143      * (relevant on producer side only).
144      */
145     @ManagedAttribute(description = "Unsolicited Fragmentation Threshold")
146     public int getUnsolicitedFragmentationThreshold() {
147         return getConfig().getUnsolicitedFragmentationThreshold();
148     }
149 
150     /**
151      * Returns the unsolicited fragmentation storage bean.
152      */
153     public UnsolicitedFragmentationStorage getUnsolicitedFragmentationStorage() {
154         return getConfig().getUnsolicitedFragmentationStorage();
155     }
156 
157     @ManagedAttribute(description = "Unsolicited Fragmentation Storage Cache Type")
158     public String getUnsolicitedFragmentationStorageType() {
159         return isSupportUnsolicitedFragmentation() ?
160                 getUnsolicitedFragmentationStorage().getClass().getName() : "";
161     }
162 
163     /**
164      * Returns <code>true</code> if this endpoint supports interactive continuation.
165      */
166     @ManagedAttribute(description = "Support Interactive Continuation Enabled")
167     public boolean isSupportInteractiveContinuation() {
168         return getConfig().isSupportInteractiveContinuation();
169     }
170 
171     /**
172      * Returns default threshold for interactive continuation
173      * (relevant on consumer side only).
174      * <p>
175      * This value will be used when interactive continuation is generally supported
176      * by this endpoint and is particularly applicable for the current response message,
177      * and the corresponding request message does not set the records count threshold
178      * explicitly (RCP-2-1==integer, RCP-2-2=='RD').
179      */
180     @ManagedAttribute(description = "Interactive Continuation Default Threshold")
181     public int getInteractiveContinuationDefaultThreshold() {
182         return getConfig().getInteractiveContinuationDefaultThreshold();
183     }
184 
185     /**
186      * Returns the interactive continuation storage bean.
187      */
188     public InteractiveContinuationStorage getInteractiveContinuationStorage() {
189         return getConfig().getInteractiveContinuationStorage();
190     }
191 
192     /**
193      * Returns true, when the producer should automatically send a cancel
194      * message after it has collected all interactive continuation pieces.
195      */
196     @ManagedAttribute(description = "Auto Cancel Enabled")
197     public boolean isAutoCancel() {
198         return getConfig().isAutoCancel();
199     }
200 
201     @ManagedAttribute(description = "Interactive Continuation Storage Cache Type")
202     public String getInteractiveContinuationStorageType() {
203         return isSupportInteractiveContinuation() ?
204                 getInteractiveContinuationStorage().getClass().getName() : "";
205     }
206 
207 }