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;
17  
18  import org.apache.cxf.binding.soap.SoapBindingConfiguration;
19  import org.apache.cxf.frontend.ServerFactoryBean;
20  import org.apache.cxf.interceptor.InterceptorProvider;
21  import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
22  import org.apache.cxf.ws.addressing.WSAddressingFeature;
23  import org.openehealth.ipf.commons.audit.AuditContext;
24  import org.openehealth.ipf.commons.ihe.core.atna.AuditStrategy;
25  import org.openehealth.ipf.commons.ihe.ws.cxf.Cxf3791WorkaroundInterceptor;
26  import org.openehealth.ipf.commons.ihe.ws.cxf.RejectionHandlerInterceptor;
27  import org.openehealth.ipf.commons.ihe.ws.cxf.WsRejectionHandlingStrategy;
28  import org.openehealth.ipf.commons.ihe.ws.cxf.audit.WsAuditDataset;
29  import org.openehealth.ipf.commons.ihe.ws.cxf.payload.InPayloadExtractorInterceptor;
30  
31  import java.util.Collections;
32  
33  import static org.openehealth.ipf.commons.ihe.ws.cxf.payload.StringPayloadHolder.PayloadType.HTTP;
34  
35  /**
36   * Factory for Web Services
37   * @author Jens Riemschneider
38   */
39  public class JaxWsServiceFactory<AuditDatasetType extends WsAuditDataset> {
40  
41      /**
42       * Transaction configuration.
43       */
44      protected final WsTransactionConfiguration<AuditDatasetType> wsTransactionConfiguration;
45      /**
46       * Service endpoint address.
47       */
48      protected final String serviceAddress;
49      /**
50       * User-defined custom CXF interceptors.
51       */
52      protected final InterceptorProvider customInterceptors;
53      /**
54       * User-defined strategy for handling rejected messages.
55       */
56      protected final WsRejectionHandlingStrategy rejectionHandlingStrategy;
57      /**
58       * Server-side ATNA audit strategy.
59       */
60      protected final AuditStrategy<AuditDatasetType> auditStrategy;
61  
62      protected final AuditContext auditContext;
63  
64      /**
65       * Constructs the factory.
66       * @param wsTransactionConfiguration
67       *          the info about the service to produce.
68       * @param serviceAddress
69       *          the address of the service that it should be published with.
70       * @param auditStrategy
71       *          server-side ATNA audit strategy.
72       * @param customInterceptors
73       *          user-defined custom CXF interceptors.
74       * @param rejectionHandlingStrategy
75       *          user-defined rejection handling strategy.
76       *
77       */
78      public JaxWsServiceFactory(
79              WsTransactionConfiguration<AuditDatasetType> wsTransactionConfiguration,
80              String serviceAddress,
81              AuditStrategy<AuditDatasetType> auditStrategy,
82              AuditContext auditContext,
83              InterceptorProvider customInterceptors,
84              WsRejectionHandlingStrategy rejectionHandlingStrategy) {
85          this.wsTransactionConfiguration = wsTransactionConfiguration;
86          this.serviceAddress = serviceAddress;
87          this.auditStrategy = auditStrategy;
88          this.auditContext = auditContext;
89          this.customInterceptors = customInterceptors;
90          this.rejectionHandlingStrategy = rejectionHandlingStrategy;
91      }
92      
93      /**
94       * Creates and configures a server factory.
95       * Use the server factory to create a server instance that can be used
96       * to start and stop the service.
97       * @param serviceImplClass
98       *          the type of the service implementation.
99       * @return the server factory.
100      */
101     public ServerFactoryBean createServerFactory(Class<?> serviceImplClass) {
102         try {
103             return createServerFactory(serviceImplClass.newInstance());
104         } catch (InstantiationException | IllegalAccessException e) {
105             throw new IllegalStateException(e);
106         }
107     }
108 
109 
110     public ServerFactoryBean createServerFactory(Object serviceImpl) {
111         ServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
112         configureService(svrFactory, serviceImpl);
113         configureBinding(svrFactory);
114         configureInterceptors(svrFactory);
115         svrFactory.setStart(false);
116         return svrFactory;
117     }
118 
119 
120     private void configureService(ServerFactoryBean svrFactory, Object service) {
121         svrFactory.setServiceClass(wsTransactionConfiguration.getSei());
122         svrFactory.setServiceName(wsTransactionConfiguration.getServiceName());
123         svrFactory.setWsdlLocation(wsTransactionConfiguration.getWsdlLocation());
124         svrFactory.setAddress(serviceAddress);
125         svrFactory.setServiceBean(service);
126         svrFactory.getFeatures().add(new WSAddressingFeature());
127         if (wsTransactionConfiguration.isMtom()) {
128             svrFactory.setProperties(Collections.singletonMap("mtom-enabled", "true"));
129         }
130     }
131 
132     private void configureBinding(ServerFactoryBean svrFactory) {
133         SoapBindingConfiguration bindingConfig = new SoapBindingConfiguration();
134         bindingConfig.setBindingName(wsTransactionConfiguration.getBindingName());
135         svrFactory.setBindingConfig(bindingConfig);
136     }
137 
138     /**
139      * Called to configure any interceptors of the service.
140      * @param svrFactory
141      *          the server factory.
142      */
143     protected void configureInterceptors(ServerFactoryBean svrFactory) {
144         svrFactory.getInInterceptors().add(new Cxf3791WorkaroundInterceptor());
145         InterceptorUtils.copyInterceptorsFromProvider(customInterceptors, svrFactory);
146 
147         if (rejectionHandlingStrategy != null) {
148             svrFactory.getInInterceptors().add(new InPayloadExtractorInterceptor(HTTP));
149 
150             RejectionHandlerInterceptor rejectionHandlerInterceptor =
151                     new RejectionHandlerInterceptor(rejectionHandlingStrategy);
152 
153             svrFactory.getOutInterceptors().add(rejectionHandlerInterceptor);
154             svrFactory.getOutFaultInterceptors().add(rejectionHandlerInterceptor);
155         }
156 
157     }
158 
159 }