Initial Import
git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/vre-management/smart-executor@111656 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
6a3577016b
commit
de7a86c9f8
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>smart-executor</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/webapp"/>
|
||||
<classpathentry kind="src" path="target/m2e-wtp/web-resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
|
||||
<attributes>
|
||||
<attribute name="hide" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
|
||||
<classpathentry kind="output" path=""/>
|
||||
</classpath>
|
|
@ -0,0 +1,6 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
|
@ -0,0 +1,8 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
|
@ -0,0 +1,4 @@
|
|||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="smart-executor">
|
||||
<wb-resource deploy-path="/WEB-INF/web.xml" source-path="/src/main/webapp/WEB-INF/web.xml"/>
|
||||
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
|
||||
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||
<dependent-module archiveName="smart-executor-api-1.0.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-executor-api/smart-executor-api">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<property name="java-output-path" value="/smart-executor/target/classes"/>
|
||||
<property name="context-root" value="smart-executor"/>
|
||||
</wb-module>
|
||||
</project-modules>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="wst.jsdt.web"/>
|
||||
<installed facet="wst.jsdt.web" version="1.0"/>
|
||||
<installed facet="java" version="1.7"/>
|
||||
<installed facet="jst.web" version="3.0"/>
|
||||
</faceted-project>
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
|
|
@ -0,0 +1 @@
|
|||
Window
|
|
@ -0,0 +1,2 @@
|
|||
disabled=06target
|
||||
eclipse.preferences.version=1
|
|
@ -0,0 +1 @@
|
|||
Used as library in the gCube Framework
|
|
@ -0,0 +1,6 @@
|
|||
gCube System - License
|
||||
------------------------------------------------------------
|
||||
|
||||
The gCube/gCore software is licensed as Free Open Source software conveying to the EUPL (http://ec.europa.eu/idabc/eupl).
|
||||
The software and documentation is provided by its authors/distributors "as is" and no expressed or
|
||||
implied warranty is given for its use, quality or fitness for a particular case.
|
|
@ -0,0 +1,2 @@
|
|||
Luca Frosini (luca.frosini@isti.cnr.it), CNR Pisa,
|
||||
Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo".
|
|
@ -0,0 +1,44 @@
|
|||
The gCube System - Executor Service
|
||||
|
||||
------------------------------------------------------------
|
||||
|
||||
This work has been partially supported by the following European projects: DILIGENT (FP6-2003-IST-2),
|
||||
D4Science (FP7-INFRA-2007-1.2.2), D4Science-II (FP7-INFRA-2008-1.2.2), iMarine (FP7-INFRASTRUCTURES-2011-2),
|
||||
and EUBrazilOpenBio (FP7-ICT-2011-EU-Brazil).
|
||||
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
* Luca Frosini (luca.frosini@isti.cnr.it), CNR Pisa,
|
||||
Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo".
|
||||
|
||||
|
||||
Version and Release Date
|
||||
------------------------
|
||||
|
||||
v. 1.0.0 * First release
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
|
||||
|
||||
Download information
|
||||
--------------------
|
||||
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
This software is licensed under the terms you may find in the file named "LICENSE" in this directory.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<ReleaseNotes>
|
||||
<Changeset component="org.gcube.vremanagement.executor.1-0-0" date="2015-01-26">
|
||||
<Change>first release</Change>
|
||||
</Changeset>
|
||||
</ReleaseNotes>
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
CREATE TABLE IF NOT EXISTS `pluginInstanceEvolution` (
|
||||
`id` INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`uuid` VARCHAR(36) NOT NULL,
|
||||
`pluginName` VARCHAR(255) NOT NULL,
|
||||
`timestamp` BIGINT NOT NULL,
|
||||
`state` INT NOT NULL
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
|
@ -0,0 +1,37 @@
|
|||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
<id>servicearchive</id>
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
<baseDirectory>/</baseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${distroDirectory}</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
<includes>
|
||||
<include>README</include>
|
||||
<include>LICENSE</include>
|
||||
<include>INSTALL</include>
|
||||
<include>MAINTAINERS</include>
|
||||
<include>changelog.xml</include>
|
||||
</includes>
|
||||
<fileMode>755</fileMode>
|
||||
<filtered>true</filtered>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<files>
|
||||
<file>
|
||||
<source>target/${build.finalName}.war</source>
|
||||
<outputDirectory>/${artifactId}</outputDirectory>
|
||||
</file>
|
||||
<file>
|
||||
<source>${distroDirectory}/svnpath.txt</source>
|
||||
<outputDirectory>/${artifactId}</outputDirectory>
|
||||
<filtered>true</filtered>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
|
@ -0,0 +1,8 @@
|
|||
<application mode='online'>
|
||||
<name>Smart-Executor</name>
|
||||
<group>VREManagement</group>
|
||||
<version>${version}</version>
|
||||
<description>Executor Service</description>
|
||||
<local-persistence location='target' />
|
||||
</application>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Resource>
|
||||
<ID></ID>
|
||||
<Type>Service</Type>
|
||||
<Profile>
|
||||
<Description>${description}</Description>
|
||||
<Class>VREManagement</Class>
|
||||
<Name>${artifactId}</Name>
|
||||
<Version>1.0.0</Version>
|
||||
<Packages>
|
||||
<Software>
|
||||
<Description>${description}</Description>
|
||||
<Name>${artifactId}</Name>
|
||||
<Version>${version}</Version>
|
||||
<MavenCoordinates>
|
||||
<groupId>${groupId}</groupId>
|
||||
<artifactId>${artifactId}</artifactId>
|
||||
<version>${version}</version>
|
||||
</MavenCoordinates>
|
||||
<Type>library</Type>
|
||||
<Files>
|
||||
<File>${build.finalName}.jar</File>
|
||||
</Files>
|
||||
</Software>
|
||||
</Packages>
|
||||
</Profile>
|
||||
</Resource>
|
||||
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.gcube.tools</groupId>
|
||||
<artifactId>maven-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.gcube.vremanagement</groupId>
|
||||
<artifactId>smart-executor</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<properties>
|
||||
<webappDirectory>${project.basedir}/src/main/webapp/WEB-INF</webappDirectory>
|
||||
<distroDirectory>${project.basedir}/distro</distroDirectory>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.gcube.distribution</groupId>
|
||||
<artifactId>maven-smartgears-bom</artifactId>
|
||||
<version>LATEST</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears-app</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.resources</groupId>
|
||||
<artifactId>registry-publisher</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.ws</groupId>
|
||||
<artifactId>jaxws-rt</artifactId>
|
||||
<version>2.1.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.vremanagement</groupId>
|
||||
<artifactId>smart-executor-api</artifactId>
|
||||
<version>[1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.185</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-jaxws-calls</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.acme</groupId>
|
||||
<artifactId>HelloWorldPlugin</artifactId>
|
||||
<version>[1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT)</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-profile</id>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<phase>process-resources</phase>
|
||||
<configuration>
|
||||
<outputDirectory>${webappDirectory}</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${distroDirectory}</directory>
|
||||
<includes>
|
||||
<include>gcube-app.xml</include>
|
||||
<include>db.sql</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<warName>smart-executor</warName>
|
||||
<webXml>src\main\webapp\WEB-INF\web.xml</webXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,352 @@
|
|||
package org.gcube.vremanagement.executor;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.jws.WebService;
|
||||
|
||||
import org.gcube.common.resources.gcore.Resource;
|
||||
import org.gcube.common.resources.gcore.Resources;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.Profile;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
|
||||
import org.gcube.common.resources.gcore.utils.Group;
|
||||
import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
|
||||
import org.gcube.informationsystem.publisher.ScopedPublisher;
|
||||
import org.gcube.informationsystem.publisher.exception.RegistryNotFoundException;
|
||||
import org.gcube.smartgears.ContextProvider;
|
||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||
import org.gcube.vremanagement.executor.api.Executor;
|
||||
import org.gcube.vremanagement.executor.api.types.LaunchParameter;
|
||||
import org.gcube.vremanagement.executor.exception.ExecutorException;
|
||||
import org.gcube.vremanagement.executor.exception.InputsNullException;
|
||||
import org.gcube.vremanagement.executor.exception.LaunchException;
|
||||
import org.gcube.vremanagement.executor.exception.PluginInstanceNotFoundException;
|
||||
import org.gcube.vremanagement.executor.exception.PluginNotFoundException;
|
||||
import org.gcube.vremanagement.executor.persistence.JDBCPersistence;
|
||||
import org.gcube.vremanagement.executor.persistence.JDBCPersistenceConnector;
|
||||
import org.gcube.vremanagement.executor.persistence.Persistence;
|
||||
import org.gcube.vremanagement.executor.plugin.Plugin;
|
||||
import org.gcube.vremanagement.executor.plugin.PluginDeclaration;
|
||||
import org.gcube.vremanagement.executor.plugin.PluginState;
|
||||
import org.gcube.vremanagement.executor.pluginmanager.PluginManager;
|
||||
import org.gcube.vremanagement.executor.pluginmanager.PluginThread;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Effective implementation of Executor
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*/
|
||||
@WebService(portName = "ExecutorPort",
|
||||
serviceName = Executor.SERVICE_NAME,
|
||||
targetNamespace = Executor.TNS,
|
||||
endpointInterface = "org.gcube.vremanagement.executor.api.Executor" )
|
||||
public class ExecutorImpl implements Executor {
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(ExecutorImpl.class);
|
||||
|
||||
/**
|
||||
* Pool for thread execution
|
||||
*/
|
||||
private static ExecutorService pool;
|
||||
|
||||
/**
|
||||
* Contains running plugin instances. The key is the associated random UUID.
|
||||
* This is needed to correctly stop the running plugin execution if the
|
||||
* container is stopped in the proper way
|
||||
*/
|
||||
private static Map<UUID,
|
||||
PluginThread<Plugin<? extends PluginDeclaration>>> pluginInstances;
|
||||
|
||||
/**
|
||||
* Contains the ServiceEnpoint Resource to be published/unpublished on IS
|
||||
*/
|
||||
private static ServiceEndpoint serviceEndpoint;
|
||||
|
||||
/**
|
||||
* Represent the connector to DB
|
||||
*/
|
||||
private static JDBCPersistenceConnector jdbcPersistenceConnector;
|
||||
|
||||
/**
|
||||
* Publish the provided resource on all Service Scopes retrieved from
|
||||
* Context
|
||||
* @param resource to be published
|
||||
* @throws RegistryNotFoundException if the Registry is not found so the
|
||||
* resource has not be published
|
||||
*/
|
||||
private static void publishScopedResource(Resource resource) throws RegistryNotFoundException, Exception {
|
||||
ApplicationContext ctx = ContextProvider.get();
|
||||
if(ctx == null){
|
||||
return;
|
||||
}
|
||||
Set<String> scopeSet = ctx.configuration().startScopes();
|
||||
List<String> scopes = new ArrayList<String>(scopeSet);
|
||||
|
||||
ScopedPublisher scopedPublisher = RegistryPublisherFactory.scopedPublisher();
|
||||
try {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
Resources.marshal(resource, stringWriter);
|
||||
logger.debug(String.format("Trying to publish %s", stringWriter.toString()));
|
||||
scopedPublisher.create(resource, scopes);
|
||||
} catch (RegistryNotFoundException e) {
|
||||
logger.error("The resource was not published", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the resource from IS
|
||||
* @param resource to be unpublished
|
||||
* @throws RegistryNotFoundException if the Registry is not found so the
|
||||
* resource has not be published
|
||||
*/
|
||||
private static void unPublishScopedResource(Resource resource) throws RegistryNotFoundException, Exception {
|
||||
ApplicationContext ctx = ContextProvider.get();
|
||||
if(ctx == null){
|
||||
return;
|
||||
}
|
||||
Set<String> scopeSet = ctx.configuration().startScopes();
|
||||
List<String> scopes = new ArrayList<String>(scopeSet);
|
||||
|
||||
ScopedPublisher scopedPublisher = RegistryPublisherFactory.scopedPublisher();
|
||||
try {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
Resources.marshal(resource, stringWriter);
|
||||
logger.debug(String.format("Trying to publish %s", stringWriter.toString()));
|
||||
scopedPublisher.remove(resource, scopes);
|
||||
} catch (RegistryNotFoundException e) {
|
||||
logger.error("The resource was not unpublished", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Service Endpoint using information related to discovered
|
||||
* available plugins and their own discoverd capabilities
|
||||
* @return
|
||||
*/
|
||||
protected static ServiceEndpoint createServiceEndpoint(){
|
||||
|
||||
logger.debug("Getting Available Plugins and their own supported capabilities");
|
||||
PluginManager pluginManager = PluginManager.getInstance();
|
||||
|
||||
logger.debug("Creating ServiceEndpoint to publish on IS available plugins and their own supported capabilities");
|
||||
ServiceEndpoint serviceEndpoint = new ServiceEndpoint();
|
||||
Profile profile = serviceEndpoint.newProfile();
|
||||
profile.category(Executor.SERVICE_NAME);
|
||||
profile.name(Executor.class.getSimpleName());
|
||||
|
||||
Group<AccessPoint> accessPoints = profile.accessPoints();
|
||||
Map<String, PluginDeclaration> availablePlugins = pluginManager.getAvailablePlugins();
|
||||
|
||||
for(String pluginName : availablePlugins.keySet()){
|
||||
AccessPoint accessPointElement = new AccessPoint();
|
||||
accessPointElement.name(pluginName);
|
||||
Group<Property> properties = accessPointElement.properties();
|
||||
|
||||
Map<String, String> pluginCapablities = availablePlugins.get(pluginName).getSupportedCapabilities();
|
||||
for(String capabilityName : pluginCapablities.keySet()){
|
||||
Property propertyElement = new Property();
|
||||
propertyElement.nameAndValue(capabilityName, pluginCapablities.get(capabilityName));
|
||||
properties.add(propertyElement);
|
||||
}
|
||||
accessPoints.add(accessPointElement);
|
||||
}
|
||||
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
Resources.marshal(serviceEndpoint, stringWriter);
|
||||
logger.debug(String.format("The created ServiceEndpoint profile is \n%s", stringWriter.toString()));
|
||||
|
||||
return serviceEndpoint;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
/**
|
||||
* This function is invoked when the service start by javax
|
||||
* thanks to {@Link #PostConstruct} annotation.
|
||||
* The method invoke function which discover the plugins available on
|
||||
* classpath and their own supported capabilities
|
||||
*/
|
||||
public static void init() throws Exception {
|
||||
pool = Executors.newCachedThreadPool();
|
||||
ExecutorImpl.serviceEndpoint = createServiceEndpoint();
|
||||
ExecutorImpl.pluginInstances = new HashMap<UUID, PluginThread<Plugin<? extends PluginDeclaration>>>();
|
||||
|
||||
initPersistence();
|
||||
|
||||
// TODO Before publishing the new Resource check if on IS there is
|
||||
// an old published ServiceEndpoint resource that where not unpublished
|
||||
// correctly
|
||||
|
||||
// TODO set task that are still on running state on DB to have a clear
|
||||
// room
|
||||
|
||||
try {
|
||||
ExecutorImpl.publishScopedResource(serviceEndpoint);
|
||||
} catch (RegistryNotFoundException e) {
|
||||
logger.error("Unable to Create ServiceEndpoint. the Service will be aborted", e);
|
||||
//throw e;
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to Create ServiceEndpoint. the Service will be aborted", e);
|
||||
//throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the DB connection and initialize the DB with data related to
|
||||
* discovered plugin and plugin state.
|
||||
* @throws Exception if fails
|
||||
*/
|
||||
protected static void initPersistence() throws Exception {
|
||||
try {
|
||||
jdbcPersistenceConnector = new JDBCPersistenceConnector();
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to initialize PersistenceConnector. The Service will be aborted", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
/**
|
||||
* This function is invoked before the service will stop and unpublish the
|
||||
* resource from the IS to maintain the infrastructure integrity
|
||||
*/
|
||||
public static void destroy(){
|
||||
|
||||
for(UUID uuid : pluginInstances.keySet()){
|
||||
PluginThread<Plugin<? extends PluginDeclaration>> pluginThread =
|
||||
pluginInstances.get(uuid);
|
||||
Plugin<? extends PluginDeclaration> pluginInstace =
|
||||
pluginThread.getPlugin();
|
||||
try {
|
||||
logger.debug(String.format("Requesting Stop to plugin instance "
|
||||
+ "identified by the UUID %s of Plugin named %s", uuid,
|
||||
pluginInstace.getPluginDeclaration().getName()));
|
||||
pluginInstace.stop();
|
||||
logger.debug(String.format("Plugin instance identified by the"
|
||||
+ "UUID %s of Plugin named %s stopped coorectly itself",
|
||||
uuid, pluginInstace.getPluginDeclaration().getName()));
|
||||
} catch (Exception e) {
|
||||
logger.debug(String.format("Running plugin instance identified "
|
||||
+ "by the UUID %s of Plugin named %s failed to request "
|
||||
+ "of being stopped", uuid,
|
||||
pluginInstace.getPluginDeclaration().getName()));
|
||||
} finally {
|
||||
pluginInstace.setState(PluginState.SUSPENDED);
|
||||
pluginInstances.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
// Forcing shutdown of all threads
|
||||
pool.shutdown();
|
||||
|
||||
try {
|
||||
ExecutorImpl.unPublishScopedResource(serviceEndpoint);
|
||||
} catch (RegistryNotFoundException e) {
|
||||
logger.error("Unable to unpublish Service Endpoint.", e);
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to unpublish Service Endpoint.", e);
|
||||
}
|
||||
|
||||
try {
|
||||
jdbcPersistenceConnector.close();
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to close Persistence", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**{@inheritDoc}*/
|
||||
@Override
|
||||
public String launch(LaunchParameter parameter) throws InputsNullException,
|
||||
PluginNotFoundException, LaunchException, ExecutorException {
|
||||
Map<String, Object> inputs = parameter.getInputs();
|
||||
if(inputs==null){
|
||||
throw new InputsNullException();
|
||||
}
|
||||
|
||||
String name = parameter.getName();
|
||||
// Retrieve the PluginDeclaration class representing the plugin which
|
||||
// have the name provided as input
|
||||
logger.debug(String.format("Trying to instatiate a Plugin named %s", name));
|
||||
PluginDeclaration pluginDeclaration = PluginManager.getInstance().getPlugin(name);
|
||||
if(pluginDeclaration == null){
|
||||
throw new PluginNotFoundException();
|
||||
}
|
||||
|
||||
// Creating the UUID to associate to plugin instance to be run
|
||||
UUID executionIdentifier = UUID.randomUUID();
|
||||
|
||||
// Retrieving the plugin instance class to be run from PluginDeclaration
|
||||
Class<? extends Plugin<? extends PluginDeclaration>> plugin = pluginDeclaration.getPluginImplementation();
|
||||
logger.debug(String.format("The class wich will run the execution will be %s", plugin.getName()));
|
||||
|
||||
// Retrieve the Constructor of Plugin to instantiate it
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class[] argTypes = { pluginDeclaration.getClass() , Persistence.class };
|
||||
logger.debug(String.format("Plugin named %s once instatiated will be identified by the UUID %s", name, executionIdentifier));
|
||||
Constructor<? extends Plugin<? extends PluginDeclaration>> executorPluginConstructor;
|
||||
try {
|
||||
executorPluginConstructor = plugin.getDeclaredConstructor(argTypes);
|
||||
} catch (Exception e) {
|
||||
throw new LaunchException();
|
||||
}
|
||||
|
||||
// Create and instance of DB connection used to persist plugin evolution
|
||||
JDBCPersistence jdbcEvolutionPersistence = new JDBCPersistence(jdbcPersistenceConnector, name, executionIdentifier);
|
||||
|
||||
// Create the Argument to pass to contructor
|
||||
Object[] arguments = { pluginDeclaration, jdbcEvolutionPersistence};
|
||||
|
||||
// Instancing the plugin
|
||||
Plugin<? extends PluginDeclaration> instantiatedPlugin;
|
||||
try {
|
||||
instantiatedPlugin = executorPluginConstructor.newInstance(arguments);
|
||||
} catch(Exception e) {
|
||||
throw new LaunchException();
|
||||
}
|
||||
logger.debug(String.format("Plugin named %s identified by the UUID %s has been instantiated", name, executionIdentifier));
|
||||
|
||||
// Creating the thread used to launch the plugin execution
|
||||
PluginThread<Plugin<? extends PluginDeclaration>> pluginThread =
|
||||
new PluginThread<Plugin<? extends PluginDeclaration>>(instantiatedPlugin, inputs, executionIdentifier);
|
||||
// Adding the thread to the pluginInstances
|
||||
pluginInstances.put(executionIdentifier, pluginThread);
|
||||
|
||||
// Launching Thread from initially created pool
|
||||
pool.execute(pluginThread);
|
||||
|
||||
logger.debug(String.format("The Plugin named %s with UUID %s has been launched with the provided inputs", name, executionIdentifier));
|
||||
|
||||
// TODO join the thread
|
||||
|
||||
return executionIdentifier.toString();
|
||||
}
|
||||
|
||||
/**{@inheritDoc}*/
|
||||
@Override
|
||||
public PluginState getState(String executionIdentifier) throws PluginInstanceNotFoundException, ExecutorException {
|
||||
try {
|
||||
return jdbcPersistenceConnector.getPluginInstanceState(UUID.fromString(executionIdentifier));
|
||||
} catch (Exception e) {
|
||||
throw new PluginInstanceNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.vremanagement.executor;
|
||||
|
||||
import javax.xml.ws.Endpoint;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class ExecutorPublisher {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Endpoint.publish("http://localhost:9999/gcube/vremanagement/executor", new ExecutorImpl());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.persistence;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.gcube.vremanagement.executor.plugin.PluginState;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class JDBCPersistence extends Persistence<JDBCPersistenceConnector> {
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(JDBCPersistence.class);
|
||||
|
||||
private final Connection connection;
|
||||
|
||||
public JDBCPersistence(JDBCPersistenceConnector jdbcPersistenceConnector,
|
||||
String name, UUID uuid){
|
||||
super(jdbcPersistenceConnector, name, uuid);
|
||||
this.connection = jdbcPersistenceConnector.getConnection();
|
||||
}
|
||||
|
||||
/**{@inheritDoc}*/
|
||||
@Override
|
||||
public void addEvolution(long timestamp, PluginState pluginState)
|
||||
throws Exception {
|
||||
|
||||
connection.setAutoCommit(false); // transaction block start
|
||||
|
||||
String insertPluginEvolution = String.format(
|
||||
"INSERT INTO `%s` (`%s`,`%s`,`%s`,`%s`) VALUES (?,?,?,?)",
|
||||
JDBCPersistenceConnector.PLUGIN_INSTANCE_EVOLUTION_TABLE,
|
||||
JDBCPersistenceConnector.PLUGIN_INSTANCE_EVOLUTION_TABLE_UUID_FIELD,
|
||||
JDBCPersistenceConnector.PLUGIN_INSTANCE_EVOLUTION_TABLE_PLUGIN_NAME_FIELD,
|
||||
JDBCPersistenceConnector.PLUGIN_INSTANCE_EVOLUTION_TABLE_TIMESTAMP_FIELD,
|
||||
JDBCPersistenceConnector.PLUGIN_INSTANCE_EVOLUTION_TABLE_STATE_FIELD);
|
||||
logger.info(String.format("Base Query : %s. Parameters : %s,%s",
|
||||
insertPluginEvolution, timestamp, pluginState.name()));
|
||||
|
||||
PreparedStatement psInsertPluginEvolution = connection
|
||||
.prepareStatement(insertPluginEvolution);
|
||||
|
||||
psInsertPluginEvolution.setString(1, uuid.toString());
|
||||
psInsertPluginEvolution.setString(2, name);
|
||||
psInsertPluginEvolution.setLong(3, timestamp);
|
||||
psInsertPluginEvolution.setInt(4, pluginState.ordinal());
|
||||
|
||||
psInsertPluginEvolution.executeUpdate();
|
||||
connection.commit(); //transaction block end
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.persistence;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.gcube.vremanagement.executor.plugin.PluginState;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class JDBCPersistenceConnector extends PersistenceConnector {
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(JDBCPersistenceConnector.class);
|
||||
|
||||
protected Connection connection;
|
||||
|
||||
public static final String driverClass = "org.h2.Driver";
|
||||
public static final String jdbcURL = "jdbc:h2:";
|
||||
public static final String username = "username";
|
||||
public static final String password = "password";
|
||||
public static final String dbName = "executor";
|
||||
public static final String queriesFilePath = "distro/db.sql";
|
||||
|
||||
public final static String PLUGIN_INSTANCE_EVOLUTION_TABLE = "pluginInstanceEvolution";
|
||||
public final static String PLUGIN_INSTANCE_EVOLUTION_TABLE_UUID_FIELD = "uuid";
|
||||
public final static String PLUGIN_INSTANCE_EVOLUTION_TABLE_PLUGIN_NAME_FIELD = "pluginName";
|
||||
public final static String PLUGIN_INSTANCE_EVOLUTION_TABLE_TIMESTAMP_FIELD = "timestamp";
|
||||
public final static String PLUGIN_INSTANCE_EVOLUTION_TABLE_STATE_FIELD = "state";
|
||||
|
||||
|
||||
public JDBCPersistenceConnector() throws Exception {
|
||||
|
||||
try {
|
||||
Class.forName(driverClass);
|
||||
logger.debug(String.format("JDBC Driver (%s) Registered!", driverClass));
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.error(String.format("Driver Class (%s) NOT available : %s", driverClass, e));
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
Path currentAbsolutePath = Paths.get(".").toAbsolutePath().normalize();
|
||||
logger.debug(String.format("Current Absolute Path : %s",currentAbsolutePath));
|
||||
String effectiveJDBCURL = String.format("%s%s/%s", jdbcURL, currentAbsolutePath.toString(), dbName);
|
||||
connection = DriverManager.getConnection(effectiveJDBCURL,username, password);
|
||||
} catch (SQLException e) {
|
||||
logger.error(String.format("Unable to connect to JDBC URL : %s", jdbcURL));
|
||||
}
|
||||
|
||||
try {
|
||||
runScript(queriesFilePath);
|
||||
}catch (Exception e){
|
||||
logger.error("Error while creating DB", e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void runScript(String queriesFilePath) throws Exception {
|
||||
SQLiteScriptRunner scriptRunner = new SQLiteScriptRunner(connection, false, true);
|
||||
FileReader fileReader = new FileReader(queriesFilePath);
|
||||
scriptRunner.runScript(fileReader);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the connection
|
||||
*/
|
||||
public Connection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**{@inheritDoc} */
|
||||
@Override
|
||||
public PluginState getPluginInstanceState(UUID uuid) throws Exception {
|
||||
String query = String.format(
|
||||
"SELECT `%s`,`%s` FROM `%s` WHERE `%s`=? ORDER BY `%s` DESC LIMIT 1",
|
||||
PLUGIN_INSTANCE_EVOLUTION_TABLE_TIMESTAMP_FIELD,
|
||||
PLUGIN_INSTANCE_EVOLUTION_TABLE_STATE_FIELD,
|
||||
PLUGIN_INSTANCE_EVOLUTION_TABLE,
|
||||
PLUGIN_INSTANCE_EVOLUTION_TABLE_UUID_FIELD,
|
||||
PLUGIN_INSTANCE_EVOLUTION_TABLE_TIMESTAMP_FIELD);
|
||||
logger.debug(query);
|
||||
PreparedStatement ps = connection.prepareStatement(query);
|
||||
ps.setString(1, uuid.toString());
|
||||
ResultSet resultSet = ps.executeQuery();
|
||||
resultSet.first();
|
||||
int stateOrdinal = resultSet.getInt(PLUGIN_INSTANCE_EVOLUTION_TABLE_STATE_FIELD);
|
||||
return PluginState.values()[stateOrdinal];
|
||||
}
|
||||
|
||||
/**{@inheritDoc} */
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
package org.gcube.vremanagement.executor.persistence;
|
||||
|
||||
/*
|
||||
* Slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class
|
||||
* from the iBATIS Apache project. Only removed dependency on Resource class
|
||||
* and a constructor
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004 Clinton Begin
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Tool to run database scripts
|
||||
*/
|
||||
public class SQLiteScriptRunner {
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(SQLiteScriptRunner.class);
|
||||
|
||||
private static final String DEFAULT_DELIMITER = ";";
|
||||
|
||||
private Connection connection;
|
||||
|
||||
private boolean stopOnError;
|
||||
private boolean autoCommit;
|
||||
|
||||
private String delimiter = DEFAULT_DELIMITER;
|
||||
private boolean fullLineDelimiter = false;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public SQLiteScriptRunner(Connection connection, boolean autoCommit,
|
||||
boolean stopOnError) {
|
||||
this.connection = connection;
|
||||
this.autoCommit = autoCommit;
|
||||
this.stopOnError = stopOnError;
|
||||
}
|
||||
|
||||
public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
|
||||
this.delimiter = delimiter;
|
||||
this.fullLineDelimiter = fullLineDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an SQL script (read in using the Reader parameter)
|
||||
*
|
||||
* @param reader
|
||||
* - the source of the script
|
||||
*/
|
||||
public void runScript(Reader reader) throws IOException, SQLException {
|
||||
try {
|
||||
boolean originalAutoCommit = connection.getAutoCommit();
|
||||
try {
|
||||
if (originalAutoCommit != this.autoCommit) {
|
||||
connection.setAutoCommit(this.autoCommit);
|
||||
}
|
||||
runScript(connection, reader);
|
||||
} finally {
|
||||
connection.setAutoCommit(originalAutoCommit);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (SQLException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error running script. Cause: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an SQL script (read in using the Reader parameter) using the
|
||||
* connection passed in
|
||||
*
|
||||
* @param conn
|
||||
* - the connection to use for the script
|
||||
* @param reader
|
||||
* - the source of the script
|
||||
* @throws SQLException
|
||||
* if any SQL errors occur
|
||||
* @throws IOException
|
||||
* if there is an error reading from the Reader
|
||||
*/
|
||||
private void runScript(Connection conn, Reader reader) throws IOException,
|
||||
SQLException {
|
||||
StringBuffer command = null;
|
||||
try {
|
||||
LineNumberReader lineReader = new LineNumberReader(reader);
|
||||
String line = null;
|
||||
while ((line = lineReader.readLine()) != null) {
|
||||
if (command == null) {
|
||||
command = new StringBuffer();
|
||||
}
|
||||
String trimmedLine = line.trim();
|
||||
if (trimmedLine.startsWith("--")) {
|
||||
logger.debug(trimmedLine);
|
||||
} else if (trimmedLine.length() < 1
|
||||
|| trimmedLine.startsWith("//")) {
|
||||
// Do nothing
|
||||
} else if (trimmedLine.length() < 1
|
||||
|| trimmedLine.startsWith("--")) {
|
||||
// Do nothing
|
||||
} else if (!fullLineDelimiter
|
||||
&& trimmedLine.endsWith(getDelimiter())
|
||||
|| fullLineDelimiter
|
||||
&& trimmedLine.equals(getDelimiter())) {
|
||||
command.append(line.substring(0, line
|
||||
.lastIndexOf(getDelimiter())));
|
||||
command.append(" ");
|
||||
Statement statement = conn.createStatement();
|
||||
|
||||
logger.debug(command.toString());
|
||||
|
||||
try {
|
||||
statement.execute(command.toString());
|
||||
} catch (SQLException e) {
|
||||
e.fillInStackTrace();
|
||||
logger.error("Error executing: " + command, e);
|
||||
if(stopOnError){
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
command = null;
|
||||
try {
|
||||
statement.close();
|
||||
} catch (Exception e) {
|
||||
// Ignore to workaround a bug in Jakarta DBCP
|
||||
}
|
||||
Thread.yield();
|
||||
} else {
|
||||
command.append(line);
|
||||
command.append(" ");
|
||||
}
|
||||
}
|
||||
if (!autoCommit) {
|
||||
conn.commit();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.fillInStackTrace();
|
||||
logger.error("Error executing: " + command, e);
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
e.fillInStackTrace();
|
||||
logger.error("Error executing: " + command, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private String getDelimiter() {
|
||||
return delimiter;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package org.gcube.vremanagement.executor.pluginmanager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import org.gcube.vremanagement.executor.plugin.PluginDeclaration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This is a singleton class which discover on classpath the available plugins
|
||||
* and map the plugin name to its implementation class.
|
||||
* The plugin implementation class can be retrieved using its name.
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*/
|
||||
public class PluginManager {
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(PluginManager.class);
|
||||
|
||||
/**
|
||||
* Singleton instance
|
||||
*/
|
||||
private static PluginManager pluginManager;
|
||||
|
||||
/**
|
||||
* Contains mapping between plugin name and the instance of its declaration
|
||||
* class
|
||||
*/
|
||||
private Map<String, PluginDeclaration> availablePlugins;
|
||||
|
||||
/**
|
||||
* Get the singleton instance of {@link #PPluginManager}.
|
||||
* The first time this function is invoked the instance is null
|
||||
* so it is created. Otherwise the already created instance is returned
|
||||
* @return singleton instance of {@link #PluginManager}
|
||||
*/
|
||||
public static PluginManager getInstance(){
|
||||
if(pluginManager== null){
|
||||
pluginManager = new PluginManager();
|
||||
}
|
||||
return pluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by {@link #getInstance()} function check the available plugin on classpath
|
||||
* and add them on {@link #availablePlugins}
|
||||
*/
|
||||
protected PluginManager(){
|
||||
logger.debug("Loading plugins available on classpath");
|
||||
this.availablePlugins = new HashMap<String, PluginDeclaration>();
|
||||
ServiceLoader<PluginDeclaration> serviceLoader = ServiceLoader.load(PluginDeclaration.class);
|
||||
for (PluginDeclaration pluginDeclaration : serviceLoader) {
|
||||
logger.debug(String.format("%s plugin found", pluginDeclaration.getName()));
|
||||
String name = pluginDeclaration.getName();
|
||||
this.availablePlugins.put(name, pluginDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name The name of the plugin
|
||||
* @return The plugin declaration if available, null otherwise
|
||||
*/
|
||||
public PluginDeclaration getPlugin(String name){
|
||||
return this.availablePlugins.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the availablePlugins
|
||||
*/
|
||||
public Map<String, PluginDeclaration> getAvailablePlugins() {
|
||||
return availablePlugins;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.pluginmanager;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.gcube.vremanagement.executor.plugin.Plugin;
|
||||
import org.gcube.vremanagement.executor.plugin.PluginDeclaration;
|
||||
import org.gcube.vremanagement.executor.plugin.PluginState;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class PluginThread<T extends Plugin<? extends PluginDeclaration>> extends Thread {
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(PluginThread.class);
|
||||
|
||||
protected static final String SEPARATOR = "---";
|
||||
|
||||
public static final String getThreadName(Plugin<? extends PluginDeclaration> plugin,
|
||||
Map<String, Object> inputs, UUID uuid){
|
||||
return String.format("%s%s%s%s%s",
|
||||
plugin.getPluginDeclaration().getName(),SEPARATOR,
|
||||
inputs.hashCode(), SEPARATOR, uuid);
|
||||
}
|
||||
|
||||
protected T plugin;
|
||||
protected Map<String, Object> inputs;
|
||||
|
||||
public PluginThread(T plugin, Map<String, Object> inputs, UUID uuid){
|
||||
super(getThreadName(plugin, inputs, uuid));
|
||||
this.plugin = plugin;
|
||||
this.inputs = inputs;
|
||||
this.plugin.setState(PluginState.CREATED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(){
|
||||
try {
|
||||
plugin.setState(PluginState.RUNNING);
|
||||
plugin.launch(inputs);
|
||||
plugin.setState(PluginState.DONE);
|
||||
} catch(Exception e) {
|
||||
logger.trace(String.format("Thread %s failed", getName()),e);
|
||||
plugin.setState(PluginState.FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the plugin
|
||||
*/
|
||||
public T getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the launchInputs
|
||||
*/
|
||||
public Map<String, Object> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
CREATE TABLE IF NOT EXISTS `pluginInstanceEvolution` (
|
||||
`id` INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`uuid` VARCHAR(36) NOT NULL,
|
||||
`pluginName` VARCHAR(255) NOT NULL,
|
||||
`timestamp` BIGINT NOT NULL,
|
||||
`state` INT NOT NULL
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
|
@ -0,0 +1,8 @@
|
|||
<application mode='online'>
|
||||
<name>Smart-Executor</name>
|
||||
<group>VREManagement</group>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<description>Executor Service</description>
|
||||
<local-persistence location='target' />
|
||||
</application>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<endpoints
|
||||
xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
|
||||
version="2.0">
|
||||
<endpoint
|
||||
name="executor"
|
||||
implementation="org.gcube.vremanagement.executor.ExecutorImpl"
|
||||
url-pattern="/gcube/vremanagement/executor"/>
|
||||
</endpoints>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
version="2.5">
|
||||
<listener>
|
||||
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
|
||||
</listener>
|
||||
<servlet>
|
||||
<servlet-name>smart-executor</servlet-name>
|
||||
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>smart-executor</servlet-name>
|
||||
<url-pattern>/gcube/vremanagement/smart-executor</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.vremanagement.executor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.acme.HelloWorldPluginDeclaration;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.Profile;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
|
||||
import org.gcube.common.resources.gcore.utils.Group;
|
||||
import org.gcube.vremanagement.executor.api.Executor;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class ExecutorImplTest {
|
||||
|
||||
public ExecutorImplTest(){
|
||||
try {
|
||||
ExecutorImpl.init();
|
||||
} catch(Exception e) {
|
||||
// OK
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createServiceEndpointTest() {
|
||||
|
||||
ServiceEndpoint serviceEndpoint = ExecutorImpl.createServiceEndpoint();
|
||||
|
||||
Profile profile = serviceEndpoint.profile();
|
||||
Assert.assertEquals(Executor.SERVICE_NAME, profile.category());
|
||||
Assert.assertEquals(Executor.class.getSimpleName(), profile.name());
|
||||
Group<AccessPoint> accessPoints = profile.accessPoints();
|
||||
Assert.assertEquals(1, accessPoints.size());
|
||||
HelloWorldPluginDeclaration hwpd = new HelloWorldPluginDeclaration();
|
||||
Map<String, String> supportedCapabilities = hwpd.getSupportedCapabilities();
|
||||
for(AccessPoint accessPoint : accessPoints){
|
||||
Assert.assertEquals(hwpd.getName(),accessPoint.name());
|
||||
Group<Property> properties = accessPoint.properties();
|
||||
Assert.assertEquals(supportedCapabilities.size(), properties.size());
|
||||
for(Property property : properties){
|
||||
String propertyName = property.name();
|
||||
Assert.assertTrue(supportedCapabilities.containsKey(propertyName));
|
||||
Assert.assertEquals(supportedCapabilities.get(propertyName), property.value());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.persistence;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.acme.HelloWorldPluginDeclaration;
|
||||
import org.gcube.vremanagement.executor.plugin.PluginState;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class JDBCPersistenceConnectorTest {
|
||||
|
||||
private JDBCPersistenceConnector jdbcPersistenceConnector;
|
||||
|
||||
public JDBCPersistenceConnectorTest() throws Exception{
|
||||
jdbcPersistenceConnector = new JDBCPersistenceConnector();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectionTest() {
|
||||
Assert.assertNotNull(jdbcPersistenceConnector.getConnection());;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPluginInstanceStateTest() throws Exception {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
JDBCPersistence jdbcPersistence = new JDBCPersistence(jdbcPersistenceConnector, HelloWorldPluginDeclaration.name, uuid);
|
||||
|
||||
PluginState[] states = PluginState.values();
|
||||
for(int i=0; i<states.length; i++){
|
||||
long timestamp = new Date().getTime();
|
||||
jdbcPersistence.addEvolution(timestamp, states[i]);
|
||||
PluginState ps = jdbcPersistenceConnector.getPluginInstanceState(uuid);
|
||||
Assert.assertEquals(states[i], ps);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.gcube.vremanagement.executor.pluginmanager;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.acme.HelloWorldPluginDeclaration;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*/
|
||||
public class PluginManagerTest {
|
||||
|
||||
@Test
|
||||
public void getInstance(){
|
||||
PluginManager pluginManager = PluginManager.getInstance();
|
||||
Assert.assertNotNull(pluginManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHelloWorldPlugin(){
|
||||
PluginManager pluginManager = PluginManager.getInstance();
|
||||
Assert.assertNotNull(pluginManager);
|
||||
Assert.assertEquals(HelloWorldPluginDeclaration.class, pluginManager.getPlugin(HelloWorldPluginDeclaration.name).getClass());
|
||||
Assert.assertNull(pluginManager.getPlugin(UUID.randomUUID().toString()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.pluginmanager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.acme.HelloWorldPlugin;
|
||||
import org.acme.HelloWorldPluginDeclaration;
|
||||
import org.gcube.vremanagement.executor.persistence.JDBCPersistence;
|
||||
import org.gcube.vremanagement.executor.persistence.JDBCPersistenceConnector;
|
||||
import org.gcube.vremanagement.executor.plugin.PluginState;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class PluginThreadTest {
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static Logger logger = LoggerFactory.getLogger(PluginThreadTest.class);
|
||||
|
||||
private HelloWorldPluginDeclaration hwpd;
|
||||
private JDBCPersistenceConnector jdbcPersistenceConnector;
|
||||
|
||||
public PluginThreadTest() throws Exception{
|
||||
this.hwpd = new HelloWorldPluginDeclaration();
|
||||
this.jdbcPersistenceConnector = new JDBCPersistenceConnector();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchNullInputsTest() throws Exception {
|
||||
logger.debug("Testing Null inputs");
|
||||
UUID uuid = UUID.randomUUID();
|
||||
JDBCPersistence jdbcPersistence = new JDBCPersistence(jdbcPersistenceConnector, hwpd.getName(), uuid);
|
||||
HelloWorldPlugin helloWorldPlugin = new HelloWorldPlugin(hwpd, jdbcPersistence);
|
||||
try {
|
||||
new PluginThread<HelloWorldPlugin>(helloWorldPlugin, null, uuid);
|
||||
} catch(Exception e){
|
||||
Assert.assertEquals(NullPointerException.class, e.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchEmptyInputsTest() throws Exception {
|
||||
logger.debug("Testing Empty inputs");
|
||||
Map<String, Object> inputs = new HashMap<String, Object>();
|
||||
UUID uuid = UUID.randomUUID();
|
||||
JDBCPersistence jdbcPersistence = new JDBCPersistence(jdbcPersistenceConnector, hwpd.getName(), uuid);
|
||||
HelloWorldPlugin helloWorldPlugin = new HelloWorldPlugin(hwpd, jdbcPersistence);
|
||||
PluginThread<HelloWorldPlugin> pt = new PluginThread<HelloWorldPlugin>(helloWorldPlugin, inputs, uuid);
|
||||
pt.start();
|
||||
Thread.sleep(1000);
|
||||
Assert.assertEquals(PluginState.FAILED, jdbcPersistence.getState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchValidInputsTest() throws Exception {
|
||||
logger.debug("Testing Some inputs");
|
||||
Map<String, Object> inputs = new HashMap<String, Object>();
|
||||
inputs.put("Test", "Test");
|
||||
|
||||
UUID uuid = UUID.randomUUID();
|
||||
JDBCPersistence jdbcPersistence = new JDBCPersistence(jdbcPersistenceConnector, hwpd.getName(), uuid);
|
||||
HelloWorldPlugin helloWorldPlugin = new HelloWorldPlugin(hwpd, jdbcPersistence);
|
||||
PluginThread<HelloWorldPlugin> pt = new PluginThread<HelloWorldPlugin>(helloWorldPlugin, inputs, uuid);
|
||||
Assert.assertEquals(PluginState.CREATED, jdbcPersistence.getState());
|
||||
|
||||
pt.start();
|
||||
|
||||
Thread.sleep(1000);
|
||||
Assert.assertEquals(PluginState.RUNNING, jdbcPersistence.getState());
|
||||
|
||||
Thread.sleep(4000);
|
||||
Assert.assertEquals(PluginState.RUNNING, jdbcPersistence.getState());
|
||||
|
||||
Thread.sleep(6000);
|
||||
Assert.assertEquals(PluginState.DONE, jdbcPersistence.getState());
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue