Coverage Report - org.kuali.rice.ksb.impl.registry.diff.ServiceRegistryDiffCalculatorImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ServiceRegistryDiffCalculatorImpl
74%
43/58
71%
20/28
3.286
 
 1  
 /*
 2  
  * Copyright 2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 1.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/ecl1.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.registry.diff;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 
 23  
 import javax.xml.namespace.QName;
 24  
 
 25  
 import org.apache.log4j.Logger;
 26  
 import org.kuali.rice.ksb.api.registry.ServiceInfo;
 27  
 import org.kuali.rice.ksb.api.registry.ServiceRegistry;
 28  
 import org.kuali.rice.ksb.impl.bus.LocalService;
 29  
 import org.kuali.rice.ksb.impl.bus.RemoteService;
 30  
 
 31  
 /**
 32  
  * Default implementation of the {@link ServiceRegistryDiffCalculator} which calculates
 33  
  * differences between client service bus state and service registry state.
 34  
  * 
 35  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 36  
  *
 37  
  */
 38  9
 public class ServiceRegistryDiffCalculatorImpl implements ServiceRegistryDiffCalculator {
 39  
 
 40  1
         private static final Logger LOG = Logger.getLogger(ServiceRegistryDiffCalculatorImpl.class);
 41  
         
 42  
         private ServiceRegistry serviceRegistry;
 43  
         
 44  
         public void setServiceRegistry(ServiceRegistry serviceRegistry) {
 45  0
                 this.serviceRegistry = serviceRegistry;
 46  0
         }
 47  
         
 48  
         @Override
 49  
         public CompleteServiceDiff diffServices(String instanceId, List<LocalService> localServices, List<RemoteService> clientRegistryCache) {
 50  0
                 List<ServiceInfo> allRegistryServicesForInstance = serviceRegistry.getAllServicesForInstance(instanceId);
 51  0
                 LocalServicesDiff localServicesDiff = calculateLocalServicesDiff(allRegistryServicesForInstance, instanceId, localServices);
 52  0
                 List<ServiceInfo> allRegistryServices = serviceRegistry.getAllOnlineServices();
 53  0
                 RemoteServicesDiff remoteServicesDiff = calculateRemoteServicesDiff(allRegistryServices, clientRegistryCache);
 54  0
                 return new CompleteServiceDiff(localServicesDiff, remoteServicesDiff);
 55  
         }
 56  
         
 57  
         protected LocalServicesDiff calculateLocalServicesDiff(List<ServiceInfo> allRegistryServicesForInstance, String instanceId, List<LocalService> localServices) {
 58  
                 
 59  8
                 List<ServiceInfo> servicesToRemoveFromRegistry = new ArrayList<ServiceInfo>();
 60  8
                 List<LocalService> localServicesToPublish = new ArrayList<LocalService>();
 61  8
                 Map<LocalService, ServiceInfo> localServicesToUpdate = new HashMap<LocalService, ServiceInfo>();
 62  
                 
 63  8
                 Map<QName, LocalService> localServiceIndex = indexLocalServices(instanceId, localServices);
 64  6
                 for (ServiceInfo serviceInfo : allRegistryServicesForInstance) {
 65  
                         // first validate that the service has a valid instance id
 66  11
                         if (!instanceId.equals(serviceInfo.getInstanceId())) {
 67  0
                                 throw new IllegalArgumentException("ServiceInfo given for local service diff does not have a valid instance id.  Should have been '" + instanceId + "' but was '" + serviceInfo.getInstanceId() + "'");
 68  
                         }
 69  11
                         LocalService localService = localServiceIndex.get(serviceInfo.getServiceName());
 70  11
                         if (localService == null) {
 71  
                                 // this means the registry has the service but there is no local service, it has been unregistered
 72  7
                                 servicesToRemoveFromRegistry.add(serviceInfo);
 73  
                         } else {
 74  
                                 // if the LocalService is not null, that means that it exists but it may have changed, or this may be the first time the service
 75  
                                 // is being published upon startup in which case it's service id will be null
 76  4
                                 if (!localService.getServiceEndpoint().getInfo().equals(serviceInfo)) {
 77  
                                         // if the service infos don't match, that means we need to re-publish our current copy of the local service
 78  4
                                         localServicesToUpdate.put(localService, serviceInfo);
 79  
                                 }
 80  
                                 // whether or not it matches, remove it from the index
 81  4
                                 localServiceIndex.remove(serviceInfo.getServiceName());
 82  
                         }
 83  11
                 }
 84  
                 // what's left in the localServiceIndex will be services that weren't in the registry at all, they need to be published
 85  6
                 localServicesToPublish.addAll(localServiceIndex.values());
 86  
                 
 87  6
                 if (LOG.isDebugEnabled()) {
 88  0
                         LOG.info("For instance '" + instanceId + "', found " + servicesToRemoveFromRegistry.size() + " services to remove from registry, "+
 89  
                                 localServicesToPublish.size() + " local services to publish");
 90  
                 }
 91  
                 
 92  6
                 return new LocalServicesDiff(servicesToRemoveFromRegistry, localServicesToPublish, localServicesToUpdate);
 93  
                                 
 94  
         }
 95  
         
 96  
         private Map<QName, LocalService> indexLocalServices(String instanceId, List<LocalService> localServices) {
 97  8
                 Map<QName, LocalService> localServiceIndex = new HashMap<QName, LocalService>(localServices.size());
 98  8
                 for (LocalService localService : localServices) {
 99  12
                         String localServiceInstanceId = localService.getServiceEndpoint().getInfo().getInstanceId(); 
 100  12
                         if (!instanceId.equals(localServiceInstanceId)) {
 101  2
                                 throw new IllegalStateException("Instance id of local service (" + localServiceInstanceId + ") does not match instance id given to the diff calculator (" + instanceId + ")");
 102  
                         }
 103  10
                         localServiceIndex.put(localService.getServiceName(), localService);
 104  10
                 }
 105  6
                 return localServiceIndex;
 106  
         }
 107  
         
 108  
         protected List<ServiceInfo> filterServicesForInstance(String instanceId, List<ServiceInfo> allServices) {
 109  0
                 List<ServiceInfo> filteredServices = new ArrayList<ServiceInfo>();
 110  0
                 for (ServiceInfo serviceInfo : allServices) {
 111  0
                         if (instanceId.equals(serviceInfo.getInstanceId())) {
 112  0
                                 filteredServices.add(serviceInfo);
 113  
                         }
 114  
                 }
 115  0
                 return filteredServices;
 116  
         }
 117  
         
 118  
         protected RemoteServicesDiff calculateRemoteServicesDiff(List<ServiceInfo> allRegistryServices, List<RemoteService> clientRegistryCache) {
 119  
                 
 120  6
                 List<ServiceInfo> servicesToAddToClientRegistryCache = new ArrayList<ServiceInfo>(allRegistryServices);
 121  6
                 List<RemoteService> servicesToRemoveFromClientRegistryCache = new ArrayList<RemoteService>();
 122  
                 
 123  6
                 Map<String, ServiceInfo> indexedRegistryServices = indexRegistryServices(allRegistryServices);
 124  6
                 for (RemoteService remoteService : clientRegistryCache) {
 125  22
                         ServiceInfo indexedRegistryService = indexedRegistryServices.get(remoteService.getServiceInfo().getServiceId());
 126  22
                         if (indexedRegistryService == null) {
 127  9
                                 servicesToRemoveFromClientRegistryCache.add(remoteService);
 128  
                         } else {
 129  13
                                 if (!remoteService.getServiceInfo().getChecksum().equals(indexedRegistryService.getChecksum())) {
 130  4
                                         servicesToRemoveFromClientRegistryCache.add(remoteService);
 131  
                                         
 132  
                                 } else {
 133  9
                                         servicesToAddToClientRegistryCache.remove(remoteService.getServiceInfo());
 134  
                                 }
 135  
                         }
 136  22
                 }
 137  
                 
 138  6
                 if (LOG.isDebugEnabled()) {
 139  0
                         LOG.debug("For instance found " + servicesToRemoveFromClientRegistryCache.size() + " services to remove from client registry cache, "+
 140  
                                 servicesToAddToClientRegistryCache.size() + " services to add to client registry cache");
 141  
                 }
 142  
                 
 143  6
                 return new RemoteServicesDiff(servicesToAddToClientRegistryCache, servicesToRemoveFromClientRegistryCache);
 144  
         }
 145  
         
 146  
         private Map<String, ServiceInfo> indexRegistryServices(List<ServiceInfo> allRegistryServices) {
 147  6
                 Map<String, ServiceInfo> indexedRegistryServices = new HashMap<String, ServiceInfo>(allRegistryServices.size());
 148  6
                 for (ServiceInfo serviceInfo : allRegistryServices) {
 149  20
                         indexedRegistryServices.put(serviceInfo.getServiceId(), serviceInfo);
 150  
                 }
 151  6
                 return indexedRegistryServices;
 152  
         }
 153  
 
 154  
 }