001: /*
002: * Copyright 2007 The Kuali Foundation
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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: */
016: package edu.iu.uis.eden.messaging;
017:
018: import java.util.ArrayList;
019: import java.util.HashMap;
020: import java.util.List;
021: import java.util.Map;
022:
023: import javax.xml.namespace.QName;
024:
025: import org.kuali.rice.exceptions.RiceRuntimeException;
026:
027: /**
028: * Takes two lists of ServiceInfo objects. One from the service def table and one from a piece
029: * of code and diffs the two.
030: *
031: *
032: * @author Kuali Rice Team (kuali-rice@googlegroups.com)
033: *
034: */
035: public class RoutingTableDiffCalculator {
036:
037: private List<ServiceInfo> servicesNeedUpdated = new ArrayList<ServiceInfo>();
038: private List<ServiceInfo> servicesNeedRemoved = new ArrayList<ServiceInfo>();
039: private List<ServiceInfo> masterServiceList = new ArrayList<ServiceInfo>();
040:
041: public boolean calculateClientSideUpdate(
042: Map<QName, List<RemotedServiceHolder>> clients,
043: List<ServiceInfo> fetchedServiceInfos) {
044: List<ServiceInfo> clientServiceList = deconstructRemoteServiceLocatorClientMap(clients);
045: if (clientServiceList.isEmpty()
046: && !fetchedServiceInfos.isEmpty()) {
047: return true;
048: }
049: Map<String, ServiceInfo> configuredServices = getRemotedService(clientServiceList);
050: Map<String, ServiceInfo> deployedServices = getRemotedService(fetchedServiceInfos);
051: for (Map.Entry<String, ServiceInfo> infoEntry : configuredServices
052: .entrySet()) {
053: if (deployedServices.containsKey(infoEntry.getKey())) {
054: ServiceInfo deployedServiceInfo = deployedServices
055: .get(infoEntry.getKey());
056: if (!isSame(infoEntry.getValue(), deployedServiceInfo)) {
057: return true;
058: }
059: } else {
060: return true;
061: }
062: }
063:
064: //iterate the bus services and make sure the configured services represent the fetched ones
065: for (Map.Entry<String, ServiceInfo> info : deployedServices
066: .entrySet()) {
067: if (!configuredServices.containsKey(info.getKey())) {
068: return true;
069: }
070: }
071:
072: return false;
073: }
074:
075: private List<ServiceInfo> deconstructRemoteServiceLocatorClientMap(
076: Map<QName, List<RemotedServiceHolder>> clients) {
077: List<ServiceInfo> clientServices = new ArrayList<ServiceInfo>();
078: for (List<RemotedServiceHolder> remoteServiceHolders : clients
079: .values()) {
080: for (RemotedServiceHolder holder : remoteServiceHolders) {
081: clientServices.add(holder.getServiceInfo());
082: }
083: }
084: return clientServices;
085: }
086:
087: public boolean calculateServerSideUpdateLists(
088: List<ServiceInfo> memoryServiceInfos,
089: List<ServiceInfo> fetchedServiceInfos) {
090: Map<String, ServiceInfo> configuredServices = getRemotedService(memoryServiceInfos);
091: Map<String, ServiceInfo> deployedServices = getRemotedService(fetchedServiceInfos);
092:
093: //iterate the configured services vs. the deployed services
094: for (Map.Entry<String, ServiceInfo> infoEntry : configuredServices
095: .entrySet()) {
096: if (deployedServices.containsKey(infoEntry.getKey())) {
097: ServiceInfo deployedServiceInfo = deployedServices
098: .get(infoEntry.getKey());
099: if (!isSame(infoEntry.getValue(), deployedServiceInfo)) {
100: this .servicesNeedUpdated.add(deployedServiceInfo);
101: }
102: updateDeployedServiceInfo(infoEntry.getValue(),
103: deployedServiceInfo);
104: this .masterServiceList.add(deployedServiceInfo);
105: } else {
106: this .servicesNeedUpdated.add(infoEntry.getValue());
107: this .masterServiceList.add(infoEntry.getValue());
108: }
109: }
110:
111: //compare fetched vs. configured and determine if any fetched services need removed
112: for (Map.Entry<String, ServiceInfo> infoEntry : deployedServices
113: .entrySet()) {
114: if (!configuredServices.containsKey(infoEntry.getKey())) {
115: this .servicesNeedRemoved.add(infoEntry.getValue());
116: }
117: }
118:
119: return !(this .servicesNeedRemoved.isEmpty() && this .servicesNeedUpdated
120: .isEmpty());
121: }
122:
123: public Map<String, ServiceInfo> getRemotedService(
124: List<ServiceInfo> serviceInfos) {
125: Map<String, ServiceInfo> serviceMap = new HashMap<String, ServiceInfo>();
126: for (ServiceInfo info : serviceInfos) {
127: String endpointURL = info.getEndpointUrl();
128: if (serviceMap.containsKey(endpointURL)) {
129: throw new RiceRuntimeException(
130: "Multiple services with same endpoint url declared and saved in routing table. "
131: + "Stopping service registration. Endpoint "
132: + endpointURL);
133: }
134:
135: serviceMap.put(endpointURL, info);
136: }
137: return serviceMap;
138: }
139:
140: private void updateDeployedServiceInfo(
141: ServiceInfo configuredServiceInfo,
142: ServiceInfo deployedServiceInfo) {
143: deployedServiceInfo.setAlive(configuredServiceInfo.getAlive());
144: deployedServiceInfo.setQname(configuredServiceInfo.getQname());
145: deployedServiceInfo.setMessageEntity(configuredServiceInfo
146: .getMessageEntity());
147: deployedServiceInfo.setServerIp(configuredServiceInfo
148: .getServerIp());
149: deployedServiceInfo.setServiceDefinition(configuredServiceInfo
150: .getServiceDefinition());
151: }
152:
153: private boolean isSame(ServiceInfo configured, ServiceInfo deployed) {
154: return configured.getAlive().equals(deployed.getAlive())
155: && configured.getQname().equals(deployed.getQname())
156: && configured.getServerIp().equals(
157: deployed.getServerIp())
158: && configured.getMessageEntity().equals(
159: deployed.getMessageEntity())
160: && configured.getServiceDefinition().isSame(
161: deployed.getServiceDefinition());
162: }
163:
164: public List<ServiceInfo> getServicesNeedRemoved() {
165: return this .servicesNeedRemoved;
166: }
167:
168: public void setServicesNeedRemoved(
169: List<ServiceInfo> servicesNeedRemoved) {
170: this .servicesNeedRemoved = servicesNeedRemoved;
171: }
172:
173: public List<ServiceInfo> getServicesNeedUpdated() {
174: return this .servicesNeedUpdated;
175: }
176:
177: public void setServicesNeedUpdated(
178: List<ServiceInfo> servicesNeedUpdated) {
179: this .servicesNeedUpdated = servicesNeedUpdated;
180: }
181:
182: public List<ServiceInfo> getMasterServiceList() {
183: return this .masterServiceList;
184: }
185:
186: public void setMasterServiceList(List<ServiceInfo> masterServiceList) {
187: this.masterServiceList = masterServiceList;
188: }
189: }
|