diff --git a/snaparchiver/src/main/java/org/tango/server/snap/archiver/SnapArchiver.java b/snaparchiver/src/main/java/org/tango/server/snap/archiver/SnapArchiver.java new file mode 100644 index 0000000000000000000000000000000000000000..7b8f0e685735abece5dcb1a0e774fa1e952e7b6a --- /dev/null +++ b/snaparchiver/src/main/java/org/tango/server/snap/archiver/SnapArchiver.java @@ -0,0 +1,258 @@ +package org.tango.server.snap.archiver; + +import SnapArchiver.grouplink.UsePluginBuilder; +import fr.esrf.Tango.DevFailed; +import fr.soleil.actiongroup.collectiveaction.onattributes.UsePlugin; +import fr.soleil.archiving.snap.api.manager.SnapManagerApi; +import fr.soleil.archiving.snap.api.persistence.SnapshotPersistenceManager; +import fr.soleil.archiving.snap.api.persistence.SnapshotPersistenceManagerFactory; +import fr.soleil.archiving.snap.api.tools.SnapAttributeExtract; +import fr.soleil.archiving.snap.api.tools.SnapContext; +import fr.soleil.archiving.snap.api.tools.Snapshot; +import fr.soleil.archiving.snap.api.tools.SnapshotingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.tango.DeviceState; +import org.tango.server.ServerManager; +import org.tango.server.annotation.Command; +import org.tango.server.annotation.Delete; +import org.tango.server.annotation.Device; +import org.tango.server.annotation.DeviceProperty; +import org.tango.server.annotation.Init; +import org.tango.server.annotation.State; +import org.tango.server.annotation.StateMachine; +import org.tango.server.annotation.Status; +import org.tango.utils.DevFailedUtils; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +@Device +public final class SnapArchiver { + + private static String VERSION; + private final Logger logger = LoggerFactory.getLogger(SnapArchiver.class); + private final ExecutorService executorService = Executors.newSingleThreadExecutor(); + private final Map<Integer, Future<Integer>> snapshotResults = new HashMap<>(); + + /** + * User identifier (name) used to connect the database for snapshots. <br> + * <b>Default value : </b> archiver + */ + @DeviceProperty + private String dbUser = ""; + /** + * Password used to connect the database for snapshots. <br> + * <b>Default value : </b> archiver + */ + @DeviceProperty + private String dbPassword = ""; + /** + * The name of the spring beans file <br> + * <b>Default value : </b> beans.xml + */ + @DeviceProperty + private String beansFileName = ""; + @DeviceProperty + private String dbHost = ""; + @DeviceProperty + private String dbName = ""; + @DeviceProperty + private String dbSchema = ""; + + @Status + private String status; + @State + private DeviceState state; + + + private SnapshotPersistenceManager manager; + + public static void main(final String[] args) { + VERSION = ResourceBundle.getBundle("application").getString("project.version"); + ServerManager.getInstance().start(args, SnapArchiver.class); + } + + /** + * Initialize the device. + */ + @Init + public void init() throws DevFailed { + try { + SnapManagerApi.initSnapConnection(dbHost, dbName, dbSchema, dbUser, dbPassword, "false"); + SnapshotPersistenceManagerFactory factory = SnapshotPersistenceManagerFactory.getInstance(); + manager = factory.getManager(beansFileName, dbUser, dbPassword); + state = DeviceState.ON; + } catch (SnapshotingException e) { + throw e.toTangoException(); + } + } + + @Delete + public void delete() { + snapshotResults.clear(); + } + + @org.tango.server.annotation.Attribute + public String getVersion() { + return VERSION; + } + + /** + * Execute command "TriggerLaunchSnapShot" on device. This command is used + * to trigger a snapShot. All informations concerning the snapshot will be + * retrieved with the identifier parameter. + * + * @param argin The snapshot associated context's identifier. + */ + @Command(name = "TriggerLaunchSnapShot", inTypeDesc = "The snapshot associated context's identifier.") + @StateMachine(deniedStates = DeviceState.RUNNING) + public void triggerLaunchSnapShot(int argin) { + state = DeviceState.RUNNING; + logger.info("in command TriggerLaunchSnapShot for context {}", argin); + Future<Integer> snapshotResult = executorService.submit(new SnapArchiver.SnapshotTask(argin)); + snapshotResults.put(argin, snapshotResult); + + } + + /** + * Command + * + * @param argin the context ID + * @return the snap created + * @throws DevFailed + */ + @Command(name = "GetSnapShotResult", inTypeDesc = "the context ID") + public int getSnapShotResult(int argin) throws DevFailed { + int result = -1; + try { + Future<Integer> snap = snapshotResults.get(argin); + if (snap != null) { + result = snapshotResults.get(argin).get(); + } + } catch (InterruptedException e) { + DevFailedUtils.throwDevFailed(e); + } catch (ExecutionException e) { + if (e.getCause() instanceof DevFailed) { + throw (DevFailed) e.getCause(); + } else { + DevFailedUtils.throwDevFailed(e.getCause()); + } + } + return result; + } + + /** + * Execute command "CreateNewContext" on device. This command is used to + * register a snapShot context. All informations concerning the snapshot + * (fr.soleil.archiving.snap.api.tools.SnapContext) are passed through an + * array (DEVVAR_STRINGARRAY). + * + * @param argin All the informations usefull to create a context ,Snapshot + * pattern). + */ + @Command(name = "CreateNewContext", inTypeDesc = "All the informations usefull to create a context ,Snapshot pattern)") + public void createNewContext(String[] argin) throws DevFailed { + logger.info("Entering CreateNewContext - {}", Arrays.toString(argin)); + SnapContext snapContext = new SnapContext(argin); + try { + int contextID = SnapManagerApi.createContext(snapContext); + logger.debug("Context with ID {} created", contextID); + } catch (SnapshotingException e) { + logger.error(e.toString(), e); + throw e.toTangoException(); + } + logger.info("Exiting create_new_context()"); + } + + + public void setDbUser(String dbUser) { + this.dbUser = dbUser; + } + + public void setDbPassword(String dbPassword) { + this.dbPassword = dbPassword; + } + + public void setBeansFileName(String beansFileName) { + this.beansFileName = beansFileName; + } + + public void setDbHost(String dbHost) { + this.dbHost = dbHost; + } + + public void setDbName(String dbName) { + this.dbName = dbName; + } + + public void setDbSchema(String dbSchema) { + this.dbSchema = dbSchema; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public DeviceState getState() { + return state; + } + + public void setState(DeviceState state) { + this.state = state; + } + + private class SnapshotTask implements Callable<Integer> { + private final int contextID; + + SnapshotTask(int contextID) { + this.contextID = contextID; + } + + @Override + public Integer call() throws Exception { + int snapId; + + try { + logger.debug("starting snapshot for context {}", contextID); + Snapshot snapShot = SnapManagerApi.registerSnapShot(contextID); + if (snapShot == null) { + throw DevFailedUtils.newDevFailed("Invalid Context ID"); + } + snapId = snapShot.getId_snap(); + logger.debug("snapshot {} of context {} created", snapId, contextID); + // For each attribute of the object 'Snapshot', a snapshot is + // triggered... + List<SnapAttributeExtract> attributeList = snapShot.getAttribute_List(); + logger.debug("snapshot {} will contains {} atttributes", snapId, attributeList.size()); + UsePluginBuilder builder = new UsePluginBuilder(snapId, manager); + UsePlugin group = builder.build(attributeList); + boolean isExecuted = group.execute(); + logger.debug("snapshot {} execution status is {}", snapId, isExecuted); + // group.getMessages(); + Map<String, String> messages = group.getMessages(); + logger.debug("snapshot {} execution messages are {}", messages); + } catch (SnapshotingException e) { + logger.error("Exception received during TriggerLaunchSnapshot", e); + throw e.toTangoException(); + } finally { + state = DeviceState.ON; + } + return snapId; + } + + } + +}