001/** 002 * Copyright 2005-2018 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.registry; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.core.api.criteria.QueryByCriteria; 020import org.kuali.rice.core.api.criteria.QueryResults; 021import org.kuali.rice.core.api.exception.RiceIllegalArgumentException; 022import org.kuali.rice.krad.data.DataObjectService; 023import org.kuali.rice.ksb.api.registry.RemoveAndPublishResult; 024import org.kuali.rice.ksb.api.registry.ServiceDescriptor; 025import org.kuali.rice.ksb.api.registry.ServiceEndpoint; 026import org.kuali.rice.ksb.api.registry.ServiceEndpointStatus; 027import org.kuali.rice.ksb.api.registry.ServiceInfo; 028import org.kuali.rice.ksb.api.registry.ServiceRegistry; 029import org.springframework.beans.factory.annotation.Required; 030 031import javax.xml.namespace.QName; 032import java.util.ArrayList; 033import java.util.Collections; 034import java.util.List; 035 036import static org.kuali.rice.core.api.criteria.PredicateFactory.equal; 037 038/** 039 * Reference implementation of the {@link ServiceRegistry} which is backed by a 040 * data access object that handles reading and writing data related to registry 041 * entries from a backend datastore. 042 * 043 * @author Kuali Rice Team (rice.collab@kuali.org) 044 * 045 */ 046public class ServiceRegistryImpl implements ServiceRegistry { 047 048 private DataObjectService dataObjectService; 049 050 @Override 051 public List<ServiceInfo> getOnlineServicesByName(QName serviceName) 052 throws RiceIllegalArgumentException { 053 if (serviceName == null) { 054 throw new RiceIllegalArgumentException("serviceName cannot be null"); 055 } 056 057 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 058 builder.setPredicates(equal("serviceName",serviceName.toString()), 059 equal("statusCode",ServiceEndpointStatus.ONLINE.getCode())); 060 List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching( 061 ServiceInfoBo.class,builder.build()).getResults(); 062 return convertServiceInfoBoList(serviceInfoBos); 063 } 064 065 @Override 066 public List<ServiceInfo> getAllOnlineServices() { 067 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 068 builder.setPredicates(equal("statusCode",ServiceEndpointStatus.ONLINE.getCode())); 069 List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching( 070 ServiceInfoBo.class,builder.build()).getResults(); 071 return convertServiceInfoBoList(serviceInfoBos); 072 } 073 074 @Override 075 public List<ServiceInfo> getAllServices() { 076 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 077 List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching( 078 ServiceInfoBo.class,builder.build()).getResults(); 079 return convertServiceInfoBoList(serviceInfoBos); 080 } 081 082 @Override 083 public List<ServiceInfo> getAllServicesForInstance(String instanceId) throws RiceIllegalArgumentException { 084 if (StringUtils.isBlank(instanceId)) { 085 throw new RiceIllegalArgumentException("instanceId cannot be blank"); 086 } 087 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 088 builder.setPredicates(equal("instanceId",instanceId)); 089 List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching( 090 ServiceInfoBo.class,builder.build()).getResults(); 091 return convertServiceInfoBoList(serviceInfoBos); 092 } 093 094 @Override 095 public List<ServiceInfo> getAllServicesForApplication(String applicationId) throws RiceIllegalArgumentException { 096 if (StringUtils.isBlank(applicationId)) { 097 throw new RiceIllegalArgumentException("applicationId cannot be blank"); 098 } 099 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 100 builder.setPredicates(equal("applicationId",applicationId)); 101 List<ServiceInfoBo> serviceInfoBos = getDataObjectService().findMatching( 102 ServiceInfoBo.class,builder.build()).getResults(); 103 return convertServiceInfoBoList(serviceInfoBos); 104 } 105 106 @Override 107 public ServiceDescriptor getServiceDescriptor(String serviceDescriptorId) 108 throws RiceIllegalArgumentException { 109 if (StringUtils.isBlank(serviceDescriptorId)) { 110 throw new RiceIllegalArgumentException("serviceDescriptorId cannot be blank"); 111 } 112 ServiceDescriptorBo serviceDescriptorBo = getDataObjectService().find( 113 ServiceDescriptorBo.class,serviceDescriptorId); 114 return ServiceDescriptorBo.to(serviceDescriptorBo); 115 } 116 117 @Override 118 public List<ServiceDescriptor> getServiceDescriptors(List<String> serviceDescriptorIds) 119 throws RiceIllegalArgumentException { 120 if (serviceDescriptorIds == null) { 121 throw new RiceIllegalArgumentException("serviceDescriptorIds cannot be null"); 122 } 123 List<ServiceDescriptor> serviceDescriptors = new ArrayList<ServiceDescriptor>(); 124 for (String serviceDescriptorId : serviceDescriptorIds) { 125 ServiceDescriptor serviceDescriptor = getServiceDescriptor(serviceDescriptorId); 126 if (serviceDescriptor != null) { 127 serviceDescriptors.add(serviceDescriptor); 128 } 129 } 130 return Collections.unmodifiableList(serviceDescriptors); 131 } 132 133 @Override 134 public ServiceEndpoint publishService(ServiceEndpoint serviceEndpoint) 135 throws RiceIllegalArgumentException { 136 if (serviceEndpoint == null) { 137 throw new RiceIllegalArgumentException("serviceEndpoint cannot be null"); 138 } 139 ServiceDescriptor serviceDescriptor = serviceEndpoint.getDescriptor(); 140 ServiceDescriptorBo serviceDescriptorBo = ServiceDescriptorBo.from(serviceDescriptor); 141 ServiceInfo serviceInfo = serviceEndpoint.getInfo(); 142 ServiceInfoBo serviceInfoBo = ServiceInfoBo.from(serviceInfo); 143 serviceDescriptorBo = getDataObjectService().save(serviceDescriptorBo); 144 serviceInfoBo.setServiceDescriptorId(serviceDescriptorBo.getId()); 145 serviceInfoBo = getDataObjectService().save(serviceInfoBo); 146 147 148 return ServiceEndpoint.Builder.create(ServiceInfo.Builder.create(serviceInfoBo), 149 ServiceDescriptor.Builder.create(serviceDescriptorBo)).build(); 150 } 151 152 @Override 153 public List<ServiceEndpoint> publishServices(List<ServiceEndpoint> serviceEndpoints) 154 throws RiceIllegalArgumentException { 155 if (serviceEndpoints == null) { 156 throw new RiceIllegalArgumentException("serviceEndpoints cannot be null"); 157 } 158 List<ServiceEndpoint> publishedEndpoints = new ArrayList<ServiceEndpoint>(); 159 for (ServiceEndpoint serviceEndpoint : serviceEndpoints) { 160 publishedEndpoints.add(publishService(serviceEndpoint)); 161 } 162 return publishedEndpoints; 163 } 164 165 @Override 166 public ServiceEndpoint removeServiceEndpoint(String serviceId) 167 throws RiceIllegalArgumentException { 168 if (StringUtils.isBlank(serviceId)) { 169 throw new RiceIllegalArgumentException("serviceId cannot be blank"); 170 } 171 ServiceInfoBo serviceInfoBo = getDataObjectService().find(ServiceInfoBo.class, serviceId); 172 if (serviceInfoBo != null) { 173 ServiceDescriptorBo serviceDescriptorBo = getDataObjectService().find( 174 ServiceDescriptorBo.class,serviceInfoBo.getServiceDescriptorId()); 175 if(serviceDescriptorBo != null) { 176 ServiceEndpoint endpointPriorRemoval = ServiceEndpoint.Builder.create(ServiceInfo.Builder.create(serviceInfoBo), 177 ServiceDescriptor.Builder.create(serviceDescriptorBo)).build(); 178 179 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 180 builder.setPredicates(equal("serviceId",serviceInfoBo.getServiceId())); 181 getDataObjectService().deleteMatching(ServiceInfoBo.class,builder.build()); 182 183 builder = QueryByCriteria.Builder.create(); 184 builder.setPredicates(equal("id",serviceInfoBo.getServiceDescriptorId())); 185 getDataObjectService().deleteMatching(ServiceDescriptorBo.class,builder.build()); 186 return endpointPriorRemoval; 187 }else{ 188 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 189 builder.setPredicates(equal("serviceId",serviceInfoBo.getServiceId())); 190 getDataObjectService().deleteMatching(ServiceInfoBo.class,builder.build()); 191 } 192 } 193 return null; 194 } 195 196 @Override 197 public List<ServiceEndpoint> removeServiceEndpoints(List<String> serviceIds) 198 throws RiceIllegalArgumentException { 199 if (serviceIds == null) { 200 throw new RiceIllegalArgumentException("serviceIds canot be null"); 201 } 202 List<ServiceEndpoint> servicesRemoved = new ArrayList<ServiceEndpoint>(); 203 for (String serviceId : serviceIds) { 204 servicesRemoved.add(removeServiceEndpoint(serviceId)); 205 } 206 return servicesRemoved; 207 } 208 209 @Override 210 public RemoveAndPublishResult removeAndPublish(List<String> removeServiceIds, 211 List<ServiceEndpoint> publishServiceEndpoints) { 212 List<ServiceEndpoint> servicesRemoved = new ArrayList<ServiceEndpoint>(); 213 List<ServiceEndpoint> servicesPublished = new ArrayList<ServiceEndpoint>(); 214 if (removeServiceIds != null && !removeServiceIds.isEmpty()) { 215 servicesRemoved = removeServiceEndpoints(removeServiceIds); 216 } 217 if (publishServiceEndpoints != null && !publishServiceEndpoints.isEmpty()) { 218 servicesPublished = publishServices(publishServiceEndpoints); 219 } 220 return RemoveAndPublishResult.create(servicesRemoved, servicesPublished); 221 } 222 223 @Override 224 public boolean updateStatus(String serviceId, ServiceEndpointStatus status) throws RiceIllegalArgumentException { 225 if (StringUtils.isBlank(serviceId)) { 226 throw new RiceIllegalArgumentException("serviceId cannot be blank"); 227 } 228 if (status == null) { 229 throw new RiceIllegalArgumentException("status cannot be null"); 230 } 231 ServiceInfoBo serviceInfoBo = getDataObjectService().find(ServiceInfoBo.class,serviceId); 232 if (serviceInfoBo == null) { 233 return false; 234 } 235 serviceInfoBo.setStatusCode(status.getCode()); 236 getDataObjectService().save(serviceInfoBo); 237 return true; 238 } 239 240 @Override 241 public List<String> updateStatuses(List<String> serviceIds, ServiceEndpointStatus status) throws RiceIllegalArgumentException { 242 if (serviceIds == null) { 243 throw new RiceIllegalArgumentException("serviceIds canot be null"); 244 } 245 if (status == null) { 246 throw new RiceIllegalArgumentException("status cannot be null"); 247 } 248 List<String> updatedServiceIds = new ArrayList<String>(); 249 for (String serviceId : serviceIds) { 250 if (updateStatus(serviceId, status)) { 251 updatedServiceIds.add(serviceId); 252 } 253 } 254 return Collections.unmodifiableList(updatedServiceIds); 255 } 256 257 @Override 258 public void takeInstanceOffline(String instanceId) 259 throws RiceIllegalArgumentException { 260 if (StringUtils.isBlank(instanceId)) { 261 throw new RiceIllegalArgumentException("instanceId cannot be blank"); 262 } 263 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 264 builder.setPredicates(equal("instanceId", instanceId)); 265 QueryResults<ServiceInfoBo> results = getDataObjectService().findMatching(ServiceInfoBo.class, builder.build()); 266 for (ServiceInfoBo serviceInfo : results.getResults()) { 267 serviceInfo.setStatusCode(ServiceEndpointStatus.OFFLINE.getCode()); 268 getDataObjectService().save(serviceInfo); 269 } 270 } 271 272 private List<ServiceInfo> convertServiceInfoBoList(List<ServiceInfoBo> serviceInfoBos) { 273 List<ServiceInfo> serviceInfos = new ArrayList<ServiceInfo>(); 274 if (serviceInfoBos != null) { 275 for (ServiceInfoBo serviceInfoBo : serviceInfoBos) { 276 serviceInfos.add(ServiceInfoBo.to(serviceInfoBo)); 277 } 278 } else { 279 return Collections.emptyList(); 280 } 281 return Collections.unmodifiableList(serviceInfos); 282 } 283 284 public DataObjectService getDataObjectService() { 285 return dataObjectService; 286 } 287 288 @Required 289 public void setDataObjectService(DataObjectService dataObjectService) { 290 this.dataObjectService = dataObjectService; 291 } 292 293 294 295}