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.net.URL;
019: import java.util.Iterator;
020: import java.util.List;
021:
022: import javax.xml.namespace.QName;
023:
024: import org.junit.Test;
025: import org.kuali.bus.services.KSBServiceLocator;
026: import org.kuali.bus.test.KSBTestCase;
027: import org.kuali.rice.config.Config;
028: import org.kuali.rice.core.Core;
029:
030: import edu.iu.uis.eden.messaging.remotedservices.TestRepeatMessageQueue;
031: import edu.iu.uis.eden.messaging.resourceloading.KSBResourceLoaderFactory;
032:
033: public class RemotedServiceRegistryTest extends KSBTestCase {
034:
035: private QName mockServiceName = new QName("KEW", "mockService");
036: private QName testTopicName = new QName("testAppsSharedTopic",
037: "sharedTopic");
038:
039: @Override
040: public void setUp() throws Exception {
041: super .setUp();
042:
043: }
044:
045: @SuppressWarnings("unchecked")
046: private ServiceDefinition addServiceToConfig() throws Exception {
047: List httpServices = (List) Core.getCurrentContextConfig()
048: .getObject(Config.BUS_DEPLOYED_SERVICES);
049: ServiceDefinition mockServiceDef = getMockServiceDefinition();
050: httpServices.add(mockServiceDef);
051: return mockServiceDef;
052: }
053:
054: private void removeServiceFromConfig() throws Exception {
055: List httpServices = (List) Core.getCurrentContextConfig()
056: .getObject(Config.BUS_DEPLOYED_SERVICES);
057: ServiceDefinition serviceToRemove = null;
058: for (Iterator iter = httpServices.iterator(); iter.hasNext();) {
059: ServiceDefinition serviceDef = (ServiceDefinition) iter
060: .next();
061: if (serviceDef.getServiceName().equals(this .testTopicName)) {
062: serviceToRemove = serviceDef;
063: break;
064: }
065: }
066: httpServices.remove(serviceToRemove);
067: }
068:
069: private void verifyServiceAdded(int originalSize, int newSize,
070: ServiceDefinition mockServiceDef) {
071: //adding +2 here because of the service and the forwarding service.
072: assertTrue("new service didn't get added to the registry",
073: originalSize + 2 == newSize);
074: RemotedServiceHolder serviceHolder = KSBServiceLocator
075: .getServiceDeployer().getPublishedServices().get(
076: this .mockServiceName);
077: assertNotNull("Mock service never put in registry memory",
078: serviceHolder);
079: assertEquals("End point url of service info is wrong",
080: mockServiceDef.getServiceEndPoint().toString(),
081: serviceHolder.getServiceInfo().getEndpointUrl());
082: }
083:
084: /**
085: * Verifies when service is added to configuration that differs from the config in the db the change is reflected.
086: */
087: @Test
088: public void testServiceRefreshAddedService() throws Exception {
089: int originalSize = KSBServiceLocator.getServiceDeployer()
090: .getPublishedServices().size();
091: ServiceDefinition mockServiceDef = getMockServiceDefinition();
092: KSBServiceLocator.getServiceDeployer().registerService(
093: mockServiceDef, true);
094: ((Runnable) KSBServiceLocator.getServiceDeployer()).run();
095: int newSize = KSBServiceLocator.getServiceDeployer()
096: .getPublishedServices().size();
097: verifyServiceAdded(originalSize, newSize, mockServiceDef);
098: }
099:
100: @Test
101: public void testServiceRefreshServiceRemoved() throws Exception {
102: int originalSize = KSBServiceLocator.getServiceDeployer()
103: .getPublishedServices().size();
104: removeServiceFromConfig();
105: ((Runnable) KSBServiceLocator.getServiceDeployer()).run();
106: int newSize = KSBServiceLocator.getServiceDeployer()
107: .getPublishedServices().size();
108: verifyServiceRemoved(originalSize, newSize);
109: }
110:
111: /**
112: * Verifies that a service added to the configuration when the app is offline will be
113: * added when the app starts.
114: * @throws Exception
115: */
116: @Test
117: public void testRestartAddedService() throws Exception {
118: int originalSize = KSBServiceLocator.getServiceDeployer()
119: .getPublishedServices().size();
120: KSBServiceLocator.getServiceDeployer().stop();
121: ServiceDefinition mockServiceDef = addServiceToConfig();
122: KSBServiceLocator.getServiceDeployer().start();
123: int newSize = KSBServiceLocator.getServiceDeployer()
124: .getPublishedServices().size();
125: verifyServiceAdded(originalSize, newSize, mockServiceDef);
126: }
127:
128: /**
129: * Verifies that a service is removed when it is removed from the config when app is offline
130: * and started again.
131: * @throws Exception
132: */
133: @Test
134: public void testRestartServiceRemoved() throws Exception {
135: int originalSize = KSBServiceLocator.getServiceDeployer()
136: .getPublishedServices().size();
137: KSBServiceLocator.getServiceDeployer().stop();
138: removeServiceFromConfig();
139: KSBServiceLocator.getServiceDeployer().start();
140: int newSize = KSBServiceLocator.getServiceDeployer()
141: .getPublishedServices().size();
142: verifyServiceRemoved(originalSize, newSize);
143: }
144:
145: /**
146: * Verifies that a service modified when the app is offline is reflected in when the
147: * app comes online.
148: *
149: * Exact scenario: the service is set alive=false (presumably by being down and another node
150: * marking the service as alive=false). The node comes back and marks it's service as alive.
151: *
152: * @throws Exception
153: */
154: @Test
155: public void testRestartServiceModified() throws Exception {
156: KSBServiceLocator.getServiceDeployer().stop();
157: ServiceInfo testTopic = findServiceInfo(this .testTopicName,
158: KSBServiceLocator.getIPTableService().fetchAll());
159: testTopic.setAlive(false);
160: KSBServiceLocator.getIPTableService().saveEntry(testTopic);
161: KSBServiceLocator.getServiceDeployer().start();
162: testTopic = findServiceInfo(this .testTopicName,
163: KSBServiceLocator.getIPTableService().fetchAll());
164: assertTrue("test topic should now be marked as alive",
165: testTopic.getAlive());
166: }
167:
168: /**
169: * Verifies when a node marking a service as dead that service is marked alive
170: * when this node refreshes it's services
171: *
172: * @throws Exception
173: */
174: @Test
175: public void testServiceRefreshServiceModified() throws Exception {
176: // stop the registry so we thread pool doesn't mess up the result
177: KSBServiceLocator.getServiceDeployer().stop();
178: KSBServiceLocator.getThreadPool().stop();
179: ServiceInfo testTopic = findServiceInfo(this .testTopicName,
180: KSBServiceLocator.getIPTableService().fetchAll());
181: testTopic.setAlive(false);
182: KSBServiceLocator.getIPTableService().saveEntry(testTopic);
183: ((Runnable) KSBServiceLocator.getServiceDeployer()).run();
184: testTopic = findServiceInfo(this .testTopicName,
185: KSBServiceLocator.getIPTableService().fetchAll());
186: assertTrue("test topic should now be marked as alive",
187: testTopic.getAlive());
188: }
189:
190: private ServiceInfo findServiceInfo(QName serviceName,
191: List<ServiceInfo> serviceInfos) {
192: for (ServiceInfo info : serviceInfos) {
193: if (info.getQname().equals(serviceName)) {
194: return info;
195: }
196: }
197: throw new RuntimeException("Should have found service "
198: + serviceName);
199: }
200:
201: @Test
202: public void testMultipleManualRefreshes() throws Exception {
203: ((Runnable) KSBResourceLoaderFactory.getRemoteResourceLocator())
204: .run();
205: ((Runnable) KSBResourceLoaderFactory.getRemoteResourceLocator())
206: .run();
207: ((Runnable) KSBResourceLoaderFactory.getRemoteResourceLocator())
208: .run();
209: assertTrue(true);
210: }
211:
212: private void verifyServiceRemoved(int originalSize, int newSize) {
213: //-2 because of store and forward service registered for each service.
214: assertEquals(
215: "new service didn't get removed from the registry",
216: originalSize - 2, newSize);
217: RemotedServiceHolder serviceHolder = KSBServiceLocator
218: .getServiceDeployer().getPublishedServices().get(
219: this .testTopicName);
220: assertNull("Service should be removed from memory",
221: serviceHolder);
222:
223: //should be gone from table
224: List<ServiceInfo> serviceInfos = KSBServiceLocator
225: .getIPTableService().fetchAll();
226: for (ServiceInfo info : serviceInfos) {
227: if (info.getQname().equals(this .testTopicName)) {
228: fail("This service should no longer be present in the service def table");
229: }
230: }
231: }
232:
233: private JavaServiceDefinition getMockServiceDefinition()
234: throws Exception {
235: JavaServiceDefinition serviceDef = new JavaServiceDefinition();
236: serviceDef.setServiceEndPoint(new URL("http://mockServiceURL"));
237: serviceDef.setPriority(3);
238: serviceDef.setRetryAttempts(3);
239: serviceDef.setService(new TestRepeatMessageQueue());
240: serviceDef.setServiceName(this .mockServiceName);
241: serviceDef.setQueue(false);
242: serviceDef.validate();
243: return serviceDef;
244: }
245: }
|