|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object cz.cuni.amis.pogamut.base.agent.impl.AbstractAgent
public abstract class AbstractAgent
Abstract agent class, provides basic interface for the agent implementing its lifecycle methods + introducing JMX.
Agent has fully implemented lifecycle methods such as start()
, startPaused()
or stop()
. It also listens for IFatalErrorEvent
on its bus in order to terminate itself
in case of any errors. Also, if all components of the agent stops themselves, the agent is stopped as well.
If you do not like this behavior, email me to jakub.gemrot@gmail.com and I will make this optional.
Note that the Pogamut agent is designed to be a multicomponent beast. And by component we're meaning objects
that implements IComponent
registers itself into getEventBus()
owned by the agent
and adhering to the lifecycle provided either by ComponentController
or
ILifecycleBus#addLifecycleManagement(IToken, cz.cuni.amis.pogamut.base.component.controller.IComponentControlHelper, cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies)
.
These components (if correctly configured, which all native components are) starts together with the call of start()
or startPaused()
, as well as stopping themselves in the case of stop()
.
This model seems to defy the OOP, in fact it is its very incarnation applying principles or "separation of concerns", "modular design", whatever you would like to call it. Many native components are designed the way they interact with each other only via interfaces, they do not depend on each other directly thus greatly enabling anybody to hack inside any internal component of any Pogamut agent.
JMX
We're purposely using neither inheritance here nor decorator (or such wrappers) because we need JMX to be usable by every descendant of the class (so we don't want to have another JMX class branch, nor wrapper that denies the inheritance by its nature).
To keep the JMX-specific methods at minimum in the agent class we're grouping them into the private inner class object JMXComponents that can be accessed via getJMX() method. This object maintain also a list of IJMXEnabled components that should be enabled when the whole JMX feature is being enabled.
Usage:
To start JMX on the agent: getJMX().enableJMX(mBeanServer, domain)
To add another JMX component to the agent: getJMX().addComponent(component)
Field Summary | |
---|---|
protected AgentEvents |
events
Gateway for sending events into the event bus. |
static java.lang.String |
INTROSPECTION_ROOT_NAME
Name of the root introspection folder. |
protected LogCategory |
log
Agent's log category. |
Constructor Summary | |
---|---|
AbstractAgent(IAgentId agentId,
IComponentBus eventBus,
IAgentLogger logger)
Introspection folder with properties and other subfolders obtained from this agent. |
Method Summary | |
---|---|
protected void |
addDependency(java.lang.Class componentClass)
|
protected void |
addDependency(IComponent component)
|
protected void |
addDependency(IToken componentId)
|
protected void |
addJMXComponents()
Called when AgentJMX (field jmx) is instantiated to populate it with agent's JMX enabled components. |
IAgentState |
awaitState(java.lang.Class awaitAgentState)
This method is designed to wait for the agent to reach state 'awaitAgentState' (usually used with IAgentStateUp . |
IAgentState |
awaitState(java.lang.Class awaitAgentState,
long timeoutMillis)
This method is designed to wait for the agent's initialization until till 'timeoutMillis'. |
protected void |
componentFatalError(IFatalErrorEvent event)
Called whenever some comopnent broadcasts IFatalErrorEvent . |
protected void |
componentStarted(IPausedEvent event)
Called whenever some component that was not started before broadcasts IPausedEvent |
protected void |
componentStarted(IStartedEvent event)
Called whenever some component that was not started before broadcasts IStartedEvent |
protected void |
componentStopped(IStoppedEvent event)
Called whenever component that was running broadcasts IStoppedEvent . |
protected void |
componentStopping(IStoppingEvent event)
Called whenever some component broadcasts IStoppingEvent |
protected AgentJMXComponents |
createAgentJMX()
|
protected Folder |
createIntrospection()
Create introspection root object. |
boolean |
equals(java.lang.Object other)
|
IAgentId |
getComponentId()
Returns agent id - contains also a human-readable name that can be changed |
IComponentBus |
getEventBus()
IComponentBus that the instance is working with. |
Folder |
getIntrospection()
Returns folder with introspection information. |
AgentJMXComponents |
getJMX()
Returns support class for the JMX feature of the agent. |
LogCategory |
getLog()
Returns log category of the agent, used by agent lifecycle management methods itself. |
IAgentLogger |
getLogger()
Returns AgentLogger for the instance allowing creating new log categories or adding new handlers to them. |
java.lang.String |
getName()
Returns human-readable agent's name. |
ImmutableFlag<IAgentState> |
getState()
Returns the state of the agent (whether it's running / dead / etc.). |
int |
hashCode()
|
boolean |
inState(java.lang.Class<?>... states)
Returns true if the agent is in one of 'states'. |
void |
kill()
Method that requests the agent to be killed - this counts as fatal error as well. |
protected void |
killAgent()
Called during kill() method - override to provide custom ruthless stopping (killing) behavior of the agent. |
boolean |
notInState(java.lang.Class<?>... states)
Returns true if the agent is not in any of 'states'. |
void |
pause()
Pauses the agent - working only if the agent is in IAgentStateRunning |
protected void |
pauseAgent()
Called during pause() method - override to provide custom pausing behavior of the agent. |
protected void |
preKillAgent()
Called before any ComponentBusEvents.fatalError(String) event is broadcast. |
protected void |
preStopAgent()
Called before any ComponentBusEvents.stopping() event is broadcast. |
protected void |
resetAgent()
Called whenever the IComponentBus broadcast IResetEvent to reset all agent's components as well
as an agent. |
protected void |
resetEvent(IResetEvent event)
|
void |
resume()
Resumes the agent - working only if the agent is in IAgentStatePaused |
protected void |
resumeAgent()
Called during resume() method - override to provide custom resuming behavior of the agent. |
protected void |
setState(AgentState state)
Sets the state of the agent ... |
void |
start()
Starts the agent. |
protected void |
startAgent()
Called during start() method - override to provide custom starting behavior of the agent. |
void |
startPaused()
Starts the agent into paused state. |
protected void |
startPausedAgent()
Called during startPaused() method - override to provide custom starting-paused behavior of the agent. |
void |
stop()
Stops the agent. |
protected void |
stopAgent()
Called during stop() method - override to provide custom stopping behavior of the agent. |
java.lang.String |
toString()
|
Methods inherited from class java.lang.Object |
---|
clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
public static final java.lang.String INTROSPECTION_ROOT_NAME
protected LogCategory log
protected AgentEvents events
Constructor Detail |
---|
public AbstractAgent(IAgentId agentId, IComponentBus eventBus, IAgentLogger logger)
agentId
- unique id of the agenteventBus
- agent's event bus systemlogger
- agent's logger, used to obtain AgentName
instanceMethod Detail |
---|
public boolean equals(java.lang.Object other)
equals
in class java.lang.Object
public int hashCode()
hashCode
in class java.lang.Object
public IAgentLogger getLogger()
IAgent
getLogger
in interface IAgent
public ImmutableFlag<IAgentState> getState()
IAgent
Note that the type AgentState wraps two things:
getState
in interface IAgent
public boolean inState(java.lang.Class<?>... states)
states
-
public boolean notInState(java.lang.Class<?>... states)
states
-
public IComponentBus getEventBus()
IComponentAware
IComponentBus
that the instance is working with.
Note that by design-choice - the IComponentBus
is a singleton inside AgentScoped
,
therefore you don't have to necessarily obtain the instance through the component, it suffice
to obtain it using injection into your object.
getEventBus
in interface IComponentAware
public java.lang.String getName()
IAgent
Do not use as unique id of the agent:
1) the name might change during the life of agent
2) we do not ensure it's unique
Use getComponentId().getToken() instead!
Use getComponentId().getName().setFlag() to change the name of the agent.
getName
in interface IAgent
public IAgentId getComponentId()
IAgent
getComponentId
in interface IAgent
getComponentId
in interface IComponent
public LogCategory getLog()
public final void start() throws ComponentCantStartException
1) switches state to IAgentStateStarting
2) broadcasts IStartingEvent
(transactional)
3) calls startAgent()
3) broadcasts IStartedEvent
(transactional)
4) switches state to IAgentStateStarted
Every agent component that wants to start together with the agent should do so during (2 or 3) and broadcast eventTransactionl(IStartedEvent
/ IPausedEvent
).
Prevents recursion.
start
in interface IAgent
start
in interface IControllable
ComponentCantStartException
public final void startPaused() throws ComponentCantStartException
1) switches state to IAgentStateStartingPaused
2) broadcasts IStartingPausedEvent
(transactional)
3) calls startAgent()
3) broadcasts IPausedEvent
(transactional)
4) switches state to IAgentStatePaused
Every agent component that wants to start together with the agent should do so during (2 or 3) and broadcast eventTransactionl(IStartedEvent
/ IPausedEvent
).
Prevents recursion.
startPaused
in interface IAgent
ComponentCantStartException
protected void preStopAgent()
ComponentBusEvents.stopping()
event is broadcast. Hook that allows you to implement just-before-death stuff
before any of agent component actually dies.
public final void stop() throws ComponentCantStopException
1) switches state to IAgentStateStopping
2) broadcasts IStoppingEvent
(transactional)
3) calls stopAgent()
4) checks whether all components has stopped, if not - performs kill().
5) broadcasts IStoppedEvent
(transactional)
6) switches state to IAgentStateStopped
Every agent's component that is still running must stop itself during (2) by broadcasting 'eventTransactional(IStoppedEvent
)'.
If there will be some component that remains started after the propagation of IStoppingEvent
the method
will perform kill() method (counts as fatal error) and throws AgentException
.
Prevents recursion.
stop
in interface IAgent
stop
in interface IControllable
ComponentCantStopException
protected void preKillAgent()
ComponentBusEvents.fatalError(String)
event is broadcast. Hook that allows you to implement just-before-death stuff
before any of agent component actually dies.
public final void kill()
1) switches state to IAgentStateFailed
2) broadcast IFatalErrorEvent
3) calls killAgent()
This should be used to ultimately kill the agent in a ruthless way - components will usually perform some dirty tricks to kill themselves.
Prevents recursion.
NEVER THROWS EXCEPTION
kill
in interface IAgent
kill
in interface IControllable
public final void pause() throws ComponentCantPauseException
IAgentStateRunning
1) switches state to IAgentStatePausing
2) broadcasts IPausingEvent
(transactional)
3) calls pauseAgent()
4) broadcasts IPausedEvent
(transactional)
5) switches state to IAgentPaused
Prevents recursion.
pause
in interface IAgent
ComponentCantPauseException
public final void resume() throws ComponentCantResumeException
IAgentStatePaused
1) switches state to IAgentStateResuming
2) broadcasts IResumingEvent
(transactional)
3) calls resumeAgent()
4) broadcasts IResumedEvent
(transactional)
5) switches state to IAgentStateRunning
Prevents recursion.
resume
in interface IAgent
ComponentCantResumeException
public final AgentJMXComponents getJMX()
public IAgentState awaitState(java.lang.Class awaitAgentState) throws AgentException
IAgentStateUp
.
The call on this method will blocks until this instance of agent switches to the desired state.
Nevertheless - if the agent switches itself to the IAgentStateDown
state, it returns null.
(if it is not the state you are awaiting for of course). If you find this unsuitable, use WaitForAgentStateChange
directly.
awaitAgentState
-
AgentException
public IAgentState awaitState(java.lang.Class awaitAgentState, long timeoutMillis) throws AgentException
The call on this method will blocks until this instance of agent switches to the IAgentStateUp
.
Nevertheless - if the agent switches itself to the IAgentStateDown
state, it returns null. If you find this unsuitable, use WaitForAgentStateChange
directly.
The method also returns null in the case of timeout.
awaitAgentState
- timeoutMillis
- how long we should wait for the agent to ini
AgentException
PogamutInterruptedException
public final Folder getIntrospection()
IAgent
getIntrospection
in interface IAgent
protected Folder createIntrospection()
protected void startAgent()
WARNING: DO NOT CALL ON YOUR OWN, ALWAYS USE PUBLIC INTERFACE (start()), but that should not be needed!
If you override this method don't forget to call super.startAgent() as the first method.
protected void startPausedAgent()
WARNING: DO NOT CALL ON YOUR OWN, ALWAYS USE PUBLIC INTERFACE (startPaused()), but that should not be needed!
If you override this method don't forget to call super.startPausedAgent() as the first method.
protected void stopAgent()
WARNING: DO NOT CALL ON YOUR OWN, ALWAYS USE PUBLIC INTERFACE (stop()).
If you override this method don't forget to call super.stopAgent() as the first method.
protected void killAgent()
WARNING: DO NOT CALL ON YOUR OWN, ALWAYS USE PUBLIC INTERFACE (kill()).
If you override this method don't forget to call super.killAgent() as the first method.
protected void pauseAgent()
WARNING: DO NOT CALL ON YOUR OWN, ALWAYS USE PUBLIC INTERFACE (pause()).
If you override this method don't forget to call super.pauseAgent() as the first method.
protected void resumeAgent()
WARNING: DO NOT CALL ON YOUR OWN, ALWAYS USE PUBLIC INTERFACE (resume()).
If you override this method don't forget to call super.resumeAgent() as the first method.
protected void resetAgent()
IComponentBus
broadcast IResetEvent
to reset all agent's components as well
as an agent. Clean up your private data structure, get ready to be started again.
WARNING: DO NOT CALL ON YOUR OWN, CALLED FROM THE resetEvent(IResetEvent)
AUTOMATICALLY.
If you override this method don't forget to call super.resetAgent() as the first method.
protected void componentStarted(IStartedEvent event)
IStartedEvent
If you override this method don't forget to call super.componentStarted(event) as the first method.
event
- protected void componentStarted(IPausedEvent event)
IPausedEvent
If you override this method don't forget to call super.componentStarted(event) as the first method.
event
- protected void componentStopping(IStoppingEvent event)
IStoppingEvent
If you override this method don't forget to call super.componentStopping(event) as the first method.
event
- protected void componentStopped(IStoppedEvent event)
IStoppedEvent
.
If you override this method don't forget to call super.componentStopped(event) as the first method.
event
- protected void componentFatalError(IFatalErrorEvent event)
IFatalErrorEvent
.
If you override this method don't forget to call super.fatalError(event) as the first method.
event
- protected void resetEvent(IResetEvent event)
protected AgentJMXComponents createAgentJMX()
protected void addDependency(IComponent component)
protected void addDependency(java.lang.Class componentClass)
protected void addDependency(IToken componentId)
protected void setState(AgentState state)
state
- protected void addJMXComponents()
Currently two components are added:
If you override this method don't forget to call super.addJMXComponents() as the first method.
Note that you don't need to override this method to introduce new jmx components if and only if:
1) you do not need the component before the agent starts up
2) your JMX component is also an IComponent
that starts together with the agent
If (2) holds, the component will be added to the 'jmx' by the agent automatically and if jmx is already started it will start it as well.
public java.lang.String toString()
toString
in class java.lang.Object
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |