1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.openehealth.ipf.platform.camel.ihe.fhir.core;
18
19 import ca.uhn.fhir.context.FhirContext;
20 import ca.uhn.fhir.parser.StrictErrorHandler;
21 import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
22 import ca.uhn.fhir.rest.gclient.IClientExecutable;
23 import lombok.Getter;
24 import org.apache.camel.spi.UriParam;
25 import org.apache.camel.spi.UriParams;
26 import org.apache.camel.util.EndpointHelper;
27 import org.apache.camel.util.jsse.SSLContextParameters;
28 import org.openehealth.ipf.commons.ihe.fhir.AbstractPlainProvider;
29 import org.openehealth.ipf.commons.ihe.fhir.ClientRequestFactory;
30 import org.openehealth.ipf.commons.ihe.fhir.IpfFhirServlet;
31 import org.openehealth.ipf.commons.ihe.fhir.audit.FhirAuditDataset;
32 import org.openehealth.ipf.commons.ihe.fhir.translation.FhirSecurityInformation;
33 import org.openehealth.ipf.platform.camel.ihe.atna.AuditableEndpointConfiguration;
34 import org.openehealth.ipf.platform.camel.ihe.core.AmbiguousBeanException;
35
36 import javax.net.ssl.HostnameVerifier;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.stream.Collectors;
40 import java.util.stream.Stream;
41
42
43
44
45
46
47
48 @UriParams
49 public class FhirEndpointConfiguration<AuditDatasetType extends FhirAuditDataset> extends AuditableEndpointConfiguration {
50
51 static final String STRICT = "strict";
52 static final String LENIENT = "lenient";
53 static final String LAZY_LOAD_BUNDLES = "lazyLoadBundles";
54 static final String CACHE_BUNDLES = "cacheBundles";
55
56 @Getter
57 private final String path;
58
59 @Getter
60 private FhirContext context;
61
62 @Getter
63 @UriParam(defaultValue = "FhirServlet")
64 private String servletName = IpfFhirServlet.DEFAULT_SERVLET_NAME;
65
66 @Getter
67 @UriParam
68 private List<? extends AbstractPlainProvider> resourceProvider;
69
70
71
72 @UriParam
73 private ClientRequestFactory<? extends IClientExecutable<?, ?>> clientRequestFactory;
74
75
76 @Getter
77 @UriParam
78 private List<HapiClientInterceptorFactory> hapiClientInterceptorFactories;
79
80 @Getter
81 @UriParam
82 private List<HapiServerInterceptorFactory> hapiServerInterceptorFactories;
83
84
85
86
87
88 @Getter
89 @UriParam
90 private boolean lazyLoadBundles;
91
92 @Getter
93 private FhirSecurityInformation securityInformation;
94
95
96
97
98
99
100 @Getter
101 @UriParam
102 private boolean cacheBundles = true;
103
104 protected FhirEndpointConfiguration(FhirComponent<AuditDatasetType> component, String path, Map<String, Object> parameters) throws Exception {
105 super(component, parameters);
106 this.path = path;
107 this.context = component.initializeFhirContext();
108
109 servletName = component.getAndRemoveParameter(parameters, "servletName", String.class, IpfFhirServlet.DEFAULT_SERVLET_NAME);
110 resourceProvider = getAndRemoveOrResolveReferenceParameters(component,
111 parameters, "resourceProvider", AbstractPlainProvider.class);
112 clientRequestFactory = component.getAndRemoveOrResolveReferenceParameter(
113 parameters, "clientRequestFactory", ClientRequestFactory.class);
114 hapiClientInterceptorFactories = component.getAndRemoveOrResolveReferenceParameter(
115 parameters, "hapiClientInterceptorFactories", List.class);
116
117 hapiServerInterceptorFactories = component.getAndRemoveOrResolveReferenceParameter(
118 parameters, "hapiServerInterceptorFactories", List.class);
119
120
121 String parserErrorHandling = component.getAndRemoveParameter(parameters, "validation", String.class, "lenient");
122 if (STRICT.equals(parserErrorHandling)) {
123 context.setParserErrorHandler(new StrictErrorHandler());
124 } else if (!LENIENT.equals(parserErrorHandling)) {
125 throw new IllegalArgumentException("Validation must be either " + LENIENT + " (default) or " + STRICT);
126 }
127 Integer connectTimeout = component.getAndRemoveParameter(parameters, "connectionTimeout", Integer.class);
128 if (connectTimeout != null) {
129 setConnectTimeout(connectTimeout);
130 }
131 Integer timeout = component.getAndRemoveParameter(parameters, "timeout", Integer.class);
132 if (timeout != null) {
133 setTimeout(timeout);
134 }
135
136 setDisableServerValidation(component.getAndRemoveParameter(parameters, "disableServerValidation", Boolean.class, false));
137 lazyLoadBundles = component.getAndRemoveParameter(parameters, LAZY_LOAD_BUNDLES, Boolean.class, false);
138 cacheBundles = component.getAndRemoveParameter(parameters, CACHE_BUNDLES, Boolean.class, true);
139
140
141 SSLContextParameters sslContextParameters = component.getAndRemoveOrResolveReferenceParameter(
142 parameters, "sslContextParameters", SSLContextParameters.class);
143 HostnameVerifier hostnameVerifier = component.getAndRemoveOrResolveReferenceParameter(
144 parameters, "hostnameVerifier", HostnameVerifier.class);
145 boolean secure = component.getAndRemoveParameter(parameters, "secure", Boolean.class, false);
146 String username = component.getAndRemoveParameter(parameters, "username", String.class);
147 String password = component.getAndRemoveParameter(parameters, "password", String.class);
148
149 if (sslContextParameters == null) {
150 Map<String, SSLContextParameters> sslContextParameterMap = component.getCamelContext().getRegistry().findByTypeWithName(SSLContextParameters.class);
151 if (sslContextParameterMap.size() == 1) {
152 Map.Entry<String, SSLContextParameters> entry = sslContextParameterMap.entrySet().iterator().next();
153 sslContextParameters = entry.getValue();
154 } else if (sslContextParameterMap.size() > 1) {
155 throw new AmbiguousBeanException(SSLContextParameters.class);
156 }
157 }
158 this.securityInformation = new FhirSecurityInformation(
159 secure,
160 sslContextParameters != null ?
161 sslContextParameters.createSSLContext(component.getCamelContext()) :
162 null,
163 hostnameVerifier,
164 username,
165 password);
166 }
167
168 public <T> List<T> getAndRemoveOrResolveReferenceParameters(FhirComponent<AuditDatasetType> component, Map<String, Object> parameters, String key, Class<T> type) {
169 String values = component.getAndRemoveParameter(parameters, key, String.class);
170 if (values == null) {
171 return null;
172 } else {
173 return Stream.of(values.split(","))
174 .map(value ->
175 EndpointHelper.isReferenceParameter(value) ?
176 EndpointHelper.resolveReferenceParameter(component.getCamelContext(), value, type) :
177 component.getCamelContext().getTypeConverter().convertTo(type, value))
178 .collect(Collectors.toList());
179 }
180 }
181
182 public <T extends IClientExecutable<?, ?>> ClientRequestFactory<T> getClientRequestFactory() {
183 return (ClientRequestFactory<T>) clientRequestFactory;
184 }
185
186 public void setConnectTimeout(int connectTimeout) {
187 context.getRestfulClientFactory().setConnectTimeout(connectTimeout);
188 }
189
190 public void setTimeout(int timeout) {
191 context.getRestfulClientFactory().setSocketTimeout(timeout);
192 }
193
194
195
196
197
198
199
200
201
202
203 public void setDisableServerValidation(boolean disableServerValidation) {
204 context.getRestfulClientFactory().setServerValidationMode(disableServerValidation ?
205 ServerValidationModeEnum.NEVER :
206 ServerValidationModeEnum.ONCE);
207 }
208 }