View Javadoc

1   /*
2    * Copyright 2007 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.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/ecl2.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.messaging;
17  
18  import java.net.URL;
19  import java.util.Iterator;
20  import java.util.List;
21  
22  import javax.xml.namespace.QName;
23  
24  import org.junit.Test;
25  import org.kuali.rice.core.config.Config;
26  import org.kuali.rice.core.config.ConfigContext;
27  import org.kuali.rice.ksb.messaging.JavaServiceDefinition;
28  import org.kuali.rice.ksb.messaging.ServiceDefinition;
29  import org.kuali.rice.ksb.messaging.ServiceHolder;
30  import org.kuali.rice.ksb.messaging.ServiceInfo;
31  import org.kuali.rice.ksb.messaging.remotedservices.TestRepeatMessageQueue;
32  import org.kuali.rice.ksb.messaging.resourceloader.KSBResourceLoaderFactory;
33  import org.kuali.rice.ksb.service.KSBServiceLocator;
34  import org.kuali.rice.ksb.test.KSBTestCase;
35  
36  
37  public class RemotedServiceRegistryTest extends KSBTestCase {
38  	
39  	private QName mockServiceName = new QName("KEW", "mockService");
40  	private QName testTopicName = new QName("testAppsSharedTopic", "sharedTopic");
41  
42  	@Override
43  	public void setUp() throws Exception {
44  	    super.setUp();
45  	    
46  	}
47  
48  	@SuppressWarnings("unchecked")
49  	private ServiceDefinition addServiceToConfig() throws Exception {
50  		List httpServices = (List) ConfigContext.getCurrentContextConfig().getObject(Config.BUS_DEPLOYED_SERVICES);
51  		ServiceDefinition mockServiceDef = getMockServiceDefinition();
52  		httpServices.add(mockServiceDef);
53  		return mockServiceDef;
54  	}
55  	
56  	private void removeServiceFromConfig() throws Exception {
57  		List httpServices = (List) ConfigContext.getCurrentContextConfig().getObject(Config.BUS_DEPLOYED_SERVICES);
58  		ServiceDefinition serviceToRemove = null;
59  		for (Iterator iter = httpServices.iterator(); iter.hasNext();) {
60  			ServiceDefinition serviceDef = (ServiceDefinition)iter.next();
61  			if (serviceDef.getServiceName().equals(this.testTopicName)) {
62  				serviceToRemove = serviceDef;
63  				break;
64  			}
65  		}
66  		httpServices.remove(serviceToRemove);
67  	}
68  	
69  	private void verifyServiceAdded(int originalSize, int newSize, ServiceDefinition mockServiceDef) {
70  		//adding +2 here because of the service and the forwarding service.
71  		assertTrue("new service didn't get added to the registry", originalSize + 2 == newSize);
72  		ServiceHolder serviceHolder = KSBServiceLocator.getServiceDeployer().getPublishedServices().get(this.mockServiceName);
73  		assertNotNull("Mock service never put in registry memory", serviceHolder);
74  		assertEquals("End point url of service info is wrong", mockServiceDef.getServiceEndPoint().toString(), serviceHolder.getServiceInfo().getEndpointUrl());
75  	}
76  	
77  	/**
78  	 * Verifies when service is added to configuration that differs from the config in the db the change is reflected.
79  	 */
80  	@Test public void testServiceRefreshAddedService() throws Exception {
81  		int originalSize = KSBServiceLocator.getServiceDeployer().getPublishedServices().size(); 
82  		ServiceDefinition mockServiceDef = getMockServiceDefinition();
83  		KSBServiceLocator.getServiceDeployer().registerService(mockServiceDef, true);
84  		((Runnable)KSBServiceLocator.getServiceDeployer()).run();
85  		int newSize = KSBServiceLocator.getServiceDeployer().getPublishedServices().size();
86  		verifyServiceAdded(originalSize, newSize, mockServiceDef);
87  	}
88  	
89  	@Test public void testServiceRefreshServiceRemoved() throws Exception {
90  		int originalSize = KSBServiceLocator.getServiceDeployer().getPublishedServices().size(); 
91  		removeServiceFromConfig();
92  		((Runnable)KSBServiceLocator.getServiceDeployer()).run();
93  		int newSize = KSBServiceLocator.getServiceDeployer().getPublishedServices().size();
94  		verifyServiceRemoved(originalSize, newSize);
95  	}
96  	
97  	/**
98  	 * Verifies that a service added to the configuration when the app is offline will be 
99  	 * added when the app starts.
100 	 * @throws Exception
101 	 */
102 	@Test public void testRestartAddedService() throws Exception {
103 		int originalSize = KSBServiceLocator.getServiceDeployer().getPublishedServices().size(); 
104 		KSBServiceLocator.getServiceDeployer().stop();
105 		ServiceDefinition mockServiceDef = addServiceToConfig();
106 		KSBServiceLocator.getServiceDeployer().start();
107 		int newSize = KSBServiceLocator.getServiceDeployer().getPublishedServices().size();
108 		verifyServiceAdded(originalSize, newSize, mockServiceDef);
109 	}
110 	
111 	/**
112 	 * Verifies that a service is removed when it is removed from the config when app is offline 
113 	 * and started again.
114 	 * @throws Exception
115 	 */
116 	@Test public void testRestartServiceRemoved() throws Exception {
117 		int originalSize = KSBServiceLocator.getServiceDeployer().getPublishedServices().size(); 
118 		KSBServiceLocator.getServiceDeployer().stop();
119 		removeServiceFromConfig();
120 		KSBServiceLocator.getServiceDeployer().start();
121 		int newSize = KSBServiceLocator.getServiceDeployer().getPublishedServices().size();
122 		verifyServiceRemoved(originalSize, newSize);
123 	}
124 	
125 	/**
126 	 * Verifies that a service modified when the app is offline is reflected in when the 
127 	 * app comes online.
128 	 * 
129 	 * Exact scenario: the service is set alive=false (presumably by being down and another node 
130 	 * marking the service as alive=false).  The node comes back and marks it's service as alive.
131 	 * 
132 	 * @throws Exception
133 	 */
134 	@Test public void testRestartServiceModified() throws Exception {
135 		KSBServiceLocator.getServiceDeployer().stop();
136 		ServiceInfo testTopic = findServiceInfo(this.testTopicName, KSBServiceLocator.getServiceRegistry().fetchAll());
137 		testTopic.setAlive(false);
138 		KSBServiceLocator.getServiceRegistry().saveEntry(testTopic);
139 		KSBServiceLocator.getServiceDeployer().start();
140 		testTopic = findServiceInfo(this.testTopicName, KSBServiceLocator.getServiceRegistry().fetchAll());
141 		assertTrue("test topic should now be marked as alive", testTopic.getAlive());
142 	}
143 	
144 	/**
145 	 * Verifies when a node marking a service as dead that service is marked alive 
146 	 * when this node refreshes it's services 
147 	 *  
148 	 * @throws Exception
149 	 */
150 	@Test public void testServiceRefreshServiceModified() throws Exception {
151 //		stop the registry so we thread pool doesn't mess up the result
152 		KSBServiceLocator.getServiceDeployer().stop();
153 		KSBServiceLocator.getThreadPool().stop();
154 		ServiceInfo testTopic = findServiceInfo(this.testTopicName, KSBServiceLocator.getServiceRegistry().fetchAll());
155 		testTopic.setAlive(false);
156 		KSBServiceLocator.getServiceRegistry().saveEntry(testTopic);
157 		((Runnable)KSBServiceLocator.getServiceDeployer()).run();
158 		testTopic = findServiceInfo(this.testTopicName, KSBServiceLocator.getServiceRegistry().fetchAll());
159 		assertTrue("test topic should now be marked as alive", testTopic.getAlive());
160 	}
161 	
162 	private ServiceInfo findServiceInfo(QName serviceName, List<ServiceInfo> serviceInfos) {
163 		for (ServiceInfo info : serviceInfos) {
164 			if (info.getQname().equals(serviceName)) {
165 				return info;
166 			}
167 		}
168 		throw new RuntimeException("Should have found service " + serviceName);
169 	}
170 	
171 	@Test public void testMultipleManualRefreshes() throws Exception {
172 		((Runnable)KSBResourceLoaderFactory.getRemoteResourceLocator()).run();
173 		((Runnable)KSBResourceLoaderFactory.getRemoteResourceLocator()).run();
174 		((Runnable)KSBResourceLoaderFactory.getRemoteResourceLocator()).run();
175 		assertTrue(true);
176 	}
177 	
178 	private void verifyServiceRemoved(int originalSize, int newSize) {
179 		//-2 because of store and forward service registered for each service.
180 		assertEquals("new service didn't get removed from the registry", originalSize - 2, newSize);
181 		ServiceHolder serviceHolder = KSBServiceLocator.getServiceDeployer().getPublishedServices().get(this.testTopicName);
182 		assertNull("Service should be removed from memory", serviceHolder);
183 		
184 		//should be gone from table
185 		List<ServiceInfo> serviceInfos = KSBServiceLocator.getServiceRegistry().fetchAll();
186 		for (ServiceInfo info : serviceInfos) {
187 			if (info.getQname().equals(this.testTopicName)) {
188 				fail("This service should no longer be present in the service def table");
189 			}
190 		}
191 	}
192 	
193 	private JavaServiceDefinition getMockServiceDefinition() throws Exception {
194 		JavaServiceDefinition serviceDef = new JavaServiceDefinition();
195 		serviceDef.setServiceEndPoint(new URL("http://mockServiceURL"));
196 		serviceDef.setPriority(3);
197 		serviceDef.setRetryAttempts(3);
198 		serviceDef.setService(new TestRepeatMessageQueue());
199 		serviceDef.setServiceName(this.mockServiceName);
200 		serviceDef.setQueue(false);
201 		serviceDef.validate();
202 		return serviceDef;
203 	}
204 }