001 /**
002 * Copyright 2005-2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.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/ecl2.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 org.kuali.rice.ksb.messaging;
017
018 import org.kuali.rice.ksb.api.messaging.AsynchronousCall;
019 import org.kuali.rice.ksb.api.messaging.AsynchronousCallback;
020
021 import java.io.Serializable;
022 import java.util.ArrayList;
023 import java.util.HashMap;
024 import java.util.List;
025 import java.util.Map;
026
027 import javax.xml.namespace.QName;
028
029 public class TestCallback implements AsynchronousCallback {
030 /**
031 *
032 */
033 private static final long serialVersionUID = 8558495197148582373L;
034
035 public static boolean callbackCalled;
036
037 public static List<Long> CURRENT_MILLIS_WHEN_CALLED;
038
039 public static int NUMBER_CALL_BACKS = 0;
040
041 public static Map<QName, Integer> SERVICE_CALL_COUNT_TRACKED = new HashMap<QName, Integer>();
042 public static Map<QName, List<AsynchronousCall>> SERVICES_CALLS_TRACKED = new HashMap<QName, List<AsynchronousCall>>();
043
044 static {
045 CURRENT_MILLIS_WHEN_CALLED = new ArrayList<Long>();
046 }
047
048 private int numberCallbacks = 0;
049
050 public static boolean isCallbackCalled() {
051 return callbackCalled;
052 }
053
054 public static void setCallbackCalled(boolean callbackCalled) {
055 TestCallback.callbackCalled = callbackCalled;
056 }
057
058 public synchronized void callback(Serializable returnObject, AsynchronousCall methodCall) {
059 CURRENT_MILLIS_WHEN_CALLED.add(System.currentTimeMillis());
060 NUMBER_CALL_BACKS++;
061 setCallbackCalled(true);
062 this.numberCallbacks++;
063 QName serviceName = methodCall.getServiceConfiguration().getServiceName();
064 Integer callCount = SERVICE_CALL_COUNT_TRACKED.get(serviceName);
065 if (callCount == null) {
066 SERVICE_CALL_COUNT_TRACKED.put(methodCall.getServiceConfiguration().getServiceName(), 1);
067 } else {
068 SERVICE_CALL_COUNT_TRACKED.put(methodCall.getServiceConfiguration().getServiceName(), callCount + 1);
069 }
070
071 List<AsynchronousCall> serviceCallsTracked = SERVICES_CALLS_TRACKED.get(serviceName);
072 if (serviceCallsTracked == null) {
073 serviceCallsTracked = new ArrayList<AsynchronousCall>();
074 SERVICES_CALLS_TRACKED.put(serviceName, serviceCallsTracked);
075 }
076 serviceCallsTracked.add(methodCall);
077
078 System.out.println("!!!Callback called number callbacks " + this.numberCallbacks);
079 }
080
081 public static void clearCallbacks() {
082 NUMBER_CALL_BACKS = 0;
083 SERVICE_CALL_COUNT_TRACKED = new HashMap<QName, Integer>();
084 }
085
086 /**
087 * sometimes it's more convenient to use a non static counter above when
088 * doing in memory queueing. Other times when doing persistent async
089 * messaging a static counter is needed. Everything could be converted to
090 * this method if the tests using the above method clear the static count
091 * before putting testing against callbacks.
092 *
093 * @param callbacks
094 * @param millisDelay
095 */
096 public void pauseUntilNumberCallbacksUsingStaticCounter(int callbacks, QName serviceName) {
097 int numPauses = 0;
098 while (true) {
099 synchronized (this.getClass()) {
100 if (serviceName == null) {
101 if (NUMBER_CALL_BACKS >= callbacks) {
102 System.out.println("!!!Returning number callback met");
103 return;
104 }
105 } else {
106 if (SERVICE_CALL_COUNT_TRACKED.get(serviceName) != null && SERVICE_CALL_COUNT_TRACKED.get(serviceName) >= callbacks) {
107 System.out.println("!!!Returning number callback met for service " + serviceName);
108 return;
109 }
110 // attributes will not be an exact match.
111 for (Map.Entry<QName, Integer> serviceCall : SERVICE_CALL_COUNT_TRACKED.entrySet()) {
112 if (serviceCall.getKey().getLocalPart().lastIndexOf(serviceName.getLocalPart()) > -1 && serviceCall.getKey().getNamespaceURI().equals(serviceName.getNamespaceURI()) && serviceCall.getValue() >= callbacks) {
113 System.out.println("!!!Returning number callback met for service " + serviceName);
114 return;
115 }
116 }
117 }
118 }
119 if (numPauses > 60 * 1) {
120 return;
121 }
122 try {
123 numPauses++;
124 System.out.println("!!!Test callback pausing for 1 second");
125 Thread.sleep(1000);
126 } catch (InterruptedException e) {
127 // nothing to do
128 }
129 }
130 }
131 }