1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.ksb.impl.bus.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.commons.collections.MapUtils;
26 import org.apache.log4j.Logger;
27 import org.kuali.rice.ksb.api.registry.ServiceInfo;
28 import org.kuali.rice.ksb.api.registry.ServiceRegistry;
29 import org.kuali.rice.ksb.impl.bus.LocalService;
30 import org.kuali.rice.ksb.impl.bus.RemoteService;
31
32
33
34
35
36
37
38
39 public class ServiceRegistryDiffCalculatorImpl implements ServiceRegistryDiffCalculator {
40
41 private static final Logger LOG = Logger.getLogger(ServiceRegistryDiffCalculatorImpl.class);
42
43 private ServiceRegistry serviceRegistry;
44
45 public void setServiceRegistry(ServiceRegistry serviceRegistry) {
46 this.serviceRegistry = serviceRegistry;
47 }
48
49 @Override
50 public CompleteServiceDiff diffServices(String instanceId, List<LocalService> localServices, List<RemoteService> clientRegistryCache) {
51 List<ServiceInfo> allRegistryServices = serviceRegistry.getAllOnlineServices();
52 List<ServiceInfo> allRegistryServicesForInstance = serviceRegistry.getAllServicesForInstance(instanceId);
53 LocalServicesDiff localServicesDiff = calculateLocalServicesDiff(allRegistryServicesForInstance, instanceId, localServices);
54 RemoteServicesDiff remoteServicesDiff = calculateRemoteServicesDiff(allRegistryServices, clientRegistryCache);
55 return new CompleteServiceDiff(localServicesDiff, remoteServicesDiff);
56 }
57
58 protected LocalServicesDiff calculateLocalServicesDiff(List<ServiceInfo> allRegistryServicesForInstance, String instanceId, List<LocalService> localServices) {
59
60 List<ServiceInfo> servicesToRemoveFromRegistry = new ArrayList<ServiceInfo>();
61 List<LocalService> localServicesToPublish = new ArrayList<LocalService>();
62 Map<LocalService, ServiceInfo> localServicesToUpdate = new HashMap<LocalService, ServiceInfo>();
63
64 Map<QName, LocalService> localServiceIndex = indexLocalServices(instanceId, localServices);
65 for (ServiceInfo serviceInfo : allRegistryServicesForInstance) {
66
67 if (!instanceId.equals(serviceInfo.getInstanceId())) {
68 StringBuffer errorMessage = new StringBuffer("ServiceInfo given for local service diff does not have a valid instance id. Should have been '" + instanceId + "' but was '" + serviceInfo.getInstanceId() + "'");
69 if (serviceInfo.getInstanceId() == null) {
70 errorMessage.append(" Null instanceIds can be the result of multiple asm.jars or none in the classpath.");
71 }
72 throw new IllegalArgumentException(errorMessage.toString());
73 }
74 LocalService localService = localServiceIndex.get(serviceInfo.getServiceName());
75 if (localService == null) {
76
77 servicesToRemoveFromRegistry.add(serviceInfo);
78 } else {
79
80
81 if (!localService.getServiceEndpoint().getInfo().equals(serviceInfo)) {
82
83 localServicesToUpdate.put(localService, serviceInfo);
84 }
85
86 localServiceIndex.remove(serviceInfo.getServiceName());
87 }
88 }
89
90 localServicesToPublish.addAll(localServiceIndex.values());
91
92 if (LOG.isDebugEnabled()) {
93 LOG.info("For instance '" + instanceId + "', found " + servicesToRemoveFromRegistry.size() + " services to remove from registry, "+
94 localServicesToPublish.size() + " local services to publish");
95 }
96
97 return new LocalServicesDiff(servicesToRemoveFromRegistry, localServicesToPublish, localServicesToUpdate);
98
99 }
100
101 private Map<QName, LocalService> indexLocalServices(String instanceId, List<LocalService> localServices) {
102 Map<QName, LocalService> localServiceIndex = new HashMap<QName, LocalService>(localServices.size());
103 for (LocalService localService : localServices) {
104 String localServiceInstanceId = localService.getServiceEndpoint().getInfo().getInstanceId();
105 if (!instanceId.equals(localServiceInstanceId)) {
106 throw new IllegalStateException("Instance id of local service (" + localServiceInstanceId + ") does not match instance id given to the diff calculator (" + instanceId + ")");
107 }
108 localServiceIndex.put(localService.getServiceName(), localService);
109 }
110 return localServiceIndex;
111 }
112
113 protected RemoteServicesDiff calculateRemoteServicesDiff(List<ServiceInfo> allRegistryServices, List<RemoteService> clientRegistryCache) {
114
115 Map<String, ServiceInfo> indexedRegistryServices = indexRegistryServices(allRegistryServices);
116 Map<String, ServiceInfo> servicesToAddToClientRegistryCache = new HashMap<String, ServiceInfo>(indexedRegistryServices);
117 List<RemoteService> servicesToRemoveFromClientRegistryCache = new ArrayList<RemoteService>();
118
119 for (RemoteService remoteService : clientRegistryCache) {
120 ServiceInfo indexedRegistryService = indexedRegistryServices.get(remoteService.getServiceInfo().getServiceId());
121 if (indexedRegistryService == null) {
122 servicesToRemoveFromClientRegistryCache.add(remoteService);
123 } else {
124 if (!remoteService.getServiceInfo().getChecksum().equals(indexedRegistryService.getChecksum())) {
125 servicesToRemoveFromClientRegistryCache.add(remoteService);
126 } else {
127 servicesToAddToClientRegistryCache.remove(remoteService.getServiceInfo().getServiceId());
128 }
129 }
130 }
131
132 if (LOG.isDebugEnabled()) {
133 LOG.debug("For instance found " + servicesToRemoveFromClientRegistryCache.size() + " services to remove from client registry cache, "+
134 servicesToAddToClientRegistryCache.size() + " services to add to client registry cache");
135 }
136
137 return new RemoteServicesDiff(new ArrayList<ServiceInfo>(servicesToAddToClientRegistryCache.values()),
138 servicesToRemoveFromClientRegistryCache);
139 }
140
141 private Map<String, ServiceInfo> indexRegistryServices(List<ServiceInfo> allRegistryServices) {
142 Map<String, ServiceInfo> indexedRegistryServices = new HashMap<String, ServiceInfo>(allRegistryServices.size());
143 for (ServiceInfo serviceInfo : allRegistryServices) {
144 indexedRegistryServices.put(serviceInfo.getServiceId(), serviceInfo);
145 }
146 return indexedRegistryServices;
147 }
148
149 }