001/**
002 * Copyright 2005-2017 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.ksb.messaging.serviceconnectors;
017
018import org.apache.http.client.HttpClient;
019import org.apache.http.impl.client.HttpClientBuilder;
020import org.apache.log4j.Logger;
021import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
022import org.kuali.rice.ksb.api.bus.support.JavaServiceConfiguration;
023import org.kuali.rice.ksb.messaging.KSBHttpInvokerProxyFactoryBean;
024import org.kuali.rice.ksb.messaging.KSBHttpInvokerRequestExecutor;
025import org.kuali.rice.ksb.security.httpinvoker.AuthenticationCommonsHttpInvokerRequestExecutor;
026
027import java.net.URL;
028
029/**
030 * @author Kuali Rice Team (rice.collab@kuali.org)
031 * @since 0.9
032 */
033public class HttpInvokerConnector extends AbstractServiceConnector {
034
035        private static final Logger LOG = Logger.getLogger(HttpInvokerConnector.class);
036
037    private static final String HTTP_CLIENT_CONFIG_BEAN = "rice.ksb.httpClientConfigurer";
038
039    /**
040     * Constructs an HttpInvokerConnector.
041     *
042     * @param serviceConfiguration the JavaServiceConfiguration
043     * @param alternateEndpointUrl an alternate URL to use for the service endpoint
044     */
045    public HttpInvokerConnector(final JavaServiceConfiguration serviceConfiguration, final URL alternateEndpointUrl) {
046                super(serviceConfiguration, alternateEndpointUrl);
047    }
048
049    @Override
050        public JavaServiceConfiguration getServiceConfiguration() {
051                return (JavaServiceConfiguration) super.getServiceConfiguration();
052        }
053        
054        public Object getService() {
055            LOG.debug("Getting connector for endpoint " + getActualEndpointUrl());
056                KSBHttpInvokerProxyFactoryBean client = new KSBHttpInvokerProxyFactoryBean();
057                client.setServiceUrl(getActualEndpointUrl().toExternalForm());
058                client.setServiceConfiguration(getServiceConfiguration());
059                
060                KSBHttpInvokerRequestExecutor executor;
061                
062                if (getCredentialsSource() != null) {
063                    executor = new AuthenticationCommonsHttpInvokerRequestExecutor(getHttpClient(), getCredentialsSource(), getServiceConfiguration());
064                } else {
065                    executor = new KSBHttpInvokerRequestExecutor(getHttpClient());
066                }
067                executor.setSecure(getServiceConfiguration().getBusSecurity());
068                client.setHttpInvokerRequestExecutor(executor); 
069                client.afterPropertiesSet();
070                return getServiceProxyWithFailureMode(client.getObject(), getServiceConfiguration());
071        }
072
073        /**
074         * Creates a httpcomponents HttpClient for service invocation.
075     *
076     * <p>The client is configured by the HttpClientConfigurer</p>
077         */
078        public HttpClient getHttpClient() {
079        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
080
081        getHttpClientConfigurer().customizeHttpClient(httpClientBuilder);
082
083        return httpClientBuilder.build();
084        }
085
086    /**
087     * Lazy initialization holder class idiom for static fields, see Effective Java item 71
088     */
089    private static class HttpClientConfigurerHolder {
090        static final HttpClientConfigurer httpClientConfigurer =
091                GlobalResourceLoader.getService(HTTP_CLIENT_CONFIG_BEAN);
092    }
093
094    /**
095     * Gets the HttpClientConfigurer that will be used to customize http clients.
096     *
097     * <p>On first call, the bean specified by {@link #HTTP_CLIENT_CONFIG_BEAN} will be lazily assigned and returned.</p>
098     *
099     * @return the HttpClientConfigurer
100     */
101    private static HttpClientConfigurer getHttpClientConfigurer() {
102        return HttpClientConfigurerHolder.httpClientConfigurer;
103    }
104}