diff options
Diffstat (limited to 'tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src')
7 files changed, 584 insertions, 0 deletions
diff --git a/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadClient.java b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadClient.java new file mode 100644 index 0000000000..f812a39058 --- /dev/null +++ b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadClient.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.itest; + +import org.osoa.sca.annotations.Remotable; + +/** + * This is the client interface for the call backs in a separate thread tests + */ +@Remotable +public interface CallBackSeparateThreadClient { + + /** + * This tests call back patterns using separate threads. + */ + void runTests(); +} diff --git a/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadClientImpl.java b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadClientImpl.java new file mode 100644 index 0000000000..e861f8a3d1 --- /dev/null +++ b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadClientImpl.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.itest; + +import java.util.concurrent.atomic.AtomicInteger; + +import junit.framework.Assert; + +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Service; + +/** + * This is the client implementation for the call backs in a separate thread tests + */ +@Service(CallBackSeparateThreadClient.class) +public class CallBackSeparateThreadClientImpl implements CallBackSeparateThreadClient, EventProcessorCallBack { + /** + * Used to sleep for 60 seconds. + */ + private static final int SIXTY_SECONDS = 60 * 1000; + + /** + * Counts the number of one second call backs + */ + private static final AtomicInteger oneSecondCallbackCount = new AtomicInteger(); + + /** + * Counts the number of five second call backs + */ + private static final AtomicInteger fiveSecondCallbackCount = new AtomicInteger(); + + /** + * This is our injected reference to the EventProcessorService + */ + @Reference + protected EventProcessorService aCallBackService; + + /** + * This tests call back patterns using separate threads. + */ + public void runTests() { + // Register for 1 second call back + registerFor1SecondCallback(); + + // Wait for a few 1 second call backs + System.out.println("Waiting for some 1 second calls"); + waitForSome1SecondCallbacks(); + + // Register for 5 second call back + registerFor5SecondCallback(); + + // Wait for a few 1 second call backs + System.out.println("Waiting for some 1 second calls"); + waitForSome1SecondCallbacks(); + + // Wait for a few 5 second call backs + System.out.println("Waiting for some 5 second calls"); + waitForSome5SecondCallbacks(); + + System.out.println("Done"); + } + + /** + * Waits for some one second call backs to be fired + */ + private void waitForSome1SecondCallbacks() { + // Reset the one second call back count + oneSecondCallbackCount.set(0); + + // Wait until we have 10 1 second call backs or 60 seconds has passed + final long start = System.currentTimeMillis(); + do { + if (oneSecondCallbackCount.get() >= 10) { + System.out.println("Received enough 1 second notifications"); + return; + } + + try { + Thread.sleep(500); + } catch (InterruptedException e) { + Assert.fail("Unexpeceted exception " + e); + } + } + while (System.currentTimeMillis() - start < SIXTY_SECONDS); + + // If we get to here then we did not receive enough events + Assert.fail("Did not receive enough 1 second events"); + } + + /** + * Waits for some five second call backs to be fired + */ + private void waitForSome5SecondCallbacks() { + // Reset the five second call back count + fiveSecondCallbackCount.set(0); + + // Wait until we have 4 5 second call backs or 60 seconds has passed + final long start = System.currentTimeMillis(); + do + { + if (fiveSecondCallbackCount.get() >= 4) { + System.out.println("Received enough 5 second notifications"); + return; + } + + try + { + Thread.sleep(500); + } + catch (InterruptedException e) + { + Assert.fail("Unexpeceted exception " + e); + } + } + while (System.currentTimeMillis() - start < SIXTY_SECONDS); + + // If we get to here then we did not receive enough events + Assert.fail("Did not receive enough 5 second events"); + } + + /** + * Register to receive one second call backs + */ + private void registerFor1SecondCallback() { + aCallBackService.registerForEvent("ONE"); + return; + } + + /** + * Register to receive five second call backs + */ + private void registerFor5SecondCallback() { + aCallBackService.registerForEvent("FIVE"); + } + + /** + * Method that is called when an Event is delivered. + * + * @param aEventName The name of the Event + * @param aEventData The Event data + */ + public void eventNotification(String aEventName, Object aEventData) { + // System.out.println("Received Event : " + aEventName + " " + aEventData); + + if (aEventName.equals("ONE")) { + final int newValue = oneSecondCallbackCount.incrementAndGet(); + //System.out.println("Received total of " + newValue + " 1 second call backs"); + } else if (aEventName.equals("FIVE")) { + final int newValue = fiveSecondCallbackCount.incrementAndGet(); + //System.out.println("Received total of " + newValue + " 5 second call backs"); + } + else + System.out.println("Unknown event type of " + aEventName); + } +} diff --git a/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorCallBack.java b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorCallBack.java new file mode 100644 index 0000000000..ae41f596fc --- /dev/null +++ b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorCallBack.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.itest; + + +import org.osoa.sca.annotations.Remotable; + +/** + * The call back interface for the EventProcessorService that is implemented + * by the client to receive event notifications + */ +@Remotable +public interface EventProcessorCallBack { + /** + * Call back notifying client of an Event + * + * @param aEventName The name of the Event + * @param aEventData The data for the Event + */ + void eventNotification(String aEventName, Object aEventData); +} diff --git a/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorService.java b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorService.java new file mode 100644 index 0000000000..c22b8cceec --- /dev/null +++ b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorService.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.itest; + +import org.osoa.sca.annotations.Callback; +import org.osoa.sca.annotations.Conversational; +import org.osoa.sca.annotations.Remotable; + + +/** + * Sample Event Processor Service + */ +@Conversational +@Callback(EventProcessorCallBack.class) +@Remotable +public interface EventProcessorService { + + /** + * Registers the client to receive notifications for the specified event + * + * @param aEventName The name of the Event to register + */ + void registerForEvent(String aEventName); + + /** + * Unregisters the client so it no longer receives notifications for the specified event + * + * @param aEventName The name of the Event to unregister + */ + void unregisterForEvent(String aEventName); +} diff --git a/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorServiceImpl.java b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorServiceImpl.java new file mode 100644 index 0000000000..4d672b3a8b --- /dev/null +++ b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/java/org/apache/tuscany/sca/itest/EventProcessorServiceImpl.java @@ -0,0 +1,197 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.itest; + +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import org.osoa.sca.CallableReference; +import org.osoa.sca.annotations.Callback; +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Sample Event Processor Service Implementation + */ +@Service(EventProcessorService.class) +@Scope("CONVERSATION") +public class EventProcessorServiceImpl implements EventProcessorService { + + /** + * Reference to the call back + */ + @Callback + protected CallableReference<EventProcessorCallBack> clientCallback; + + /** + * This map contains the call backs for each of the registered Event names + */ + private final Map<String, CallableReference<EventProcessorCallBack>> eventListeners; + + /** + * The list of all Event Generators we create + */ + private final EventGenerator[] allEventGenerators; + + /** + * Constructor. Starts the Event Generators + */ + public EventProcessorServiceImpl() { + eventListeners = new ConcurrentHashMap<String, CallableReference<EventProcessorCallBack>>(); + + // We will simulate an Event generator + allEventGenerators = new EventGenerator[2]; + allEventGenerators[0] = new EventGenerator("ONE", 1); // Generate the SECOND event every second + allEventGenerators[1] = new EventGenerator("FIVE", 5); // Generate the FIVE event every 5 seconds + } + + /** + * Registers the client to receive notifications for the specified event + * + * @param aEventName The name of the Event to register + */ + public void registerForEvent(String aEventName) + { + // Register for the Event + eventListeners.put(aEventName, clientCallback); + + // Send the "register" started event to the client + receiveEvent(aEventName, "SameThread: Registered to receive notifications for " + aEventName); + } + + /** + * Unregisters the client so it no longer receives notifications for the specified event + * + * @param aEventName The name of the Event to unregister + */ + public void unregisterForEvent(String aEventName) + { + // Send the "register" started event to the client + receiveEvent(aEventName, "SameThread: Unregister from receiving notifications for " + aEventName); + + eventListeners.remove(aEventName); + } + + /** + * This method is called whenever the EventProcessorService receives an Event + * + * @param aEventName The name of the Event received + * @param aEventData The Event data + */ + private void receiveEvent(String aEventName, Object aEventData) + { + // Get the listener for the Event + final CallableReference<EventProcessorCallBack> callback = eventListeners.get(aEventName); + if (callback == null) + { + //System.out.println("No registered listeners for " + aEventName); + return; + } + + // Trigger the call back + // System.out.println("Notifying " + callback + " of event " + aEventName); + callback.getService().eventNotification(aEventName, aEventData); + // System.out.println("Done notify " + callback + " of event " + aEventName); + } + + /** + * Shuts down the Event Processor + */ + @Destroy + public void shutdown() + { + System.out.println("Shutting down the EventProcessor"); + + // Clear list of call back locations as we don't want to send any more notifications + eventListeners.clear(); + + // Stop the Event Generators + for (EventGenerator generator : allEventGenerators) + { + generator.stop(); + } + } + + /** + * Utility class for generating Events + */ + private class EventGenerator + { + /** + * The Timer we are using to generate the events + */ + private final Timer timer = new Timer(); + + /** + * Constructor + * + * @param aEventName The name of the Event to generate + * @param frequencyInSeconds How frequently we should generate the Events + */ + private EventGenerator(String aEventName, int frequencyInSeconds) + { + timer.schedule(new EventGeneratorTimerTask(aEventName), + frequencyInSeconds * 1000, frequencyInSeconds * 1000); + } + + /** + * Stop this Event Generator + */ + private void stop() + { + timer.cancel(); + } + + /** + * The TimerTask that is invoked by the Timer for the EventGenerator + */ + private class EventGeneratorTimerTask extends TimerTask + { + /** + * The name of the Event we should generate + */ + private final String eventName; + + /** + * Constructor + * + * @param aEventName The name of the Event we should generate + */ + private EventGeneratorTimerTask(String aEventName) + { + eventName = aEventName; + } + + /** + * Timer calls this method and it will generate an Event + */ + @Override + public void run() + { + // System.out.println("Generating new event " + eventName); + receiveEvent(eventName, "Separate Thread Notification: " + UUID.randomUUID().toString()); + } + } + } +} diff --git a/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/resources/CallBackSeparateThreadTest.composite b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/resources/CallBackSeparateThreadTest.composite new file mode 100644 index 0000000000..e111e5074c --- /dev/null +++ b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/main/resources/CallBackSeparateThreadTest.composite @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://callback" name="CallBackSeparateThreadTest">
+
+ <component name="CallBackSeparateThreadClient">
+ <implementation.java class="org.apache.tuscany.sca.itest.CallBackSeparateThreadClientImpl"/>
+ <reference name="aCallBackService" target="EventProcessorService"/>
+ </component>
+
+ <component name="EventProcessorService">
+ <implementation.java class="org.apache.tuscany.sca.itest.EventProcessorServiceImpl"/>
+ </component>
+
+</composite>
diff --git a/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/test/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadTestCase.java b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/test/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadTestCase.java new file mode 100644 index 0000000000..f7e7be2133 --- /dev/null +++ b/tags/java/sca/1.3.1-RC0/itest/callback-separatethread/src/test/java/org/apache/tuscany/sca/itest/CallBackSeparateThreadTestCase.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.itest; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.host.embedded.SCADomain; + +/** + * This test case will attempt to trigger a call back using a separate thread + */ +public class CallBackSeparateThreadTestCase extends TestCase { + + /** + * The SCADomain we are using + */ + private SCADomain domain; + + /** + * The client the tests should use + */ + private CallBackSeparateThreadClient aCallBackClient; + + /** + * Run the call back in separate thread tests + */ + public void testCallBackSeparateThread() { + aCallBackClient.runTests(); + } + + /** + * Load the Call back in separate thread composite and look up the client. + */ + @Override + protected void setUp() throws Exception { + domain = SCADomain.newInstance("CallBackSeparateThreadTest.composite"); + aCallBackClient = domain.getService(CallBackSeparateThreadClient.class, "CallBackSeparateThreadClient"); + } + + /** + * Shutdown the SCA domain + */ + @Override + protected void tearDown() throws Exception { + domain.close(); + } +} |