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    }