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.List;
020: import java.util.Map;
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.exceptions.RiceRuntimeException;
028: import org.kuali.rice.util.ClassLoaderUtils;
029:
030: import edu.iu.uis.eden.messaging.exceptionhandling.DefaultMessageExceptionHandler;
031: import edu.iu.uis.eden.messaging.exceptionhandling.MessageExceptionHandler;
032: import edu.iu.uis.eden.messaging.remotedservices.TestRepeatMessageQueue;
033: import edu.iu.uis.eden.messaging.resourceloading.KSBResourceLoaderFactory;
034:
035: /**
036: * Tests RemoteResourceLoader is working correctly by itself and working correctly with the RemoteServiceRegistry in marking
037: * services bad/refreshing services/etc.
038: *
039: * @author Kuali Rice Team (kuali-rice@googlegroups.com)
040: *
041: */
042: public class RemoteResourceLoaderTest extends KSBTestCase {
043:
044: private QName mockServiceName = new QName("KEW", "mockService");
045: private QName testTopicName = new QName("testAppsSharedTopic",
046: "sharedTopic");
047: private RemoteResourceServiceLocator rrl;
048:
049: @Override
050: public void setUp() throws Exception {
051: super .setUp();
052: this .rrl = KSBResourceLoaderFactory.getRemoteResourceLocator();
053: KSBServiceLocator.getScheduledPool().stop();
054: KSBServiceLocator.getServiceDeployer().getPublishedServices()
055: .clear();
056: }
057:
058: /*
059: * test scenarios service marked inactive/changed at db picked up by RRL service 'removed' by RRL marked inactive at
060: * db/can no longer be fetched service 'removed' by RRL - refreshed on by RSR - refresh on by RRL - now active
061: */
062:
063: /**
064: * mark a service inactive through the rrl api verify that the db reflects the change.
065: */
066: @Test
067: public void testMarkingInactiveWorksAtDBLevel() throws Exception {
068: this .rrl.removeResourceLoader(this .testTopicName);
069: ServiceInfo testTopicInfo = this .findServiceInfo(
070: this .testTopicName, KSBServiceLocator
071: .getIPTableService().fetchAll());
072: assertTrue("Service should be marked inactive at the db",
073: testTopicInfo.getAlive());
074: }
075:
076: /**
077: * change service at the db level (change by another node) and verify the service is removed from current rrl
078: */
079: @Test
080: public void testChangedServicePickedUpOnRefresh() throws Exception {
081: ServiceInfo testTopicInfo = this .findServiceInfo(
082: this .testTopicName, KSBServiceLocator
083: .getIPTableService().fetchAll());
084: testTopicInfo.setAlive(false);
085: this .saveServiceInfo(testTopicInfo, 0);
086: ((Runnable) this .rrl).run();
087: try {
088: this .rrl.getService(this .testTopicName);
089: fail("Should have thrown exception trying to fetch non-existent service");
090: } catch (Exception e) {
091: // this is okay
092: }
093: }
094:
095: /**
096: * change service start rrl. make sure service isn't there.
097: *
098: * @throws Exception
099: */
100: @Test
101: public void testChangedServicePickedUpOnStartup() throws Exception {
102: ServiceInfo testTopicInfo = this .findServiceInfo(
103: this .testTopicName, KSBServiceLocator
104: .getIPTableService().fetchAll());
105: testTopicInfo.setAlive(false);
106: this .saveServiceInfo(testTopicInfo, 0);
107: ((Runnable) this .rrl).run();
108: try {
109: this .rrl.getService(this .testTopicName);
110: fail("Should have thrown exception trying to fetch non-existent service");
111: } catch (Exception e) {
112: // this is okay
113: }
114: }
115:
116: /**
117: * add service refresh rrl. make sure it's there.
118: *
119: * @throws Exception
120: */
121: @Test
122: public void testServiceAddedShowUpOnRefresh() throws Exception {
123: this .addServiceToDB();
124: ((Runnable) this .rrl).run();
125: Object service = this .rrl.getService(this .mockServiceName);
126: assertNotNull(
127: "service should be in memory after run on RemoteResourceLocator",
128: service);
129: }
130:
131: /**
132: * add service start rrl. make sure it's there.
133: *
134: * @throws Exception
135: */
136: @Test
137: public void testServiceAddedShowUpOnStartup() throws Exception {
138: // this.rrl.stop();
139: this .addServiceToDB();
140: ((Runnable) this .rrl).run();
141: Object service = this .rrl.getService(this .mockServiceName);
142: assertNotNull(
143: "service should be in memory after starting RemoteResourceLocator",
144: service);
145: }
146:
147: /**
148: * test fetching of service that is there and not
149: */
150: @Test
151: public void testServiceFetch() throws Exception {
152:
153: KEWJavaService testTopic = (KEWJavaService) this .rrl
154: .getService(this .testTopicName);
155: assertNotNull("Sould have fetched service", testTopic);
156: try {
157: this .rrl.getService(new QName("KEW", "FakeyMcService"));
158: fail("Should have thrown exception fetching non-existent service");
159: } catch (Exception e) {
160: // this is okay
161: }
162: }
163:
164: @Test
165: public void testExceptionHandlerFetching() throws Exception {
166: MessageExceptionHandler exceptionHandler = this .rrl
167: .getMessageExceptionHandler(this .testTopicName);
168: assertNotNull("Exception handler should have been fetched",
169: exceptionHandler);
170: Object obj = ClassLoaderUtils.unwrapFromProxy(exceptionHandler);
171: assertTrue(
172: "Exception handler should be instance of default exception handler",
173: obj instanceof DefaultMessageExceptionHandler);
174:
175: try {
176: this .rrl.getMessageExceptionHandler(new QName("KEW",
177: "FakeyMcService"));
178: fail("should have thrown exception get exception handler by non existent service");
179: } catch (Exception e) {
180: // this is okay
181: }
182: }
183:
184: /**
185: * put in because of a weird bug where inactive services were forcing client refreshes no matter what.
186: *
187: * this test verifies that setting a service inactive will for a refresh ONCE. but not again.
188: *
189: * @throws Exception
190: */
191: @Test
192: public void testInactiveServiceDoesntForceRefresh()
193: throws Exception {
194: ServiceInfo testTopicInfo = this .findServiceInfo(
195: this .testTopicName, KSBServiceLocator
196: .getIPTableService().fetchAll());
197: testTopicInfo.setAlive(false);
198: this .saveServiceInfo(testTopicInfo, 0);
199: ((Runnable) this .rrl).run();
200: Map<QName, List<RemotedServiceHolder>> clients1 = ((RemoteResourceServiceLocatorImpl) this .rrl)
201: .getClients();
202: ((Runnable) this .rrl).run();
203: Map<QName, List<RemotedServiceHolder>> clients2 = ((RemoteResourceServiceLocatorImpl) this .rrl)
204: .getClients();
205: for (QName name : clients1.keySet()) {
206: List<RemotedServiceHolder> remotedServices1 = clients1
207: .get(name);
208: List<RemotedServiceHolder> remotedServices2 = clients2
209: .get(name);
210: assertEquals(remotedServices1, remotedServices2);
211: }
212: }
213:
214: private ServiceInfo findServiceInfo(QName serviceName,
215: List<ServiceInfo> serviceInfos) {
216: for (ServiceInfo info : serviceInfos) {
217: if (info.getQname().equals(serviceName)) {
218: return info;
219: }
220: }
221: throw new RuntimeException("Should have found service "
222: + serviceName);
223: }
224:
225: private void saveServiceInfo(ServiceInfo serviceInfo, int count) {
226: if (count++ > 5) {
227: throw new RiceRuntimeException(
228: "saveServiceInfo called 5 times and received opt lock exception each time");
229: }
230: try {
231: KSBServiceLocator.getIPTableService()
232: .saveEntry(serviceInfo);
233: } catch (Exception e) {
234: if (KSBServiceLocator.getOptimisticLockFailureService()
235: .checkForOptimisticLockFailure(e)) {
236: saveServiceInfo(serviceInfo, count);
237: }
238: }
239: }
240:
241: private void addServiceToDB() throws Exception {
242: ServiceDefinition mockServiceDef = getMockServiceDefinition();
243: mockServiceDef.validate();
244: ServiceInfo mockService = new ServiceInfo(mockServiceDef);
245: saveServiceInfo(mockService, 0);
246: }
247:
248: private ServiceDefinition getMockServiceDefinition()
249: throws Exception {
250: ServiceDefinition serviceDef = new JavaServiceDefinition();
251: serviceDef.setServiceEndPoint(new URL("http://mockServiceURL"));
252: serviceDef.setPriority(3);
253: serviceDef.setRetryAttempts(3);
254: serviceDef.setService(new TestRepeatMessageQueue());
255: serviceDef.setServiceName(this .mockServiceName);
256: serviceDef.setQueue(false);
257: serviceDef.validate();
258: return serviceDef;
259: }
260: }
|