Implementation of DB read and store procedures for Actions and triggers(not tested). issue 6
This commit is contained in:
parent
44d5fa0227
commit
4b24615f4f
11 changed files with 249 additions and 22 deletions
BIN
hal-default.db
BIN
hal-default.db
Binary file not shown.
|
|
@ -7,6 +7,7 @@ import se.hal.intf.HalJsonPage;
|
|||
import se.hal.page.*;
|
||||
import se.hal.struct.Event;
|
||||
import se.hal.struct.Sensor;
|
||||
import se.hal.struct.TriggerFlow;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.io.file.FileUtil;
|
||||
import zutil.log.LogUtil;
|
||||
|
|
@ -47,16 +48,20 @@ public class HalServer {
|
|||
TriggerManager.initialize(pluginManager);
|
||||
|
||||
|
||||
// Init sensors,events and controllers
|
||||
// Import sensors,events and controllers
|
||||
for(Sensor sensor : Sensor.getLocalSensors(db)){
|
||||
ControllerManager.getInstance().register(sensor);
|
||||
}
|
||||
for(Event event : Event.getLocalEvents(db)){
|
||||
ControllerManager.getInstance().register(event);
|
||||
}
|
||||
// Import triggers
|
||||
for(TriggerFlow flow : TriggerFlow.getTriggerFlows(db)){
|
||||
TriggerManager.getInstance().register(flow);
|
||||
}
|
||||
|
||||
|
||||
// init daemons
|
||||
// Init daemons
|
||||
// We set only one thread for easier troubleshooting
|
||||
daemonExecutor = Executors.newScheduledThreadPool(1);
|
||||
for (Iterator<HalDaemon> it=pluginManager.getObjectIterator(HalDaemon.class); it.hasNext(); )
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ import se.hal.struct.TriggerFlow;
|
|||
import zutil.log.LogUtil;
|
||||
import zutil.plugin.PluginManager;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
|
|
@ -30,6 +32,7 @@ public class TriggerManager {
|
|||
private ScheduledExecutorService executor;
|
||||
|
||||
|
||||
|
||||
public void setEvaluationInterval(long interval) {
|
||||
if (executor != null)
|
||||
executor.shutdownNow();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,40 @@
|
|||
package se.hal.intf;
|
||||
|
||||
import se.hal.struct.dso.ActionDSO;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.bean.DBBean;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Defines a action that will be executed
|
||||
*/
|
||||
public interface HalAction {
|
||||
public abstract class HalAction{
|
||||
private ActionDSO dso;
|
||||
|
||||
void execute();
|
||||
|
||||
public static HalAction getAction(DBConnection db, long id) throws SQLException {
|
||||
ActionDSO dso = DBBean.load(db, ActionDSO.class, id);
|
||||
dso.getObject().dso = dso;
|
||||
return dso.getObject();
|
||||
}
|
||||
|
||||
|
||||
public Long getId(){
|
||||
return (dso!=null ? dso.getId() : null);
|
||||
}
|
||||
|
||||
public void save(DBConnection db) throws SQLException {
|
||||
if (dso == null)
|
||||
dso = new ActionDSO();
|
||||
dso.setObject(this);
|
||||
dso.save(db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Executes this specific action
|
||||
*/
|
||||
public abstract void execute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,47 @@
|
|||
package se.hal.intf;
|
||||
|
||||
import se.hal.struct.dso.TriggerDSO;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.bean.DBBean;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* A interfaces that declares a trigger/condition that
|
||||
* A class that declares a trigger/condition that
|
||||
* needs to be validated before an action can be run
|
||||
*/
|
||||
public interface HalTrigger {
|
||||
public abstract class HalTrigger{
|
||||
private TriggerDSO dso;
|
||||
|
||||
|
||||
public static HalTrigger getTrigger(DBConnection db, long id) throws SQLException {
|
||||
TriggerDSO dso = DBBean.load(db, TriggerDSO.class, id);
|
||||
dso.getObject().dso = dso;
|
||||
return dso.getObject();
|
||||
}
|
||||
|
||||
|
||||
public Long getId(){
|
||||
return (dso!=null ? dso.getId() : null);
|
||||
}
|
||||
|
||||
public void save(DBConnection db) throws SQLException {
|
||||
if (dso == null)
|
||||
dso = new TriggerDSO();
|
||||
dso.setObject(this);
|
||||
dso.save(db);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluates if this trigger has passed. If the trigger is
|
||||
* true then this method will return true until the {@link #reset()}
|
||||
* method is called.
|
||||
*/
|
||||
boolean evaluate();
|
||||
public abstract boolean evaluate();
|
||||
|
||||
/**
|
||||
* Reset the evaluation to false.
|
||||
*/
|
||||
void reset();
|
||||
public abstract void reset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ public abstract class AbstractDevice<T,D> extends DBBean {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DBConnection db) throws SQLException {
|
||||
if (deviceConfig != null)
|
||||
updateConfigString();
|
||||
|
|
|
|||
|
|
@ -1,34 +1,94 @@
|
|||
package se.hal.struct;
|
||||
|
||||
import se.hal.HalContext;
|
||||
import se.hal.intf.HalAction;
|
||||
import se.hal.intf.HalTrigger;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.bean.DBBean;
|
||||
import zutil.db.bean.DBBeanSQLResultHandler;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.parser.DataNode;
|
||||
import zutil.parser.json.JSONParser;
|
||||
import zutil.parser.json.JSONWriter;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A class that encapsulates triggers and their actions.
|
||||
* A class that encapsulates triggerList and their actionList.
|
||||
* TODO: Bad class name, should be renamed when we come up with a better one
|
||||
*/
|
||||
@DBBean.DBTable("trigger_flow")
|
||||
public class TriggerFlow extends DBBean {
|
||||
private ArrayList<HalTrigger> triggers = new ArrayList<>();
|
||||
private ArrayList<HalAction> actions = new ArrayList<>();
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
private String triggers; // only used for flat DB storage
|
||||
private transient ArrayList<HalTrigger> triggerList = new ArrayList<>();
|
||||
private String actions; // only used for flat DB storage
|
||||
private transient ArrayList<HalAction> actionList = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
public static List<TriggerFlow> getTriggerFlows(DBConnection db) throws SQLException {
|
||||
PreparedStatement stmt = db.getPreparedStatement("SELECT * FROM trigger_flow");
|
||||
return DBConnection.exec(stmt, DBBeanSQLResultHandler.createList(TriggerFlow.class, db));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void save(DBConnection db) throws SQLException {
|
||||
DataNode root = new DataNode(DataNode.DataType.List);
|
||||
for (HalTrigger t : triggerList)
|
||||
root.add(t.getId());
|
||||
triggers = JSONWriter.toString(root);
|
||||
for (HalAction a : actionList)
|
||||
root.add(a.getId());
|
||||
actions = JSONWriter.toString(root);
|
||||
|
||||
super.save(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postUpdateAction() {
|
||||
DBConnection db = HalContext.getDB();
|
||||
|
||||
triggerList.clear();
|
||||
for (DataNode tId : JSONParser.read(triggers))
|
||||
try {
|
||||
triggerList.add(HalTrigger.getTrigger(db, tId.getInt()));
|
||||
} catch (SQLException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
|
||||
actionList.clear();
|
||||
for (DataNode aId : JSONParser.read(actions))
|
||||
try {
|
||||
actionList.add(HalAction.getAction(db, aId.getInt()));
|
||||
} catch (SQLException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addTrigger(HalTrigger trigger) {
|
||||
triggers.add(trigger);
|
||||
triggerList.add(trigger);
|
||||
}
|
||||
public void addAction(HalAction action) {
|
||||
actions.add(action);
|
||||
actionList.add(action);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if any one of the triggers evaluate to true,
|
||||
* false if there are no triggers added.
|
||||
* Note: this method will not execute any actions
|
||||
* @return true if any one of the triggerList evaluate to true,
|
||||
* false if there are no triggerList added.
|
||||
* Note: this method will not execute any actionList
|
||||
*/
|
||||
public boolean evaluate(){
|
||||
for(HalTrigger trigger : triggers){
|
||||
for(HalTrigger trigger : triggerList){
|
||||
if (trigger.evaluate())
|
||||
return true;
|
||||
}
|
||||
|
|
@ -36,10 +96,10 @@ public class TriggerFlow extends DBBean {
|
|||
}
|
||||
|
||||
/**
|
||||
* Executes the associated actions in this flow
|
||||
* Executes the associated actionList in this flow
|
||||
*/
|
||||
public void execute(){
|
||||
for(HalAction action : actions){
|
||||
for(HalAction action : actionList){
|
||||
action.execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +108,7 @@ public class TriggerFlow extends DBBean {
|
|||
* Resets all trigger evaluations
|
||||
*/
|
||||
public void reset() {
|
||||
for(HalTrigger trigger : triggers){
|
||||
for(HalTrigger trigger : triggerList){
|
||||
trigger.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
14
src/se/hal/struct/dso/ActionDSO.java
Executable file
14
src/se/hal/struct/dso/ActionDSO.java
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
package se.hal.struct.dso;
|
||||
|
||||
import se.hal.intf.HalAction;
|
||||
import zutil.db.bean.DBBean;
|
||||
|
||||
|
||||
/**
|
||||
* A intermediate class for loading HalAction objects from DB
|
||||
*/
|
||||
@DBBean.DBTable(value = "action", superBean = true)
|
||||
public class ActionDSO extends ObjectDSO<HalAction>{
|
||||
|
||||
|
||||
}
|
||||
72
src/se/hal/struct/dso/ObjectDSO.java
Executable file
72
src/se/hal/struct/dso/ObjectDSO.java
Executable file
|
|
@ -0,0 +1,72 @@
|
|||
package se.hal.struct.dso;
|
||||
|
||||
import se.hal.intf.HalTrigger;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.bean.DBBean;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.parser.json.JSONParser;
|
||||
import zutil.parser.json.JSONWriter;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* A intermediate class for loading HalTrigger objects from DB
|
||||
*/
|
||||
public abstract class ObjectDSO<T> extends DBBean{
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
// DB parameters
|
||||
private String type;
|
||||
private String config;
|
||||
|
||||
// Local parameters
|
||||
private transient T cachedObj;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void postUpdateAction() {
|
||||
if (type != null && !type.isEmpty()) {
|
||||
if (cachedObj == null) {
|
||||
try {
|
||||
Class clazz = Class.forName(type);
|
||||
cachedObj = (T) clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Unable instantiate class: " + type, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (config != null && !config.isEmpty()) {
|
||||
Configurator<T> configurator = new Configurator<>(cachedObj);
|
||||
configurator.setValues(JSONParser.read(config));
|
||||
configurator.applyConfiguration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DBConnection db) throws SQLException {
|
||||
if (cachedObj == null)
|
||||
this.config = null;
|
||||
else {
|
||||
Configurator<T> configurator = new Configurator<>(cachedObj);
|
||||
this.config = JSONWriter.toString(configurator.getValuesAsNode());
|
||||
}
|
||||
super.save(db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public T getObject(){
|
||||
return cachedObj;
|
||||
}
|
||||
|
||||
public void setObject(T obj){
|
||||
this.cachedObj = obj;
|
||||
}
|
||||
|
||||
}
|
||||
14
src/se/hal/struct/dso/TriggerDSO.java
Executable file
14
src/se/hal/struct/dso/TriggerDSO.java
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
package se.hal.struct.dso;
|
||||
|
||||
import se.hal.intf.HalTrigger;
|
||||
import zutil.db.bean.DBBean;
|
||||
|
||||
|
||||
/**
|
||||
* A intermediate class for loading HalTrigger objects from DB
|
||||
*/
|
||||
@DBBean.DBTable(value = "trigger", superBean = true)
|
||||
public class TriggerDSO extends ObjectDSO<HalTrigger>{
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ public class TriggerManagerTest {
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static class TestTrigger implements HalTrigger {
|
||||
private static class TestTrigger extends HalTrigger {
|
||||
boolean evaluation;
|
||||
TestTrigger(boolean b){ evaluation = b; }
|
||||
@Override
|
||||
|
|
@ -86,7 +86,7 @@ public class TriggerManagerTest {
|
|||
}
|
||||
|
||||
|
||||
private class TestAction implements HalAction {
|
||||
private class TestAction extends HalAction {
|
||||
int nrOfExecutions;
|
||||
@Override
|
||||
public void execute() { nrOfExecutions++; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue