001/** 002 * Copyright 2005-2015 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.impl.bus; 017 018import org.apache.commons.lang.StringUtils; 019import org.apache.cxf.Bus; 020import org.apache.cxf.frontend.ClientProxyFactoryBean; 021import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; 022import org.kuali.rice.core.api.config.property.ConfigContext; 023import org.kuali.rice.core.api.exception.RiceIllegalArgumentException; 024import org.kuali.rice.core.api.exception.RiceRuntimeException; 025import org.kuali.rice.ksb.api.registry.RemoveAndPublishResult; 026import org.kuali.rice.ksb.api.registry.ServiceDescriptor; 027import org.kuali.rice.ksb.api.registry.ServiceEndpoint; 028import org.kuali.rice.ksb.api.registry.ServiceEndpointStatus; 029import org.kuali.rice.ksb.api.registry.ServiceInfo; 030import org.kuali.rice.ksb.api.registry.ServiceRegistry; 031import org.kuali.rice.ksb.impl.cxf.interceptors.ImmutableCollectionsInInterceptor; 032import org.kuali.rice.ksb.security.soap.CXFWSS4JInInterceptor; 033import org.kuali.rice.ksb.security.soap.CXFWSS4JOutInterceptor; 034import org.kuali.rice.ksb.util.KSBConstants; 035 036import javax.xml.namespace.QName; 037import java.util.List; 038 039/** 040 * TODO... 041 * 042 * @author Kuali Rice Team (rice.collab@kuali.org) 043 * 044 */ 045public 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}