View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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.kuali.rice.ksb.messaging.serviceconnectors;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.kuali.rice.core.api.config.property.Config;
21  import org.kuali.rice.core.api.config.property.ConfigContext;
22  import org.kuali.rice.core.api.exception.RiceRuntimeException;
23  import org.kuali.rice.core.api.security.credentials.CredentialsSource;
24  import org.kuali.rice.core.api.security.credentials.CredentialsSourceFactory;
25  import org.kuali.rice.ksb.api.bus.ServiceConfiguration;
26  import org.kuali.rice.ksb.api.bus.ServiceDefinition;
27  import org.kuali.rice.ksb.api.bus.support.JavaServiceConfiguration;
28  import org.kuali.rice.ksb.api.bus.support.RestServiceConfiguration;
29  import org.kuali.rice.ksb.api.bus.support.SoapServiceConfiguration;
30  import org.kuali.rice.ksb.messaging.AlternateEndpoint;
31  import org.kuali.rice.ksb.messaging.AlternateEndpointLocation;
32  import org.kuali.rice.ksb.util.KSBConstants;
33  
34  import java.net.MalformedURLException;
35  import java.net.URL;
36  import java.util.List;
37  import java.util.regex.Matcher;
38  import java.util.regex.Pattern;
39  
40  /**
41   * Constructs a ServiceConnector based on the provided
42   * ServiceInfo/ServiceDefinition. Connects that ServiceConnector to the
43   * appropriate CredentialsSource.
44   * <p>
45   * ServiceConnector will fail if a CredentialsSource for the Service Definition
46   * cannot be located.
47   * 
48   * @author Kuali Rice Team (rice.collab@kuali.org)
49   * 
50   * @since 0.9
51   * @see ServiceConnector
52   * @see ServiceDefinition
53   * @see CredentialsSource
54   */
55  public class ServiceConnectorFactory {
56  
57  	private static final Logger LOG = Logger.getLogger(ServiceConnectorFactory.class);
58  	
59  	public static ServiceConnector getServiceConnector(
60  			final ServiceConfiguration serviceConfiguration) {
61  		final CredentialsSourceFactory credentialsSourceFactory = (CredentialsSourceFactory) ConfigContext
62  				.getCurrentContextConfig().getObjects()
63  				.get(Config.CREDENTIALS_SOURCE_FACTORY);
64  		final CredentialsSource credentialsSource = credentialsSourceFactory != null ? credentialsSourceFactory
65  				.getCredentialsForType(serviceConfiguration.getCredentialsType()) : null;
66  		ServiceConnector serviceConnector = null;
67  
68  		if (serviceConfiguration.getCredentialsType() != null && credentialsSource == null) {
69  			throw new RiceRuntimeException("Service requires credentials but no factory or CredentialsSource could be located.");
70  		}
71  
72  		String alternateEndpoint = determineAlternateEndpoint(serviceConfiguration);
73  		URL alternateEndpointUrl = null;
74  		if (!StringUtils.isBlank(alternateEndpoint)) {
75  			try {
76  				alternateEndpointUrl = new URL(alternateEndpoint);
77  			} catch (MalformedURLException e) {
78  				throw new IllegalStateException("Encountered invalid alternate endpoint url: " + alternateEndpoint, e);
79  			}
80  		}
81  		
82  		// TODO switch this to use serviceConfiguration.getType() at some point in the future and allow for
83  		// this to be easily "pluggable" with new connector types
84  		//
85  		// if set in local mode then preempt any protocol connectors
86  		if (ConfigContext.getCurrentContextConfig().getDevMode()) {
87  			serviceConnector = new BusLocalConnector(serviceConfiguration);
88  		} else if (serviceConfiguration instanceof JavaServiceConfiguration) {
89  			serviceConnector = new HttpInvokerConnector((JavaServiceConfiguration) serviceConfiguration, alternateEndpointUrl);
90  		} else if (serviceConfiguration instanceof SoapServiceConfiguration) {
91  			serviceConnector = new SOAPConnector((SoapServiceConfiguration) serviceConfiguration, alternateEndpointUrl);
92  		} else if (serviceConfiguration instanceof RestServiceConfiguration) {
93  			serviceConnector = new RESTConnector((RestServiceConfiguration) serviceConfiguration, alternateEndpointUrl);
94  		}
95  
96  		if (serviceConnector == null) {
97  			throw new RiceRuntimeException("Don't support service type of "	+ serviceConfiguration);
98  		}
99  		serviceConnector.setCredentialsSource(credentialsSource);
100 
101 		return serviceConnector;
102 	}
103 	
104 	public static String determineAlternateEndpoint(ServiceConfiguration serviceConfiguration) {
105 		String alternateEndpointUrl = null;
106 		List<AlternateEndpointLocation> alternateEndpointLocations = (List<AlternateEndpointLocation>) ConfigContext.getCurrentContextConfig().getObject(KSBConstants.Config.KSB_ALTERNATE_ENDPOINT_LOCATIONS);
107 		if (alternateEndpointLocations != null) {
108 		    for (AlternateEndpointLocation alternateEndpointLocation : alternateEndpointLocations) {
109 		    	if (Pattern.matches(".*" + alternateEndpointLocation.getEndpointHostReplacementPattern() + ".*", serviceConfiguration.getEndpointUrl().toExternalForm())) {
110 		    		Pattern myPattern = Pattern.compile(alternateEndpointLocation.getEndpointHostReplacementPattern());
111 		    		Matcher myMatcher = myPattern.matcher(serviceConfiguration.getEndpointUrl().toExternalForm());
112 		    		String alternateEndpoint = myMatcher.replaceFirst(alternateEndpointLocation.getEndpointHostReplacementValue());
113 		    		if ( LOG.isInfoEnabled() ) {
114 		    			LOG.info("Found an alternate url host value ("
115 		    					+ alternateEndpointLocation.getEndpointHostReplacementValue() + ") for endpoint: "
116 		    					+ serviceConfiguration.getEndpointUrl() + " -> instead using: " + alternateEndpoint);
117 		    		}
118 		    		alternateEndpointUrl = alternateEndpoint;
119 		    		break;
120 		    	}
121 		    }
122 		}
123 		List<AlternateEndpoint> alternateEndpoints = (List<AlternateEndpoint>) ConfigContext.getCurrentContextConfig().getObject(KSBConstants.Config.KSB_ALTERNATE_ENDPOINTS);
124 		if (alternateEndpoints != null) {
125 		    for (AlternateEndpoint alternateEndpoint : alternateEndpoints) {
126 		    	if (Pattern.matches(alternateEndpoint.getEndpointUrlPattern(), serviceConfiguration.getEndpointUrl().toExternalForm())) {
127 		    		if ( LOG.isInfoEnabled() ) {
128 		    			LOG.info("Found an alternate url for endpoint: " + serviceConfiguration.getEndpointUrl() + " -> instead using: " + alternateEndpoint.getActualEndpoint());
129 		    		}
130 		    		alternateEndpointUrl = alternateEndpoint.getActualEndpoint();
131 		    		break;
132 		    	}
133 		    }
134 		}
135 		return alternateEndpointUrl;
136 	}
137 
138 }