JaxWsClientInitializer.java
- /*
- * #%L
- * wcm.io
- * %%
- * Copyright (C) 2016 wcm.io
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
- package io.wcm.caravan.jaxws.consumer;
- import java.io.IOException;
- import java.security.GeneralSecurityException;
- import javax.net.ssl.KeyManagerFactory;
- import javax.net.ssl.TrustManagerFactory;
- import javax.xml.ws.BindingProvider;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.lang3.builder.EqualsBuilder;
- import org.apache.commons.lang3.builder.HashCodeBuilder;
- import org.apache.cxf.configuration.jsse.TLSClientParameters;
- import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
- import org.apache.cxf.endpoint.Client;
- import org.apache.cxf.frontend.ClientFactoryBean;
- import org.apache.cxf.frontend.ClientProxy;
- import org.apache.cxf.interceptor.Fault;
- import org.apache.cxf.jaxws.JaxWsClientProxy;
- import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
- import org.apache.cxf.message.Message;
- import org.apache.cxf.phase.AbstractPhaseInterceptor;
- import org.apache.cxf.phase.Phase;
- import org.apache.cxf.transport.http.HTTPConduit;
- import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
- import org.apache.cxf.transports.http.configuration.ProxyServerType;
- import org.apache.cxf.ws.addressing.AddressingProperties;
- import org.apache.cxf.ws.addressing.AttributedURIType;
- import org.apache.cxf.ws.addressing.JAXWSAConstants;
- import org.apache.cxf.ws.addressing.WSAddressingFeature;
- import org.osgi.annotation.versioning.ConsumerType;
- import io.wcm.caravan.jaxws.consumer.impl.CertificateLoader;
- import io.wcm.caravan.jaxws.consumer.impl.OsgiAwareJaxWsClientFactoryBean;
- /**
- * Default JAX-WS SOAP client initializer
- */
- @ConsumerType
- public class JaxWsClientInitializer {
- // Use to disable jaxb default validation for CXF
- private static final String JAXB_VALIDATION = "set-jaxb-validation-event-handler";
- private static final String SCHEMA_VALIDATION = "schema-validation-enabled";
- /**
- * List of properties of this class that contain sensitive information which should not be logged.
- */
- public static final String[] SENSITIVE_PROPERTY_NAMES = new String[] {
- "proxyPassword",
- "certstorePassword",
- "trustStorePassword"
- };
- private int connectTimeout;
- private int socketTimeout;
- private String httpUser;
- private String httpPassword;
- private String proxyHost;
- private int proxyPort;
- private String proxyUser;
- private String proxyPassword;
- private String sslContextType = CertificateLoader.SSL_CONTEXT_TYPE_DEFAULT;
- private String keyManagerType = CertificateLoader.KEY_MANAGER_TYPE_DEFAULT;
- private String keyStoreType = CertificateLoader.KEY_STORE_TYPE_DEFAULT;
- private String keyStoreProvider;
- private String keyStorePath;
- private String keyStorePassword;
- private String trustManagerType = CertificateLoader.TRUST_MANAGER_TYPE_DEFAULT;
- private String trustStoreType = CertificateLoader.TRUST_STORE_TYPE_DEFAULT;
- private String trustStoreProvider;
- private String trustStorePath;
- private String trustStorePassword;
- private String wsAddressingToUri;
- private boolean ignoreUnexpectedElements;
- private boolean allowChunking = true;
- private transient TLSClientParameters tlsClientParameters;
- /**
- * Initialize JAXWS proxy factory bean
- * @param factory JAXWS Proxy factory bean
- */
- public void initializeFactory(JaxWsProxyFactoryBean factory) {
- // set outgoing security (username/password)
- if (StringUtils.isNotEmpty(getHttpUser())) {
- factory.setUsername(getHttpUser());
- factory.setPassword(getHttpPassword());
- }
- // enable WS-addressing
- if (StringUtils.isNotEmpty(getWSAddressingToUri())) {
- factory.getFeatures().add(new WSAddressingFeature());
- }
- }
- /**
- * Initialize SOAP client pFactory and create SOAP client object instance.
- * @param factory JAXWS proxy pFactory bean (has to be already initialized)
- * @return SOAP client object
- */
- public Object createClient(JaxWsProxyFactoryBean factory) {
- try {
- // create port object
- Object portObject = createPortObject(factory);
- // initialize endpiont client
- Client endpointClient = ClientProxy.getClient(portObject);
- initializeEndpointClient(endpointClient);
- // set http settings
- HTTPConduit httpConduit = (HTTPConduit)endpointClient.getConduit();
- initializeHttpConduit(httpConduit);
- // make sure request context is per thread local
- // see http://cxf.apache.org/faq.html#FAQ-AreJAXWSclientproxiesthreadsafe%3F
- ((BindingProvider)portObject).getRequestContext().put(JaxWsClientProxy.THREAD_LOCAL_REQUEST_CONTEXT, Boolean.TRUE);
- // ignore unexpected elements and attributes on data binding
- if (isIgnoreUnexpectedElements()) {
- // disable schema validation to be upward-compatible to future schema changes
- ((BindingProvider)portObject).getRequestContext().put(JAXB_VALIDATION, false);
- ((BindingProvider)portObject).getRequestContext().put(SCHEMA_VALIDATION, false);
- }
- return portObject;
- }
- catch (Throwable ex) {
- throw new JaxWsClientInitializeException("SOAP client initialization failed "
- + "(" + factory.getServiceClass().getName() + ").", ex);
- }
- }
- /**
- * Create port object
- * @param factory JAXWS proxy factory bean
- * @return Port object
- */
- protected Object createPortObject(JaxWsProxyFactoryBean factory) {
- return factory.create();
- }
- /**
- * Initialize endpoint client
- * @param endpointClient Endpoint client
- */
- protected void initializeEndpointClient(Client endpointClient) {
- // set destination address for WS-addressing
- if (StringUtils.isNotEmpty(getWSAddressingToUri())) {
- endpointClient.getOutInterceptors().add(new AbstractPhaseInterceptor<Message>(Phase.SETUP) {
- @Override
- public void handleMessage(Message pMessage) throws Fault {
- AttributedURIType uri = new AttributedURIType();
- uri.setValue(getWSAddressingToUri());
- AddressingProperties maps = new AddressingProperties();
- maps.setTo(uri);
- pMessage.put(JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES, maps);
- }
- });
- }
- // add interceptors
- addInterceptors(endpointClient);
- }
- /**
- * Add interceptors (e.g. for request/response logging)
- * @param endpointClient Endpoint client
- */
- protected void addInterceptors(Client endpointClient) {
- // can be overridden by subclasses
- }
- /**
- * Initialize HTTP conduit
- * @param httpConduit HTTP conduit
- * @throws GeneralSecurityException security exception
- * @throws IOException I/O exception
- */
- protected void initializeHttpConduit(HTTPConduit httpConduit) throws IOException, GeneralSecurityException {
- HTTPClientPolicy clientPolicy = httpConduit.getClient();
- clientPolicy.setAllowChunking(isAllowChunking());
- if (getConnectTimeout() > 0) {
- clientPolicy.setConnectionTimeout(getConnectTimeout());
- }
- if (getSocketTimeout() > 0) {
- clientPolicy.setReceiveTimeout(getSocketTimeout());
- }
- // optionally enable proxy server
- if (StringUtils.isNotEmpty(getProxyHost()) && getProxyPort() > 0) {
- clientPolicy.setProxyServerType(ProxyServerType.HTTP);
- clientPolicy.setProxyServer(getProxyHost());
- clientPolicy.setProxyServerPort(getProxyPort());
- // optionally define proxy authentication
- if (StringUtils.isNotEmpty(getProxyUser())) {
- ProxyAuthorizationPolicy proxyAuthentication = new ProxyAuthorizationPolicy();
- proxyAuthentication.setUserName(getProxyUser());
- proxyAuthentication.setPassword(getProxyPassword());
- httpConduit.setProxyAuthorization(proxyAuthentication);
- }
- }
- // setup TLS - enable certificate for WS access
- if (CertificateLoader.isSslKeyManagerEnabled(this) || CertificateLoader.isSslTrustStoreEnbaled(this)) {
- httpConduit.setTlsClientParameters(getTLSClientParameters());
- }
- }
- /**
- * Get JAX-WS client factory bean instance.
- * @return Client factory bean.
- */
- public ClientFactoryBean createClientFactoryBean() {
- return new OsgiAwareJaxWsClientFactoryBean();
- }
- /**
- * @return Connection timeout in ms.
- */
- public final int getConnectTimeout() {
- return this.connectTimeout;
- }
- /**
- * @param value Connection timeout in ms.
- */
- public final void setConnectTimeout(int value) {
- this.connectTimeout = value;
- }
- /**
- * @return Response timeout in ms.
- */
- public final int getSocketTimeout() {
- return this.socketTimeout;
- }
- /**
- * @param value Response timeout in ms.
- */
- public final void setSocketTimeout(int value) {
- this.socketTimeout = value;
- }
- /**
- * @return Http basic authentication user.
- */
- public final String getHttpUser() {
- return this.httpUser;
- }
- /**
- * @param value Http basic authentication user.
- */
- public final void setHttpUser(String value) {
- this.httpUser = value;
- }
- /**
- * @return Http basic authentication password
- */
- public final String getHttpPassword() {
- return this.httpPassword;
- }
- /**
- * @param value Http basic authentication password
- */
- public final void setHttpPassword(String value) {
- this.httpPassword = value;
- }
- /**
- * @return Proxy host name
- */
- public final String getProxyHost() {
- return this.proxyHost;
- }
- /**
- * @param value Proxy host name
- */
- public final void setProxyHost(String value) {
- this.proxyHost = value;
- }
- /**
- * @return Proxy port
- */
- public final int getProxyPort() {
- return this.proxyPort;
- }
- /**
- * @param value Proxy port
- */
- public final void setProxyPort(int value) {
- this.proxyPort = value;
- }
- /**
- * @return Proxy user name
- */
- public final String getProxyUser() {
- return this.proxyUser;
- }
- /**
- * @param value Proxy user name
- */
- public final void setProxyUser(String value) {
- this.proxyUser = value;
- }
- /**
- * @return Proxy password
- */
- public final String getProxyPassword() {
- return this.proxyPassword;
- }
- /**
- * @param value Proxy password
- */
- public final void setProxyPassword(String value) {
- this.proxyPassword = value;
- }
- /**
- * @return SSL context type (default: TLS)
- */
- public final String getSslContextType() {
- return this.sslContextType;
- }
- /**
- * @param value SSL context type (default: TLS)
- */
- public final void setSslContextType(String value) {
- this.sslContextType = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Key manager type (default: SunX509)
- */
- public final String getKeyManagerType() {
- return this.keyManagerType;
- }
- /**
- * @param value Key manager type (default: SunX509)
- */
- public final void setKeyManagerType(String value) {
- this.keyManagerType = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Key store type (default: PKCS12)
- */
- public final String getKeyStoreType() {
- return this.keyStoreType;
- }
- /**
- * @param value Key store type (default: PKCS12)
- */
- public final void setKeyStoreType(String value) {
- this.keyStoreType = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Key store provider (default: null = use first matching security provider)
- */
- public String getKeyStoreProvider() {
- return this.keyStoreProvider;
- }
- /**
- * @param value Key store provider (default: null = use first matching security provider)
- */
- public void setKeyStoreProvider(String value) {
- this.keyStoreProvider = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Key store file path
- */
- public final String getKeyStorePath() {
- return this.keyStorePath;
- }
- /**
- * @param value Key store file path
- */
- public final void setKeyStorePath(String value) {
- this.keyStorePath = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Key store password
- */
- public final String getKeyStorePassword() {
- return this.keyStorePassword;
- }
- /**
- * @param value Key store password
- */
- public final void setKeyStorePassword(String value) {
- this.keyStorePassword = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Trust manager type (default: SunX509)
- */
- public final String getTrustManagerType() {
- return this.trustManagerType;
- }
- /**
- * @param value Trust manager type (default: SunX509)
- */
- public final void setTrustManagerType(String value) {
- this.trustManagerType = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Trust store type (default: JKS)
- */
- public final String getTrustStoreType() {
- return this.trustStoreType;
- }
- /**
- * @param value Trust store type (default: JKS)
- */
- public final void setTrustStoreType(String value) {
- this.trustStoreType = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Trust store provider (default: null = use first matching security provider)
- */
- public String getTrustStoreProvider() {
- return this.trustStoreProvider;
- }
- /**
- * @param value Trust store provider (default: null = use first matching security provider)
- */
- public void setTrustStoreProvider(String value) {
- this.trustStoreProvider = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Trust store file path
- */
- public final String getTrustStorePath() {
- return this.trustStorePath;
- }
- /**
- * @param value Trust store file path
- */
- public final void setTrustStorePath(String value) {
- this.trustStorePath = value;
- this.tlsClientParameters = null;
- }
- /**
- * @return Trust store password
- */
- public final String getTrustStorePassword() {
- return this.trustStorePassword;
- }
- /**
- * @param vaule Trust store password
- */
- public final void setTrustStorePassword(String vaule) {
- this.trustStorePassword = vaule;
- this.tlsClientParameters = null;
- }
- /**
- * Create TLS client parameters based on given certstore path/password parameters.
- * Caches the parameter in member variable of this factory.
- * @return TLS client parameters
- * @throws IOException I/O exception
- * @throws GeneralSecurityException General security exception
- */
- public final TLSClientParameters getTLSClientParameters() throws IOException, GeneralSecurityException {
- if (tlsClientParameters == null) {
- TLSClientParameters tlsCP = new TLSClientParameters();
- // initialize certstore
- if (CertificateLoader.isSslTrustStoreEnbaled(this)) {
- try {
- KeyManagerFactory keyManagerFactory = CertificateLoader.getKeyManagerFactory(this);
- tlsCP.setKeyManagers(keyManagerFactory.getKeyManagers());
- }
- catch (Throwable ex) {
- throw new RuntimeException("Unable to initialize certificate store for SOAP endpoint.\n"
- + "Please check configuration parameters 'certstorePath' and 'certstorePassword' in this config:\n"
- + this.toString(), ex);
- }
- }
- // initialize trustStore
- if (CertificateLoader.isSslTrustStoreEnbaled(this)) {
- try {
- TrustManagerFactory trustManagerFactory = CertificateLoader.getTrustManagerFactory(this);
- tlsCP.setTrustManagers(trustManagerFactory.getTrustManagers());
- }
- catch (Throwable ex) {
- throw new RuntimeException("Unable to initialize trust store for SOAP endpoint.\n"
- + "Please check configuration parameters 'trustStorePath' and 'trustStorePassword' in this config:\n"
- + this.toString(), ex);
- }
- }
- tlsClientParameters = tlsCP;
- }
- return tlsClientParameters;
- }
- /**
- * @param value CXF TSL client parameters
- */
- public final void setTLSClientParameters(TLSClientParameters value) {
- this.tlsClientParameters = value;
- }
- /**
- * @return Addressing-To URI to be sent as WS-Adressing header
- */
- public final String getWSAddressingToUri() {
- return this.wsAddressingToUri;
- }
- /**
- * @param value Addressing-To URI to be sent as WS-Adressing header
- */
- public final void setWSAddressingToUri(String value) {
- this.wsAddressingToUri = value;
- }
- /**
- * @return If true compatibility mode for WSDL/schema changes is activated.
- * If the SOAP server returns unknown XML element they are ignored during validation.
- */
- public final boolean isIgnoreUnexpectedElements() {
- return this.ignoreUnexpectedElements;
- }
- /**
- * @param value If true compatibility mode for WSDL/schema changes is activated.
- * If the SOAP server returns unknown XML element they are ignored during validation.
- */
- public final void setIgnoreUnexpectedElements(boolean value) {
- this.ignoreUnexpectedElements = value;
- }
- /**
- * @return Allow HTTP 1.1 chunking
- */
- public final boolean isAllowChunking() {
- return this.allowChunking;
- }
- /**
- * @param value Allow HTTP 1.1 chunking
- */
- public final void setAllowChunking(boolean value) {
- this.allowChunking = value;
- }
- @Override
- public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this, false);
- }
- @Override
- public boolean equals(Object pObj) {
- return EqualsBuilder.reflectionEquals(this, pObj, false);
- }
- }