notify-dpml AT lists.ibiblio.org
Subject: DPML Notify
List archive
r1243 - in trunk/main/util: . job job/api job/api/src job/api/src/main job/api/src/main/net job/api/src/main/net/dpml job/api/src/main/net/dpml/job job/impl job/impl/etc job/impl/etc/test job/impl/src job/impl/src/main job/impl/src/main/net job/impl/src/main/net/dpml job/impl/src/main/net/dpml/job job/impl/src/main/net/dpml/job/impl job/impl/src/test job/impl/src/test/net job/impl/src/test/net/dpml job/impl/src/test/net/dpml/job job/impl/src/test/net/dpml/job/test
- From: mcconnell at BerliOS <mcconnell AT mail.berlios.de>
- To: notify-dpml AT lists.ibiblio.org
- Subject: r1243 - in trunk/main/util: . job job/api job/api/src job/api/src/main job/api/src/main/net job/api/src/main/net/dpml job/api/src/main/net/dpml/job job/impl job/impl/etc job/impl/etc/test job/impl/src job/impl/src/main job/impl/src/main/net job/impl/src/main/net/dpml job/impl/src/main/net/dpml/job job/impl/src/main/net/dpml/job/impl job/impl/src/test job/impl/src/test/net job/impl/src/test/net/dpml job/impl/src/test/net/dpml/job job/impl/src/test/net/dpml/job/test
- Date: Wed, 22 Mar 2006 17:45:16 +0100
Author: mcconnell
Date: 2006-03-22 17:45:13 +0100 (Wed, 22 Mar 2006)
New Revision: 1243
Added:
trunk/main/util/job/
trunk/main/util/job/api/
trunk/main/util/job/api/src/
trunk/main/util/job/api/src/main/
trunk/main/util/job/api/src/main/net/
trunk/main/util/job/api/src/main/net/dpml/
trunk/main/util/job/api/src/main/net/dpml/job/
trunk/main/util/job/api/src/main/net/dpml/job/Commissionable.java
trunk/main/util/job/api/src/main/net/dpml/job/Commissioner.java
trunk/main/util/job/api/src/main/net/dpml/job/CommissionerController.java
trunk/main/util/job/api/src/main/net/dpml/job/CommissionerEvent.java
trunk/main/util/job/api/src/main/net/dpml/job/TimeoutError.java
trunk/main/util/job/api/src/main/net/dpml/job/TimeoutException.java
trunk/main/util/job/api/src/main/net/dpml/job/package.html
trunk/main/util/job/impl/
trunk/main/util/job/impl/etc/
trunk/main/util/job/impl/etc/test/
trunk/main/util/job/impl/etc/test/logging.properties
trunk/main/util/job/impl/src/
trunk/main/util/job/impl/src/main/
trunk/main/util/job/impl/src/main/net/
trunk/main/util/job/impl/src/main/net/dpml/
trunk/main/util/job/impl/src/main/net/dpml/job/
trunk/main/util/job/impl/src/main/net/dpml/job/impl/
trunk/main/util/job/impl/src/main/net/dpml/job/impl/DefaultCommissioner.java
trunk/main/util/job/impl/src/main/net/dpml/job/impl/FIFO.java
trunk/main/util/job/impl/src/main/net/dpml/job/impl/Job.java
trunk/main/util/job/impl/src/main/net/dpml/job/impl/package.html
trunk/main/util/job/impl/src/test/
trunk/main/util/job/impl/src/test/net/
trunk/main/util/job/impl/src/test/net/dpml/
trunk/main/util/job/impl/src/test/net/dpml/job/
trunk/main/util/job/impl/src/test/net/dpml/job/test/
trunk/main/util/job/impl/src/test/net/dpml/job/test/DefaultCommissionerTestCase.java
Modified:
trunk/main/util/module.xml
Log:
add api and impl dealing with ordered background commissioning and
decommissioning of objects
Added: trunk/main/util/job/api/src/main/net/dpml/job/Commissionable.java
===================================================================
--- trunk/main/util/job/api/src/main/net/dpml/job/Commissionable.java
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/api/src/main/net/dpml/job/Commissionable.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job;
+
+/**
+ * Interface implemented by objects that implement
commission/decommmissioning
+ * lifecycles.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface Commissionable
+{
+ /**
+ */
+ void commission() throws Exception;
+
+ /**
+ */
+ void decommission();
+}
Added: trunk/main/util/job/api/src/main/net/dpml/job/Commissioner.java
===================================================================
--- trunk/main/util/job/api/src/main/net/dpml/job/Commissioner.java
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/api/src/main/net/dpml/job/Commissioner.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Interface implemented by systems that handle ordered commissioning
+ * (or decommissioning) of a of commissionable objects.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface Commissioner
+{
+ /**
+ * Commissions the given Commissonable, and allows a maximum time
+ * for commissioning/decommissioning to complete.
+ *
+ * @param commissionable the commissionable instance
+ * @param timeout the maximum number of milliseconds to allow
+ *
+ * @throws TimeoutException if the deployment was not
+ * completed within the timeout deadline and interuption
+ * of the deployment was successful
+ * @throws TimeoutError if the deployment was not
+ * completed within the timeout deadline and interuption
+ * of the deployment was not successful
+ * @throws InvocationTargetException if the deployment target raises an
error.
+ **/
+ void add( Commissionable commissionable, long timeout )
+ throws TimeoutException, TimeoutError, InvocationTargetException;
+}
Added:
trunk/main/util/job/api/src/main/net/dpml/job/CommissionerController.java
===================================================================
--- trunk/main/util/job/api/src/main/net/dpml/job/CommissionerController.java
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/api/src/main/net/dpml/job/CommissionerController.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job;
+
+import java.lang.reflect.InvocationTargetException;
+
+
+/**
+ * Interface implemented by commissioner controllers.
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public interface CommissionerController
+{
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has commenced.
+ * @param event the commissioner event
+ */
+ void started( CommissionerEvent event );
+
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has successfully completed.
+ * @param event the commissioner event
+ */
+ void completed( CommissionerEvent event );
+
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has been interrupted.
+ * @param event the commissioner event
+ * @exception TimeoutException optional controller initiated exception
+ */
+ void interrupted( CommissionerEvent event ) throws TimeoutException;
+
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has failed due to a timeout and the target commissionable
+ * object failed to resopond to an interrup and was subsequently
+ * terminated.
+ * @param event the commissioner event
+ * @exception InvocationTargetException optional wrapped client exception
+ */
+ void failed( CommissionerEvent event, Throwable e ) throws
InvocationTargetException;
+
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has failed.
+ * @param event the commissioner event
+ * @exception TimeoutException optional controller initiated timeout
exception
+ */
+ void terminated( CommissionerEvent event ) throws TimeoutError;
+}
Added: trunk/main/util/job/api/src/main/net/dpml/job/CommissionerEvent.java
===================================================================
--- trunk/main/util/job/api/src/main/net/dpml/job/CommissionerEvent.java
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/api/src/main/net/dpml/job/CommissionerEvent.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2005 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job;
+
+import java.util.EventObject;
+
+/**
+ * Event raised by a commissioner.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public class CommissionerEvent extends EventObject
+{
+ /**
+ * Serial version identifier.
+ */
+ static final long serialVersionUID = 1L;
+
+ private final boolean m_flag;
+ private final long m_duration;
+
+ /**
+ * Construct a new <code>CommissionerEvent</code>.
+ *
+ * @param target the commissionable target
+ * @param stage the commissioning stage
+ * @param flag if true then commissioning else decommissioning
+ * @param duration the applicable duration relative to the stage
+ */
+ public CommissionerEvent( final Commissionable target, boolean flag,
long duration )
+ {
+ super( target );
+ m_flag = flag;
+ m_duration = duration;
+ }
+
+ /**
+ * Return true if the event is related to commissioning of a
Commissionable
+ * instance, otherwise the event is related to a decommissioning activity.
+ * @return the commossion/decommission flag
+ */
+ public boolean isCommissioning()
+ {
+ return m_flag;
+ }
+
+ /**
+ * Get the application duration. If the event is related to the STARTED,
+ * INTERUPTED or FAILED the value returned is the timeout constraint. If
the
+ * stage is COMPLETED the value is equal to the actual time taken to
execute
+ * the commissioning or decommissioning process.
+ */
+ public long getDuration()
+ {
+ return m_duration;
+ }
+}
+
Added: trunk/main/util/job/api/src/main/net/dpml/job/TimeoutError.java
===================================================================
--- trunk/main/util/job/api/src/main/net/dpml/job/TimeoutError.java
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/api/src/main/net/dpml/job/TimeoutError.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job;
+
+/**
+ * Error raised in response to an timeout.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public class TimeoutError extends Error
+{
+ private long m_timeout;
+
+ /**
+ * Construct a new <code>TimeoutError</code> instance.
+ *
+ * @param message The detail message for this exception.
+ */
+ public TimeoutError( long timeout )
+ {
+ super( "" + timeout );
+ m_timeout = timeout;
+ }
+
+ /**
+ * Get the timout value.
+ *
+ * @return the timeout value
+ */
+ public long getDuration()
+ {
+ return m_timeout;
+ }
+}
+
Added: trunk/main/util/job/api/src/main/net/dpml/job/TimeoutException.java
===================================================================
--- trunk/main/util/job/api/src/main/net/dpml/job/TimeoutException.java
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/api/src/main/net/dpml/job/TimeoutException.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job;
+
+/**
+ * Exception raised in response to an timeout.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public class TimeoutException extends Exception
+{
+ private long m_timeout;
+
+ /**
+ * Construct a new <code>TimeoutException</code> instance.
+ *
+ * @param message The detail message for this exception.
+ */
+ public TimeoutException( long timeout )
+ {
+ super( "" + timeout );
+ m_timeout = timeout;
+ }
+
+ /**
+ * Get the timout value.
+ *
+ * @return the timeout value
+ */
+ public long getDuration()
+ {
+ return m_timeout;
+ }
+}
+
Added: trunk/main/util/job/api/src/main/net/dpml/job/package.html
===================================================================
--- trunk/main/util/job/api/src/main/net/dpml/job/package.html 2006-03-22
16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/api/src/main/net/dpml/job/package.html 2006-03-22
16:45:13 UTC (rev 1243)
@@ -0,0 +1,6 @@
+
+<body>
+<p>
+Interfaces supporting commissioning and decommissioning jobs.
+</p>
+</body>
Added: trunk/main/util/job/impl/etc/test/logging.properties
===================================================================
--- trunk/main/util/job/impl/etc/test/logging.properties 2006-03-22
16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/impl/etc/test/logging.properties 2006-03-22
16:45:13 UTC (rev 1243)
@@ -0,0 +1,3 @@
+.level=FINE
+sun.rmi.level=INFO
+sun.rmi.transport.tcp.level=INFO
Added:
trunk/main/util/job/impl/src/main/net/dpml/job/impl/DefaultCommissioner.java
===================================================================
---
trunk/main/util/job/impl/src/main/net/dpml/job/impl/DefaultCommissioner.java
2006-03-22 16:37:15 UTC (rev 1242)
+++
trunk/main/util/job/impl/src/main/net/dpml/job/impl/DefaultCommissioner.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job.impl;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.dpml.job.Commissionable;
+import net.dpml.job.Commissioner;
+import net.dpml.job.CommissionerController;
+import net.dpml.job.CommissionerEvent;
+import net.dpml.job.TimeoutException;
+import net.dpml.job.TimeoutError;
+
+/**
+ * Runnable deployment thread that handles the commissioning of an
+ * arbitary number of commissionable instances. The commissioner maintains
a
+ * list of commissioning requests which are queued on a first come first
+ * serve basis.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public class DefaultCommissioner implements Commissioner, Runnable
+{
+ //------------------------------------------------------------
+ // static
+ //------------------------------------------------------------
+
+ private static int m_counter = 0;
+
+ //------------------------------------------------------------
+ // immutable state
+ //------------------------------------------------------------
+
+ private final FIFO m_queue = new FIFO();
+
+ private final boolean m_flag;
+
+ private final CommissionerController m_listener;
+
+ //------------------------------------------------------------
+ // mutable static
+ //------------------------------------------------------------
+
+ private Thread m_thread;
+
+ //------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------
+
+ public DefaultCommissioner( String name, boolean flag,
CommissionerController listener )
+ {
+ if( null == name )
+ {
+ throw new NullPointerException( "name" );
+ }
+ if( null == listener )
+ {
+ throw new NullPointerException( "listener" );
+ }
+ m_flag = flag;
+ m_listener = listener;
+ m_thread = new Thread( this, name );
+ m_thread.start();
+ }
+
+ //------------------------------------------------------------
+ // implementation
+ //------------------------------------------------------------
+
+ /**
+ * Commissions the given Commissonable, and allows a maximum time
+ * for commissioning/decommissioning to complete.
+ *
+ * @param commissionable the commissionable instance
+ * @param timeout the maximum number of milliseconds to allow
+ *
+ * @throws TimeoutException if the deployment was not
+ * completed within the timeout deadline and interuption
+ * of the deployment was successful
+ * @throws TimeoutError if the deployment was not
+ * completed within the timeout deadline and interuption
+ * of the deployment was not successful
+ * @throws InvocationTargetException if the deployment target raises an
exception
+ **/
+ public void add( Commissionable commissionable, long timeout )
+ throws TimeoutException, TimeoutError, InvocationTargetException
+ {
+ if( null == commissionable )
+ {
+ throw new NullPointerException( "commissionable" );
+ }
+
+ if( null != m_thread )
+ {
+ CommissionerEvent event =
+ new CommissionerEvent(
+ commissionable, m_flag, timeout );
+ m_listener.started( event );
+
+ Job job = new Job( commissionable, m_thread, timeout );
+ m_queue.put( job );
+ try
+ {
+ long t = job.waitForCompletion();
+
+ CommissionerEvent completionEvent =
+ new CommissionerEvent(
+ commissionable, m_flag, t );
+ m_listener.completed( completionEvent );
+ }
+ catch( TimeoutException e )
+ {
+ CommissionerEvent interruptedEvent =
+ new CommissionerEvent(
+ commissionable, m_flag, e.getDuration() );
+ m_listener.interrupted( interruptedEvent );
+ }
+ catch( TimeoutError e )
+ {
+ CommissionerEvent terminatedEvent =
+ new CommissionerEvent(
+ commissionable, m_flag, e.getDuration() );
+ m_listener.terminated( terminatedEvent );
+ }
+ catch( Throwable e )
+ {
+ CommissionerEvent failedEvent =
+ new CommissionerEvent(
+ commissionable, m_flag, timeout );
+ m_listener.failed( failedEvent, e );
+ }
+ }
+ else
+ {
+ throw new IllegalStateException( "disposed" );
+ }
+ }
+
+ /**
+ * Disposal of the Commissioner.
+ * The Commissioner allocates a deployment thread, which needs to be
+ * disposed of before releasing the Commissioner reference.
+ **/
+ public void dispose()
+ {
+ if( null != m_thread )
+ {
+ m_thread.interrupt();
+ }
+ }
+
+ public void run()
+ {
+ try
+ {
+ while( true )
+ {
+ Job job = (Job) m_queue.get();
+ Commissionable model = job.getCommissionable();
+ try
+ {
+ if( m_flag )
+ {
+ model.commission();
+ }
+ else
+ {
+ model.decommission();
+ }
+ job.done();
+ }
+ catch( InterruptedException e )
+ {
+ job.interrupted();
+ }
+ catch( Throwable e )
+ {
+ job.exception( e );
+ }
+ }
+ }
+ catch( InterruptedException e )
+ {
+ // ignore, part of dispose;
+ }
+ m_thread = null;
+ }
+}
Added: trunk/main/util/job/impl/src/main/net/dpml/job/impl/FIFO.java
===================================================================
--- trunk/main/util/job/impl/src/main/net/dpml/job/impl/FIFO.java
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/impl/src/main/net/dpml/job/impl/FIFO.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job.impl;
+
+import java.util.ArrayList;
+
+/**
+ * First-in-first-out queue.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+*/
+class FIFO
+{
+ private ArrayList m_queue;
+
+ FIFO()
+ {
+ m_queue = new ArrayList();
+ }
+
+ void clear()
+ {
+ synchronized( this )
+ {
+ m_queue.clear();
+ }
+ }
+
+ void put( Object obj )
+ {
+ synchronized( this )
+ {
+ m_queue.add( obj );
+ notifyAll();
+ }
+ }
+
+ Object get() throws InterruptedException
+ {
+ synchronized( this )
+ {
+ while( m_queue.size() == 0 )
+ {
+ wait(100);
+ }
+ return m_queue.remove(0);
+ }
+ }
+
+ int size()
+ {
+ synchronized( this )
+ {
+ return m_queue.size();
+ }
+ }
+}
Added: trunk/main/util/job/impl/src/main/net/dpml/job/impl/Job.java
===================================================================
--- trunk/main/util/job/impl/src/main/net/dpml/job/impl/Job.java
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/impl/src/main/net/dpml/job/impl/Job.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job.impl;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.dpml.job.Commissionable;
+import net.dpml.job.TimeoutException;
+import net.dpml.job.TimeoutError;
+
+/**
+ * A job request handler.
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+class Job
+{
+ //------------------------------------------------------------
+ // immutable state
+ //------------------------------------------------------------
+
+ private final Commissionable m_commissionable;
+ private final Thread m_thread;
+ private final long m_timeout;
+
+ //------------------------------------------------------------
+ // mutable state
+ //------------------------------------------------------------
+
+ private boolean m_completed;
+ private boolean m_interrupted;
+ private Throwable m_exception;
+
+ //------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------
+
+ /**
+ * Creation of a new commission request.
+ * @param model the model to commission
+ * @param thread the deployment thread
+ */
+ Job( Commissionable model, Thread thread, long timeout )
+ {
+ m_commissionable = model;
+ m_completed = false;
+ m_interrupted = false;
+ m_exception = null;
+ m_thread = thread;
+ m_timeout = timeout;
+ }
+
+ //------------------------------------------------------------
+ // implementation
+ //------------------------------------------------------------
+
+ /**
+ * Return the deployment model that it the subject of the
+ * commission request.
+ * @return the model
+ */
+ Commissionable getCommissionable()
+ {
+ return m_commissionable;
+ }
+
+ long waitForCompletion()
+ throws Exception
+ {
+ long t1 = System.currentTimeMillis();
+ synchronized( this )
+ {
+ waitForCompletion( m_timeout );
+ processException();
+ if( m_completed )
+ {
+ long t2 = System.currentTimeMillis();
+ return t2-t1;
+ }
+ m_thread.interrupt();
+ waitForCompletion( m_timeout ); // wait for shutdown
+ processException();
+ if( m_interrupted || m_completed )
+ {
+ throw new TimeoutException( m_timeout );
+ }
+ else
+ {
+ throw new TimeoutError( m_timeout );
+ }
+ }
+ }
+
+ private void waitForCompletion( long timeout ) throws
InterruptedException
+ {
+ if( timeout > 0 )
+ {
+ if( !m_completed )
+ {
+ wait( timeout );
+ }
+ }
+ else
+ {
+ while( !m_completed )
+ {
+ wait( 60 );
+ }
+ }
+ }
+
+ private void processException()
+ throws Exception
+ {
+ if( m_exception != null )
+ {
+ if( m_exception instanceof Exception )
+ {
+ throw (Exception) m_exception;
+ }
+ else if( m_exception instanceof Error )
+ {
+ throw (Error) m_exception;
+ }
+ else
+ {
+ final String error =
+ "Unexpected deployment error.";
+ throw new InvocationTargetException( m_exception, error );
+ }
+ }
+ }
+
+ void done()
+ {
+ synchronized( this )
+ {
+ m_completed = true;
+ notifyAll();
+ }
+ }
+
+ void interrupted()
+ {
+ m_interrupted = true;
+ synchronized( this )
+ {
+ notify();
+ }
+ }
+
+ void exception( Throwable e )
+ {
+ m_exception = e;
+ synchronized( this )
+ {
+ m_completed = true;
+ notify();
+ }
+ }
+}
+
Added: trunk/main/util/job/impl/src/main/net/dpml/job/impl/package.html
===================================================================
--- trunk/main/util/job/impl/src/main/net/dpml/job/impl/package.html
2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/job/impl/src/main/net/dpml/job/impl/package.html
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,6 @@
+
+<body>
+<p>
+Default implementation of a commissioning job handler.
+</p>
+</body>
Added:
trunk/main/util/job/impl/src/test/net/dpml/job/test/DefaultCommissionerTestCase.java
===================================================================
---
trunk/main/util/job/impl/src/test/net/dpml/job/test/DefaultCommissionerTestCase.java
2006-03-22 16:37:15 UTC (rev 1242)
+++
trunk/main/util/job/impl/src/test/net/dpml/job/test/DefaultCommissionerTestCase.java
2006-03-22 16:45:13 UTC (rev 1243)
@@ -0,0 +1,391 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.job.test;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.dpml.lang.Logger;
+
+import net.dpml.transit.monitor.LoggingAdapter;
+
+import net.dpml.job.Commissioner;
+import net.dpml.job.Commissionable;
+import net.dpml.job.CommissionerController;
+import net.dpml.job.CommissionerEvent;
+import net.dpml.job.TimeoutException;
+import net.dpml.job.TimeoutError;
+
+import net.dpml.job.impl.DefaultCommissioner;
+
+import junit.framework.TestCase;
+
+/**
+ * Validation exception testcase verifies the ValidationException and
+ * ValidationException#Issue class implementations.
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public class DefaultCommissionerTestCase extends TestCase
+{
+ static
+ {
+ System.setProperty(
+ "java.util.logging.config.class",
+ "net.dpml.transit.util.ConfigurationHandler" );
+ System.setProperty(
+ "dpml.logging.config",
+ "file:" + System.getProperty( "project.test.dir" ) +
"/logging.properties" );
+ }
+
+ private static final Logger LOGGER = new LoggingAdapter( "test" );
+
+ /**
+ * Test the commissioner implementation.
+ * @exception Exception if an error occurs
+ */
+ public void testCommission() throws Exception
+ {
+ DefaultCommissioner queue =
+ new DefaultCommissioner( "demo", true, new
DefaultCommissionerController() );
+ try
+ {
+ Widget widget = new Widget();
+ long timeout = 200;
+ queue.add( widget, timeout );
+ }
+ finally
+ {
+ queue.dispose();
+ }
+ }
+
+ /**
+ * Test the commissioner implementation.
+ * @exception Exception if an error occurs
+ */
+ public void testDecommission() throws Exception
+ {
+ DefaultCommissioner queue =
+ new DefaultCommissioner( "demo", false, new
DefaultCommissionerController() );
+ try
+ {
+ Widget widget = new Widget();
+ long timeout = 200;
+ queue.add( widget, timeout );
+ }
+ finally
+ {
+ queue.dispose();
+ }
+ }
+
+ /**
+ * Test the commissioner implementation.
+ * @exception Exception if an error occurs
+ */
+ public void testCommissionWithTimeout() throws Exception
+ {
+ DefaultCommissioner queue =
+ new DefaultCommissioner( "demo", true, new
DefaultCommissionerController() );
+ try
+ {
+ Widget widget = new Widget();
+ long timeout = 10;
+ queue.add( widget, timeout );
+ fail( "did not timeout" );
+ }
+ catch( TimeoutException e )
+ {
+ // success
+ }
+ finally
+ {
+ queue.dispose();
+ }
+ }
+
+ /**
+ * Test the commissioner implementation.
+ * @exception Exception if an error occurs
+ */
+ public void testDecommissionWithTimeout() throws Exception
+ {
+ DefaultCommissioner queue =
+ new DefaultCommissioner( "demo", false, new
DefaultCommissionerController() );
+ try
+ {
+ Widget widget = new Widget();
+ long timeout = 10;
+ queue.add( widget, timeout );
+ fail( "did not timeout" );
+ }
+ catch( TimeoutException e )
+ {
+ // success
+ }
+ finally
+ {
+ queue.dispose();
+ }
+ }
+
+ /**
+ * Test the commissioner implementation.
+ * @exception Exception if an error occurs
+ */
+ public void testCommissionWithTimeoutAndNoResponse() throws Exception
+ {
+ DefaultCommissioner queue =
+ new DefaultCommissioner( "demo", true, new
DefaultCommissionerController() );
+ try
+ {
+ Gizmo gizmo = new Gizmo();
+ long timeout = 100;
+ queue.add( gizmo, timeout );
+ fail( "did not timeout" );
+ }
+ catch( TimeoutError e )
+ {
+ // success
+ }
+ finally
+ {
+ queue.dispose();
+ }
+ }
+
+ /**
+ * Test the commissioner implementation.
+ * @exception Exception if an error occurs
+ */
+ public void testClientError() throws Exception
+ {
+ DefaultCommissioner queue =
+ new DefaultCommissioner( "demo", false, new
DefaultCommissionerController() );
+ try
+ {
+ Gizmo gizmo = new Gizmo();
+ long timeout = 100;
+ queue.add( gizmo, timeout );
+ fail( "did not throw client exception" );
+ }
+ catch( InvocationTargetException e )
+ {
+ // success
+ }
+ finally
+ {
+ queue.dispose();
+ }
+ }
+
+ private class Widget implements Commissionable
+ {
+ /**
+ * Commission the widget.
+ * @throws Exception if a error occurs
+ */
+ public void commission() throws Exception
+ {
+ try
+ {
+ Thread.currentThread().sleep( 100 );
+ }
+ catch( Exception e )
+ {
+ }
+ }
+
+ /**
+ * Decommission the widget.
+ */
+ public void decommission()
+ {
+ try
+ {
+ Thread.currentThread().sleep( 100 );
+ }
+ catch( Exception e )
+ {
+ }
+ }
+
+ /**
+ * Return the instance as a string.
+ * @return the string
+ */
+ public String toString()
+ {
+ return "widget";
+ }
+ }
+
+ private class Gizmo implements Commissionable
+ {
+ /**
+ * Commission the gizmo.
+ * @throws Exception if a error occurs
+ */
+ public void commission() throws Exception
+ {
+ while( true )
+ {
+ try
+ {
+ Thread.currentThread().sleep( 100 );
+ }
+ catch( Exception e )
+ {
+ }
+ }
+ }
+
+ /**
+ * Decommission the widget.
+ */
+ public void decommission()
+ {
+ throw new UnsupportedOperationException( "I'm bad!" );
+ }
+
+ /**
+ * Return the instance as a string.
+ * @return the string
+ */
+ public String toString()
+ {
+ return "gizmo";
+ }
+ }
+
+ public class DefaultCommissionerController implements
CommissionerController
+ {
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has commenced.
+ * @param event the commissioner event
+ * @exception RemoteException if a remote exception occurs
+ */
+ public void started( CommissionerEvent event )
+ {
+ String message =
+ getAction( event )
+ + "["
+ + event.getSource()
+ + "]";
+ LOGGER.debug( message );
+ }
+
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has completed.
+ * @param event the commissioner event
+ * @exception RemoteException if a remote exception occurs
+ */
+ public void completed( CommissionerEvent event )
+ {
+ String message =
+ getAction( event )
+ + "["
+ + event.getSource()
+ + "] completed in "
+ + event.getDuration()
+ + " milliseconds";
+ LOGGER.debug( message );
+ }
+
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has been interrupted.
+ * @param event the commissioner event
+ * @exception Exception client initiated exception
+ */
+ public void interrupted( CommissionerEvent event ) throws
TimeoutException
+ {
+ String message =
+ getAction( event )
+ + "of ["
+ + event.getSource()
+ + "] interrupted after "
+ + event.getDuration()
+ + " milliseconds";
+ LOGGER.debug( message );
+ throw new TimeoutException( event.getDuration() );
+ }
+
+ /**
+ * Notification that a commissioning or decommissioning
+ * process has been terminated.
+ * @param event the commissioner event
+ * @exception Exception client initiated exception
+ */
+ public void terminated( CommissionerEvent event ) throws TimeoutError
+ {
+ String message =
+ getAction( event )
+ + "of ["
+ + event.getSource()
+ + "] terminated after "
+ + event.getDuration()
+ + " milliseconds";
+ LOGGER.debug( message );
+ throw new TimeoutError( event.getDuration() );
+ }
+
+ /**
+ * Notification that a commissioning or decommissioning
+ * process failed.
+ * @param event the commissioner event
+ * @param cause the causal exception
+ * @exception Throwable controller initiated exception
+ */
+ public void failed( CommissionerEvent event, Throwable cause )
throws InvocationTargetException
+ {
+ String message =
+ getAction( event )
+ + "of ["
+ + event.getSource()
+ + "] failed due ["
+ + cause.getClass().getName()
+ + "]";
+ LOGGER.error( message );
+ if( cause instanceof InvocationTargetException )
+ {
+ throw (InvocationTargetException) cause;
+ }
+ else
+ {
+ throw new InvocationTargetException( cause );
+ }
+ }
+
+ private String getAction( CommissionerEvent event )
+ {
+ if( event.isCommissioning() )
+ {
+ return "commissioning ";
+ }
+ else
+ {
+ return "decommissioning ";
+ }
+ }
+ }
+}
Modified: trunk/main/util/module.xml
===================================================================
--- trunk/main/util/module.xml 2006-03-22 16:37:15 UTC (rev 1242)
+++ trunk/main/util/module.xml 2006-03-22 16:45:13 UTC (rev 1243)
@@ -7,6 +7,28 @@
<include key="transit"/>
</dependencies>
+ <project name="dpml-job-api" basedir="job/api">
+ <types>
+ <type id="jar"/>
+ </types>
+ </project>
+
+ <project name="dpml-job-impl" basedir="job/impl">
+ <properties>
+ <property name="project.test.fork" value="true"/>
+ </properties>
+ <types>
+ <type id="jar"/>
+ </types>
+ <dependencies>
+ <include ref="dpml/util/dpml-job-api"/>
+ <include ref="dpml/transit/dpml-transit-main"/>
+ </dependencies>
+ <dependencies scope="test">
+ <include ref="ant/ant-junit"/>
+ </dependencies>
+ </project>
+
<project name="dpml-util-i18n" basedir="i18n">
<types>
<type id="jar"/>
- r1243 - in trunk/main/util: . job job/api job/api/src job/api/src/main job/api/src/main/net job/api/src/main/net/dpml job/api/src/main/net/dpml/job job/impl job/impl/etc job/impl/etc/test job/impl/src job/impl/src/main job/impl/src/main/net job/impl/src/main/net/dpml job/impl/src/main/net/dpml/job job/impl/src/main/net/dpml/job/impl job/impl/src/test job/impl/src/test/net job/impl/src/test/net/dpml job/impl/src/test/net/dpml/job job/impl/src/test/net/dpml/job/test, mcconnell at BerliOS, 03/22/2006
Archive powered by MHonArc 2.6.24.