Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* COOS - Connected Objects Operating System (www.connectedobjects.org).
*
* Copyright (C) 2009 Telenor ASA and Tellu AS. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see .
*
* You may also contact one of the following for additional information:
* Telenor ASA, Snaroyveien 30, N-1331 Fornebu, Norway (www.telenor.no)
* Tellu AS, Hagalokkveien 13, N-1383 Asker, Norway (www.tellu.no)
*/
package org.coos.actorframe.application;
import java.util.Enumeration;
import java.util.Vector;
import org.coos.javaframe.*;
import org.coos.javaframe.messages.AFPropertyMsg;
import org.coos.javaframe.messages.ActorMsg;
import org.coos.javaframe.messages.JFConstants;
/**
* @author Geir Melby, Tellu AS
* @author Robert Bjarum, Tellu AS
*/
public class Application implements ApplicationConstants, JFConstants {
// Is the name of this applicaton
// protected String applicationName = "appName";
// The description of this application
protected ApplicationSpec applicationSpec;
// Logger
protected static Logger logger = LoggerFactory.getLogger("org.coos.actorframe");
// instance varaible to this class
protected static Application instance;
// contains the schedulerData that is run
protected SchedulerData schedulerData;
// Is reference to the container that runs this application
protected Container container;
// is the session that connects the application to the message bus
// protected SessionManager sessionManager;
// Contains the state of the application. The different states are
// defined in ApplicationConstants file
protected int state;
// Keeps the reference to the actor router. May be null.
protected ActorRouterI actorRouter;
public Application(ApplicationSpec appSpec) {
setApplicationSpec(appSpec);
instance = this;
}
public Application() {
instance = this;
}
/**
* Initialize application. Called by Container.
*
* To extend the initialization of the application, implement the method
* extendInitApplication().
*/
public final void initApplication() {
state = STATE_INITIALIZING;
logger = LoggerFactory.getLogger(this.getClass().getName());
/* Call extension of this method. */
extendInitApplication();
if (applicationSpec == null) {
logger.log(TraceConstants.tlWarn, "Application: applicationSpec not set.");
applicationSpec = readApplicationSpec();
}
state = STATE_INITIALIZED;
}
/**
* Get the actor router, may be null;
*
* @return
*/
public ActorRouterI getActorRouter() {
return actorRouter;
}
public void setActorRouter(ActorRouterI actorRouter) {
this.actorRouter = actorRouter;
}
/**
* Return static reference to Logger object
*
* @return Logger object
*/
public Logger getLogger() {
return logger;
}
/**
* Adds an adapter to the default scheduler. This adapther may behave like a StateMachine.
* @param schedulableAdapter is the adapter that implements the Scheduable interface
*/
public void addSchedulerAdapter(Schedulable schedulableAdapter) {
schedulerData.getDefaultScheduler().addSchedulable(schedulableAdapter, schedulableAdapter.getMyActorAddress());
}
/*
* public void startApplication() { startApplication(new
* ActorAddress("callback", "Exithandler")); }
*/
/**
* Starts the application. The application may run one or more domains. Each
* of them is started
*/
public void startApplication() {
ActorAddress sender = getSenderAddress();
if (getApplicationSpec() == null) {
throw new NullPointerException("Application,startApplication: ApplicationSpec is null");
}
DomainSpec domainSpec = getApplicationSpec().getDomainSpec();
if (domainSpec == null) {
domainSpec = new org.coos.actorframe.application.DomainSpec("default", "ActorDomain");
getApplicationSpec().setDomainSpec(domainSpec);
}
schedulerData = createDomain(domainSpec);
// add schedulable adapter to receive ROLE_PLAY-messages
addSchedulerAdapter(new SchedulableAdapter(sender) {
public boolean processMessage(ActorMsg sig) {
if (sig.equals(ROLE_PLAY_ENDED_MSG)) {
applicationEnded();
if (getScheduler().isTraceOn())
logger.log(TraceConstants.tlInfo, "ROLE_PLAY_ENDED_MSG: Application ended.");
} else if (sig.equals(ROLE_CREATE_ACK_MSG)) {
if (getScheduler().isTraceOn())
logger.log(TraceConstants.tlInfo, "ROLE_PLAY_ACK_MSG: Application created.");
applictionActive();
} else if (sig.equals(ROLE_CREATE_NACK_MSG)) {
if (getScheduler().isTraceOn())
logger.log(TraceConstants.tlError, "ROLE_CREATE_NACK_MSG: Application start failed.");
} else if (sig.equals(SUSPENDED_MSG)) {
applicationSuspended();
} else if (sig.equals(RESUMED_MSG)) {
applicationResumed();
} else if (sig.equals(ROLE_UPDATE_ACK_MSG)) {
applicationUpdated();
} else {
if (getScheduler().isTraceOn())
logger.log(TraceConstants.tlInfo, "Received message: " + sig.messageContent());
messageHandler(sig);
}
return true;
}
});
// Start the application
addRouterSession();
if (getApplicationSpec().autoStartRouter()) {
getContainer().startRouter();
}
String actorId = schedulerData.getActorDomainName();
String actorType = domainSpec.getActor();
ActorAddress receiver = new ActorAddress(actorId, actorType);
AFPropertyMsg msg = new AFPropertyMsg(ROLE_CREATE_MSG, true);
msg.setReceiverRole(receiver);
msg.setSenderRole(sender);
msg.setBoolean(ROLE_CREATE_MSG_VISIBLE, true);
msg.setInt(JFConstants.TRACE_LEVEL_PROP, TraceConstants.tlWarn);
getSchedulerData().getDefaultScheduler().output(msg, null);
}
/**
* Soft restarting of the application. A msg "RESTART" is send to all actors
* of the scheduler data MY_SYSTEM table
*/
public void restart() {
AFPropertyMsg msg = new AFPropertyMsg(ROLE_RESTART_MSG, true);
msg.setReceiverRole(new ActorAddress(schedulerData.getActorDomainName(), "ActorDomain"));
schedulerData.getDefaultScheduler().output(msg, null);
}
public void setApplicationSpec(ApplicationSpec applicationSpec) {
this.applicationSpec = applicationSpec;
}
/**
* Creates the domains for this actor domain. It includes for all domains
* the scheduler, the definition of actors to be run in each scheduler.
*/
protected SchedulerData createDomain(DomainSpec domainSpec) {
final String domainName;
if (container == null)
throw new NullPointerException("Container has not been initialized!");
if (domainSpec == null) {
domainSpec = new DomainSpec("default", "ActorDomain");
}
domainName = domainSpec.getDomainName();
setActorDomainName(domainName);
SchedulerData schedulerData = new SchedulerData();
schedulerData.setActorDomainName(domainName);
Vector schedulerSpecs = domainSpec.getSchedulerSpecs();
Scheduler sched;
// parse scheduler
if ((schedulerSpecs == null) || schedulerSpecs.isEmpty()) {
SchedulerSpec ss = new SchedulerSpec();
ss.setId("default");
domainSpec.addSchedulerSpec(ss);
}
logger.log(TraceConstants.tlInfo, "Creation of scheduler starting");
try {
for (int k = 0; k < schedulerSpecs.size(); k++) {
SchedulerSpec schedulerSpec = (SchedulerSpec) schedulerSpecs.elementAt(k);
// create scheduler
sched = (Scheduler) Class.forName(schedulerSpec.getClassName()).newInstance();
sched.setThreads(schedulerSpec.getThreads());
sched.setName(schedulerSpec.getId());
Vector vs = schedulerSpec.getActorTypes();
schedulerData.setDefaultScheduler(sched);
sched.setSchedulerData(schedulerData);
sched.setClassLoader(getContainer());
StringBuffer sb = new StringBuffer("Scheduler " + sched.getName() + " is started. Actor types: ");
if (vs != null) {
for (int n = 0; n < vs.size(); n++) {
String s = (String) vs.elementAt(n);
sb.append(s + " , " );
sched.configure(s);
}
}
sb.append(" Threads: " + schedulerSpec.getThreads());
schedulerData.setContainer(getContainer());
schedulerData.setApplicationSpec(getApplicationSpec());
if (logger != null) {
logger.log(TraceConstants.tlInfo, sb.toString());
}
sched.start();
}
schedulerData.getDefaultScheduler().setTrace(getApplicationSpec().isTraceEnabled());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
logger.log(Logger.DEBUG, "Creation of scheduler finished");
return schedulerData;
}
public void addRouterSession() {
try {
String domainName = getApplicationSpec().getDomainSpec().getDomainName();
org.coos.actorframe.application.Session domainSession = getContainer().createMessageBusAdapter(domainName);
if (domainSession != null) {
getSchedulerData().getDefaultScheduler().addRouter(domainSession);
}
} catch (ActorFrameException e) {
return;
}
}
/**
* Returns the shceduler data for the domain
*
* @return SchedulerData instance
*/
public SchedulerData getSchedulerData() {
return schedulerData;
}
/**
* Creates an state machine based on a class name description
*
* @param className is the name of the class
* @return a state machine
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
protected StateMachine createClass(String className) throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (StateMachine) Class.forName(className).newInstance();
}
/**
* Deletes the application by using the actor frame protocol. RoleRemove is
* send to all actor domains. The domains will then recursively send
* RoleRemove to all its parts.
*/
public void deleteApplication() {
AFPropertyMsg msg = new AFPropertyMsg(ROLE_REMOVE_MSG, true);
msg.setReceiverRole(new ActorAddress(schedulerData.getActorDomainName(), schedulerData.getApplicationSpec().getDomainSpec().getActor()));
schedulerData.getDefaultScheduler().output(msg, null);
}
/**
* Resumes alle domains of the application
*/
public void resume() {
resume(null);
}
/**
* Resume part of the application
*
* @param receiver is the receiver of resume msg
*/
public void resume(ActorAddress receiver) {
state = STATE_RESUMING;
sendMessage(new AFPropertyMsg(RESUME_MSG, true), receiver);
}
/**
* Suspends all the domains of the application
*/
public void suspend() {
suspend(null);
}
/**
* Suspends part of a the application
*
* @param receiver is the receiver address of the message to suspended
*/
public void suspend(ActorAddress receiver) {
state = STATE_SUSPENDING;
sendMessage(new AFPropertyMsg(SUSPEND_MSG, true), receiver);
}
public void updateApplication() {
state = STATE_UPDATING;
sendMessage(new AFPropertyMsg(ROLE_UPDATE_MSG, true), "");
}
/**
* Sends an actor msg to an actor
*
* @param msg is the message to be send
* @param receiver is the receiver of the message
*/
public void sendMessage(ActorMsg msg, String receiver) {
sendMessage(msg, new ActorAddress(receiver));
}
/**
* Sends an actor msg to an actor
*
* @param msg is the message to be send
* @param receiver is the receiver of the message
*/
public void sendMessage(ActorMsg msg, ActorAddress receiver) {
if (receiver == null) {
receiver = new ActorAddress(schedulerData.getApplicationSpec().getDomainSpec().getActor());
}
String domainName = schedulerData.getActorDomainName();
if (receiver.getActorID() == null) {
receiver.setActorID(domainName);
}
msg.setReceiverRole(receiver);
if (msg.getSenderRole() == null) {
msg.setSenderRole(getSenderAddress());
}
schedulerData.getDefaultScheduler().output(msg, null);
}
/**
* Defines the application. The specification has to be put in the
* application spec.
*
* @return application spec
* @deprecated Use setApplicationSpec() instead
*/
protected ApplicationSpec readApplicationSpec() {
logger.log(TraceConstants.tlFatal,
"Application: applicationSpec not set and deprecated readApplicationSpec not implemented.");
return null;
}
// @deprecated should be removed
public static String getActorDomain() {
return AFServiceFactory.getAFServiceProperty(ACTOR_DOMAIN_NAME);
}
// @deprecated should be removed. Use the application spec
public static String getApplicationName() {
return AFServiceFactory.getAFServiceProperty(APPLICATION_NAME);
}
// @deprecated should be removed.
public static void setActorDomainName(String actorDomainName) {
AFServiceFactory.addAFService(ACTOR_DOMAIN_NAME, actorDomainName);
}
// @deprecated should be removed.
public void setApplicationName(String applicationName) {
AFServiceFactory.addAFService(APPLICATION_NAME, applicationName);
}
protected void extendInitApplication() {
logger.log(TraceConstants.tlInfo, "Application: extendInitApplication: no values set");
}
// @deprecated Implement extendInitApplication() instead.
protected final void readExternalValues() {
logger.log(TraceConstants.tlInfo, "Application: readExternalValues: no values read");
}
/**
* Destroys all domains. The scheduler is stopped. The session is decoupled
* from the router
*/
public void destroyApp() {
logger.log(TraceConstants.tlInfo, "Application shutdown starting.");
// removes the session that was connected to the router
schedulerData.setTheRouterSession(null);
// Stop all scheduables connected to each scheduler
// The scheduler thread itself are also stopped
Enumeration en = schedulerData.getSchedulerConfig().elements();
while (en.hasMoreElements()) {
Scheduler scheduler = (Scheduler) en.nextElement();
scheduler.stop();
}
// clear the scheduler data
schedulerData.getMySystem().clear();
schedulerData.getSchedulerConfig().clear();
schedulerData.setDefaultScheduler(null);
schedulerData = null;
container.exit();
logger.log(TraceConstants.tlInfo, "Application shutdown completed.");
}
public static Application getInstance() {
return instance;
}
public void setContainerContext(Container container) {
this.container = container;
}
public ApplicationSpec getApplicationSpec() {
return applicationSpec;
}
public ActorAddress getSenderAddress() {
return new ActorAddress("callback", "Exithandler");
}
/**
* Called when the application is resumed after it has been suspended
*/
protected void applicationResumed() {
state = STATE_ACTIVE;
logger.log(TraceConstants.tlInfo, "StartApplication: Application resumed");
}
/**
* Called when the application has been reconfigured. The system is in the
* suspended state.
*/
protected void applicationUpdated() {
state = STATE_UPDATED;
logger.log(TraceConstants.tlInfo, "StartApplication: Application updtated");
}
protected void applicationError(String reason) {
logger.log(TraceConstants.tlInfo, "StartApplication: Application ERROR: " + reason);
}
protected void applicationSuspended() {
state = STATE_SUSPENDED;
logger.log(TraceConstants.tlInfo, "StartApplication: Application suspended");
}
public void applictionActive() {
state = STATE_ACTIVE;
logger.log(TraceConstants.tlInfo, "StartApplication: Application started");
}
public void applicationEnded() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if (LoggerFactory.isTraceOn()) {
logger.log(TraceConstants.tlError, "InterruptedException thrown.");
}
e.printStackTrace();
}
getContainer().exit();
}
public void messageHandler(ActorMsg sig) {
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public Container getContainer() {
return container;
}
/**
* Methods used to do testing and management of the this actor domain
*/
/**
* Search the system for a state machine based on actor address. The actor
* id includes the full path name susch as "/test/actorB@ActorB"
*
* @param id is the instance id
* @return the state machine if it exists
*/
public StateMachine getStateMachine(String id) {
Enumeration en = getSchedulerData().getMySystem().keys();
while (en.hasMoreElements()) {
String s = (String) en.nextElement();
if (s.endsWith(id)) {
return (StateMachine) getSchedulerData().getMySystem().get(s);
}
}
return null;
}
}