From 2213475ef93df60dcaf3a4345a0dc300b652579e Mon Sep 17 00:00:00 2001 From: rfeng Date: Tue, 9 Dec 2008 18:56:13 +0000 Subject: Adjust the package names and move test cases around git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@724826 13f79535-47bb-0310-9956-ffa450edef68 --- .../sca/core/work/DefaultWorkScheduler.java | 191 ---------------- .../sca/core/work/ThreadPoolWorkManager.java | 229 ------------------- .../org/apache/tuscany/sca/core/work/Work.java | 65 ------ .../apache/tuscany/sca/core/work/WorkEvent.java | 80 ------- .../org/apache/tuscany/sca/core/work/WorkItem.java | 167 -------------- .../apache/tuscany/sca/core/work/WorkListener.java | 32 --- .../sca/core/work/impl/DefaultWorkScheduler.java | 191 ++++++++++++++++ .../sca/core/work/impl/ThreadPoolWorkManager.java | 229 +++++++++++++++++++ .../apache/tuscany/sca/core/work/impl/Work.java | 65 ++++++ .../tuscany/sca/core/work/impl/WorkEvent.java | 80 +++++++ .../tuscany/sca/core/work/impl/WorkItem.java | 167 ++++++++++++++ .../tuscany/sca/core/work/impl/WorkListener.java | 32 +++ .../org.apache.tuscany.sca.work.WorkScheduler | 2 +- .../DefaultExtensionPointRegistryTestCase.java | 56 ----- ...CallbackInterfaceInterceptorTestCase.java.fixme | 62 ++++++ .../impl/InvocationChainImplTestCase.java | 96 ++++++++ .../impl/NonBlockingInterceptorTestCase.java.fixme | 74 +++++++ ...CallbackInterfaceInterceptorTestCase.java.fixme | 62 ------ .../sca/core/wire/InvocationChainImplTestCase.java | 96 -------- .../wire/NonBlockingInterceptorTestCase.java.fixme | 74 ------- .../apache/tuscany/sca/core/work/FailingWork.java | 53 ----- .../sca/core/work/JSR237MyFailingRunnable.java | 43 ---- .../tuscany/sca/core/work/JSR237MyRunnable.java | 71 ------ .../sca/core/work/JSR237MyRunnerListener.java | 154 ------------- .../sca/core/work/Jsr237WorkSchedulerTestCase.java | 240 -------------------- .../tuscany/sca/core/work/TestWorkListener.java | 153 ------------- .../core/work/ThreadPoolWorkManagerTestCase.java | 243 -------------------- .../tuscany/sca/core/work/TimeDelayWork.java | 86 -------- .../tuscany/sca/core/work/impl/FailingWork.java | 55 +++++ .../core/work/impl/JSR237MyFailingRunnable.java | 43 ++++ .../sca/core/work/impl/JSR237MyRunnable.java | 71 ++++++ .../sca/core/work/impl/JSR237MyRunnerListener.java | 154 +++++++++++++ .../work/impl/Jsr237WorkSchedulerTestCase.java | 241 ++++++++++++++++++++ .../sca/core/work/impl/TestWorkListener.java | 155 +++++++++++++ .../work/impl/ThreadPoolWorkManagerTestCase.java | 244 +++++++++++++++++++++ .../tuscany/sca/core/work/impl/TimeDelayWork.java | 88 ++++++++ 36 files changed, 2048 insertions(+), 2096 deletions(-) delete mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/DefaultWorkScheduler.java delete mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManager.java delete mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Work.java delete mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkEvent.java delete mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkItem.java delete mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkListener.java create mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/DefaultWorkScheduler.java create mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/ThreadPoolWorkManager.java create mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/Work.java create mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkEvent.java create mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkItem.java create mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkListener.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistryTestCase.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/CallbackInterfaceInterceptorTestCase.java.fixme create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/InvocationChainImplTestCase.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/NonBlockingInterceptorTestCase.java.fixme delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/CallbackInterfaceInterceptorTestCase.java.fixme delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/InvocationChainImplTestCase.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/NonBlockingInterceptorTestCase.java.fixme delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/FailingWork.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyFailingRunnable.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyRunnable.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyRunnerListener.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/Jsr237WorkSchedulerTestCase.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/TestWorkListener.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManagerTestCase.java delete mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/TimeDelayWork.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/FailingWork.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyFailingRunnable.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyRunnable.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyRunnerListener.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/Jsr237WorkSchedulerTestCase.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/TestWorkListener.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/ThreadPoolWorkManagerTestCase.java create mode 100644 java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/TimeDelayWork.java (limited to 'java/sca/modules/core/src') diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/DefaultWorkScheduler.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/DefaultWorkScheduler.java deleted file mode 100644 index 2085a796ab..0000000000 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/DefaultWorkScheduler.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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.core.work; - -import java.security.AccessController; -import java.security.PrivilegedAction; - -import org.apache.tuscany.sca.work.NotificationListener; -import org.apache.tuscany.sca.work.WorkScheduler; -import org.apache.tuscany.sca.work.WorkSchedulerException; - -/** - * A work scheduler implementation based on a JSR 237 work manager. - *

- *

- * This needs a JSR 237 work manager implementation available for scheduling work. Instances can be configured with a - * work manager implementation that is injected in. It is the responsibility of the runtime environment to make a work - * manager implementation available. For example, if the managed environment supports work manager the runtime can use - * the appropriate lookup mechanism to inject the work manager implementation.

- * - * @version $Rev$ $Date$ - */ -public class DefaultWorkScheduler implements WorkScheduler { - - /** - * Underlying JSR-237 work manager - */ - private ThreadPoolWorkManager jsr237WorkManager; - - /** - * Initializes the JSR 237 work manager. - * - * @param jsr237WorkManager JSR 237 work manager. - */ - public DefaultWorkScheduler() { - } - - private synchronized ThreadPoolWorkManager getWorkManager() { - if (jsr237WorkManager != null) { - return jsr237WorkManager; - } -// try { -// InitialContext ctx = new InitialContext(); -// jsr237WorkManager = (ThreadPoolWorkManager)ctx.lookup("java:comp/env/wm/TuscanyWorkManager"); -// } catch (Throwable e) { -// // ignore -// } - if (jsr237WorkManager == null) { - jsr237WorkManager = new ThreadPoolWorkManager(10); - } - return jsr237WorkManager; - } - - /** - * Schedules a unit of work for future execution. The notification listener is used to register interest in - * callbacks regarding the status of the work. - * - * @param work The unit of work that needs to be asynchronously executed. - */ - public void scheduleWork(T work) { - scheduleWork(work, null); - } - - /** - * Schedules a unit of work for future execution. The notification listener is used to register interest in - * callbacks regarding the status of the work. - * - * @param work The unit of work that needs to be asynchronously executed. - * @param listener Notification listener for callbacks. - */ - public void scheduleWork(T work, NotificationListener listener) { - - if (work == null) { - throw new IllegalArgumentException("Work cannot be null"); - } - - Work jsr237Work = new Work(work); - try { - if (listener == null) { - getWorkManager().schedule(jsr237Work); - } else { - Jsr237WorkListener jsr237WorkListener = new Jsr237WorkListener(listener, work); - getWorkManager().schedule(jsr237Work, jsr237WorkListener); - } - } catch (IllegalArgumentException ex) { - if (listener != null) { - listener.workRejected(work); - } else { - throw new WorkSchedulerException(ex); - } - } catch (Exception ex) { - throw new WorkSchedulerException(ex); - } - - } - - public void destroy() { - if (jsr237WorkManager instanceof ThreadPoolWorkManager) { - // Allow privileged access to modify threads. Requires RuntimePermission in security - // policy. - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ((ThreadPoolWorkManager)jsr237WorkManager).destroy(); - return null; - } - }); - } - } - - /* - * WorkListener for keeping track of work status callbacks. - * - */ - private class Jsr237WorkListener implements WorkListener { - - // Notification listener - private NotificationListener listener; - - // Work - private T work; - - /* - * Initializes the notification listener. - */ - public Jsr237WorkListener(NotificationListener listener, T work) { - this.listener = listener; - this.work = work; - } - - /* - * Callback when the work is accepted. - */ - public void workAccepted(WorkEvent workEvent) { - T work = getWork(); - listener.workAccepted(work); - } - - /* - * Callback when the work is rejected. - */ - public void workRejected(WorkEvent workEvent) { - T work = getWork(); - listener.workRejected(work); - } - - /* - * Callback when the work is started. - */ - public void workStarted(WorkEvent workEvent) { - T work = getWork(); - listener.workStarted(work); - } - - /* - * Callback when the work is completed. - */ - public void workCompleted(WorkEvent workEvent) { - T work = getWork(); - Exception exception = workEvent.getException(); - if (exception != null) { - listener.workFailed(work, exception); - } else { - listener.workCompleted(work); - } - } - - /* - * Gets the underlying work from the work event. - */ - private T getWork() { - return work; - } - - } -} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManager.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManager.java deleted file mode 100644 index dad5968f65..0000000000 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManager.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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.core.work; - -import java.rmi.server.UID; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ThreadFactory; - -import org.apache.tuscany.sca.work.WorkSchedulerException; -import org.osoa.sca.annotations.Destroy; - -/** - * A thread-pool based implementation for the JSR-237 work manager. - *

- *

- * This implementation supports only local work. - *

- * TODO Elaborate the implementation.

- * - * @version $Rev$ $Date$ - */ -public class ThreadPoolWorkManager { - - // Map of work items currently handled by the work manager - private Map workItems = new ConcurrentHashMap(); - - // Thread-pool - private ExecutorService executor; - - /** - * Initializes the thread-pool. - * - * @param threadPoolSize Thread-pool size. - * @throws IllegalArgumentException if threadPoolSize < 1 - */ - public ThreadPoolWorkManager(int threadPoolSize) { - if (threadPoolSize < 1) { - throw new IllegalArgumentException("Invalid threadPoolSize of " - + threadPoolSize + ". It must be >= 1"); - } - - // Creates a new Executor, use a custom ThreadFactory that - // creates daemon threads. - executor = Executors.newFixedThreadPool(threadPoolSize, new ThreadFactory() { - public Thread newThread(Runnable r) { - Thread thread = new Thread(r); - thread.setDaemon(true); - return thread; - } - }); - } - - /** - * Schedules a unit of work asynchronously. - * - * @param work Work that needs to be scheduled. - * @return Work Work item representing the asynchronous work - */ - public WorkItem schedule(Work work) throws IllegalArgumentException { - return schedule(work, null); - } - - /** - * Schedules a unit of work asynchronously. - * - * @param work Work that needs to be scheduled. - * @param workListener Work listener for callbacks. - * @return Work Work item representing the asynchronous work - */ - public WorkItem schedule(Work work, WorkListener workListener) throws IllegalArgumentException { - - WorkItem workItem = new WorkItem(new UID().toString(), work); - if (workListener != null) { - workItems.put(workItem, workListener); - } - workAccepted(workItem, work); - if (scheduleWork(work, workItem)) { - return workItem; - } else { - workItem.setStatus(WorkEvent.WORK_REJECTED); - if (workListener != null) { - workListener.workRejected(new WorkEvent(workItem)); - } - throw new IllegalArgumentException("Unable to schedule work"); - } - } - - /** - * Wait for all the specified units of work to finish. - * - * @param works Units of the work that need to finish. - * @param timeout Timeout for waiting for the units of work to finish. - */ - public boolean waitForAll(Collection works, long timeout) { - throw new UnsupportedOperationException("waitForAll not supported"); - } - - /** - * Wait for any of the specified units of work to finish. - * - * @param works Units of the work that need to finish. - * @param timeout Timeout for waiting for the units of work to finish. - */ - public Collection waitForAny(Collection works, long timeout) { - throw new UnsupportedOperationException("waitForAny not supported"); - } - - /** - * Method provided for subclasses to indicate a work acceptance. - * - * @param workItem Work item representing the work that was accepted. - * @param work Work that was accepted. - */ - private void workAccepted(final WorkItem workItem, final Work work) { - WorkListener listener = workItems.get(workItem); - if (listener != null) { - workItem.setStatus(WorkEvent.WORK_ACCEPTED); - WorkEvent event = new WorkEvent(workItem); - listener.workAccepted(event); - } - } - - /* - * Method to indicate a work start. - */ - private void workStarted(final WorkItem workItem, final Work work) { - WorkListener listener = workItems.get(workItem); - if (listener != null) { - workItem.setStatus(WorkEvent.WORK_STARTED); - WorkEvent event = new WorkEvent(workItem); - listener.workStarted(event); - } - } - - /* - * Method to indicate a work completion. - */ - private void workCompleted(final WorkItem workItem, final Work work) { - workCompleted(workItem, work, null); - } - - /* - * Method to indicate a work completion. - */ - private void workCompleted(final WorkItem workItem, final Work work, final WorkSchedulerException exception) { - WorkListener listener = workItems.get(workItem); - if (listener != null) { - workItem.setStatus(WorkEvent.WORK_COMPLETED); - workItem.setResult(work); - workItem.setException(exception); - WorkEvent event = new WorkEvent(workItem); - listener.workCompleted(event); - workItems.remove(workItem); - } - } - - /* - * Schedules the work using the ThreadPool. - */ - private boolean scheduleWork(final Work work, final WorkItem workItem) { - try { - executor.execute(new DecoratingWork(workItem, work)); - return true; - } catch (RejectedExecutionException ex) { - return false; - } - } - - /* - * Class that decorates the original worker so that it can get callbacks when work is done. - */ - private final class DecoratingWork implements Runnable { - - // Work item for this work. - private WorkItem workItem; - - // The original work. - private Work decoratedWork; - - /* - * Initializes the work item and underlying work. - */ - private DecoratingWork(final WorkItem workItem, final Work decoratedWork) { - this.workItem = workItem; - this.decoratedWork = decoratedWork; - } - - /* - * Overrides the run method. - */ - public void run() { - workStarted(workItem, decoratedWork); - try { - decoratedWork.run(); - workCompleted(workItem, decoratedWork); - } catch (Throwable th) { - workCompleted(workItem, decoratedWork, new WorkSchedulerException(th.getMessage(), th)); - } - } - - } - - @Destroy - public void destroy() { - executor.shutdown(); - } - -} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Work.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Work.java deleted file mode 100644 index c521c60f79..0000000000 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/Work.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.core.work; - -/** - * JCA work wrapper. - * - * @version $Rev$ $Date$ - */ -public class Work { - - // Work that is being executed. - private T work; - - /* - * Initializes the work instance. - */ - public Work(T work) { - this.work = work; - } - - /* - * Returns the completed work. - */ - public T getWork() { - return work; - } - - /* - * Release the work. - */ - public void release() { - } - - /* - * Work attributes are not daemon. - */ - public boolean isDaemon() { - return false; - } - - /* - * Runs the work. - */ - public void run() { - work.run(); - } -} \ No newline at end of file diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkEvent.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkEvent.java deleted file mode 100644 index 8e9a3b4c53..0000000000 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkEvent.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.core.work; - -import org.apache.tuscany.sca.work.WorkSchedulerException; - - - -/** - * Default immutable implementation of the WorkEvent class. - * - * @version $Rev$ $Date$ - */ -class WorkEvent { - - public static final int WORK_ACCEPTED = 1; - public static final int WORK_REJECTED = 2; - public static final int WORK_STARTED = 3; - public static final int WORK_COMPLETED = 4; - - // Work item for this event - private WorkItem workItem; - - // Exception if something has gone wrong - private WorkSchedulerException exception; - - /** - * Instantiates the event. - * - * @param workItem Work item for this event. - */ - public WorkEvent(final WorkItem workItem) { - this.workItem = workItem; - this.exception = workItem.getException(); - } - - /** - * Returns the work type based on whether the work was accepted, started, - * rejected or completed. - * - * @return Work type. - */ - public int getType() { - return workItem.getStatus(); - } - - /** - * Returns the work item associated with this work type. - * - * @return Work item. - */ - public WorkItem getWorkItem() { - return workItem; - } - - /** - * Returns the exception if the work completed with an exception. - * - * @return Work exception. - */ - public WorkSchedulerException getException() { - return exception; - } -} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkItem.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkItem.java deleted file mode 100644 index 8320c7364f..0000000000 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkItem.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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.core.work; - -import org.apache.tuscany.sca.work.WorkSchedulerException; - -/** - * An identity based immutable implementation of the WorkItem - * interface. - * - * @version $Rev$ $Date$ - */ -class WorkItem { - - // Id scoped for the VM - private String id; - - // Status - private int status = -1; - - // Result - private Work result; - - // Original work - private Work originalWork; - - // Exception - private WorkSchedulerException exception; - - /** - * Instantiates an id for this item. - * - * @param id of this work event. - */ - protected WorkItem(final String id, final Work orginalWork) { - this.id = id; - this.originalWork = orginalWork; - } - - /** - * Returns the id. - * - * @return Id of this item. - */ - public String getId() { - return id; - } - - /** - * Returns the original work. - * - * @return Original work. - */ - public Work getOriginalWork() { - return originalWork; - } - - /** - * Returns the work result if the work completed. - * - * @return Work. - * @throws WorkException If the work completed with an exception. - */ - public Work getResult() { - return result; - } - - /** - * Sets the result. - * - * @param result Result. - */ - protected void setResult(final Work result) { - this.result = result; - } - - /** - * Returns the exception if work completed with an exception. - * - * @return Work exception. - */ - protected WorkSchedulerException getException() { - return exception; - } - - /** - * Sets the exception. - * - * @param exception Exception. - */ - protected void setException(final WorkSchedulerException exception) { - this.exception = exception; - } - - /** - * Returns the work type based on whether the work was accepted, started, - * rejected or completed. - * - * @return Work status. - */ - public int getStatus() { - return status; - } - - /** - * Sets the status. - * - * @param status Status. - */ - protected void setStatus(final int status) { - this.status = status; - } - - /** - * @see Object#hashCode() - */ - @Override - public int hashCode() { - return id.hashCode(); - } - - /** - * Indicates whether some other object is "equal to" this one. - * - * @param obj Object to be compared. - * @return true if this object is the same as the obj argument; false - * otherwise.. - */ - @Override - public boolean equals(final Object obj) { - return (obj != null) && (obj.getClass() == WorkItem.class) && ((WorkItem) obj).id.equals(id); - } - - /** - * Compares this object with the specified object for order. Returns a - * negative integer, zero, or a positive integer as this object is less - * than, equal to, or greater than the specified object. - * - * @param o Object to be compared. - * @return A negative integer, zero, or a positive integer as this object - * is less than, equal to, or greater than the specified object. - * @throws ClassCastException needs better documentation. - */ - public int compareTo(final Object o) { - if (o.getClass() != WorkItem.class) { - throw new ClassCastException(o.getClass().getName()); - } else { - return ((WorkItem) o).getId().compareTo(getId()); - } - } -} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkListener.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkListener.java deleted file mode 100644 index 90b11108e9..0000000000 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/WorkListener.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.core.work; - -public interface WorkListener { - - long IMMEDIATE = 0; - long INDEFINITE = java.lang.Long.MAX_VALUE; - - void workAccepted(WorkEvent event); - void workCompleted(WorkEvent event); - void workRejected(WorkEvent event); - void workStarted(WorkEvent event); - -} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/DefaultWorkScheduler.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/DefaultWorkScheduler.java new file mode 100644 index 0000000000..3df2f7188b --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/DefaultWorkScheduler.java @@ -0,0 +1,191 @@ +/* + * 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.core.work.impl; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +import org.apache.tuscany.sca.work.NotificationListener; +import org.apache.tuscany.sca.work.WorkScheduler; +import org.apache.tuscany.sca.work.WorkSchedulerException; + +/** + * A work scheduler implementation based on a JSR 237 work manager. + *

+ *

+ * This needs a JSR 237 work manager implementation available for scheduling work. Instances can be configured with a + * work manager implementation that is injected in. It is the responsibility of the runtime environment to make a work + * manager implementation available. For example, if the managed environment supports work manager the runtime can use + * the appropriate lookup mechanism to inject the work manager implementation.

+ * + * @version $Rev$ $Date$ + */ +public class DefaultWorkScheduler implements WorkScheduler { + + /** + * Underlying JSR-237 work manager + */ + private ThreadPoolWorkManager jsr237WorkManager; + + /** + * Initializes the JSR 237 work manager. + * + * @param jsr237WorkManager JSR 237 work manager. + */ + public DefaultWorkScheduler() { + } + + private synchronized ThreadPoolWorkManager getWorkManager() { + if (jsr237WorkManager != null) { + return jsr237WorkManager; + } +// try { +// InitialContext ctx = new InitialContext(); +// jsr237WorkManager = (ThreadPoolWorkManager)ctx.lookup("java:comp/env/wm/TuscanyWorkManager"); +// } catch (Throwable e) { +// // ignore +// } + if (jsr237WorkManager == null) { + jsr237WorkManager = new ThreadPoolWorkManager(10); + } + return jsr237WorkManager; + } + + /** + * Schedules a unit of work for future execution. The notification listener is used to register interest in + * callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + */ + public void scheduleWork(T work) { + scheduleWork(work, null); + } + + /** + * Schedules a unit of work for future execution. The notification listener is used to register interest in + * callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + * @param listener Notification listener for callbacks. + */ + public void scheduleWork(T work, NotificationListener listener) { + + if (work == null) { + throw new IllegalArgumentException("Work cannot be null"); + } + + Work jsr237Work = new Work(work); + try { + if (listener == null) { + getWorkManager().schedule(jsr237Work); + } else { + Jsr237WorkListener jsr237WorkListener = new Jsr237WorkListener(listener, work); + getWorkManager().schedule(jsr237Work, jsr237WorkListener); + } + } catch (IllegalArgumentException ex) { + if (listener != null) { + listener.workRejected(work); + } else { + throw new WorkSchedulerException(ex); + } + } catch (Exception ex) { + throw new WorkSchedulerException(ex); + } + + } + + public void destroy() { + if (jsr237WorkManager instanceof ThreadPoolWorkManager) { + // Allow privileged access to modify threads. Requires RuntimePermission in security + // policy. + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ((ThreadPoolWorkManager)jsr237WorkManager).destroy(); + return null; + } + }); + } + } + + /* + * WorkListener for keeping track of work status callbacks. + * + */ + private class Jsr237WorkListener implements WorkListener { + + // Notification listener + private NotificationListener listener; + + // Work + private T work; + + /* + * Initializes the notification listener. + */ + public Jsr237WorkListener(NotificationListener listener, T work) { + this.listener = listener; + this.work = work; + } + + /* + * Callback when the work is accepted. + */ + public void workAccepted(WorkEvent workEvent) { + T work = getWork(); + listener.workAccepted(work); + } + + /* + * Callback when the work is rejected. + */ + public void workRejected(WorkEvent workEvent) { + T work = getWork(); + listener.workRejected(work); + } + + /* + * Callback when the work is started. + */ + public void workStarted(WorkEvent workEvent) { + T work = getWork(); + listener.workStarted(work); + } + + /* + * Callback when the work is completed. + */ + public void workCompleted(WorkEvent workEvent) { + T work = getWork(); + Exception exception = workEvent.getException(); + if (exception != null) { + listener.workFailed(work, exception); + } else { + listener.workCompleted(work); + } + } + + /* + * Gets the underlying work from the work event. + */ + private T getWork() { + return work; + } + + } +} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/ThreadPoolWorkManager.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/ThreadPoolWorkManager.java new file mode 100644 index 0000000000..0da04d4646 --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/ThreadPoolWorkManager.java @@ -0,0 +1,229 @@ +/* + * 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.core.work.impl; + +import java.rmi.server.UID; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadFactory; + +import org.apache.tuscany.sca.work.WorkSchedulerException; +import org.osoa.sca.annotations.Destroy; + +/** + * A thread-pool based implementation for the JSR-237 work manager. + *

+ *

+ * This implementation supports only local work. + *

+ * TODO Elaborate the implementation.

+ * + * @version $Rev$ $Date$ + */ +public class ThreadPoolWorkManager { + + // Map of work items currently handled by the work manager + private Map workItems = new ConcurrentHashMap(); + + // Thread-pool + private ExecutorService executor; + + /** + * Initializes the thread-pool. + * + * @param threadPoolSize Thread-pool size. + * @throws IllegalArgumentException if threadPoolSize < 1 + */ + public ThreadPoolWorkManager(int threadPoolSize) { + if (threadPoolSize < 1) { + throw new IllegalArgumentException("Invalid threadPoolSize of " + + threadPoolSize + ". It must be >= 1"); + } + + // Creates a new Executor, use a custom ThreadFactory that + // creates daemon threads. + executor = Executors.newFixedThreadPool(threadPoolSize, new ThreadFactory() { + public Thread newThread(Runnable r) { + Thread thread = new Thread(r); + thread.setDaemon(true); + return thread; + } + }); + } + + /** + * Schedules a unit of work asynchronously. + * + * @param work Work that needs to be scheduled. + * @return Work Work item representing the asynchronous work + */ + public WorkItem schedule(Work work) throws IllegalArgumentException { + return schedule(work, null); + } + + /** + * Schedules a unit of work asynchronously. + * + * @param work Work that needs to be scheduled. + * @param workListener Work listener for callbacks. + * @return Work Work item representing the asynchronous work + */ + public WorkItem schedule(Work work, WorkListener workListener) throws IllegalArgumentException { + + WorkItem workItem = new WorkItem(new UID().toString(), work); + if (workListener != null) { + workItems.put(workItem, workListener); + } + workAccepted(workItem, work); + if (scheduleWork(work, workItem)) { + return workItem; + } else { + workItem.setStatus(WorkEvent.WORK_REJECTED); + if (workListener != null) { + workListener.workRejected(new WorkEvent(workItem)); + } + throw new IllegalArgumentException("Unable to schedule work"); + } + } + + /** + * Wait for all the specified units of work to finish. + * + * @param works Units of the work that need to finish. + * @param timeout Timeout for waiting for the units of work to finish. + */ + public boolean waitForAll(Collection> works, long timeout) { + throw new UnsupportedOperationException("waitForAll not supported"); + } + + /** + * Wait for any of the specified units of work to finish. + * + * @param works Units of the work that need to finish. + * @param timeout Timeout for waiting for the units of work to finish. + */ + public Collection> waitForAny(Collection> works, long timeout) { + throw new UnsupportedOperationException("waitForAny not supported"); + } + + /** + * Method provided for subclasses to indicate a work acceptance. + * + * @param workItem Work item representing the work that was accepted. + * @param work Work that was accepted. + */ + private void workAccepted(final WorkItem workItem, final Work work) { + WorkListener listener = workItems.get(workItem); + if (listener != null) { + workItem.setStatus(WorkEvent.WORK_ACCEPTED); + WorkEvent event = new WorkEvent(workItem); + listener.workAccepted(event); + } + } + + /* + * Method to indicate a work start. + */ + private void workStarted(final WorkItem workItem, final Work work) { + WorkListener listener = workItems.get(workItem); + if (listener != null) { + workItem.setStatus(WorkEvent.WORK_STARTED); + WorkEvent event = new WorkEvent(workItem); + listener.workStarted(event); + } + } + + /* + * Method to indicate a work completion. + */ + private void workCompleted(final WorkItem workItem, final Work work) { + workCompleted(workItem, work, null); + } + + /* + * Method to indicate a work completion. + */ + private void workCompleted(final WorkItem workItem, final Work work, final WorkSchedulerException exception) { + WorkListener listener = workItems.get(workItem); + if (listener != null) { + workItem.setStatus(WorkEvent.WORK_COMPLETED); + workItem.setResult(work); + workItem.setException(exception); + WorkEvent event = new WorkEvent(workItem); + listener.workCompleted(event); + workItems.remove(workItem); + } + } + + /* + * Schedules the work using the ThreadPool. + */ + private boolean scheduleWork(final Work work, final WorkItem workItem) { + try { + executor.execute(new DecoratingWork(workItem, work)); + return true; + } catch (RejectedExecutionException ex) { + return false; + } + } + + /* + * Class that decorates the original worker so that it can get callbacks when work is done. + */ + private final class DecoratingWork implements Runnable { + + // Work item for this work. + private WorkItem workItem; + + // The original work. + private Work decoratedWork; + + /* + * Initializes the work item and underlying work. + */ + private DecoratingWork(final WorkItem workItem, final Work decoratedWork) { + this.workItem = workItem; + this.decoratedWork = decoratedWork; + } + + /* + * Overrides the run method. + */ + public void run() { + workStarted(workItem, decoratedWork); + try { + decoratedWork.run(); + workCompleted(workItem, decoratedWork); + } catch (Throwable th) { + workCompleted(workItem, decoratedWork, new WorkSchedulerException(th.getMessage(), th)); + } + } + + } + + @Destroy + public void destroy() { + executor.shutdown(); + } + +} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/Work.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/Work.java new file mode 100644 index 0000000000..ca06d0e854 --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/Work.java @@ -0,0 +1,65 @@ +/* + * 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.core.work.impl; + +/** + * JCA work wrapper. + * + * @version $Rev$ $Date$ + */ +public class Work { + + // Work that is being executed. + private T work; + + /* + * Initializes the work instance. + */ + public Work(T work) { + this.work = work; + } + + /* + * Returns the completed work. + */ + public T getWork() { + return work; + } + + /* + * Release the work. + */ + public void release() { + } + + /* + * Work attributes are not daemon. + */ + public boolean isDaemon() { + return false; + } + + /* + * Runs the work. + */ + public void run() { + work.run(); + } +} \ No newline at end of file diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkEvent.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkEvent.java new file mode 100644 index 0000000000..4580011806 --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkEvent.java @@ -0,0 +1,80 @@ +/* + * 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.core.work.impl; + +import org.apache.tuscany.sca.work.WorkSchedulerException; + + + +/** + * Default immutable implementation of the WorkEvent class. + * + * @version $Rev$ $Date$ + */ +class WorkEvent { + + public static final int WORK_ACCEPTED = 1; + public static final int WORK_REJECTED = 2; + public static final int WORK_STARTED = 3; + public static final int WORK_COMPLETED = 4; + + // Work item for this event + private WorkItem workItem; + + // Exception if something has gone wrong + private WorkSchedulerException exception; + + /** + * Instantiates the event. + * + * @param workItem Work item for this event. + */ + public WorkEvent(final WorkItem workItem) { + this.workItem = workItem; + this.exception = workItem.getException(); + } + + /** + * Returns the work type based on whether the work was accepted, started, + * rejected or completed. + * + * @return Work type. + */ + public int getType() { + return workItem.getStatus(); + } + + /** + * Returns the work item associated with this work type. + * + * @return Work item. + */ + public WorkItem getWorkItem() { + return workItem; + } + + /** + * Returns the exception if the work completed with an exception. + * + * @return Work exception. + */ + public WorkSchedulerException getException() { + return exception; + } +} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkItem.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkItem.java new file mode 100644 index 0000000000..0fc104d0fc --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkItem.java @@ -0,0 +1,167 @@ +/* + * 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.core.work.impl; + +import org.apache.tuscany.sca.work.WorkSchedulerException; + +/** + * An identity based immutable implementation of the WorkItem + * interface. + * + * @version $Rev$ $Date$ + */ +class WorkItem { + + // Id scoped for the VM + private String id; + + // Status + private int status = -1; + + // Result + private Work result; + + // Original work + private Work originalWork; + + // Exception + private WorkSchedulerException exception; + + /** + * Instantiates an id for this item. + * + * @param id of this work event. + */ + protected WorkItem(final String id, final Work orginalWork) { + this.id = id; + this.originalWork = orginalWork; + } + + /** + * Returns the id. + * + * @return Id of this item. + */ + public String getId() { + return id; + } + + /** + * Returns the original work. + * + * @return Original work. + */ + public Work getOriginalWork() { + return originalWork; + } + + /** + * Returns the work result if the work completed. + * + * @return Work. + * @throws WorkException If the work completed with an exception. + */ + public Work getResult() { + return result; + } + + /** + * Sets the result. + * + * @param result Result. + */ + protected void setResult(final Work result) { + this.result = result; + } + + /** + * Returns the exception if work completed with an exception. + * + * @return Work exception. + */ + protected WorkSchedulerException getException() { + return exception; + } + + /** + * Sets the exception. + * + * @param exception Exception. + */ + protected void setException(final WorkSchedulerException exception) { + this.exception = exception; + } + + /** + * Returns the work type based on whether the work was accepted, started, + * rejected or completed. + * + * @return Work status. + */ + public int getStatus() { + return status; + } + + /** + * Sets the status. + * + * @param status Status. + */ + protected void setStatus(final int status) { + this.status = status; + } + + /** + * @see Object#hashCode() + */ + @Override + public int hashCode() { + return id.hashCode(); + } + + /** + * Indicates whether some other object is "equal to" this one. + * + * @param obj Object to be compared. + * @return true if this object is the same as the obj argument; false + * otherwise.. + */ + @Override + public boolean equals(final Object obj) { + return (obj != null) && (obj.getClass() == WorkItem.class) && ((WorkItem) obj).id.equals(id); + } + + /** + * Compares this object with the specified object for order. Returns a + * negative integer, zero, or a positive integer as this object is less + * than, equal to, or greater than the specified object. + * + * @param o Object to be compared. + * @return A negative integer, zero, or a positive integer as this object + * is less than, equal to, or greater than the specified object. + * @throws ClassCastException needs better documentation. + */ + public int compareTo(final Object o) { + if (o.getClass() != WorkItem.class) { + throw new ClassCastException(o.getClass().getName()); + } else { + return ((WorkItem) o).getId().compareTo(getId()); + } + } +} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkListener.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkListener.java new file mode 100644 index 0000000000..facb2dfe56 --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/work/impl/WorkListener.java @@ -0,0 +1,32 @@ +/* + * 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.core.work.impl; + +public interface WorkListener { + + long IMMEDIATE = 0; + long INDEFINITE = java.lang.Long.MAX_VALUE; + + void workAccepted(WorkEvent event); + void workCompleted(WorkEvent event); + void workRejected(WorkEvent event); + void workStarted(WorkEvent event); + +} diff --git a/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.work.WorkScheduler b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.work.WorkScheduler index 93d93491a8..9923ba5927 100644 --- a/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.work.WorkScheduler +++ b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.work.WorkScheduler @@ -15,4 +15,4 @@ # specific language governing permissions and limitations # under the License. -org.apache.tuscany.sca.core.work.DefaultWorkScheduler +org.apache.tuscany.sca.core.work.impl.DefaultWorkScheduler diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistryTestCase.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistryTestCase.java deleted file mode 100644 index d3e31eb570..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/DefaultExtensionPointRegistryTestCase.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.core; - -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; - -import org.junit.Before; -import org.junit.Test; - -public class DefaultExtensionPointRegistryTestCase { - private ExtensionPointRegistry registry; - - @Before - public void setUp() throws Exception { - registry = new DefaultExtensionPointRegistry(); - } - - @Test - public void testRegistry() { - MyExtensionPoint service = new MyExtensionPointImpl(); - registry.addExtensionPoint(service); - assertSame(service, registry.getExtensionPoint(MyExtensionPoint.class)); - registry.removeExtensionPoint(service); - assertNull(registry.getExtensionPoint(MyExtensionPoint.class)); - } - - public static interface MyExtensionPoint { - void doSomething(); - } - - private static class MyExtensionPointImpl implements MyExtensionPoint { - - public void doSomething() { - } - - } - -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/CallbackInterfaceInterceptorTestCase.java.fixme b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/CallbackInterfaceInterceptorTestCase.java.fixme new file mode 100644 index 0000000000..27985425bc --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/CallbackInterfaceInterceptorTestCase.java.fixme @@ -0,0 +1,62 @@ +/* + * 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.core.wire; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.core.assembly.impl.EndpointReferenceImpl; +import org.apache.tuscany.sca.core.invocation.CallbackInterfaceInterceptor; +import org.apache.tuscany.sca.core.invocation.impl.MessageFactoryImpl; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Message; +import org.easymock.EasyMock; +import org.osoa.sca.NoRegisteredCallbackException; + +/** + * @version $Rev$ $Date$ + */ +public class CallbackInterfaceInterceptorTestCase extends TestCase { + + public void testHasCallbackObject() { + CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(); + Interceptor next = EasyMock.createMock(Interceptor.class); + EasyMock.expect(next.invoke(EasyMock.isA(Message.class))).andReturn(null); + EasyMock.replay(next); + interceptor.setNext(next); + Message msg = new MessageFactoryImpl().createMessage(); + msg.setFrom(new EndpointReferenceImpl("uri")); + msg.getFrom().getReferenceParameters().setCallbackObjectID("ABC"); + interceptor.invoke(msg); + EasyMock.verify(next); + } + + public void testNoCallbackObject() { + CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(); + Message msg = new MessageFactoryImpl().createMessage(); + msg.setFrom(new EndpointReferenceImpl("uri")); + msg.getFrom().getReferenceParameters().setCallbackObjectID(null); + try { + interceptor.invoke(msg); + fail(); + } catch (NoRegisteredCallbackException e) { + // expected + } + } + +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/InvocationChainImplTestCase.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/InvocationChainImplTestCase.java new file mode 100644 index 0000000000..866b0994e7 --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/InvocationChainImplTestCase.java @@ -0,0 +1,96 @@ +/* + * 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.core.invocation.impl; + +import static org.junit.Assert.assertEquals; + +import org.apache.tuscany.sca.core.invocation.impl.InvocationChainImpl; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.impl.OperationImpl; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.InvocationChain; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.invocation.Phase; +import org.junit.Test; + +/** + * @version $Rev$ $Date$ + */ +public class InvocationChainImplTestCase { + + @Test + public void testInsertAtEnd() throws Exception { + Operation op = newOperation("foo"); + InvocationChain chain = new InvocationChainImpl(op, op, true); + Interceptor inter2 = new MockInterceptor(); + Interceptor inter1 = new MockInterceptor(); + chain.addInterceptor(inter1); + chain.addInterceptor(inter2); + Interceptor head = (Interceptor)chain.getHeadInvoker(); + assertEquals(inter1, head); + assertEquals(inter2, head.getNext()); + assertEquals(inter2, chain.getTailInvoker()); + + } + + @Test + public void testAddByPhase() throws Exception { + Operation op = newOperation("foo"); + InvocationChain chain = new InvocationChainImpl(op, op, false); + Interceptor inter1 = new MockInterceptor(); + Interceptor inter2 = new MockInterceptor(); + Interceptor inter3 = new MockInterceptor(); + Interceptor inter4 = new MockInterceptor(); + chain.addInterceptor(inter3); // SERVICE + chain.addInterceptor(Phase.IMPLEMENTATION_POLICY, inter4); + chain.addInterceptor(Phase.SERVICE_POLICY, inter2); + chain.addInterceptor(Phase.SERVICE_BINDING, inter1); + Interceptor head = (Interceptor)chain.getHeadInvoker(); + assertEquals(inter1, head); + assertEquals(inter2, inter1.getNext()); + assertEquals(inter3, inter2.getNext()); + assertEquals(inter4, inter3.getNext()); + assertEquals(inter4, chain.getTailInvoker()); + } + + private class MockInterceptor implements Interceptor { + + private Invoker next; + + public Message invoke(Message msg) { + return null; + } + + public void setNext(Invoker next) { + this.next = next; + } + + public Invoker getNext() { + return next; + } + + } + + private static Operation newOperation(String name) { + Operation operation = new OperationImpl(); + operation.setName(name); + return operation; + } +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/NonBlockingInterceptorTestCase.java.fixme b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/NonBlockingInterceptorTestCase.java.fixme new file mode 100644 index 0000000000..b8150d4edc --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/invocation/impl/NonBlockingInterceptorTestCase.java.fixme @@ -0,0 +1,74 @@ +/* + * 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.core.wire; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.getCurrentArguments; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import junit.framework.TestCase; + +import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor; +import org.apache.tuscany.sca.core.invocation.ThreadMessageContext; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.work.WorkScheduler; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * @version $Rev$ $Date$ + */ +public class NonBlockingInterceptorTestCase extends TestCase { + + public void testInvoke() throws Exception { + WorkScheduler scheduler = createMock(WorkScheduler.class); + scheduler.scheduleWork(isA(Runnable.class)); + expectLastCall().andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + Runnable runnable = (Runnable) getCurrentArguments()[0]; + runnable.run(); + return null; + } + }); + replay(scheduler); + Message context = createMock(Message.class); + //String convID = "convID"; + //TODO port to the new way of dealing with conversation IDs later + //EasyMock.expect(context.getConversationID()).andReturn(convID); + EasyMock.replay(context); + ThreadMessageContext.setMessageContext(context); + Message msg = createMock(Message.class); + //TODO port to the new way of dealing with conversation IDs later + //msg.setConversationID(convID); + Interceptor next = EasyMock.createMock(Interceptor.class); + EasyMock.expect(next.invoke(EasyMock.eq(msg))).andReturn(msg); + EasyMock.expect(msg.isFault()).andReturn(false); + EasyMock.replay(next); + EasyMock.replay(msg); + Interceptor interceptor = new NonBlockingInterceptor(scheduler, next); + interceptor.invoke(msg); + verify(context); + verify(next); + verify(msg); + } + +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/CallbackInterfaceInterceptorTestCase.java.fixme b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/CallbackInterfaceInterceptorTestCase.java.fixme deleted file mode 100644 index 27985425bc..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/CallbackInterfaceInterceptorTestCase.java.fixme +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.core.wire; - -import junit.framework.TestCase; - -import org.apache.tuscany.sca.core.assembly.impl.EndpointReferenceImpl; -import org.apache.tuscany.sca.core.invocation.CallbackInterfaceInterceptor; -import org.apache.tuscany.sca.core.invocation.impl.MessageFactoryImpl; -import org.apache.tuscany.sca.invocation.Interceptor; -import org.apache.tuscany.sca.invocation.Message; -import org.easymock.EasyMock; -import org.osoa.sca.NoRegisteredCallbackException; - -/** - * @version $Rev$ $Date$ - */ -public class CallbackInterfaceInterceptorTestCase extends TestCase { - - public void testHasCallbackObject() { - CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(); - Interceptor next = EasyMock.createMock(Interceptor.class); - EasyMock.expect(next.invoke(EasyMock.isA(Message.class))).andReturn(null); - EasyMock.replay(next); - interceptor.setNext(next); - Message msg = new MessageFactoryImpl().createMessage(); - msg.setFrom(new EndpointReferenceImpl("uri")); - msg.getFrom().getReferenceParameters().setCallbackObjectID("ABC"); - interceptor.invoke(msg); - EasyMock.verify(next); - } - - public void testNoCallbackObject() { - CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(); - Message msg = new MessageFactoryImpl().createMessage(); - msg.setFrom(new EndpointReferenceImpl("uri")); - msg.getFrom().getReferenceParameters().setCallbackObjectID(null); - try { - interceptor.invoke(msg); - fail(); - } catch (NoRegisteredCallbackException e) { - // expected - } - } - -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/InvocationChainImplTestCase.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/InvocationChainImplTestCase.java deleted file mode 100644 index cfd18ab18e..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/InvocationChainImplTestCase.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.core.wire; - -import static org.junit.Assert.assertEquals; - -import org.apache.tuscany.sca.core.invocation.impl.InvocationChainImpl; -import org.apache.tuscany.sca.interfacedef.Operation; -import org.apache.tuscany.sca.interfacedef.impl.OperationImpl; -import org.apache.tuscany.sca.invocation.Interceptor; -import org.apache.tuscany.sca.invocation.InvocationChain; -import org.apache.tuscany.sca.invocation.Invoker; -import org.apache.tuscany.sca.invocation.Message; -import org.apache.tuscany.sca.invocation.Phase; -import org.junit.Test; - -/** - * @version $Rev$ $Date$ - */ -public class InvocationChainImplTestCase { - - @Test - public void testInsertAtEnd() throws Exception { - Operation op = newOperation("foo"); - InvocationChain chain = new InvocationChainImpl(op, op, true); - Interceptor inter2 = new MockInterceptor(); - Interceptor inter1 = new MockInterceptor(); - chain.addInterceptor(inter1); - chain.addInterceptor(inter2); - Interceptor head = (Interceptor)chain.getHeadInvoker(); - assertEquals(inter1, head); - assertEquals(inter2, head.getNext()); - assertEquals(inter2, chain.getTailInvoker()); - - } - - @Test - public void testAddByPhase() throws Exception { - Operation op = newOperation("foo"); - InvocationChain chain = new InvocationChainImpl(op, op, false); - Interceptor inter1 = new MockInterceptor(); - Interceptor inter2 = new MockInterceptor(); - Interceptor inter3 = new MockInterceptor(); - Interceptor inter4 = new MockInterceptor(); - chain.addInterceptor(inter3); // SERVICE - chain.addInterceptor(Phase.IMPLEMENTATION_POLICY, inter4); - chain.addInterceptor(Phase.SERVICE_POLICY, inter2); - chain.addInterceptor(Phase.SERVICE_BINDING, inter1); - Interceptor head = (Interceptor)chain.getHeadInvoker(); - assertEquals(inter1, head); - assertEquals(inter2, inter1.getNext()); - assertEquals(inter3, inter2.getNext()); - assertEquals(inter4, inter3.getNext()); - assertEquals(inter4, chain.getTailInvoker()); - } - - private class MockInterceptor implements Interceptor { - - private Invoker next; - - public Message invoke(Message msg) { - return null; - } - - public void setNext(Invoker next) { - this.next = next; - } - - public Invoker getNext() { - return next; - } - - } - - private static Operation newOperation(String name) { - Operation operation = new OperationImpl(); - operation.setName(name); - return operation; - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/NonBlockingInterceptorTestCase.java.fixme b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/NonBlockingInterceptorTestCase.java.fixme deleted file mode 100644 index b8150d4edc..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/wire/NonBlockingInterceptorTestCase.java.fixme +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.core.wire; - -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expectLastCall; -import static org.easymock.EasyMock.getCurrentArguments; -import static org.easymock.EasyMock.isA; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; -import junit.framework.TestCase; - -import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor; -import org.apache.tuscany.sca.core.invocation.ThreadMessageContext; -import org.apache.tuscany.sca.invocation.Interceptor; -import org.apache.tuscany.sca.invocation.Message; -import org.apache.tuscany.sca.work.WorkScheduler; -import org.easymock.EasyMock; -import org.easymock.IAnswer; - -/** - * @version $Rev$ $Date$ - */ -public class NonBlockingInterceptorTestCase extends TestCase { - - public void testInvoke() throws Exception { - WorkScheduler scheduler = createMock(WorkScheduler.class); - scheduler.scheduleWork(isA(Runnable.class)); - expectLastCall().andStubAnswer(new IAnswer() { - public Object answer() throws Throwable { - Runnable runnable = (Runnable) getCurrentArguments()[0]; - runnable.run(); - return null; - } - }); - replay(scheduler); - Message context = createMock(Message.class); - //String convID = "convID"; - //TODO port to the new way of dealing with conversation IDs later - //EasyMock.expect(context.getConversationID()).andReturn(convID); - EasyMock.replay(context); - ThreadMessageContext.setMessageContext(context); - Message msg = createMock(Message.class); - //TODO port to the new way of dealing with conversation IDs later - //msg.setConversationID(convID); - Interceptor next = EasyMock.createMock(Interceptor.class); - EasyMock.expect(next.invoke(EasyMock.eq(msg))).andReturn(msg); - EasyMock.expect(msg.isFault()).andReturn(false); - EasyMock.replay(next); - EasyMock.replay(msg); - Interceptor interceptor = new NonBlockingInterceptor(scheduler, next); - interceptor.invoke(msg); - verify(context); - verify(next); - verify(msg); - } - -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/FailingWork.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/FailingWork.java deleted file mode 100644 index c69a1908e8..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/FailingWork.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.core.work; - - -/** - * Simple Work item that will throw an exception - * - * @version $Rev$ $Date$ - */ -public class FailingWork extends Work { - - public FailingWork() { - super(null); - } - - /** - * {@inheritDoc} - */ - public boolean isDaemon() { - return false; - } - - /** - * {@inheritDoc} - */ - public void release() { - } - - /** - * Throws an IllegalArgumentException - */ - public void run() { - System.out.println("Starting " + this + " and throwing an Exception"); - throw new IllegalArgumentException("Sample exception from " + this); - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyFailingRunnable.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyFailingRunnable.java deleted file mode 100644 index 91b45dfbcb..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyFailingRunnable.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.core.work; - -/** - * Simple Runnable that throws an IllegalArgumentException - * - * @version $Rev$ $Date$ - */ -public class JSR237MyFailingRunnable extends JSR237MyRunnable { - - /** - * Constructor - */ - public JSR237MyFailingRunnable() { - super(-1); - } - - /** - * Sleeps for a period of time defined by sleepTime - */ - @Override - public void run() { - System.out.println("Starting " + this + " and throwing an Exception"); - throw new IllegalArgumentException("Sample exception from " + this); - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyRunnable.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyRunnable.java deleted file mode 100644 index a7617f7a70..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyRunnable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.core.work; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Simple Runnable that is used for testing Jsr237WorkScheduler - * - * @version $Rev$ $Date$ - */ -public class JSR237MyRunnable implements Runnable { - - /** - * Count of workAccepted() method calls - */ - private AtomicInteger runCompletedCount = new AtomicInteger(); - - /** - * The amount of time to sleep in the Run loop - */ - private final long sleepTime; - - /** - * Constructor - * - * @param sleepTime The amount of time to sleep (in milliseconds) in the run() method - */ - public JSR237MyRunnable(long sleepTime) { - this.sleepTime = sleepTime; - } - - /** - * Sleeps for a period of time defined by sleepTime - */ - public void run() { - System.out.println("Starting " + this); - try { - Thread.sleep(sleepTime); - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.println("Done " + this); - runCompletedCount.incrementAndGet(); - } - - /** - * Returns the number of completed calls to run() - * - * @return The number of completed calls to run() - */ - public int getRunCompletedCount() { - return runCompletedCount.get(); - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyRunnerListener.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyRunnerListener.java deleted file mode 100644 index 75840efef4..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/JSR237MyRunnerListener.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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.core.work; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.tuscany.sca.work.NotificationListener; - -/** - * Simple NotificationListener that is used for testing Jsr237WorkScheduler - * - * @version $Rev$ $Date$ - */ -public class JSR237MyRunnerListener implements NotificationListener { - - /** - * Count of workAccepted() method calls - */ - private AtomicInteger workAcceptedCallCount = new AtomicInteger(); - - /** - * Count of workStarted() method calls - */ - private AtomicInteger workStartedCallCount = new AtomicInteger(); - - /** - * Count of workCompleted() method calls - */ - private AtomicInteger workCompletedCallCount = new AtomicInteger(); - - /** - * Count of workFailed() method calls - */ - private AtomicInteger workFailedCallCount = new AtomicInteger(); - - /** - * Count of workRejected() method calls - */ - private AtomicInteger workRejectedCallCount = new AtomicInteger(); - - /** - * List of all exceptions thrown by Work items - */ - private List workExceptions = Collections.synchronizedList(new ArrayList()); - - /** - * {@inheritDoc} - */ - public void workAccepted(JSR237MyRunnable work) { - workAcceptedCallCount.incrementAndGet(); - } - - /** - * {@inheritDoc} - */ - public void workCompleted(JSR237MyRunnable work) { - workCompletedCallCount.incrementAndGet(); - } - - /** - * {@inheritDoc} - */ - public void workFailed(JSR237MyRunnable work, Throwable error) { - workExceptions.add(error); - workFailedCallCount.incrementAndGet(); - } - - /** - * {@inheritDoc} - */ - public void workRejected(JSR237MyRunnable work) { - workRejectedCallCount.incrementAndGet(); - } - - /** - * {@inheritDoc} - */ - public void workStarted(JSR237MyRunnable work) { - workStartedCallCount.incrementAndGet(); - } - - /** - * Returns the number of calls to workAccepted() - * - * @return The number of calls to workAccepted() - */ - public int getWorkAcceptedCallCount() { - return workAcceptedCallCount.get(); - } - - /** - * Returns the number of calls to workStarted() - * - * @return The number of calls to workStarted() - */ - public int getWorkStartedCallCount() { - return workStartedCallCount.get(); - } - - /** - * Returns the number of calls to workCompleted() - * - * @return The number of calls to workCompleted() - */ - public int getWorkCompletedCallCount() { - return workCompletedCallCount.get(); - } - - /** - * Returns the number of calls to workFailed() - * - * @return The number of calls to workFailed() - */ - public int getWorkFailedCallCount() { - return workFailedCallCount.get(); - } - - /** - * Returns the number of calls to workRejected() - * - * @return The number of calls to workRejected() - */ - public int getWorkRejectedCallCount() { - return workRejectedCallCount.get(); - } - - /** - * Returns a List of all exceptions that are thrown by the Work items - * - * @return A List of all exceptions that are thrown by the Work items - */ - public List getWorkExceptions() { - return Collections.unmodifiableList(workExceptions); - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/Jsr237WorkSchedulerTestCase.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/Jsr237WorkSchedulerTestCase.java deleted file mode 100644 index 38c8459da8..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/Jsr237WorkSchedulerTestCase.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * 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.core.work; - -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Test case for Jsr237WorkScheduler - * - * @version $Rev$ $Date$ - */ -public class Jsr237WorkSchedulerTestCase { - - /** - * Wait up to 20 seconds for the Work units to complete - */ - private static final long WAIT_TIMEOUT = 20000; - - /** - * This is the shared instance of the ThreadPoolWorkManager used by the tests - */ - private static DefaultWorkScheduler workSchedular = null; - - /** - * Setup the Jsr237WorkScheduler - */ - @BeforeClass - public static void setup() { - workSchedular = new DefaultWorkScheduler(); - } - - /** - * Make sure that the Jsr237WorkScheduler is stopped after running the tests - */ - @AfterClass - public static void destroy() { - if (workSchedular != null) { - workSchedular.destroy(); - } - } - - /** - * Tests running a single fast job on the Jsr237WorkScheduler - */ - @Test - public void testSingleFastJob() { - // Create the work and register it - JSR237MyRunnable fast = new JSR237MyRunnable(10); - JSR237MyRunnerListener listener = new JSR237MyRunnerListener(); - workSchedular.scheduleWork(fast, listener); - - // Wait for the 1 job to complete - waitForWorkToComplete(listener, 1); - - // Test that the job completed successfully. - Assert.assertEquals(1, listener.getWorkAcceptedCallCount()); - Assert.assertEquals(0, listener.getWorkRejectedCallCount()); - Assert.assertEquals(1, listener.getWorkStartedCallCount()); - Assert.assertEquals(1, listener.getWorkCompletedCallCount()); - Assert.assertEquals(0, listener.getWorkExceptions().size()); - } - - /** - * Tests running a single job that fails on the Jsr237WorkScheduler - */ - @Test - public void testSingleFailingJob() { - // Create the work and register it - JSR237MyFailingRunnable fail = new JSR237MyFailingRunnable(); - JSR237MyRunnerListener listener = new JSR237MyRunnerListener(); - workSchedular.scheduleWork(fail, listener); - - // Wait for the 1 job to complete - waitForWorkToComplete(listener, 1); - - // Test that the job completed successfully. - Assert.assertEquals(1, listener.getWorkAcceptedCallCount()); - Assert.assertEquals(0, listener.getWorkRejectedCallCount()); - Assert.assertEquals(1, listener.getWorkStartedCallCount()); - Assert.assertEquals(0, listener.getWorkCompletedCallCount()); - Assert.assertEquals(1, listener.getWorkFailedCallCount()); - Assert.assertEquals(1, listener.getWorkExceptions().size()); - } - - /** - * Tests running a mixture of fast and slow jobs on the Jsr237WorkScheduler - */ - @Test - public void testMultipleJobs() { - // Create the work and register it - JSR237MyRunnable fast1 = new JSR237MyRunnable(5); - JSR237MyRunnable fast2 = new JSR237MyRunnable(10); - JSR237MyRunnable fast3 = new JSR237MyRunnable(20); - JSR237MyRunnable slow1= new JSR237MyRunnable(200); - JSR237MyRunnable slow2 = new JSR237MyRunnable(200); - JSR237MyRunnerListener listener = new JSR237MyRunnerListener(); - workSchedular.scheduleWork(fast1, listener); - workSchedular.scheduleWork(fast2, listener); - workSchedular.scheduleWork(fast3, listener); - workSchedular.scheduleWork(slow1, listener); - workSchedular.scheduleWork(slow2, listener); - - // Wait for the 5 jobs to complete - waitForWorkToComplete(listener, 5); - - // Test that the job completed successfully. - Assert.assertEquals(5, listener.getWorkAcceptedCallCount()); - Assert.assertEquals(0, listener.getWorkRejectedCallCount()); - Assert.assertEquals(5, listener.getWorkStartedCallCount()); - Assert.assertEquals(5, listener.getWorkCompletedCallCount()); - Assert.assertEquals(0, listener.getWorkExceptions().size()); - } - - /** - * Tests running a mixture of fast and slow jobs some of which fail on the - * Jsr237WorkScheduler - */ - @Test - public void testMultipleJobsSomeFail() { - // Create the work and register it - JSR237MyRunnable fast1 = new JSR237MyRunnable(5); - JSR237MyRunnable fast2 = new JSR237MyRunnable(10); - JSR237MyRunnable fast3 = new JSR237MyRunnable(20); - JSR237MyRunnable slow1= new JSR237MyRunnable(200); - JSR237MyRunnable slow2 = new JSR237MyRunnable(200); - JSR237MyFailingRunnable fail1 = new JSR237MyFailingRunnable(); - JSR237MyFailingRunnable fail2 = new JSR237MyFailingRunnable(); - JSR237MyRunnerListener listener = new JSR237MyRunnerListener(); - workSchedular.scheduleWork(fast1, listener); - workSchedular.scheduleWork(fast2, listener); - workSchedular.scheduleWork(fail1, listener); - workSchedular.scheduleWork(fast3, listener); - workSchedular.scheduleWork(slow1, listener); - workSchedular.scheduleWork(fail2, listener); - workSchedular.scheduleWork(slow2, listener); - - // Wait for the 7 jobs to complete - waitForWorkToComplete(listener, 7); - - // Test that the job completed successfully. - Assert.assertEquals(7, listener.getWorkAcceptedCallCount()); - Assert.assertEquals(0, listener.getWorkRejectedCallCount()); - Assert.assertEquals(7, listener.getWorkStartedCallCount()); - Assert.assertEquals(5, listener.getWorkCompletedCallCount()); - Assert.assertEquals(2, listener.getWorkFailedCallCount()); - Assert.assertEquals(2, listener.getWorkExceptions().size()); - } - - /** - * Tests running a single job that has no listener - */ - @Test - public void testSingleFastJobWithNoListener() { - // Create the work and register it - JSR237MyRunnable fast = new JSR237MyRunnable(10); - workSchedular.scheduleWork(fast); - - // Wait for the job to complete - long startTime = System.currentTimeMillis(); - while (true) { - int completedCount = fast.getRunCompletedCount(); - if (completedCount == 1) { - break; - } - - if (System.currentTimeMillis() - startTime > WAIT_TIMEOUT) { - Assert.fail("Only " + completedCount + " work items completed before timeout"); - return; - } - - // Lets wait for the job to complete - try { - Thread.sleep(25); - } catch (InterruptedException ex) { - Assert.fail("Unexpected exception: " + ex); - } - } - } - - /** - * Tests scheduling a null as the work item - */ - @Test - public void testNullWork() { - try { - workSchedular.scheduleWork(null); - Assert.fail("Should have thrown IllegalArgumentException "); - } catch (IllegalArgumentException ex) { - // As expected - Assert.assertTrue(ex.toString().indexOf("null") != -1); - } - } - - /** - * Waits for the specified number of jobs to complete or the timeout to fire. - * - * @param listener The listener to use to track Work unit completion - * @param completedWorkItemsToWaitFor The number of Work items to complete - */ - private void waitForWorkToComplete(JSR237MyRunnerListener listener, int completedWorkItemsToWaitFor) { - long startTime = System.currentTimeMillis(); - while (true) { - int completedCount = listener.getWorkCompletedCallCount() + listener.getWorkFailedCallCount(); - if (completedCount == completedWorkItemsToWaitFor) { - return; - } - - if (System.currentTimeMillis() - startTime > WAIT_TIMEOUT) { - Assert.fail("Only " + completedCount + " work items completed before timeout"); - return; - } - - // Lets wait for more jobs to complete - try { - Thread.sleep(25); - } catch (InterruptedException ex) { - Assert.fail("Unexpected exception: " + ex); - } - } - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/TestWorkListener.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/TestWorkListener.java deleted file mode 100644 index 58a1b87c48..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/TestWorkListener.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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.core.work; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.tuscany.sca.work.WorkSchedulerException; -import org.junit.Assert; - -/** - * A simple WorkListener that tracks invocations to it. - * - * @version $Rev$ $Date$ - */ -public class TestWorkListener implements WorkListener { - - /** - * Count of workAccepted() method calls - */ - private AtomicInteger workAcceptedCallCount = new AtomicInteger(); - - /** - * Count of workStarted() method calls - */ - private AtomicInteger workStartedCallCount = new AtomicInteger(); - - /** - * Count of workCompleted() method calls - */ - private AtomicInteger workCompletedCallCount = new AtomicInteger(); - - /** - * Count of workRejected() method calls - */ - private AtomicInteger workRejectedCallCount = new AtomicInteger(); - - /** - * List of all exceptions thrown by Work items - */ - private List workExceptions = Collections.synchronizedList(new ArrayList()); - - /** - * {@inheritDoc} - */ - public void workAccepted(WorkEvent work) { - workAcceptedCallCount.incrementAndGet(); - - // Validate the WorkEvent - Assert.assertNotNull(work.getWorkItem()); - Assert.assertEquals(WorkEvent.WORK_ACCEPTED, work.getType()); - } - - /** - * {@inheritDoc} - */ - public void workStarted(WorkEvent work) { - workStartedCallCount.incrementAndGet(); - - // Validate the WorkEvent - Assert.assertNotNull(work.getWorkItem()); - Assert.assertEquals(WorkEvent.WORK_STARTED, work.getType()); - } - - /** - * {@inheritDoc} - */ - public void workCompleted(WorkEvent work) { - if (work.getException() != null) { - workExceptions.add(work.getException()); - } - - // Validate the WorkEvent - Assert.assertNotNull(work.getWorkItem()); - Assert.assertEquals(WorkEvent.WORK_COMPLETED, work.getType()); - - workCompletedCallCount.incrementAndGet(); - } - - /** - * {@inheritDoc} - */ - public void workRejected(WorkEvent work) { - workRejectedCallCount.incrementAndGet(); - - // Validate the WorkEvent - Assert.assertNotNull(work.getWorkItem()); - Assert.assertEquals(WorkEvent.WORK_REJECTED, work.getType()); - } - - /** - * Returns the number of calls to workAccepted() - * - * @return The number of calls to workAccepted() - */ - public int getWorkAcceptedCallCount() { - return workAcceptedCallCount.get(); - } - - /** - * Returns the number of calls to workStarted() - * - * @return The number of calls to workStarted() - */ - public int getWorkStartedCallCount() { - return workStartedCallCount.get(); - } - - /** - * Returns the number of calls to workCompleted() - * - * @return The number of calls to workCompleted() - */ - public int getWorkCompletedCallCount() { - return workCompletedCallCount.get(); - } - - /** - * Returns the number of calls to workRejected() - * - * @return The number of calls to workRejected() - */ - public int getWorkRejectedCallCount() { - return workRejectedCallCount.get(); - } - - /** - * Returns a List of all exceptions that are thrown by the Work items - * - * @return A List of all exceptions that are thrown by the Work items - */ - public List getWorkExceptions() { - return Collections.unmodifiableList(workExceptions); - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManagerTestCase.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManagerTestCase.java deleted file mode 100644 index 8e04579019..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/ThreadPoolWorkManagerTestCase.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * 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.core.work; - -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * This test case will test the ThreadPoolWorkManager - * - * @version $Rev$ $Date$ - */ -public class ThreadPoolWorkManagerTestCase { - - /** - * Wait up to 20 seconds for the Work units to complete - */ - private static final long WAIT_TIMEOUT = 20000; - - /** - * This is the shared instance of the ThreadPoolWorkManager used by the tests - */ - private static ThreadPoolWorkManager workManager = null; - - /** - * Setup the ThreadPoolWorkManager - */ - @BeforeClass - public static void setup() { - workManager = new ThreadPoolWorkManager(10); - } - - /** - * Make sure that the ThreadPoolWorkManager is stopped after running the tests - */ - @AfterClass - public static void destroy() { - if (workManager != null) { - workManager.destroy(); - } - } - - /** - * Tests running a single fast job on the ThreadPoolWorkManager - */ - @Test - public void testSingleFastJob() { - // Create the work and register it - TimeDelayWork fast = new TimeDelayWork(10); - TestWorkListener listener = new TestWorkListener(); - workManager.schedule(fast, listener); - - // Wait for the 1 job to complete - waitForWorkToComplete(listener, 1); - - // Test that the job completed successfully. - Assert.assertEquals(1, listener.getWorkAcceptedCallCount()); - Assert.assertEquals(0, listener.getWorkRejectedCallCount()); - Assert.assertEquals(1, listener.getWorkStartedCallCount()); - Assert.assertEquals(1, listener.getWorkCompletedCallCount()); - Assert.assertEquals(0, listener.getWorkExceptions().size()); - } - - /** - * Tests running a single job that fails on the ThreadPoolWorkManager - */ - @Test - public void testSingleFailingJob() { - // Create the work and register it - FailingWork fail = new FailingWork(); - TestWorkListener listener = new TestWorkListener(); - workManager.schedule(fail, listener); - - // Wait for the 1 job to complete - waitForWorkToComplete(listener, 1); - - // Test that the job completed successfully. - Assert.assertEquals(1, listener.getWorkAcceptedCallCount()); - Assert.assertEquals(0, listener.getWorkRejectedCallCount()); - Assert.assertEquals(1, listener.getWorkStartedCallCount()); - Assert.assertEquals(1, listener.getWorkCompletedCallCount()); - Assert.assertEquals(1, listener.getWorkExceptions().size()); - } - - /** - * Tests running a mixture of fast and slow jobs on the ThreadPoolWorkManager - */ - @Test - public void testMultipleJobs() { - // Create the work and register it - TimeDelayWork fast1 = new TimeDelayWork(5); - TimeDelayWork fast2 = new TimeDelayWork(10); - TimeDelayWork fast3 = new TimeDelayWork(20); - TimeDelayWork slow1= new TimeDelayWork(200); - TimeDelayWork slow2 = new TimeDelayWork(200); - TestWorkListener listener = new TestWorkListener(); - workManager.schedule(fast1, listener); - workManager.schedule(fast2, listener); - workManager.schedule(fast3, listener); - workManager.schedule(slow1, listener); - workManager.schedule(slow2, listener); - - // Wait for the 5 jobs to complete - waitForWorkToComplete(listener, 5); - - // Test that the job completed successfully. - Assert.assertEquals(5, listener.getWorkAcceptedCallCount()); - Assert.assertEquals(0, listener.getWorkRejectedCallCount()); - Assert.assertEquals(5, listener.getWorkStartedCallCount()); - Assert.assertEquals(5, listener.getWorkCompletedCallCount()); - Assert.assertEquals(0, listener.getWorkExceptions().size()); - } - - /** - * Tests running a mixture of fast and slow jobs some of which fail on the - * ThreadPoolWorkManager - */ - @Test - public void testMultipleJobsSomeFail() { - // Create the work and register it - TimeDelayWork fast1 = new TimeDelayWork(5); - TimeDelayWork fast2 = new TimeDelayWork(10); - TimeDelayWork fast3 = new TimeDelayWork(20); - TimeDelayWork slow1= new TimeDelayWork(200); - TimeDelayWork slow2 = new TimeDelayWork(200); - FailingWork fail1 = new FailingWork(); - FailingWork fail2 = new FailingWork(); - TestWorkListener listener = new TestWorkListener(); - workManager.schedule(fast1, listener); - workManager.schedule(fast2, listener); - workManager.schedule(fail1, listener); - workManager.schedule(fast3, listener); - workManager.schedule(slow1, listener); - workManager.schedule(fail2, listener); - workManager.schedule(slow2, listener); - - // Wait for the 7 jobs to complete - waitForWorkToComplete(listener, 7); - - // Test that the job completed successfully. - Assert.assertEquals(7, listener.getWorkAcceptedCallCount()); - Assert.assertEquals(0, listener.getWorkRejectedCallCount()); - Assert.assertEquals(7, listener.getWorkStartedCallCount()); - Assert.assertEquals(7, listener.getWorkCompletedCallCount()); - Assert.assertEquals(2, listener.getWorkExceptions().size()); - } - - /** - * Tests creating a ThreadPoolWorkManager with invalid pool sizes of -10 to 0 - * inclusive - */ - @Test - public void testThreadPoolWorkManagerLessThan1Size() { - for (int i = 0; i >= -10; i--) { - try { - new ThreadPoolWorkManager(i); - Assert.fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException ex) { - Assert.assertTrue(ex.toString().indexOf(Integer.toString(i)) != -1); - } - } - } - - /** - * Tests running a single job that has no listener - */ - @Test - public void testSingleFastJobWithNoListener() { - // Create the work and register it - TimeDelayWork fast = new TimeDelayWork(10); - workManager.schedule(fast); - - // Wait for the job to complete - long startTime = System.currentTimeMillis(); - while (true) { - int completedCount = fast.getRunCompletedCount(); - if (completedCount == 1) { - break; - } - - if (System.currentTimeMillis() - startTime > WAIT_TIMEOUT) { - Assert.fail("Only " + completedCount + " work items completed before timeout"); - return; - } - - // Lets wait for the job to complete - try { - Thread.sleep(25); - } catch (InterruptedException ex) { - Assert.fail("Unexpected exception: " + ex); - } - } - - // Make sure we have got one completed run - Assert.assertEquals(1, fast.getRunCompletedCount()); - } - - /** - * Waits for the specified number of jobs to complete or the timeout to fire. - * - * @param listener The listener to use to track Work unit completion - * @param completedWorkItemsToWaitFor The number of Work items to complete - */ - private void waitForWorkToComplete(TestWorkListener listener, int completedWorkItemsToWaitFor) { - long startTime = System.currentTimeMillis(); - while (true) { - int completedCount = listener.getWorkCompletedCallCount(); - if (completedCount == completedWorkItemsToWaitFor) { - return; - } - - if (System.currentTimeMillis() - startTime > WAIT_TIMEOUT) { - Assert.fail("Only " + completedCount + " work items completed before timeout"); - return; - } - - // Lets wait for more jobs to complete - try { - Thread.sleep(25); - } catch (InterruptedException ex) { - Assert.fail("Unexpected exception: " + ex); - } - } - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/TimeDelayWork.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/TimeDelayWork.java deleted file mode 100644 index 6c10057046..0000000000 --- a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/TimeDelayWork.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.core.work; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Simple Work item that will sleep in the run() method for the specified - * period of time - * - * @version $Rev$ $Date$ - */ -public class TimeDelayWork extends Work { - - /** - * Count of completed run() method calls - */ - private AtomicInteger runCompletedCount = new AtomicInteger(); - - /** - * The amount of time to sleep in the Run loop - */ - private final long sleepTime; - - /** - * Constructor - * - * @param sleepTime The amount of time to sleep (in milliseconds) in the run() method - */ - public TimeDelayWork(long sleepTime) { - super(null); - this.sleepTime = sleepTime; - } - - /** - * {@inheritDoc} - */ - public boolean isDaemon() { - return false; - } - - /** - * {@inheritDoc} - */ - public void release() { - } - - /** - * Sleeps for a period of time defined by sleepTime - */ - public void run() { - System.out.println("Starting " + this); - try { - Thread.sleep(sleepTime); - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.println("Done " + this); - runCompletedCount.incrementAndGet(); - } - - /** - * Returns the number of completed calls to run() - * - * @return The number of completed calls to run() - */ - public int getRunCompletedCount() { - return runCompletedCount.get(); - } -} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/FailingWork.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/FailingWork.java new file mode 100644 index 0000000000..fe29a9501f --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/FailingWork.java @@ -0,0 +1,55 @@ +/* + * 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.core.work.impl; + +import org.apache.tuscany.sca.core.work.impl.Work; + + +/** + * Simple Work item that will throw an exception + * + * @version $Rev$ $Date$ + */ +public class FailingWork extends Work { + + public FailingWork() { + super(null); + } + + /** + * {@inheritDoc} + */ + public boolean isDaemon() { + return false; + } + + /** + * {@inheritDoc} + */ + public void release() { + } + + /** + * Throws an IllegalArgumentException + */ + public void run() { + System.out.println("Starting " + this + " and throwing an Exception"); + throw new IllegalArgumentException("Sample exception from " + this); + } +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyFailingRunnable.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyFailingRunnable.java new file mode 100644 index 0000000000..2d791e5012 --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyFailingRunnable.java @@ -0,0 +1,43 @@ +/* + * 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.core.work.impl; + +/** + * Simple Runnable that throws an IllegalArgumentException + * + * @version $Rev$ $Date$ + */ +public class JSR237MyFailingRunnable extends JSR237MyRunnable { + + /** + * Constructor + */ + public JSR237MyFailingRunnable() { + super(-1); + } + + /** + * Sleeps for a period of time defined by sleepTime + */ + @Override + public void run() { + System.out.println("Starting " + this + " and throwing an Exception"); + throw new IllegalArgumentException("Sample exception from " + this); + } +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyRunnable.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyRunnable.java new file mode 100644 index 0000000000..c0183b6f9b --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyRunnable.java @@ -0,0 +1,71 @@ +/* + * 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.core.work.impl; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Simple Runnable that is used for testing Jsr237WorkScheduler + * + * @version $Rev$ $Date$ + */ +public class JSR237MyRunnable implements Runnable { + + /** + * Count of workAccepted() method calls + */ + private AtomicInteger runCompletedCount = new AtomicInteger(); + + /** + * The amount of time to sleep in the Run loop + */ + private final long sleepTime; + + /** + * Constructor + * + * @param sleepTime The amount of time to sleep (in milliseconds) in the run() method + */ + public JSR237MyRunnable(long sleepTime) { + this.sleepTime = sleepTime; + } + + /** + * Sleeps for a period of time defined by sleepTime + */ + public void run() { + System.out.println("Starting " + this); + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Done " + this); + runCompletedCount.incrementAndGet(); + } + + /** + * Returns the number of completed calls to run() + * + * @return The number of completed calls to run() + */ + public int getRunCompletedCount() { + return runCompletedCount.get(); + } +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyRunnerListener.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyRunnerListener.java new file mode 100644 index 0000000000..307f24aca7 --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/JSR237MyRunnerListener.java @@ -0,0 +1,154 @@ +/* + * 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.core.work.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.tuscany.sca.work.NotificationListener; + +/** + * Simple NotificationListener that is used for testing Jsr237WorkScheduler + * + * @version $Rev$ $Date$ + */ +public class JSR237MyRunnerListener implements NotificationListener { + + /** + * Count of workAccepted() method calls + */ + private AtomicInteger workAcceptedCallCount = new AtomicInteger(); + + /** + * Count of workStarted() method calls + */ + private AtomicInteger workStartedCallCount = new AtomicInteger(); + + /** + * Count of workCompleted() method calls + */ + private AtomicInteger workCompletedCallCount = new AtomicInteger(); + + /** + * Count of workFailed() method calls + */ + private AtomicInteger workFailedCallCount = new AtomicInteger(); + + /** + * Count of workRejected() method calls + */ + private AtomicInteger workRejectedCallCount = new AtomicInteger(); + + /** + * List of all exceptions thrown by Work items + */ + private List workExceptions = Collections.synchronizedList(new ArrayList()); + + /** + * {@inheritDoc} + */ + public void workAccepted(JSR237MyRunnable work) { + workAcceptedCallCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public void workCompleted(JSR237MyRunnable work) { + workCompletedCallCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public void workFailed(JSR237MyRunnable work, Throwable error) { + workExceptions.add(error); + workFailedCallCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public void workRejected(JSR237MyRunnable work) { + workRejectedCallCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public void workStarted(JSR237MyRunnable work) { + workStartedCallCount.incrementAndGet(); + } + + /** + * Returns the number of calls to workAccepted() + * + * @return The number of calls to workAccepted() + */ + public int getWorkAcceptedCallCount() { + return workAcceptedCallCount.get(); + } + + /** + * Returns the number of calls to workStarted() + * + * @return The number of calls to workStarted() + */ + public int getWorkStartedCallCount() { + return workStartedCallCount.get(); + } + + /** + * Returns the number of calls to workCompleted() + * + * @return The number of calls to workCompleted() + */ + public int getWorkCompletedCallCount() { + return workCompletedCallCount.get(); + } + + /** + * Returns the number of calls to workFailed() + * + * @return The number of calls to workFailed() + */ + public int getWorkFailedCallCount() { + return workFailedCallCount.get(); + } + + /** + * Returns the number of calls to workRejected() + * + * @return The number of calls to workRejected() + */ + public int getWorkRejectedCallCount() { + return workRejectedCallCount.get(); + } + + /** + * Returns a List of all exceptions that are thrown by the Work items + * + * @return A List of all exceptions that are thrown by the Work items + */ + public List getWorkExceptions() { + return Collections.unmodifiableList(workExceptions); + } +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/Jsr237WorkSchedulerTestCase.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/Jsr237WorkSchedulerTestCase.java new file mode 100644 index 0000000000..851528b20c --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/Jsr237WorkSchedulerTestCase.java @@ -0,0 +1,241 @@ +/* + * 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.core.work.impl; + +import org.apache.tuscany.sca.core.work.impl.DefaultWorkScheduler; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test case for Jsr237WorkScheduler + * + * @version $Rev$ $Date$ + */ +public class Jsr237WorkSchedulerTestCase { + + /** + * Wait up to 20 seconds for the Work units to complete + */ + private static final long WAIT_TIMEOUT = 20000; + + /** + * This is the shared instance of the ThreadPoolWorkManager used by the tests + */ + private static DefaultWorkScheduler workSchedular = null; + + /** + * Setup the Jsr237WorkScheduler + */ + @BeforeClass + public static void setup() { + workSchedular = new DefaultWorkScheduler(); + } + + /** + * Make sure that the Jsr237WorkScheduler is stopped after running the tests + */ + @AfterClass + public static void destroy() { + if (workSchedular != null) { + workSchedular.destroy(); + } + } + + /** + * Tests running a single fast job on the Jsr237WorkScheduler + */ + @Test + public void testSingleFastJob() { + // Create the work and register it + JSR237MyRunnable fast = new JSR237MyRunnable(10); + JSR237MyRunnerListener listener = new JSR237MyRunnerListener(); + workSchedular.scheduleWork(fast, listener); + + // Wait for the 1 job to complete + waitForWorkToComplete(listener, 1); + + // Test that the job completed successfully. + Assert.assertEquals(1, listener.getWorkAcceptedCallCount()); + Assert.assertEquals(0, listener.getWorkRejectedCallCount()); + Assert.assertEquals(1, listener.getWorkStartedCallCount()); + Assert.assertEquals(1, listener.getWorkCompletedCallCount()); + Assert.assertEquals(0, listener.getWorkExceptions().size()); + } + + /** + * Tests running a single job that fails on the Jsr237WorkScheduler + */ + @Test + public void testSingleFailingJob() { + // Create the work and register it + JSR237MyFailingRunnable fail = new JSR237MyFailingRunnable(); + JSR237MyRunnerListener listener = new JSR237MyRunnerListener(); + workSchedular.scheduleWork(fail, listener); + + // Wait for the 1 job to complete + waitForWorkToComplete(listener, 1); + + // Test that the job completed successfully. + Assert.assertEquals(1, listener.getWorkAcceptedCallCount()); + Assert.assertEquals(0, listener.getWorkRejectedCallCount()); + Assert.assertEquals(1, listener.getWorkStartedCallCount()); + Assert.assertEquals(0, listener.getWorkCompletedCallCount()); + Assert.assertEquals(1, listener.getWorkFailedCallCount()); + Assert.assertEquals(1, listener.getWorkExceptions().size()); + } + + /** + * Tests running a mixture of fast and slow jobs on the Jsr237WorkScheduler + */ + @Test + public void testMultipleJobs() { + // Create the work and register it + JSR237MyRunnable fast1 = new JSR237MyRunnable(5); + JSR237MyRunnable fast2 = new JSR237MyRunnable(10); + JSR237MyRunnable fast3 = new JSR237MyRunnable(20); + JSR237MyRunnable slow1= new JSR237MyRunnable(200); + JSR237MyRunnable slow2 = new JSR237MyRunnable(200); + JSR237MyRunnerListener listener = new JSR237MyRunnerListener(); + workSchedular.scheduleWork(fast1, listener); + workSchedular.scheduleWork(fast2, listener); + workSchedular.scheduleWork(fast3, listener); + workSchedular.scheduleWork(slow1, listener); + workSchedular.scheduleWork(slow2, listener); + + // Wait for the 5 jobs to complete + waitForWorkToComplete(listener, 5); + + // Test that the job completed successfully. + Assert.assertEquals(5, listener.getWorkAcceptedCallCount()); + Assert.assertEquals(0, listener.getWorkRejectedCallCount()); + Assert.assertEquals(5, listener.getWorkStartedCallCount()); + Assert.assertEquals(5, listener.getWorkCompletedCallCount()); + Assert.assertEquals(0, listener.getWorkExceptions().size()); + } + + /** + * Tests running a mixture of fast and slow jobs some of which fail on the + * Jsr237WorkScheduler + */ + @Test + public void testMultipleJobsSomeFail() { + // Create the work and register it + JSR237MyRunnable fast1 = new JSR237MyRunnable(5); + JSR237MyRunnable fast2 = new JSR237MyRunnable(10); + JSR237MyRunnable fast3 = new JSR237MyRunnable(20); + JSR237MyRunnable slow1= new JSR237MyRunnable(200); + JSR237MyRunnable slow2 = new JSR237MyRunnable(200); + JSR237MyFailingRunnable fail1 = new JSR237MyFailingRunnable(); + JSR237MyFailingRunnable fail2 = new JSR237MyFailingRunnable(); + JSR237MyRunnerListener listener = new JSR237MyRunnerListener(); + workSchedular.scheduleWork(fast1, listener); + workSchedular.scheduleWork(fast2, listener); + workSchedular.scheduleWork(fail1, listener); + workSchedular.scheduleWork(fast3, listener); + workSchedular.scheduleWork(slow1, listener); + workSchedular.scheduleWork(fail2, listener); + workSchedular.scheduleWork(slow2, listener); + + // Wait for the 7 jobs to complete + waitForWorkToComplete(listener, 7); + + // Test that the job completed successfully. + Assert.assertEquals(7, listener.getWorkAcceptedCallCount()); + Assert.assertEquals(0, listener.getWorkRejectedCallCount()); + Assert.assertEquals(7, listener.getWorkStartedCallCount()); + Assert.assertEquals(5, listener.getWorkCompletedCallCount()); + Assert.assertEquals(2, listener.getWorkFailedCallCount()); + Assert.assertEquals(2, listener.getWorkExceptions().size()); + } + + /** + * Tests running a single job that has no listener + */ + @Test + public void testSingleFastJobWithNoListener() { + // Create the work and register it + JSR237MyRunnable fast = new JSR237MyRunnable(10); + workSchedular.scheduleWork(fast); + + // Wait for the job to complete + long startTime = System.currentTimeMillis(); + while (true) { + int completedCount = fast.getRunCompletedCount(); + if (completedCount == 1) { + break; + } + + if (System.currentTimeMillis() - startTime > WAIT_TIMEOUT) { + Assert.fail("Only " + completedCount + " work items completed before timeout"); + return; + } + + // Lets wait for the job to complete + try { + Thread.sleep(25); + } catch (InterruptedException ex) { + Assert.fail("Unexpected exception: " + ex); + } + } + } + + /** + * Tests scheduling a null as the work item + */ + @Test + public void testNullWork() { + try { + workSchedular.scheduleWork(null); + Assert.fail("Should have thrown IllegalArgumentException "); + } catch (IllegalArgumentException ex) { + // As expected + Assert.assertTrue(ex.toString().indexOf("null") != -1); + } + } + + /** + * Waits for the specified number of jobs to complete or the timeout to fire. + * + * @param listener The listener to use to track Work unit completion + * @param completedWorkItemsToWaitFor The number of Work items to complete + */ + private void waitForWorkToComplete(JSR237MyRunnerListener listener, int completedWorkItemsToWaitFor) { + long startTime = System.currentTimeMillis(); + while (true) { + int completedCount = listener.getWorkCompletedCallCount() + listener.getWorkFailedCallCount(); + if (completedCount == completedWorkItemsToWaitFor) { + return; + } + + if (System.currentTimeMillis() - startTime > WAIT_TIMEOUT) { + Assert.fail("Only " + completedCount + " work items completed before timeout"); + return; + } + + // Lets wait for more jobs to complete + try { + Thread.sleep(25); + } catch (InterruptedException ex) { + Assert.fail("Unexpected exception: " + ex); + } + } + } +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/TestWorkListener.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/TestWorkListener.java new file mode 100644 index 0000000000..24a91331a4 --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/TestWorkListener.java @@ -0,0 +1,155 @@ +/* + * 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.core.work.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.tuscany.sca.core.work.impl.WorkEvent; +import org.apache.tuscany.sca.core.work.impl.WorkListener; +import org.apache.tuscany.sca.work.WorkSchedulerException; +import org.junit.Assert; + +/** + * A simple WorkListener that tracks invocations to it. + * + * @version $Rev$ $Date$ + */ +public class TestWorkListener implements WorkListener { + + /** + * Count of workAccepted() method calls + */ + private AtomicInteger workAcceptedCallCount = new AtomicInteger(); + + /** + * Count of workStarted() method calls + */ + private AtomicInteger workStartedCallCount = new AtomicInteger(); + + /** + * Count of workCompleted() method calls + */ + private AtomicInteger workCompletedCallCount = new AtomicInteger(); + + /** + * Count of workRejected() method calls + */ + private AtomicInteger workRejectedCallCount = new AtomicInteger(); + + /** + * List of all exceptions thrown by Work items + */ + private List workExceptions = Collections.synchronizedList(new ArrayList()); + + /** + * {@inheritDoc} + */ + public void workAccepted(WorkEvent work) { + workAcceptedCallCount.incrementAndGet(); + + // Validate the WorkEvent + Assert.assertNotNull(work.getWorkItem()); + Assert.assertEquals(WorkEvent.WORK_ACCEPTED, work.getType()); + } + + /** + * {@inheritDoc} + */ + public void workStarted(WorkEvent work) { + workStartedCallCount.incrementAndGet(); + + // Validate the WorkEvent + Assert.assertNotNull(work.getWorkItem()); + Assert.assertEquals(WorkEvent.WORK_STARTED, work.getType()); + } + + /** + * {@inheritDoc} + */ + public void workCompleted(WorkEvent work) { + if (work.getException() != null) { + workExceptions.add(work.getException()); + } + + // Validate the WorkEvent + Assert.assertNotNull(work.getWorkItem()); + Assert.assertEquals(WorkEvent.WORK_COMPLETED, work.getType()); + + workCompletedCallCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public void workRejected(WorkEvent work) { + workRejectedCallCount.incrementAndGet(); + + // Validate the WorkEvent + Assert.assertNotNull(work.getWorkItem()); + Assert.assertEquals(WorkEvent.WORK_REJECTED, work.getType()); + } + + /** + * Returns the number of calls to workAccepted() + * + * @return The number of calls to workAccepted() + */ + public int getWorkAcceptedCallCount() { + return workAcceptedCallCount.get(); + } + + /** + * Returns the number of calls to workStarted() + * + * @return The number of calls to workStarted() + */ + public int getWorkStartedCallCount() { + return workStartedCallCount.get(); + } + + /** + * Returns the number of calls to workCompleted() + * + * @return The number of calls to workCompleted() + */ + public int getWorkCompletedCallCount() { + return workCompletedCallCount.get(); + } + + /** + * Returns the number of calls to workRejected() + * + * @return The number of calls to workRejected() + */ + public int getWorkRejectedCallCount() { + return workRejectedCallCount.get(); + } + + /** + * Returns a List of all exceptions that are thrown by the Work items + * + * @return A List of all exceptions that are thrown by the Work items + */ + public List getWorkExceptions() { + return Collections.unmodifiableList(workExceptions); + } +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/ThreadPoolWorkManagerTestCase.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/ThreadPoolWorkManagerTestCase.java new file mode 100644 index 0000000000..89fd74ef38 --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/ThreadPoolWorkManagerTestCase.java @@ -0,0 +1,244 @@ +/* + * 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.core.work.impl; + +import org.apache.tuscany.sca.core.work.impl.ThreadPoolWorkManager; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * This test case will test the ThreadPoolWorkManager + * + * @version $Rev$ $Date$ + */ +public class ThreadPoolWorkManagerTestCase { + + /** + * Wait up to 20 seconds for the Work units to complete + */ + private static final long WAIT_TIMEOUT = 20000; + + /** + * This is the shared instance of the ThreadPoolWorkManager used by the tests + */ + private static ThreadPoolWorkManager workManager = null; + + /** + * Setup the ThreadPoolWorkManager + */ + @BeforeClass + public static void setup() { + workManager = new ThreadPoolWorkManager(10); + } + + /** + * Make sure that the ThreadPoolWorkManager is stopped after running the tests + */ + @AfterClass + public static void destroy() { + if (workManager != null) { + workManager.destroy(); + } + } + + /** + * Tests running a single fast job on the ThreadPoolWorkManager + */ + @Test + public void testSingleFastJob() { + // Create the work and register it + TimeDelayWork fast = new TimeDelayWork(10); + TestWorkListener listener = new TestWorkListener(); + workManager.schedule(fast, listener); + + // Wait for the 1 job to complete + waitForWorkToComplete(listener, 1); + + // Test that the job completed successfully. + Assert.assertEquals(1, listener.getWorkAcceptedCallCount()); + Assert.assertEquals(0, listener.getWorkRejectedCallCount()); + Assert.assertEquals(1, listener.getWorkStartedCallCount()); + Assert.assertEquals(1, listener.getWorkCompletedCallCount()); + Assert.assertEquals(0, listener.getWorkExceptions().size()); + } + + /** + * Tests running a single job that fails on the ThreadPoolWorkManager + */ + @Test + public void testSingleFailingJob() { + // Create the work and register it + FailingWork fail = new FailingWork(); + TestWorkListener listener = new TestWorkListener(); + workManager.schedule(fail, listener); + + // Wait for the 1 job to complete + waitForWorkToComplete(listener, 1); + + // Test that the job completed successfully. + Assert.assertEquals(1, listener.getWorkAcceptedCallCount()); + Assert.assertEquals(0, listener.getWorkRejectedCallCount()); + Assert.assertEquals(1, listener.getWorkStartedCallCount()); + Assert.assertEquals(1, listener.getWorkCompletedCallCount()); + Assert.assertEquals(1, listener.getWorkExceptions().size()); + } + + /** + * Tests running a mixture of fast and slow jobs on the ThreadPoolWorkManager + */ + @Test + public void testMultipleJobs() { + // Create the work and register it + TimeDelayWork fast1 = new TimeDelayWork(5); + TimeDelayWork fast2 = new TimeDelayWork(10); + TimeDelayWork fast3 = new TimeDelayWork(20); + TimeDelayWork slow1= new TimeDelayWork(200); + TimeDelayWork slow2 = new TimeDelayWork(200); + TestWorkListener listener = new TestWorkListener(); + workManager.schedule(fast1, listener); + workManager.schedule(fast2, listener); + workManager.schedule(fast3, listener); + workManager.schedule(slow1, listener); + workManager.schedule(slow2, listener); + + // Wait for the 5 jobs to complete + waitForWorkToComplete(listener, 5); + + // Test that the job completed successfully. + Assert.assertEquals(5, listener.getWorkAcceptedCallCount()); + Assert.assertEquals(0, listener.getWorkRejectedCallCount()); + Assert.assertEquals(5, listener.getWorkStartedCallCount()); + Assert.assertEquals(5, listener.getWorkCompletedCallCount()); + Assert.assertEquals(0, listener.getWorkExceptions().size()); + } + + /** + * Tests running a mixture of fast and slow jobs some of which fail on the + * ThreadPoolWorkManager + */ + @Test + public void testMultipleJobsSomeFail() { + // Create the work and register it + TimeDelayWork fast1 = new TimeDelayWork(5); + TimeDelayWork fast2 = new TimeDelayWork(10); + TimeDelayWork fast3 = new TimeDelayWork(20); + TimeDelayWork slow1= new TimeDelayWork(200); + TimeDelayWork slow2 = new TimeDelayWork(200); + FailingWork fail1 = new FailingWork(); + FailingWork fail2 = new FailingWork(); + TestWorkListener listener = new TestWorkListener(); + workManager.schedule(fast1, listener); + workManager.schedule(fast2, listener); + workManager.schedule(fail1, listener); + workManager.schedule(fast3, listener); + workManager.schedule(slow1, listener); + workManager.schedule(fail2, listener); + workManager.schedule(slow2, listener); + + // Wait for the 7 jobs to complete + waitForWorkToComplete(listener, 7); + + // Test that the job completed successfully. + Assert.assertEquals(7, listener.getWorkAcceptedCallCount()); + Assert.assertEquals(0, listener.getWorkRejectedCallCount()); + Assert.assertEquals(7, listener.getWorkStartedCallCount()); + Assert.assertEquals(7, listener.getWorkCompletedCallCount()); + Assert.assertEquals(2, listener.getWorkExceptions().size()); + } + + /** + * Tests creating a ThreadPoolWorkManager with invalid pool sizes of -10 to 0 + * inclusive + */ + @Test + public void testThreadPoolWorkManagerLessThan1Size() { + for (int i = 0; i >= -10; i--) { + try { + new ThreadPoolWorkManager(i); + Assert.fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + Assert.assertTrue(ex.toString().indexOf(Integer.toString(i)) != -1); + } + } + } + + /** + * Tests running a single job that has no listener + */ + @Test + public void testSingleFastJobWithNoListener() { + // Create the work and register it + TimeDelayWork fast = new TimeDelayWork(10); + workManager.schedule(fast); + + // Wait for the job to complete + long startTime = System.currentTimeMillis(); + while (true) { + int completedCount = fast.getRunCompletedCount(); + if (completedCount == 1) { + break; + } + + if (System.currentTimeMillis() - startTime > WAIT_TIMEOUT) { + Assert.fail("Only " + completedCount + " work items completed before timeout"); + return; + } + + // Lets wait for the job to complete + try { + Thread.sleep(25); + } catch (InterruptedException ex) { + Assert.fail("Unexpected exception: " + ex); + } + } + + // Make sure we have got one completed run + Assert.assertEquals(1, fast.getRunCompletedCount()); + } + + /** + * Waits for the specified number of jobs to complete or the timeout to fire. + * + * @param listener The listener to use to track Work unit completion + * @param completedWorkItemsToWaitFor The number of Work items to complete + */ + private void waitForWorkToComplete(TestWorkListener listener, int completedWorkItemsToWaitFor) { + long startTime = System.currentTimeMillis(); + while (true) { + int completedCount = listener.getWorkCompletedCallCount(); + if (completedCount == completedWorkItemsToWaitFor) { + return; + } + + if (System.currentTimeMillis() - startTime > WAIT_TIMEOUT) { + Assert.fail("Only " + completedCount + " work items completed before timeout"); + return; + } + + // Lets wait for more jobs to complete + try { + Thread.sleep(25); + } catch (InterruptedException ex) { + Assert.fail("Unexpected exception: " + ex); + } + } + } +} diff --git a/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/TimeDelayWork.java b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/TimeDelayWork.java new file mode 100644 index 0000000000..bada856af3 --- /dev/null +++ b/java/sca/modules/core/src/test/java/org/apache/tuscany/sca/core/work/impl/TimeDelayWork.java @@ -0,0 +1,88 @@ +/* + * 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.core.work.impl; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.tuscany.sca.core.work.impl.Work; + +/** + * Simple Work item that will sleep in the run() method for the specified + * period of time + * + * @version $Rev$ $Date$ + */ +public class TimeDelayWork extends Work { + + /** + * Count of completed run() method calls + */ + private AtomicInteger runCompletedCount = new AtomicInteger(); + + /** + * The amount of time to sleep in the Run loop + */ + private final long sleepTime; + + /** + * Constructor + * + * @param sleepTime The amount of time to sleep (in milliseconds) in the run() method + */ + public TimeDelayWork(long sleepTime) { + super(null); + this.sleepTime = sleepTime; + } + + /** + * {@inheritDoc} + */ + public boolean isDaemon() { + return false; + } + + /** + * {@inheritDoc} + */ + public void release() { + } + + /** + * Sleeps for a period of time defined by sleepTime + */ + public void run() { + System.out.println("Starting " + this); + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Done " + this); + runCompletedCount.incrementAndGet(); + } + + /** + * Returns the number of completed calls to run() + * + * @return The number of completed calls to run() + */ + public int getRunCompletedCount() { + return runCompletedCount.get(); + } +} -- cgit v1.2.3