View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.client.bindings.spi.webservices;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.Map;
24  
25  import javax.net.ssl.HostnameVerifier;
26  import javax.net.ssl.SSLSocketFactory;
27  import javax.xml.namespace.QName;
28  import javax.xml.ws.Binding;
29  import javax.xml.ws.BindingProvider;
30  import javax.xml.ws.soap.MTOMFeature;
31  import javax.xml.ws.soap.SOAPBinding;
32  
33  import org.apache.chemistry.opencmis.client.bindings.impl.CmisBindingsHelper;
34  import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
35  import org.apache.chemistry.opencmis.commons.SessionParameter;
36  import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
37  import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
38  import org.apache.chemistry.opencmis.commons.spi.AuthenticationProvider;
39  import org.apache.cxf.Bus;
40  import org.apache.cxf.configuration.jsse.TLSClientParameters;
41  import org.apache.cxf.endpoint.Client;
42  import org.apache.cxf.frontend.ClientProxy;
43  import org.apache.cxf.headers.Header;
44  import org.apache.cxf.transport.http.HTTPConduit;
45  import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
46  import org.slf4j.Logger;
47  import org.slf4j.LoggerFactory;
48  import org.w3c.dom.Element;
49  
50  /**
51   * Apache CXF JAX-WS implementation.
52   */
53  public class CXFPortProvider extends AbstractPortProvider {
54      private static final Logger LOG = LoggerFactory.getLogger(CXFPortProvider.class);
55  
56      private int contentThreshold;
57      private int responseThreshold;
58  
59      @Override
60      public void setSession(BindingSession session) {
61          super.setSession(session);
62  
63          contentThreshold = session.get(SessionParameter.WEBSERVICES_MEMORY_THRESHOLD, 4 * 1024 * 1024);
64          responseThreshold = session.get(SessionParameter.WEBSERVICES_REPSONSE_MEMORY_THRESHOLD, -1);
65  
66          if (responseThreshold > contentThreshold) {
67              contentThreshold = responseThreshold;
68          }
69      }
70  
71      /**
72       * Creates a port object.
73       */
74      @Override
75      protected BindingProvider createPortObject(CmisServiceHolder serviceHolder) {
76          if (LOG.isDebugEnabled()) {
77              LOG.debug("Session {}: Creating Web Service port object of {} ...", getSession().getSessionId(),
78                      serviceHolder.getServiceName());
79          }
80  
81          try {
82              // create port object
83              BindingProvider portObject = createPortObjectFromServiceHolder(serviceHolder, new MTOMFeature());
84  
85              Binding binding = portObject.getBinding();
86              ((SOAPBinding) binding).setMTOMEnabled(true);
87  
88              Client client = ClientProxy.getClient(portObject);
89              HTTPConduit http = (HTTPConduit) client.getConduit();
90              HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
91              httpClientPolicy.setAllowChunking(true);
92  
93              // temp files and large stream handlding
94              Bus bus = client.getBus();
95  
96              Object tempDir = getSession().get(SessionParameter.WEBSERVICES_TEMP_DIRECTORY);
97              if (tempDir != null) {
98                  bus.setProperty("bus.io.CachedOutputStream.OutputDirectory", tempDir.toString());
99              }
100 
101             if (serviceHolder.getService().handlesContent()) {
102                 bus.setProperty("bus.io.CachedOutputStream.Threshold", String.valueOf(contentThreshold));
103             } else if (responseThreshold > -1) {
104                 bus.setProperty("bus.io.CachedOutputStream.Threshold", String.valueOf(responseThreshold));
105             }
106 
107             bus.setProperty("bus.io.CachedOutputStream.MaxSize", "-1");
108 
109             if (getSession().get(SessionParameter.WEBSERVICES_TEMP_ENCRYPT, false)) {
110                 bus.setProperty("bus.io.CachedOutputStream.CipherTransformation", "AES/CTR/PKCS5Padding");
111             }
112 
113             // add SOAP and HTTP authentication headers
114             AuthenticationProvider authProvider = CmisBindingsHelper.getAuthenticationProvider(getSession());
115             Map<String, List<String>> httpHeaders = null;
116             if (authProvider != null) {
117                 // SOAP header
118                 Element soapHeader = authProvider.getSOAPHeaders(portObject);
119                 if (soapHeader != null) {
120                     List<Header> soapHeaderList = new ArrayList<Header>(2);
121                     soapHeaderList.add(new Header(new QName(soapHeader.getNamespaceURI(), soapHeader.getLocalName()), soapHeader));
122                     portObject.getRequestContext().put(Header.HEADER_LIST, soapHeaderList);
123                 }
124 
125                 // HTTP header
126                 String url = (serviceHolder.getEndpointUrl() != null ? serviceHolder.getEndpointUrl().toString()
127                         : serviceHolder.getServiceObject().getWSDLDocumentLocation().toString());
128                 httpHeaders = authProvider.getHTTPHeaders(url);
129 
130                 // SSL factory and hostname verifier
131                 SSLSocketFactory sslSocketFactory = authProvider.getSSLSocketFactory();
132                 HostnameVerifier hostnameVerifier = authProvider.getHostnameVerifier();
133                 if (sslSocketFactory != null || hostnameVerifier != null) {
134                     TLSClientParameters tlsCP = new TLSClientParameters();
135                     if (sslSocketFactory != null) {
136                         tlsCP.setSSLSocketFactory(sslSocketFactory);
137                     }
138                     if (hostnameVerifier != null) {
139                         tlsCP.setHostnameVerifier(hostnameVerifier);
140                     }
141                     http.setTlsClientParameters(tlsCP);
142                 }
143             }
144 
145             // set HTTP headers
146             setHTTPHeaders(portObject, httpHeaders);
147 
148             // set endpoint URL
149             setEndpointUrl(portObject, serviceHolder.getEndpointUrl());
150 
151             // timeouts
152             int connectTimeout = getSession().get(SessionParameter.CONNECT_TIMEOUT, -1);
153             if (connectTimeout >= 0) {
154                 httpClientPolicy.setConnectionTimeout(connectTimeout);
155             }
156 
157             int readTimeout = getSession().get(SessionParameter.READ_TIMEOUT, -1);
158             if (readTimeout >= 0) {
159                 httpClientPolicy.setReceiveTimeout(readTimeout);
160             }
161 
162             http.setClient(httpClientPolicy);
163 
164             return portObject;
165         } catch (CmisBaseException ce) {
166             throw ce;
167         } catch (Exception e) {
168             throw new CmisConnectionException("Cannot initalize Web Services port object: " + e.getMessage(), e);
169         }
170     }
171 }