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  
17  package org.openehealth.ipf.platform.camel.ihe.mllp.core;
18  
19  import lombok.Getter;
20  import org.apache.camel.util.EndpointHelper;
21  import org.apache.camel.util.jsse.ClientAuthentication;
22  import org.apache.camel.util.jsse.SSLContextParameters;
23  import org.apache.mina.filter.codec.ProtocolCodecFactory;
24  import org.openehealth.ipf.commons.ihe.core.ClientAuthType;
25  import org.openehealth.ipf.platform.camel.ihe.atna.AuditableEndpointConfiguration;
26  import org.openehealth.ipf.platform.camel.ihe.core.AmbiguousBeanException;
27  import org.openehealth.ipf.platform.camel.ihe.mllp.core.intercept.consumer.ConsumerDispatchingInterceptor;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  import javax.net.ssl.SSLContext;
32  import java.util.Map;
33  
34  /**
35   * Configuration of an MLLP endpoint.
36   *
37   * @author Dmytro Rud
38   */
39  public class MllpEndpointConfiguration extends AuditableEndpointConfiguration {
40  
41      private static final long serialVersionUID = -3604219045768985192L;
42      private static final Logger LOG = LoggerFactory.getLogger(MllpEndpointConfiguration.class);
43      protected static final String UNKNOWN_URI = "unknown";
44  
45      @Getter
46      private final ProtocolCodecFactory codecFactory;
47      @Getter
48      private final SSLContext sslContext;
49      @Getter
50      private final ClientAuthType clientAuthType;
51      @Getter
52      private final String[] sslProtocols;
53      @Getter
54      private final String[] sslCiphers;
55  
56      @Getter
57      private final boolean supportSegmentFragmentation;
58      @Getter
59      private final int segmentFragmentationThreshold;
60  
61      @Getter
62      private ConsumerDispatchingInterceptor dispatcher;
63  
64      /**
65       * @deprecated
66       */
67      protected MllpEndpointConfiguration(MllpComponent<?, ?> component, Map<String, Object> parameters) throws Exception {
68          this(component, UNKNOWN_URI, parameters);
69      }
70  
71      protected MllpEndpointConfiguration(MllpComponent<?, ?> component, String uri, Map<String, Object> parameters) throws Exception {
72          super(component, parameters);
73          codecFactory = EndpointHelper.resolveReferenceParameter(component.getCamelContext(), (String)parameters.get("codec"), ProtocolCodecFactory.class);
74  
75          // Will only be effective if sslContext is set and overrides
76          String sslProtocolsString = component.getAndRemoveParameter(parameters, "sslProtocols", String.class, null);
77          String sslCiphersString = component.getAndRemoveParameter(parameters, "sslCiphers", String.class, null);
78          this.sslProtocols = sslProtocolsString != null ? sslProtocolsString.split("\\s*,\\s*") : null;
79          this.sslCiphers = sslCiphersString != null ? sslCiphersString.split("\\s*,\\s*") : null;
80  
81          ClientAuthType configuredClientAuthType = component.getAndRemoveParameter(parameters, "clientAuth", ClientAuthType.class, ClientAuthType.NONE);
82          boolean secure = component.getAndRemoveParameter(parameters, "secure", boolean.class, false);
83          SSLContextParameters configuredSslContextParameters = component.resolveAndRemoveReferenceParameter(parameters, "sslContextParameters", SSLContextParameters.class);
84          SSLContext configuredSslContext = component.resolveAndRemoveReferenceParameter(parameters, "sslContext", SSLContext.class);
85  
86          if (secure || configuredSslContextParameters != null || configuredSslContext != null) {
87              LOG.debug("Setting up TLS security for MLLP endpoint {}", uri);
88              if (configuredSslContext == null) {
89                  if (configuredSslContextParameters == null) {
90                      Map<String, SSLContextParameters> sslContextParameterMap = component.getCamelContext().getRegistry().findByTypeWithName(SSLContextParameters.class);
91                      if (sslContextParameterMap.size() == 1) {
92                          Map.Entry<String, SSLContextParameters> entry = sslContextParameterMap.entrySet().iterator().next();
93                          configuredSslContextParameters = entry.getValue();
94                          LOG.debug("Setting up SSLContext from SSLContextParameters bean with name {}", entry.getKey());
95                      } else if (sslContextParameterMap.size() > 1) {
96                          throw new AmbiguousBeanException(SSLContextParameters.class);
97                      }
98                  } else {
99                      LOG.debug("Setting up SSLContext from SSLContextParameters provided in endpoint URI");
100                 }
101                 if (configuredSslContextParameters == null) {
102                     LOG.debug("Setting up default SSLContext");
103                     configuredSslContext = SSLContext.getDefault();
104                 } else {
105                     configuredSslContext = configuredSslContextParameters.createSSLContext(component.getCamelContext());
106                     // If not already specified, extract client authentication
107                     if (configuredClientAuthType == null) {
108                         String clientAuthenticationString = configuredSslContextParameters.getServerParameters().getClientAuthentication();
109                         if (clientAuthenticationString != null) {
110                             ClientAuthentication clientAuthentication = ClientAuthentication.valueOf(clientAuthenticationString.toUpperCase());
111                             switch (clientAuthentication) {
112                                 case WANT: configuredClientAuthType = ClientAuthType.WANT; break;
113                                 case REQUIRE: configuredClientAuthType = ClientAuthType.MUST; break;
114                                 case NONE: configuredClientAuthType = ClientAuthType.NONE;
115                             }
116                         }
117                     }
118 
119                 }
120             }
121             this.sslContext = configuredSslContext;
122         } else {
123             this.sslContext = null;
124         }
125 
126         clientAuthType = configuredClientAuthType;
127         supportSegmentFragmentation = component.getAndRemoveParameter(
128                 parameters, "supportSegmentFragmentation", boolean.class, false);
129         segmentFragmentationThreshold = component.getAndRemoveParameter(
130                 parameters, "segmentFragmentationThreshold", int.class, -1);                // >= 5 characters
131 
132         dispatcher = component.resolveAndRemoveReferenceParameter(parameters, "dispatcher", ConsumerDispatchingInterceptor.class);
133 
134     }
135 
136 }