1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
33
34
35
36
37
38 public class ServiceRegistryDiffCalculatorImpl implements ServiceRegistryDiffCalculator {
39
40 private static final Logger LOG = Logger.getLogger(ServiceRegistryDiffCalculatorImpl.class);
41
42 private ServiceRegistry serviceRegistry;
43
44 public void setServiceRegistry(ServiceRegistry serviceRegistry) {
45 this.serviceRegistry = serviceRegistry;
46 }
47
48 @Override
49 public CompleteServiceDiff diffServices(String instanceId, List<LocalService> localServices, List<RemoteService> clientRegistryCache) {
50 List<ServiceInfo> allRegistryServicesForInstance = serviceRegistry.getAllServicesForInstance(instanceId);
51 LocalServicesDiff localServicesDiff = calculateLocalServicesDiff(allRegistryServicesForInstance, instanceId, localServices);
52 List<ServiceInfo> allRegistryServices = serviceRegistry.getAllOnlineServices();
53 RemoteServicesDiff remoteServicesDiff = calculateRemoteServicesDiff(allRegistryServices, clientRegistryCache);
54 return new CompleteServiceDiff(localServicesDiff, remoteServicesDiff);
55 }
56
57 protected LocalServicesDiff calculateLocalServicesDiff(List<ServiceInfo> allRegistryServicesForInstance, String instanceId, List<LocalService> localServices) {
58
59 List<ServiceInfo> servicesToRemoveFromRegistry = new ArrayList<ServiceInfo>();
60 List<LocalService> localServicesToPublish = new ArrayList<LocalService>();
61 Map<LocalService, ServiceInfo> localServicesToUpdate = new HashMap<LocalService, ServiceInfo>();
62
63 Map<QName, LocalService> localServiceIndex = indexLocalServices(instanceId, localServices);
64 for (ServiceInfo serviceInfo : allRegistryServicesForInstance) {
65
66 if (!instanceId.equals(serviceInfo.getInstanceId())) {
67 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 LocalService localService = localServiceIndex.get(serviceInfo.getServiceName());
70 if (localService == null) {
71
72 servicesToRemoveFromRegistry.add(serviceInfo);
73 } else {
74
75
76 if (!localService.getServiceEndpoint().getInfo().equals(serviceInfo)) {
77
78 localServicesToUpdate.put(localService, serviceInfo);
79 }
80
81 localServiceIndex.remove(serviceInfo.getServiceName());
82 }
83 }
84
85 localServicesToPublish.addAll(localServiceIndex.values());
86
87 if (LOG.isDebugEnabled()) {
88 LOG.info("For instance '" + instanceId + "', found " + servicesToRemoveFromRegistry.size() + " services to remove from registry, "+
89 localServicesToPublish.size() + " local services to publish");
90 }
91
92 return new LocalServicesDiff(servicesToRemoveFromRegistry, localServicesToPublish, localServicesToUpdate);
93
94 }
95
96 private Map<QName, LocalService> indexLocalServices(String instanceId, List<LocalService> localServices) {
97 Map<QName, LocalService> localServiceIndex = new HashMap<QName, LocalService>(localServices.size());
98 for (LocalService localService : localServices) {
99 String localServiceInstanceId = localService.getServiceEndpoint().getInfo().getInstanceId();
100 if (!instanceId.equals(localServiceInstanceId)) {
101 throw new IllegalStateException("Instance id of local service (" + localServiceInstanceId + ") does not match instance id given to the diff calculator (" + instanceId + ")");
102 }
103 localServiceIndex.put(localService.getServiceName(), localService);
104 }
105 return localServiceIndex;
106 }
107
108 protected List<ServiceInfo> filterServicesForInstance(String instanceId, List<ServiceInfo> allServices) {
109 List<ServiceInfo> filteredServices = new ArrayList<ServiceInfo>();
110 for (ServiceInfo serviceInfo : allServices) {
111 if (instanceId.equals(serviceInfo.getInstanceId())) {
112 filteredServices.add(serviceInfo);
113 }
114 }
115 return filteredServices;
116 }
117
118 protected RemoteServicesDiff calculateRemoteServicesDiff(List<ServiceInfo> allRegistryServices, List<RemoteService> clientRegistryCache) {
119
120 List<ServiceInfo> servicesToAddToClientRegistryCache = new ArrayList<ServiceInfo>(allRegistryServices);
121 List<RemoteService> servicesToRemoveFromClientRegistryCache = new ArrayList<RemoteService>();
122
123 Map<String, ServiceInfo> indexedRegistryServices = indexRegistryServices(allRegistryServices);
124 for (RemoteService remoteService : clientRegistryCache) {
125 ServiceInfo indexedRegistryService = indexedRegistryServices.get(remoteService.getServiceInfo().getServiceId());
126 if (indexedRegistryService == null) {
127 servicesToRemoveFromClientRegistryCache.add(remoteService);
128 } else {
129 if (!remoteService.getServiceInfo().getChecksum().equals(indexedRegistryService.getChecksum())) {
130 servicesToRemoveFromClientRegistryCache.add(remoteService);
131
132 } else {
133 servicesToAddToClientRegistryCache.remove(remoteService.getServiceInfo());
134 }
135 }
136 }
137
138 if (LOG.isDebugEnabled()) {
139 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 return new RemoteServicesDiff(servicesToAddToClientRegistryCache, servicesToRemoveFromClientRegistryCache);
144 }
145
146 private Map<String, ServiceInfo> indexRegistryServices(List<ServiceInfo> allRegistryServices) {
147 Map<String, ServiceInfo> indexedRegistryServices = new HashMap<String, ServiceInfo>(allRegistryServices.size());
148 for (ServiceInfo serviceInfo : allRegistryServices) {
149 indexedRegistryServices.put(serviceInfo.getServiceId(), serviceInfo);
150 }
151 return indexedRegistryServices;
152 }
153
154 }