001 /**
002 * Copyright 2005-2013 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 */
016 package org.kuali.rice.ksb.impl.bus;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.apache.cxf.Bus;
020 import org.apache.cxf.frontend.ClientProxyFactoryBean;
021 import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
022 import org.kuali.rice.core.api.config.property.ConfigContext;
023 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
024 import org.kuali.rice.core.api.exception.RiceRuntimeException;
025 import org.kuali.rice.ksb.api.registry.RemoveAndPublishResult;
026 import org.kuali.rice.ksb.api.registry.ServiceDescriptor;
027 import org.kuali.rice.ksb.api.registry.ServiceEndpoint;
028 import org.kuali.rice.ksb.api.registry.ServiceEndpointStatus;
029 import org.kuali.rice.ksb.api.registry.ServiceInfo;
030 import org.kuali.rice.ksb.api.registry.ServiceRegistry;
031 import org.kuali.rice.ksb.impl.cxf.interceptors.ImmutableCollectionsInInterceptor;
032 import org.kuali.rice.ksb.security.soap.CXFWSS4JInInterceptor;
033 import org.kuali.rice.ksb.security.soap.CXFWSS4JOutInterceptor;
034 import org.kuali.rice.ksb.util.KSBConstants;
035
036 import javax.xml.namespace.QName;
037 import java.util.List;
038
039 /**
040 * TODO...
041 *
042 * @author Kuali Rice Team (rice.collab@kuali.org)
043 *
044 */
045 public class LazyRemoteServiceRegistryConnector implements ServiceRegistry {
046
047 private static final String SERVICE_REGISTRY_SECURITY_CONFIG = "rice.ksb.serviceRegistry.security";
048
049 private final Object initLock = new Object();
050 private volatile ServiceRegistry delegate;
051
052 // injected
053 private Bus cxfBus;
054
055 public void setCxfBus(Bus cxfBus) {
056 this.cxfBus = cxfBus;
057 }
058
059 @Override
060 public List<ServiceInfo> getOnlineServicesByName(QName serviceName)
061 throws RiceIllegalArgumentException {
062 return getDelegate().getOnlineServicesByName(serviceName);
063 }
064
065 @Override
066 public List<ServiceInfo> getAllOnlineServices() {
067 return getDelegate().getAllOnlineServices();
068 }
069
070 @Override
071 public List<ServiceInfo> getAllServices() {
072 return getDelegate().getAllServices();
073 }
074
075 @Override
076 public List<ServiceInfo> getAllServicesForInstance(String instanceId) {
077 return getDelegate().getAllServicesForInstance(instanceId);
078 }
079
080 @Override
081 public List<ServiceInfo> getAllServicesForApplication(String applicationId) {
082 return getDelegate().getAllServicesForApplication(applicationId);
083 }
084
085 @Override
086 public ServiceDescriptor getServiceDescriptor(String serviceDescriptorId)
087 throws RiceIllegalArgumentException {
088 return getDelegate().getServiceDescriptor(serviceDescriptorId);
089 }
090
091 @Override
092 public List<ServiceDescriptor> getServiceDescriptors(
093 List<String> serviceDescriptorIds)
094 throws RiceIllegalArgumentException {
095 return getDelegate().getServiceDescriptors(serviceDescriptorIds);
096 }
097
098 @Override
099 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 }