View Javadoc
1   /**
2    * Copyright 2005-2015 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.impl.bus;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.cxf.Bus;
20  import org.apache.cxf.frontend.ClientProxyFactoryBean;
21  import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
22  import org.kuali.rice.core.api.config.property.ConfigContext;
23  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
24  import org.kuali.rice.core.api.exception.RiceRuntimeException;
25  import org.kuali.rice.ksb.api.registry.RemoveAndPublishResult;
26  import org.kuali.rice.ksb.api.registry.ServiceDescriptor;
27  import org.kuali.rice.ksb.api.registry.ServiceEndpoint;
28  import org.kuali.rice.ksb.api.registry.ServiceEndpointStatus;
29  import org.kuali.rice.ksb.api.registry.ServiceInfo;
30  import org.kuali.rice.ksb.api.registry.ServiceRegistry;
31  import org.kuali.rice.ksb.impl.cxf.interceptors.ImmutableCollectionsInInterceptor;
32  import org.kuali.rice.ksb.security.soap.CXFWSS4JInInterceptor;
33  import org.kuali.rice.ksb.security.soap.CXFWSS4JOutInterceptor;
34  import org.kuali.rice.ksb.util.KSBConstants;
35  
36  import javax.xml.namespace.QName;
37  import java.util.List;
38  
39  /**
40   * TODO... 
41   * 
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   *
44   */
45  public class LazyRemoteServiceRegistryConnector implements ServiceRegistry {
46  
47      private static final String SERVICE_REGISTRY_SECURITY_CONFIG = "rice.ksb.serviceRegistry.security";
48  
49  	private final Object initLock = new Object();
50  	private volatile ServiceRegistry delegate;
51  	
52  	// injected
53  	private Bus cxfBus;
54  	
55  	public void setCxfBus(Bus cxfBus) {
56  		this.cxfBus = cxfBus;
57  	}
58  	
59  	@Override
60  	public List<ServiceInfo> getOnlineServicesByName(QName serviceName)
61  			throws RiceIllegalArgumentException {
62  		return getDelegate().getOnlineServicesByName(serviceName);
63  	}
64  
65  	@Override
66  	public List<ServiceInfo> getAllOnlineServices() {
67  		return getDelegate().getAllOnlineServices();
68  	}
69  
70  	@Override
71  	public List<ServiceInfo> getAllServices() {
72  		return getDelegate().getAllServices();
73  	}
74  	
75  	@Override
76  	public List<ServiceInfo> getAllServicesForInstance(String instanceId) {
77  		return getDelegate().getAllServicesForInstance(instanceId);
78  	}
79  
80      @Override
81      public List<ServiceInfo> getAllServicesForApplication(String applicationId) {
82          return getDelegate().getAllServicesForApplication(applicationId);
83      }
84  
85  	@Override
86  	public ServiceDescriptor getServiceDescriptor(String serviceDescriptorId)
87  			throws RiceIllegalArgumentException {
88  		return getDelegate().getServiceDescriptor(serviceDescriptorId);
89  	}
90  
91  	@Override
92  	public List<ServiceDescriptor> getServiceDescriptors(
93  			List<String> serviceDescriptorIds)
94  			throws RiceIllegalArgumentException {
95  		return getDelegate().getServiceDescriptors(serviceDescriptorIds);
96  	}
97  
98  	@Override
99  	public ServiceEndpoint publishService(ServiceEndpoint serviceEndpoint)
100 			throws RiceIllegalArgumentException {
101 		return getDelegate().publishService(serviceEndpoint);
102 	}
103 
104 	@Override
105 	public List<ServiceEndpoint> publishServices(List<ServiceEndpoint> serviceEndpoints)
106 			throws RiceIllegalArgumentException {
107 		return getDelegate().publishServices(serviceEndpoints);
108 	}
109 
110 	@Override
111 	public ServiceEndpoint removeServiceEndpoint(String serviceId)
112 			throws RiceIllegalArgumentException {
113 		return getDelegate().removeServiceEndpoint(serviceId);
114 	}
115 
116 	@Override
117 	public List<ServiceEndpoint> removeServiceEndpoints(List<String> serviceIds)
118 			throws RiceIllegalArgumentException {
119 		return getDelegate().removeServiceEndpoints(serviceIds);
120 	}
121 
122 	@Override
123 	public RemoveAndPublishResult removeAndPublish(List<String> removeServiceIds,
124 			List<ServiceEndpoint> publishServiceEndpoints) {
125 		return getDelegate().removeAndPublish(removeServiceIds, publishServiceEndpoints);
126 	}
127 
128 	@Override
129 	public boolean updateStatus(String serviceId, ServiceEndpointStatus status) throws RiceIllegalArgumentException {
130 		return getDelegate().updateStatus(serviceId, status);
131 	}
132 
133 	@Override
134 	public List<String> updateStatuses(List<String> serviceIds, ServiceEndpointStatus status) throws RiceIllegalArgumentException {
135 		return getDelegate().updateStatuses(serviceIds, status);
136 	}
137 
138 	@Override
139 	public void takeInstanceOffline(String instanceId)
140 			throws RiceIllegalArgumentException {
141         // if Service Registry has not been initialized by this point, do not shutdown
142         if (this.delegate != null) {
143 		    getDelegate().takeInstanceOffline(instanceId);
144         }
145 	}
146 	
147 	private ServiceRegistry getDelegate() {
148 		// double-checked locking idiom - see Effective Java, Item 71
149 		ServiceRegistry internalDelegate = this.delegate;
150 		if (internalDelegate == null) {
151 			synchronized (initLock) {
152 				internalDelegate = this.delegate;
153 				if (internalDelegate == null) {
154 					this.delegate = internalDelegate = initializeRemoteServiceRegistry();
155 				}
156 			}
157 		}
158 		return internalDelegate;
159 	}
160 	
161 	protected ServiceRegistry initializeRemoteServiceRegistry() {
162 		String registryBootstrapUrl = ConfigContext.getCurrentContextConfig().getProperty(KSBConstants.Config.REGISTRY_SERVICE_URL);
163 		if (StringUtils.isBlank(registryBootstrapUrl)) {
164 			throw new RiceRuntimeException("Failed to load registry bootstrap service from url: " + registryBootstrapUrl);
165 		}
166 		ClientProxyFactoryBean clientFactory = new JaxWsProxyFactoryBean();
167 		clientFactory.setServiceClass(ServiceRegistry.class);
168 		clientFactory.setBus(cxfBus);
169 		clientFactory.setAddress(registryBootstrapUrl);
170 
171         boolean registrySecurity = ConfigContext.getCurrentContextConfig().getBooleanProperty(SERVICE_REGISTRY_SECURITY_CONFIG, true);
172 
173 		// Set security interceptors
174 		clientFactory.getOutInterceptors().add(new CXFWSS4JOutInterceptor(registrySecurity));
175 		clientFactory.getInInterceptors().add(new CXFWSS4JInInterceptor(registrySecurity));
176 
177         //Set transformation interceptors
178         clientFactory.getInInterceptors().add(new ImmutableCollectionsInInterceptor());
179 		
180 		Object service = clientFactory.create();
181 		if (!(service instanceof ServiceRegistry)) {
182 			throw new RiceRuntimeException("Endpoint to service registry at URL '" + registryBootstrapUrl + "' was not an instance of ServiceRegistry, instead was: " + service);
183 		}
184 		return (ServiceRegistry)service;
185 	}
186 	
187 }