Commit 5d79f9e6 authored by Munilla Christophe's avatar Munilla Christophe
Browse files

frascati-starter - Add reference-container to be able to wait for multiple...

frascati-starter - Add reference-container to be able to wait for multiple components starting from one starter
frascati-starter - Add rearmed mechanism to allow to replay initialization each time waited component(s) is (are) restarted  
parent 940423e0
......@@ -63,6 +63,12 @@
<version>4.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
......
......@@ -25,6 +25,7 @@
*/
package org.ow2.frascati.starter.api;
import org.osoa.sca.annotations.Property;
import org.osoa.sca.annotations.Reference;
import org.osoa.sca.annotations.Scope;
import org.osoa.sca.annotations.Service;
......@@ -43,6 +44,12 @@ public abstract class AbstractInitializable
// --------------------------------------------------------------------------
// Internal state.
// --------------------------------------------------------------------------
/**
* Is the rearmed mechanism available ?
*/
@Property(name="rearmed-available", required=false)
boolean rearmedAvailable;
/** the next InitializableItf object to initialize */
@Reference(name = "next-initializable", required = false)
......@@ -96,6 +103,19 @@ public abstract class AbstractInitializable
initialized = true;
}
/**
* {@inheritDoc}
*
* @see org.ow2.frascati.starter.api.InitializableItf#setInitializable(boolean)
*/
public void setInitializable(boolean initializable)
{
if(!initializable || rearmedAvailable)
{
initialized = !initializable;
}
}
/**
* {@inheritDoc}
*
......
/**
* OW2 FraSCAti : Starter
* Copyright (c) 2008 - 2012 Inria, University of Lille 1
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: frascati@ow2.org
*
* Author: Christophe Munilla
*
* Contributor(s):
*
*/
package org.ow2.frascati.starter.api;
import java.util.logging.Level;
import juliac.generated.SCALifeCycleControllerImpl;
import org.objectweb.fractal.julia.ComponentInterface;
import org.objectweb.fractal.julia.control.lifecycle.LifeCycleCoordinator;
import org.osoa.sca.annotations.EagerInit;
import org.osoa.sca.annotations.Property;
import org.osoa.sca.annotations.Reference;
import org.osoa.sca.annotations.Scope;
import org.osoa.sca.annotations.Service;
import org.ow2.frascati.tinfi.TinfiComponentInterceptor;
import org.ow2.frascati.tinfi.api.IntentHandler;
import org.ow2.frascati.util.AbstractLoggeable;
import org.ow2.frascati.util.reference.ServiceReferenceUtil;
/**
* @author munilla
*
*/
@EagerInit
@Scope("COMPOSITE")
@Service(StarterItf.class)
public abstract class AbstractStarter extends AbstractLoggeable implements StarterItf
{
/**
* Is the rearmed mechanism available ?
*/
@Property(name="rearmed-available", required=false)
protected boolean rearmedAvailable;
/**
* The required Starter Container
*/
@Reference(name = "starter-container")
protected StarterContainerItf starterContainer;
/**
* {@inheritDoc}
*
* @see org.ow2.frascati.starter.api.StarterItf#startContainer()
*/
public void startContainer()
{
if(rearmedAvailable)
{
this.starterContainer.rearmed();
}
}
/**
* Weave the IntentHandler passed on as a parameter with the
* {@see org.objectweb.fractal.api.control.LifeCycleController} of the SCA object to spy
*
* @param spied
* the SCA object to spy
* @param handler
* the IntentHandler to weave
* @return
* true if the IntentHandler has successfully been woven
* false otherwise
*/
protected boolean weaveLyfeCycleIntent(Object spied, IntentHandler handler)
{
java.lang.reflect.Field lifecycleField = null;
TinfiComponentInterceptor<?> interceptor = ServiceReferenceUtil.getInterceptor(
spied);
if(interceptor != null)
{
try
{ //retrieve the private field referencing the life cycle controller of
//the spied object
lifecycleField = interceptor.getClass().getDeclaredField("_lc");
SCALifeCycleControllerImpl lifeCycleController = null;
lifecycleField.setAccessible(true);
lifeCycleController = (SCALifeCycleControllerImpl) lifecycleField.get(
interceptor);
//method call to listen : setFcStarted
java.lang.reflect.Method methodStart = LifeCycleCoordinator.class.getMethod(
"setFcStarted", (Class<?>[]) null);
// //method call to listen : startFc
// java.lang.reflect.Method methodStartFc = LifeCycleController.class.getMethod(
// "startFc", (Class<?>[]) null);
//method call to listen : setFcStopped
java.lang.reflect.Method methodStop = LifeCycleCoordinator.class.getMethod(
"setFcStopped", (Class<?>[]) null);
// //method call to listen : stopFc
// java.lang.reflect.Method methodStopFc = LifeCycleController.class.getMethod(
// "stopFc", (Class<?>[]) null);
//Weave
TinfiComponentInterceptor<?> tci = (TinfiComponentInterceptor<?>)
((ComponentInterface) lifeCycleController.getFcCoordinator()).getFcItfImpl();
tci.addIntentHandler(handler, methodStart);
//tci.addIntentHandler(handler, methodStartFc);
tci.addIntentHandler(handler, methodStop);
//tci.addIntentHandler(handler, methodStopFc);
return true;
} catch (java.lang.NoSuchFieldException e)
{
if(log.isLoggable(Level.SEVERE))
{
log.log(Level.SEVERE,"The field relative to the life cycle controller " +
"('_lc') of the component cannot be retrieve");
}
} catch (NoSuchMethodException e)
{
if(log.isLoggable(Level.SEVERE))
{
log.log(Level.SEVERE,"The methods relative to the life cycle controller " +
"('setFcStarted', 'setFcStopped')" +
" of the component cannot be retrieve");
}
} catch (IllegalArgumentException e)
{
if(log.isLoggable(Level.SEVERE))
{
log.log(Level.SEVERE,e.getMessage());
}
} catch (IllegalAccessException e)
{
if(log.isLoggable(Level.SEVERE))
{
log.log(Level.SEVERE,e.getMessage());
}
}
}
return false;
}
}
......@@ -28,10 +28,9 @@ package org.ow2.frascati.starter.api;
import org.osoa.sca.annotations.Service;
/**
* Allow to link the initilization process of an SCA component to another one
* The initialize method of an InitializableItf object will be called when
* the after the call of the startFc method of the LifeCycleController of the
* linked SCA Component
* Allow to link the initialization process of an SCA component to another one
* The initialize method of an InitializableItf object will be called after the call
* of the startFc method of the LifeCycleController of the linked SCA Component
* */
@Service
public interface InitializableItf
......@@ -42,6 +41,15 @@ public interface InitializableItf
*/
void initialize();
/**
* Define whether the 'initialize' method of the current InitializableItf implementation
* instance has to be called or not
*
* @param initializable
* Is the current InitializableItf instance "initializable" ?
*/
void setInitializable(boolean initializable);
/**
* Return the next InitializableItf object to initialize
*
......
/**
* OW2 FraSCAti : Starter
* Copyright (c) 2008 - 2012 Inria, University of Lille 1
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: frascati@ow2.org
*
* Author: Christophe Munilla
*
* Contributor(s):
*
*/
package org.ow2.frascati.starter.api;
import java.util.Iterator;
import org.osoa.sca.annotations.Service;
/**
* Contains not chained InitilizableItf objects
* */
@Service
public interface ReferenceContainerItf extends Iterator<Object>
{
/**
* Return the number of objects registered in the container
*
* @return
* size of the container
*/
int size();
/**
* Increment the number of received start event
*
* @return
* true if all expected start event have bee received
* false otherwise
*/
boolean incrementAndGet();
/**
* Increment the number of received stop event
*
* @return
* true if all expected stop event have been received
* false otherwise
*/
boolean decrementAndGet();
/**
* Increment the maximum number of successive 'start' or 'stop' events
* that can be received
*/
int plus();
}
......@@ -34,7 +34,7 @@ import org.osoa.sca.annotations.Service;
* */
@Service
public interface StarterContainerItf extends Iterator<InitializableItf>
{
{
/**
* Return the number of InitializableItf objects registered in
* the container
......@@ -43,4 +43,10 @@ public interface StarterContainerItf extends Iterator<InitializableItf>
* size of the container
*/
int size();
/**
* Authorize a new iteration of registered InitializableItf
* components
*/
void rearmed();
}
......@@ -35,8 +35,21 @@ import org.osoa.sca.annotations.Service;
public interface StarterItf
{
/**
* Called to ask the Starter object to initialize Initializable
* objects that have been registered
* Tell the StarterItf implementation object that the listened Component has
* been started. So, InitializableItf registered objects initialization
* can be executed
*/
void start();
/**
* Tell the StarterItf implementation object that the StarterContainerItf
* instance has been started (or re-started).
*/
void startContainer();
/**
* Tell the StarterItf implementation object that the listened Component has
* been stopped
*/
void stop();
}
/**
* OW2 FraSCAti : Starter
* Copyright (c) 2011 - 2012 Inria, University of Lille 1
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: frascati@ow2.org
*
* Author: Christophe Munilla
*
* Contributor(s):
*
*/
package org.ow2.frascati.starter.core;
import org.osoa.sca.annotations.Scope;
import org.osoa.sca.annotations.Service;
import org.ow2.frascati.starter.api.StarterItf;
import org.ow2.frascati.tinfi.api.IntentHandler;
import org.ow2.frascati.tinfi.api.IntentJoinPoint;
import org.ow2.frascati.util.AbstractLoggeable;
/**
* An IntentHandler implementation to weave with the LyfeCycleController of the
* StarterContainerItf implementation instance
* */
@Scope("COMPOSITE")
@Service(IntentHandler.class)
public class ContainerIntent extends AbstractLoggeable implements IntentHandler
{
/**
* The required Starter
*/
StarterItf starter;
/** define whether the startFc method has already been called */
private boolean started = false;
/**
* @param multiReferenceStarter
*/
public ContainerIntent(StarterItf starter)
{
this.starter = starter;
}
/**
* {@inheritDoc}
*
* @see org.ow2.frascati.tinfi.api.IntentHandler
* #invoke(org.ow2.frascati.tinfi.api.IntentJoinPoint)
*/
public Object invoke(IntentJoinPoint ijp) throws Throwable
{
Object ret;
ret = ijp.proceed();
String method = ijp.getMethod().getName();
if("setFcStarted".equals(method))// || "startFc".equals(method))
{
if (!started)
{
started = true;
starter.startContainer();
}
} else if("setFcStopped".equals(method))// || "stopFc".equals(method))
{
if(started)
{
started = false;
}
}
return ret;
}
}
/**
* OW2 FraSCAti : Starter
* Copyright (c) 2008 - 2012 Inria, University of Lille 1
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: frascati@ow2.org
*
* Author: Christophe Munilla
*
* Contributor(s):
*
*/
package org.ow2.frascati.starter.core;
import java.util.logging.Level;
import org.osoa.sca.annotations.Init;
import org.osoa.sca.annotations.Reference;
import org.ow2.frascati.starter.api.AbstractStarter;
import org.ow2.frascati.starter.api.InitializableItf;
import org.ow2.frascati.starter.api.ReferenceContainerItf;
import org.ow2.frascati.starter.api.StarterItf;
/**
* A {@link StarterItf} implementation for more than one component
* starting waiting
*/
public class MultiReferenceStarter extends AbstractStarter
{
/**
* The required Starter Container
*/
@Reference(name = "reference-container")
private ReferenceContainerItf referenceContainer;
/**
* Initialization
*/
@Init
public void init()
{
//launch the initialization and wait for the start event of
//the referenceContainer to finalize it
//Spy the referenceContainer's lifecycle to avoid deadlock
if(weaveLyfeCycleIntent(referenceContainer, new ReferenceIntent(this)))
{
if(log.isLoggable(Level.CONFIG))
{
log.log(Level.CONFIG,"Now listen to the events relative " +
"to the lifecyle of the referenceContainer");
}
} else if(log.isLoggable(Level.CONFIG))
{
log.log(Level.CONFIG,"Unable to weave the ReferenceIntent with the ReferenceContainer");
}
}
/**
* Post-initialization
* Weave
*/
public void postInit()
{
if(log.isLoggable(Level.CONFIG))
{
log.log(Level.CONFIG, "ServiceReferenceContainer init[" + this + "]");
}
//Spy the starterContainer's lifecycle to rearmed it if it is authorized (
// cf. 'rearmed-available' property) and necessary (starterContainer re-start)
if(weaveLyfeCycleIntent(starterContainer, new ContainerIntent(this)))
{
if(log.isLoggable(Level.CONFIG))
{
log.log(Level.CONFIG,"Now listen to the events relative " +
"to the lifecyle of the referenceContainer");
}
} else if(log.isLoggable(Level.CONFIG))
{
log.log(Level.CONFIG,"Unable to weave the ContainerIntent with the ReferenceContainer");
}
//spy all ServiceReferences' life cycles
synchronized(referenceContainer)
{
while(referenceContainer.hasNext())
{
Object serviceReference = referenceContainer.next();
if(weaveLyfeCycleIntent(serviceReference, new StarterIntent(this)))
{
referenceContainer.plus();
}
}
}
}
/**
* {@inheritDoc}
*
* @see org.ow2.frascati.starter.StarterItf#start()
*/
public void start()
{