diff --git a/.checkstyle b/.checkstyle new file mode 100644 index 0000000..411691c --- /dev/null +++ b/.checkstyle @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml index 45fbdef..25d173a 100644 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,7 +1,8 @@ - - + + + diff --git a/distro/descriptor.xml b/distro/descriptor.xml index 089683d..11561cb 100644 --- a/distro/descriptor.xml +++ b/distro/descriptor.xml @@ -24,7 +24,7 @@ - target/${build.finalName}.jar + target/${build.finalName}.war /${artifactId} diff --git a/distro/gcube-handlers.xml b/distro/gcube-handlers.xml deleted file mode 100644 index 949cee3..0000000 --- a/distro/gcube-handlers.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index b791a68..0006ab0 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,13 @@ + + org.gcube.distribution + gcube-bom + LATEST + pom + import + org.gcube.distribution maven-smartgears-bom @@ -42,6 +49,16 @@ + + org.gcube.resources.discovery + ic-client + provided + + + org.gcube.resources.discovery + discovery-client + provided + org.gcube.core @@ -50,56 +67,55 @@ org.gcube.core - common-smartgears-app - - - org.gcube.resources - common-gcore-resources - provided - - - org.gcube.resources.discovery - ic-client + common-encryption provided org.gcube.core - common-encryption - provided + common-smartgears-app - - org.slf4j - slf4j-api + org.gcube.common + authorization-client provided - javax.servlet - javax.servlet-api - [3.0.0, 4.0.0) + org.gcube.common + common-authorization provided - org.gcube.vremanagement smart-executor-api - [1.2.0-SNAPSHOT, 2.0.0-SNAPSHOT) + [1.4.0-SNAPSHOT, 2.0.0-SNAPSHOT) + + javax.servlet + javax.servlet-api + [3.0.1, 4.0.0) + provided + com.sun.xml.ws jaxws-rt 2.1.7 + + org.slf4j + slf4j-api + provided + + org.json json 20090211 jar - + org.ektorp @@ -123,16 +139,11 @@ 4.11 test - - ch.qos.logback - logback-classic - 1.0.13 - test - + org.acme HelloWorldPlugin - [1.1.0-SNAPSHOT, 2.0.0-SNAPSHOT) + [1.2.0-SNAPSHOT, 2.0.0-SNAPSHOT) test @@ -168,7 +179,8 @@ 2.6 smart-executor - src\main\webapp\WEB-INF\web.xml + false + diff --git a/src/main/java/org/gcube/vremanagement/executor/SmartExecutorImpl.java b/src/main/java/org/gcube/vremanagement/executor/SmartExecutorImpl.java index 2b02fc5..760da13 100644 --- a/src/main/java/org/gcube/vremanagement/executor/SmartExecutorImpl.java +++ b/src/main/java/org/gcube/vremanagement/executor/SmartExecutorImpl.java @@ -4,7 +4,7 @@ import java.util.UUID; import javax.jws.WebService; -import org.gcube.smartgears.context.application.ApplicationContext; +import org.gcube.smartgears.annotations.ManagedBy; import org.gcube.vremanagement.executor.api.SmartExecutor; import org.gcube.vremanagement.executor.api.types.LaunchParameter; import org.gcube.vremanagement.executor.exception.ExecutorException; @@ -17,6 +17,7 @@ import org.gcube.vremanagement.executor.exception.SchedulerNotFoundException; import org.gcube.vremanagement.executor.persistence.SmartExecutorPersistenceConnector; import org.gcube.vremanagement.executor.persistence.SmartExecutorPersistenceFactory; import org.gcube.vremanagement.executor.plugin.PluginState; +import org.gcube.vremanagement.executor.plugin.PluginStateEvolution; import org.gcube.vremanagement.executor.scheduler.SmartExecutorScheduler; import org.quartz.SchedulerException; import org.slf4j.Logger; @@ -31,6 +32,7 @@ portName = "SmartExecutorPort", serviceName = SmartExecutor.WEB_SERVICE_SERVICE_NAME, targetNamespace = SmartExecutor.TARGET_NAMESPACE, endpointInterface = "org.gcube.vremanagement.executor.api.SmartExecutor" ) +@ManagedBy(SmartExecutorInitializator.class) public class SmartExecutorImpl implements SmartExecutor { /** @@ -38,23 +40,19 @@ public class SmartExecutorImpl implements SmartExecutor { */ private static Logger logger = LoggerFactory.getLogger(SmartExecutorImpl.class); - protected static ApplicationContext ctx; - - /** - * @return the ctx - */ - public static ApplicationContext getCtx() { - return ctx; - } - /**{@inheritDoc}*/ @Override public String launch(LaunchParameter parameter) throws InputsNullException, PluginNotFoundException, LaunchException, ExecutorException { + logger.info("Launch requested {}", parameter); + SmartExecutorScheduler smartExecutorScheduler = SmartExecutorScheduler.getInstance(); UUID uuid = smartExecutorScheduler.schedule(parameter); - logger.debug(String.format("The Plugin named %s with UUID %s has been launched with the provided inputs", parameter.getPluginName(), uuid)); + logger.info( + String.format( + "The Plugin named %s with UUID %s has been launched %s", + parameter.getPluginName(), uuid.toString(), parameter)); return uuid.toString(); } @@ -62,20 +60,21 @@ public class SmartExecutorImpl implements SmartExecutor { /**{@inheritDoc}*/ @Override public boolean stop(String executionIdentifier) throws ExecutorException { - return unSchedule(executionIdentifier, true, false); - } - - /**{@inheritDoc}*/ - @Override - public boolean unSchedule(String executionIdentifier) throws ExecutorException { - return unSchedule(executionIdentifier, false, false); + logger.info("Stop requested for {}", executionIdentifier); + boolean ret = unSchedule(executionIdentifier, true, false); + logger.info("{} was{} stopped succesfully", executionIdentifier, ret? "" : " not"); + return ret; } /**{@inheritDoc}*/ @Override public boolean unSchedule(String executionIdentifier, boolean globally) throws ExecutorException { - return unSchedule(executionIdentifier, false, globally); + logger.info("UnSchedule requested for {} globally : {}", + executionIdentifier, globally); + boolean ret = unSchedule(executionIdentifier, false, globally); + logger.info("{} was{} unscheduled {} succesfully", executionIdentifier, ret? "" : " not", globally? "globally": "locally"); + return ret; } // TODO Manage better exception to to advise the caller @@ -85,41 +84,70 @@ public class SmartExecutorImpl implements SmartExecutor { SmartExecutorScheduler smartExecutorScheduler = SmartExecutorScheduler.getInstance(); UUID uuid = UUID.fromString(executionIdentifier); smartExecutorScheduler.stop(uuid, stopOnly, globally); - } catch (SchedulerNotFoundException snfe) { - currentStopped = true; - logger.error("Error unscheduling task {}", executionIdentifier, snfe); - } catch(SchedulerException e){ - currentStopped = false; + } catch (SchedulerNotFoundException e) { + // currentStopped = true; logger.error("Error unscheduling task {}", executionIdentifier, e); - } catch(SchedulePersistenceException ex){ - currentStopped = true; - logger.error("Error removing scheduled task from persistence.", ex); + throw new ExecutorException(e); + } catch(SchedulerException e){ + // currentStopped = false; + logger.error("Error unscheduling task {}", executionIdentifier, e); + throw new ExecutorException(e); + } catch(SchedulePersistenceException e){ + // currentStopped = true; + logger.error("Error removing scheduled task from persistence.", e); + } catch (Exception e) { + // currentStopped = false; + logger.error("Error unscheduling task {}", executionIdentifier, e); + throw new ExecutorException(e); } return currentStopped; } /**{@inheritDoc}*/ @Override - public PluginState getState(String executionIdentifier) + @Deprecated + public PluginState getState(String executionIdentifier) throws PluginInstanceNotFoundException, ExecutorException { + return getStateEvolution(executionIdentifier).getPluginState(); + } + + /**{@inheritDoc}*/ + @Override + public PluginStateEvolution getStateEvolution(String executionIdentifier) + throws PluginInstanceNotFoundException, ExecutorException { + logger.info("getStateEvolution() requested for {}", executionIdentifier); try { SmartExecutorPersistenceConnector persistenceConnector = SmartExecutorPersistenceFactory.getPersistenceConnector(); - return persistenceConnector.getLastPluginInstanceState(UUID.fromString(executionIdentifier)); + PluginStateEvolution pluginStateEvolution = persistenceConnector.getLastPluginInstanceState(UUID.fromString(executionIdentifier)); + logger.info("getState() for {} is : {}", executionIdentifier, pluginStateEvolution); + return pluginStateEvolution; } catch (Exception e) { - throw new PluginInstanceNotFoundException(); + throw new PluginInstanceNotFoundException(e); } } /**{@inheritDoc}*/ @Override + @Deprecated public PluginState getIterationState(String executionIdentifier, int iterationNumber) throws PluginInstanceNotFoundException, ExecutorException { + return getIterationStateEvolution(executionIdentifier, iterationNumber).getPluginState(); + } + + /**{@inheritDoc}*/ + @Override + public PluginStateEvolution getIterationStateEvolution(String executionIdentifier, int iterationNumber) + throws PluginInstanceNotFoundException, ExecutorException { + logger.info("getIterationStateEvolution() requested for {} (iteration n. {})", executionIdentifier, iterationNumber); try { SmartExecutorPersistenceConnector persistenceConnector = SmartExecutorPersistenceFactory.getPersistenceConnector(); - return persistenceConnector.getPluginInstanceState(UUID.fromString(executionIdentifier), iterationNumber); + PluginStateEvolution pluginStateEvolution = persistenceConnector.getPluginInstanceState(UUID.fromString(executionIdentifier), iterationNumber); + logger.info("getIterationState() for {} (iteration n. {}) is : {}", executionIdentifier, iterationNumber, pluginStateEvolution); + return pluginStateEvolution; } catch (Exception e) { - throw new PluginInstanceNotFoundException(); + throw new PluginInstanceNotFoundException(e); } } + } diff --git a/src/main/java/org/gcube/vremanagement/executor/SmartExecutorInitializator.java b/src/main/java/org/gcube/vremanagement/executor/SmartExecutorInitializator.java index aead28b..dcef38d 100644 --- a/src/main/java/org/gcube/vremanagement/executor/SmartExecutorInitializator.java +++ b/src/main/java/org/gcube/vremanagement/executor/SmartExecutorInitializator.java @@ -1,22 +1,14 @@ -/** - * - */ package org.gcube.vremanagement.executor; import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; -import javax.xml.bind.annotation.XmlRootElement; - -import org.gcube.common.resources.gcore.GCoreEndpoint; +import org.gcube.common.authorization.client.Constants; +import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.resources.gcore.Resource; import org.gcube.common.resources.gcore.Resources; -import org.gcube.common.resources.gcore.ScopeGroup; import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; import org.gcube.common.resources.gcore.ServiceEndpoint.Profile; @@ -25,17 +17,15 @@ import org.gcube.common.resources.gcore.ServiceEndpoint.Runtime; import org.gcube.common.resources.gcore.common.Platform; import org.gcube.common.resources.gcore.utils.Group; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.informationsystem.publisher.AdvancedScopedPublisher; +import org.gcube.informationsystem.publisher.RegistryPublisher; import org.gcube.informationsystem.publisher.RegistryPublisherFactory; -import org.gcube.informationsystem.publisher.ScopedPublisher; import org.gcube.informationsystem.publisher.exception.RegistryNotFoundException; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.SimpleQuery; import org.gcube.resources.discovery.icclient.ICFactory; +import org.gcube.smartgears.ApplicationManager; +import org.gcube.smartgears.ContextProvider; import org.gcube.smartgears.configuration.container.ContainerConfiguration; -import org.gcube.smartgears.context.application.ApplicationContext; -import org.gcube.smartgears.handlers.application.ApplicationLifecycleEvent; -import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler; import org.gcube.vremanagement.executor.persistence.SmartExecutorPersistenceConnector; import org.gcube.vremanagement.executor.persistence.SmartExecutorPersistenceFactory; import org.gcube.vremanagement.executor.plugin.PluginDeclaration; @@ -48,8 +38,7 @@ import org.slf4j.LoggerFactory; * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ -@XmlRootElement(name = "plugin-registration-handler") -public class SmartExecutorInitializator extends ApplicationLifecycleHandler { +public class SmartExecutorInitializator implements ApplicationManager { /** * Logger @@ -58,38 +47,15 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { public static final long JOIN_TIMEOUT = 1000; - /* * - * Contains the ServiceEnpoint Resource to be published/unpublished on IS - * / - private static ServiceEndpoint serviceEndpoint; - */ - - /* * - * The application context - * / - protected static ApplicationContext ctx; - - /** - * @return the ctx - * / - public static ApplicationContext getCtx() { - return ctx; - } - */ - - /* - protected static ScheduledTaskConfiguration launchConfiguration; - - /** - * @return the configuredTasks - * / - public static ScheduledTaskConfiguration getConfiguredTasks() { - return launchConfiguration; - } - */ - - public static String getCurrentScope(){ - return ScopeProvider.instance.get(); + public static String getScopeFromToken(){ + String token = SecurityTokenProvider.instance.get(); + AuthorizationEntry authorizationEntry; + try { + authorizationEntry = Constants.authorizationService().get(token); + } catch (Exception e) { + return ScopeProvider.instance.get(); + } + return authorizationEntry.getContext(); } /** @@ -99,15 +65,16 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { * @throws RegistryNotFoundException if the Registry is not found so the * resource has not be published */ - private static void publishScopedResource(Resource resource, List scopes) throws RegistryNotFoundException, Exception { + private static void publishResource(Resource resource) throws Exception { StringWriter stringWriter = new StringWriter(); Resources.marshal(resource, stringWriter); - ScopedPublisher scopedPublisher = RegistryPublisherFactory.scopedPublisher(); + RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); + try { - logger.debug("Trying to publish to {}:\n{}", scopes, stringWriter); - scopedPublisher.create(resource, scopes); - } catch (RegistryNotFoundException e) { + logger.debug("Trying to publish to {}:\n{}", getScopeFromToken(), stringWriter); + registryPublisher.create(resource); + } catch (Exception e) { logger.error("The resource was not published", e); throw e; } @@ -119,18 +86,16 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { * @throws RegistryNotFoundException if the Registry is not found so the * resource has not be published */ - private static void unPublishScopedResource(Resource resource) throws RegistryNotFoundException, Exception { + private static void unPublishResource(Resource resource) throws Exception { //StringWriter stringWriter = new StringWriter(); //Resources.marshal(resource, stringWriter); - ScopedPublisher scopedPublisher = RegistryPublisherFactory.scopedPublisher(); - AdvancedScopedPublisher advancedScopedPublisher = new AdvancedScopedPublisher(scopedPublisher); + RegistryPublisher registryPublisher = RegistryPublisherFactory.create(); - String id = resource.id(); - logger.debug("Trying to remove {} with ID {} from {}", resource.getClass().getSimpleName(), id, ScopeProvider.instance.get()); + String id = resource.id(); + logger.debug("Trying to remove {} with ID {} from {}", resource.getClass().getSimpleName(), id, getScopeFromToken()); - //scopedPublisher.remove(resource, scopes); - advancedScopedPublisher.forceRemove(resource); + registryPublisher.remove(resource); logger.debug("{} with ID {} removed successfully", resource.getClass().getSimpleName(), id); } @@ -192,13 +157,13 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { 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(SmartExecutorImpl.ctx.configuration().serviceClass()); - profile.name(SmartExecutorImpl.ctx.configuration().name()); - String version = SmartExecutorImpl.ctx.configuration().version(); + profile.category(ContextProvider.get().configuration().serviceClass()); + profile.name(ContextProvider.get().configuration().name()); + String version = ContextProvider.get().configuration().version(); profile.version(version); - profile.description(SmartExecutorImpl.ctx.configuration().description()); + profile.description(ContextProvider.get().configuration().description()); - String runningOn = getRunningOn(SmartExecutorImpl.ctx.container().configuration()); + String runningOn = getRunningOn(ContextProvider.get().container().configuration()); Platform platform = profile.newPlatform(); platform.name(runningOn); @@ -210,7 +175,7 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { Runtime runtime = profile.newRuntime(); runtime.hostedOn(runningOn); - runtime.status(SmartExecutorImpl.ctx.configuration().mode().toString()); + runtime.status(ContextProvider.get().configuration().mode().toString()); Group accessPoints = profile.accessPoints(); Map availablePlugins = pluginManager.getAvailablePlugins(); @@ -245,34 +210,12 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { return serviceEndpoint; } - public static List getScopes(ApplicationContext applicationContext){ - Collection scopes; - - ScopeGroup scopeGroup = applicationContext.profile(GCoreEndpoint.class).scopes(); - if(scopeGroup==null || scopeGroup.isEmpty()){ - Set applicationScopes = applicationContext.configuration().startScopes(); - Set containerScopes = applicationContext.container().configuration().startScopes(); - - if(applicationScopes==null || applicationScopes.isEmpty()){ - scopes = containerScopes; - logger.debug("Application Scopes ({}). The Container Scopes ({}) will be used.", applicationScopes, scopes); - } else{ - logger.debug("Container Scopes ({}). Application Scopes ({}) will be used.", containerScopes, applicationScopes); - scopes = new HashSet(applicationScopes); - } - }else { - scopes = scopeGroup.asCollection(); - } - - return new ArrayList(scopes); - } - - private void cleanServiceEndpoints(String scope){ + private void cleanServiceEndpoints(){ try { SimpleQuery query = ICFactory.queryFor(ServiceEndpoint.class) - .addCondition(String.format("$resource/Profile/Category/text() eq '%s'", SmartExecutorImpl.ctx.configuration().serviceClass())) - .addCondition(String.format("$resource/Profile/Name/text() eq '%s'", SmartExecutorImpl.ctx.configuration().name())) - .addCondition(String.format("$resource/Profile/RunTime/HostedOn/text() eq '%s'", getRunningOn(SmartExecutorImpl.ctx.container().configuration()))) + .addCondition(String.format("$resource/Profile/Category/text() eq '%s'", ContextProvider.get().configuration().serviceClass())) + .addCondition(String.format("$resource/Profile/Name/text() eq '%s'", ContextProvider.get().configuration().name())) + .addCondition(String.format("$resource/Profile/RunTime/HostedOn/text() eq '%s'", getRunningOn(ContextProvider.get().container().configuration()))) .setResult("$resource"); DiscoveryClient client = ICFactory.clientFor(ServiceEndpoint.class); @@ -281,11 +224,11 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { for (ServiceEndpoint serviceEndpoint : serviceEndpoints) { try { logger.debug("Trying to unpublish the old ServiceEndpoint with ID {} from scope {}", - serviceEndpoint.id(), scope); - unPublishScopedResource(serviceEndpoint); + serviceEndpoint.id(), getScopeFromToken()); + unPublishResource(serviceEndpoint); } catch(Exception e){ logger.debug("Exception tryng to unpublish the old ServiceEndpoint with ID {} from scope {}", - serviceEndpoint.id(), scope, e); + serviceEndpoint.id(), getScopeFromToken(), e); } } }catch(Exception e){ @@ -301,37 +244,31 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { * Furthermore create/connect to DB */ @Override - public void onStart(ApplicationLifecycleEvent.Start applicationLifecycleEventStart) { + public void onInit() { + String scope = getScopeFromToken(); logger.trace( "\n-------------------------------------------------------\n" - + "Smart Executor is Starting\n" - + "-------------------------------------------------------"); - - SmartExecutorImpl.ctx = applicationLifecycleEventStart.context(); + + "Smart Executor is Starting on scope {}\n" + + "-------------------------------------------------------", + scope); ServiceEndpoint serviceEndpoint = createServiceEndpoint(); - // Checking if there are old unpublished ServiceEndpoints related to - // this vHN and trying to unpublish them - List scopes = getScopes(SmartExecutorImpl.ctx); - - for(String scope : scopes){ - ScopeProvider.instance.set(scope); - cleanServiceEndpoints(scope); - try { - SmartExecutorPersistenceFactory.getPersistenceConnector(); - } catch (Exception e) { - logger.error("Unable to isntantiate {} for scope {}", - SmartExecutorPersistenceConnector.class.getSimpleName(), scope, e); - throw new RuntimeException(e); - } - } - - // TODO set task that are still on running state on DB to have a clear - // room + cleanServiceEndpoints(); try { - publishScopedResource(serviceEndpoint, scopes); + SmartExecutorPersistenceFactory.getPersistenceConnector(scope); + } catch (Exception e) { + logger.error("Unable to instantiate {} for scope {}", + SmartExecutorPersistenceConnector.class.getSimpleName(), scope, e); + throw new RuntimeException(e); + } + + // TODO set task that are still on running state to FAILED state on + // Persistence to clean previous situation of a failure of HostingNode + + try { + publishResource(serviceEndpoint); } catch (RegistryNotFoundException e) { logger.error("Unable to Create ServiceEndpoint. the Service will be aborted", e); return; @@ -342,12 +279,10 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { logger.trace( "\n-------------------------------------------------------\n" - + "Smart Executor Started Successfully\n" - + "-------------------------------------------------------"); - - // TODO Launch initializer thread - + + "Smart Executor Started Successfully on scope {}\n" + + "-------------------------------------------------------", scope); + // TODO Launch repetitive thread for global task take over } /** @@ -357,31 +292,32 @@ public class SmartExecutorInitializator extends ApplicationLifecycleHandler { * Furthermore close the connection to DB. */ @Override - public void onStop(ApplicationLifecycleEvent.Stop applicationLifecycleEventStop) { + public void onShutdown(){ + + logger.trace( "\n-------------------------------------------------------\n" - + "Smart Executor is Stopping\n" - + "-------------------------------------------------------"); + + "Smart Executor is Stopping on scope {}\n" + + "-------------------------------------------------------", + getScopeFromToken()); SmartExecutorScheduler.getInstance().stopAll(); + - List scopes = getScopes(SmartExecutorImpl.ctx); - - for(String scope : scopes){ - ScopeProvider.instance.set(scope); - cleanServiceEndpoints(scope); - try { - SmartExecutorPersistenceFactory.getPersistenceConnector().close(); - } catch (Exception e) { - logger.error("Unable to correctly close {} for scope {}", - SmartExecutorPersistenceConnector.class.getSimpleName(), scope, e); - } + cleanServiceEndpoints(); + try { + SmartExecutorPersistenceFactory.getPersistenceConnector().close(); + } catch (Exception e) { + logger.error("Unable to correctly close {} for scope {}", + SmartExecutorPersistenceConnector.class.getSimpleName(), + getScopeFromToken(), e); } logger.trace( "\n-------------------------------------------------------\n" - + "Smart Executor Stopped Successfully\n" - + "-------------------------------------------------------"); + + "Smart Executor Stopped Successfully on scope {}\n" + + "-------------------------------------------------------", + getScopeFromToken()); } } diff --git a/src/main/java/org/gcube/vremanagement/executor/configuration/OrphanTaskMonitor.java b/src/main/java/org/gcube/vremanagement/executor/configuration/OrphanTaskMonitor.java deleted file mode 100644 index b341f2d..0000000 --- a/src/main/java/org/gcube/vremanagement/executor/configuration/OrphanTaskMonitor.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * - */ -package org.gcube.vremanagement.executor.configuration; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public class OrphanTaskMonitor implements Runnable { - - private final static Logger logger = LoggerFactory.getLogger(OrphanTaskMonitor.class); - - protected final ScheduledExecutorService scheduler; - - public final static int INITIAL_DELAY = 1; - public final static int DELAY = 5; - public final static TimeUnit TIME_UNIT = TimeUnit.MINUTES; - - public OrphanTaskMonitor(){ - this.scheduler = Executors.newScheduledThreadPool(1); - this.scheduler.scheduleAtFixedRate(this, INITIAL_DELAY, DELAY, TimeUnit.MINUTES); - } - - protected void check(){ - // TODO Insert Code Here - } - - - /* (non-Javadoc) - * @see java.lang.Runnable#run() - */ - @Override - public void run() { - logger.debug("Looking for orphan task to take in charge"); - check(); - } - -} diff --git a/src/main/java/org/gcube/vremanagement/executor/configuration/ScheduledTaskConfiguration.java b/src/main/java/org/gcube/vremanagement/executor/configuration/ScheduledTaskConfiguration.java index a42d18e..5b654f1 100644 --- a/src/main/java/org/gcube/vremanagement/executor/configuration/ScheduledTaskConfiguration.java +++ b/src/main/java/org/gcube/vremanagement/executor/configuration/ScheduledTaskConfiguration.java @@ -10,9 +10,6 @@ import org.gcube.vremanagement.executor.api.types.LaunchParameter; import org.gcube.vremanagement.executor.exception.SchedulePersistenceException; /** - * Every implementation MUST take in account to store/query the records - * on the current scope which is not passed as argument but MUST be retrieved - * from thread local * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ */ public interface ScheduledTaskConfiguration { diff --git a/src/main/java/org/gcube/vremanagement/executor/configuration/jsonbased/FileScheduledTaskConfiguration.java b/src/main/java/org/gcube/vremanagement/executor/configuration/jsonbased/FileScheduledTaskConfiguration.java index 5262205..5173f1e 100644 --- a/src/main/java/org/gcube/vremanagement/executor/configuration/jsonbased/FileScheduledTaskConfiguration.java +++ b/src/main/java/org/gcube/vremanagement/executor/configuration/jsonbased/FileScheduledTaskConfiguration.java @@ -13,8 +13,7 @@ import java.util.List; import java.util.UUID; import org.apache.commons.io.FileUtils; -//import org.gcube.smartgears.ContextProvider; -import org.gcube.vremanagement.executor.SmartExecutorImpl; +import org.gcube.smartgears.ContextProvider; import org.gcube.vremanagement.executor.api.types.LaunchParameter; import org.gcube.vremanagement.executor.api.types.Scheduling; import org.gcube.vremanagement.executor.configuration.ScheduledTaskConfiguration; @@ -45,8 +44,7 @@ public class FileScheduledTaskConfiguration implements ScheduledTaskConfiguratio public static final String CONFIG_TASK_FILENAME = "definedTasks.json"; public FileScheduledTaskConfiguration() throws Exception { - this(SmartExecutorImpl.getCtx().persistence().location()); - //this(ContextProvider.get().persistence().location()); + this(ContextProvider.get().persistence().location()); } public FileScheduledTaskConfiguration(String location) throws IOException, JSONException { diff --git a/src/main/java/org/gcube/vremanagement/executor/configuration/jsonbased/JSONLaunchParameter.java b/src/main/java/org/gcube/vremanagement/executor/configuration/jsonbased/JSONLaunchParameter.java index 74fa74c..fe253f3 100644 --- a/src/main/java/org/gcube/vremanagement/executor/configuration/jsonbased/JSONLaunchParameter.java +++ b/src/main/java/org/gcube/vremanagement/executor/configuration/jsonbased/JSONLaunchParameter.java @@ -48,23 +48,23 @@ public class JSONLaunchParameter extends LaunchParameter { public JSONLaunchParameter(String pluginName, Map pluginCapabilities, Map inputs) { super(pluginName, pluginCapabilities, inputs); - this.scope = SmartExecutorInitializator.getCurrentScope(); + this.scope = SmartExecutorInitializator.getScopeFromToken(); } public JSONLaunchParameter(String pluginName, Map inputs, Scheduling scheduling) throws ParseException { super(pluginName, inputs, scheduling); - this.scope = SmartExecutorInitializator.getCurrentScope(); + this.scope = SmartExecutorInitializator.getScopeFromToken(); } public JSONLaunchParameter(String pluginName, Map pluginCapabilities, Map inputs, Scheduling scheduling) throws ParseException { super(pluginName, pluginCapabilities, inputs, scheduling); - this.scope = SmartExecutorInitializator.getCurrentScope(); + this.scope = SmartExecutorInitializator.getScopeFromToken(); } public JSONLaunchParameter(LaunchParameter parameter) throws ParseException { super(parameter.getPluginName(), parameter.getPluginCapabilities(), parameter.getInputs(), parameter.getScheduling()); this.scheduling = new JSONScheduling(parameter.getScheduling()); - this.scope = SmartExecutorInitializator.getCurrentScope(); + this.scope = SmartExecutorInitializator.getScopeFromToken(); } public JSONLaunchParameter(JSONObject jsonObject) throws JSONException, ParseException, ScopeNotMatchException { @@ -100,7 +100,7 @@ public class JSONLaunchParameter extends LaunchParameter { this.usedBy = jsonObject.getString(USED_BY); } - this.scope = SmartExecutorInitializator.getCurrentScope(); + this.scope = SmartExecutorInitializator.getScopeFromToken(); if(jsonObject.has(SCOPE)){ String jsonScope = jsonObject.getString(SCOPE); if(jsonScope.compareTo(scope)!=0){ @@ -163,7 +163,7 @@ public class JSONLaunchParameter extends LaunchParameter { try { return toJSON().toString(); } catch (JSONException e) { - return String.format("{} : {}", this.getClass().getSimpleName(), + return String.format("%s : %s", this.getClass().getSimpleName(), super.toString()); } } diff --git a/src/main/java/org/gcube/vremanagement/executor/exception/InvalidPluginStateEvolutionException.java b/src/main/java/org/gcube/vremanagement/executor/exception/InvalidPluginStateEvolutionException.java new file mode 100644 index 0000000..58bd428 --- /dev/null +++ b/src/main/java/org/gcube/vremanagement/executor/exception/InvalidPluginStateEvolutionException.java @@ -0,0 +1,33 @@ +/** + * + */ +package org.gcube.vremanagement.executor.exception; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class InvalidPluginStateEvolutionException extends Exception { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -7730594422282391883L; + + public InvalidPluginStateEvolutionException() { + super(); + } + + public InvalidPluginStateEvolutionException(String message) { + super(message); + } + + public InvalidPluginStateEvolutionException(Throwable throwable){ + super(throwable); + } + + public InvalidPluginStateEvolutionException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConfiguration.java b/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConfiguration.java index e70a717..aa6c6b9 100644 --- a/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConfiguration.java +++ b/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConfiguration.java @@ -126,7 +126,7 @@ public class SmartExecutorPersistenceConfiguration { List serviceEndpoints = client.submit(query); if(serviceEndpoints.size()>1){ query.addCondition(String.format("$resource/Profile/AccessPoint/Properties/Property/Name/text() eq '%s'", TARGET_SCOPE)); - query.addCondition(String.format("$resource/Profile/AccessPoint/Properties/Property/Value/text() eq '%s'", SmartExecutorInitializator.getCurrentScope())); + query.addCondition(String.format("$resource/Profile/AccessPoint/Properties/Property/Value/text() eq '%s'", SmartExecutorInitializator.getScopeFromToken())); serviceEndpoints = client.submit(query); } return serviceEndpoints.get(0); diff --git a/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConnector.java b/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConnector.java index ff5d04b..d4079dd 100644 --- a/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConnector.java +++ b/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConnector.java @@ -3,22 +3,25 @@ */ package org.gcube.vremanagement.executor.persistence; +import java.util.HashMap; import java.util.UUID; import org.gcube.vremanagement.executor.plugin.Plugin; import org.gcube.vremanagement.executor.plugin.PluginState; +import org.gcube.vremanagement.executor.plugin.PluginStateEvolution; import org.gcube.vremanagement.executor.plugin.PluginStateNotification; /** * Model the connector which create or open the connection to DB. - * Every implementation MUST take in account to store/query the records - * on the current scope which is not passed as argument but MUSt be retrieved - * from thread local. * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ */ -public abstract class SmartExecutorPersistenceConnector implements PluginStateNotification { +public abstract class SmartExecutorPersistenceConnector extends PluginStateNotification { - /** + public SmartExecutorPersistenceConnector() { + super(new HashMap()); + } + + /** * Close the connection to DB * @throws Exception if fails */ @@ -32,7 +35,7 @@ public abstract class SmartExecutorPersistenceConnector implements PluginStateNo * @return the actual/last {@link PluginState} of the Plugin * @throws Exception if fails */ - public abstract PluginState getPluginInstanceState(UUID uuid, int iterationNumber) + public abstract PluginStateEvolution getPluginInstanceState(UUID uuid, int iterationNumber) throws Exception; /** * Retrieve the status of the iterationNumber of the last running/run {@link Plugin} which is/was identified @@ -41,7 +44,7 @@ public abstract class SmartExecutorPersistenceConnector implements PluginStateNo * @return the actual/last {@link PluginState} of the Plugin * @throws Exception if fails */ - public abstract PluginState getLastPluginInstanceState(UUID uuid) + public abstract PluginStateEvolution getLastPluginInstanceState(UUID uuid) throws Exception; } diff --git a/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceFactory.java b/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceFactory.java index f1dcd73..237a1b3 100644 --- a/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceFactory.java +++ b/src/main/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceFactory.java @@ -25,7 +25,7 @@ public abstract class SmartExecutorPersistenceFactory { persistenceConnectors = new HashMap(); } - private static SmartExecutorPersistenceConnector getPersistenceConnector(String scope){ + public static SmartExecutorPersistenceConnector getPersistenceConnector(String scope){ if(scope==null){ String error = "No Scope available."; logger.error(error); @@ -42,28 +42,31 @@ public abstract class SmartExecutorPersistenceFactory { * @return the persistenceConnector */ public static synchronized SmartExecutorPersistenceConnector getPersistenceConnector() throws Exception { - String scope = SmartExecutorInitializator.getCurrentScope(); + String scope = SmartExecutorInitializator.getScopeFromToken(); SmartExecutorPersistenceConnector persistence = - getPersistenceConnector(SmartExecutorInitializator.getCurrentScope()); + getPersistenceConnector(scope); if(persistence==null){ logger.trace("Retrieving {} for scope {} not found on internal {}. Intializing it.", - SmartExecutorPersistenceConnector.class.getSimpleName(), scope, Map.class.getSimpleName()); + SmartExecutorPersistenceConnector.class.getSimpleName(), + scope, Map.class.getSimpleName()); String className = CouchDBPersistenceConnector.class.getSimpleName(); SmartExecutorPersistenceConfiguration configuration = new SmartExecutorPersistenceConfiguration(className); persistence = new CouchDBPersistenceConnector(configuration); - persistenceConnectors.put(scope, persistence); + persistenceConnectors.put(SmartExecutorInitializator.getScopeFromToken(), + persistence); } return persistence; } public static synchronized void closePersistenceConnector() throws Exception { - String scope = SmartExecutorInitializator.getCurrentScope(); - SmartExecutorPersistenceConnector persistence = getPersistenceConnector(scope); + String scope = SmartExecutorInitializator.getScopeFromToken(); + SmartExecutorPersistenceConnector persistence = + getPersistenceConnector(scope); if(persistence!=null){ persistence.close(); persistenceConnectors.remove(scope); diff --git a/src/main/java/org/gcube/vremanagement/executor/persistence/couchdb/CouchDBPersistenceConnector.java b/src/main/java/org/gcube/vremanagement/executor/persistence/couchdb/CouchDBPersistenceConnector.java index e66a52c..1a51edc 100644 --- a/src/main/java/org/gcube/vremanagement/executor/persistence/couchdb/CouchDBPersistenceConnector.java +++ b/src/main/java/org/gcube/vremanagement/executor/persistence/couchdb/CouchDBPersistenceConnector.java @@ -38,7 +38,6 @@ import org.gcube.vremanagement.executor.exception.ScopeNotMatchException; import org.gcube.vremanagement.executor.persistence.SmartExecutorPersistenceConfiguration; import org.gcube.vremanagement.executor.persistence.SmartExecutorPersistenceConnector; import org.gcube.vremanagement.executor.plugin.PluginDeclaration; -import org.gcube.vremanagement.executor.plugin.PluginState; import org.gcube.vremanagement.executor.plugin.PluginStateEvolution; import org.json.JSONException; import org.json.JSONObject; @@ -131,7 +130,7 @@ public class CouchDBPersistenceConnector extends SmartExecutorPersistenceConnect * {@inheritDoc} */ @Override - public void pluginStateEvolution(PluginStateEvolution pluginStateEvolution) throws Exception { + public void pluginStateEvolution(PluginStateEvolution pluginStateEvolution, Exception e) throws Exception { ObjectNode objectNode = PluginStateEvolutionObjectNode.getObjectMapper(pluginStateEvolution); createItem(objectNode, null); } @@ -141,7 +140,7 @@ public class CouchDBPersistenceConnector extends SmartExecutorPersistenceConnect */ @Override @Deprecated - public PluginState getPluginInstanceState(UUID uuid, int iterationNumber) + public PluginStateEvolution getPluginInstanceState(UUID uuid, int iterationNumber) throws Exception { return reallyQuery(null, uuid, iterationNumber); } @@ -151,7 +150,7 @@ public class CouchDBPersistenceConnector extends SmartExecutorPersistenceConnect */ @Override @Deprecated - public PluginState getLastPluginInstanceState(UUID uuid) throws Exception { + public PluginStateEvolution getLastPluginInstanceState(UUID uuid) throws Exception { return reallyQuery(null, uuid, LAST); } @@ -200,12 +199,12 @@ public class CouchDBPersistenceConnector extends SmartExecutorPersistenceConnect * @return * @throws Exception */ - protected PluginState reallyQuery(PluginDeclaration pluginDeclaration, UUID uuid, int iterationNumber) + protected PluginStateEvolution reallyQuery(PluginDeclaration pluginDeclaration, UUID uuid, int iterationNumber) throws Exception { ViewQuery query = new ViewQuery().designDocId(String.format("%s%s", MAP_REDUCE__DESIGN, PLUGIN_STATE_DOCUMENT)); - String scope = SmartExecutorInitializator.getCurrentScope(); + String scope = SmartExecutorInitializator.getScopeFromToken(); ArrayNode startKey = new ObjectMapper().createArrayNode(); startKey.add(scope); ArrayNode endKey = new ObjectMapper().createArrayNode(); @@ -238,19 +237,21 @@ public class CouchDBPersistenceConnector extends SmartExecutorPersistenceConnect query.reduce(false); - PluginState pluginState = null; + PluginStateEvolution pluginStateEvolution = null; ViewResult viewResult = query(query); for (ViewResult.Row row : viewResult) { //JsonNode key = row.getKeyAsNode(); JsonNode value = row.getValueAsNode(); - pluginState = PluginState.valueOf(value.findValue("state").getTextValue()); + pluginStateEvolution = PluginStateEvolutionObjectNode.getPluginStateEvolution(value); + + } - if(pluginState==null){ + if(pluginStateEvolution==null){ throw new PluginStateNotRetrievedException(); } - return pluginState; + return pluginStateEvolution; } @@ -273,7 +274,7 @@ public class CouchDBPersistenceConnector extends SmartExecutorPersistenceConnect ViewQuery query = new ViewQuery().designDocId(String.format("%s%s", MAP_REDUCE__DESIGN, SCHEDULED_TASKS_DOCUMENT)); query = query.viewName(ORPHAN_VIEW); - String scope = SmartExecutorInitializator.getCurrentScope(); + String scope = SmartExecutorInitializator.getScopeFromToken(); ArrayNode startKey = new ObjectMapper().createArrayNode(); startKey.add(scope); ArrayNode endKey = new ObjectMapper().createArrayNode(); @@ -316,7 +317,7 @@ public class CouchDBPersistenceConnector extends SmartExecutorPersistenceConnect JSONObject obj = jlp.toJSON(); obj.append(TYPE_JSON_FIELD, SCHEDULED_TASK_TYPE); obj.append(USED_BY_FIELD, consumerID); - obj.append(ScheduledTaskConfiguration.SCOPE, SmartExecutorInitializator.getCurrentScope()); + obj.append(ScheduledTaskConfiguration.SCOPE, SmartExecutorInitializator.getScopeFromToken()); createItem(obj, uuid.toString()); } catch (Exception e) { logger.error("Error Adding Scheduled Task UUID : {}, Consumer : {}, LaunchParameter : {}", diff --git a/src/main/java/org/gcube/vremanagement/executor/persistence/couchdb/PluginStateEvolutionObjectNode.java b/src/main/java/org/gcube/vremanagement/executor/persistence/couchdb/PluginStateEvolutionObjectNode.java index 977b1b8..0b36cf1 100644 --- a/src/main/java/org/gcube/vremanagement/executor/persistence/couchdb/PluginStateEvolutionObjectNode.java +++ b/src/main/java/org/gcube/vremanagement/executor/persistence/couchdb/PluginStateEvolutionObjectNode.java @@ -3,16 +3,21 @@ */ package org.gcube.vremanagement.executor.persistence.couchdb; +import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.UUID; +import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.node.ObjectNode; import org.gcube.common.resources.gcore.GCoreEndpoint; -//import org.gcube.smartgears.ContextProvider; -import org.gcube.vremanagement.executor.SmartExecutorImpl; +import org.gcube.smartgears.ContextProvider; import org.gcube.vremanagement.executor.SmartExecutorInitializator; +import org.gcube.vremanagement.executor.exception.InvalidPluginStateEvolutionException; +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.plugin.PluginStateEvolution; /** @@ -43,15 +48,15 @@ public class PluginStateEvolutionObjectNode { public final static String LOCALHOST = "localhost"; + public final static String PERCENTAGE = "percentage"; + protected static ObjectNode getRunOn(){ ObjectMapper objectMapper = new ObjectMapper(); ObjectNode objectNode = objectMapper.createObjectNode(); try { - GCoreEndpoint gCoreEndpoint = SmartExecutorImpl.getCtx().profile(GCoreEndpoint.class); - //GCoreEndpoint gCoreEndpoint = ContextProvider.get().profile(GCoreEndpoint.class); + GCoreEndpoint gCoreEndpoint = ContextProvider.get().profile(GCoreEndpoint.class); objectNode.put(GHN_ID_FIELD, gCoreEndpoint.profile().ghnId()); - objectNode.put(GHN_HOSTNAME_FIELD, SmartExecutorImpl.getCtx().container().configuration().hostname()); - //objectNode.put(GHN_HOSTNAME_FIELD, ContextProvider.get().container().configuration().hostname()); + objectNode.put(GHN_HOSTNAME_FIELD, ContextProvider.get().container().configuration().hostname()); }catch(Exception e){ objectNode.put(GHN_ID_FIELD, LOCALHOST + "_" + UUID.randomUUID()); objectNode.put(GHN_HOSTNAME_FIELD, LOCALHOST); @@ -78,8 +83,51 @@ public class PluginStateEvolutionObjectNode { return objectNode; } + protected static PluginDeclaration getPluginDeclaration(final JsonNode jsonNode){ + PluginDeclaration pluginDeclaration = new PluginDeclaration() { + + @Override + public void init() throws Exception {} + + @Override + public String getVersion() { + return jsonNode.get(PLUGIN_DECLARATION_VERSION_FIELD).asText(); + } + + @Override + public Map getSupportedCapabilities() { + Map capabilities = new HashMap<>(); + JsonNode node = jsonNode.get(PLUGIN_DECLARATION_VERSION_FIELD); + Iterator iterator = node.getFieldNames(); + while(iterator.hasNext()) { + String key = iterator.next(); + capabilities.put(key, node.get(key).asText()); + } + return capabilities; + } + + @Override + public Class> getPluginImplementation() { + return null; + } + + @Override + public String getName() { + return jsonNode.get(PLUGIN_DECLARATION_NAME_FIELD).asText(); + } + + @Override + public String getDescription() { + return jsonNode.get(PLUGIN_DECLARATION_DESCRIPTION_FIELD).asText(); + } + }; + + return pluginDeclaration; + } + + public static void addScope(ObjectNode objectNode){ - objectNode.put(SCOPE_FIELD, SmartExecutorInitializator.getCurrentScope()); + objectNode.put(SCOPE_FIELD, SmartExecutorInitializator.getScopeFromToken()); } public static ObjectNode getObjectMapper(PluginStateEvolution pluginStateEvolution){ @@ -93,6 +141,8 @@ public class PluginStateEvolutionObjectNode { objectNode.put(STATE_FIELD, pluginStateEvolution.getPluginState().toString()); + objectNode.put(PERCENTAGE, pluginStateEvolution.getPercentage()); + addScope(objectNode); objectNode.put(CouchDBPersistenceConnector.TYPE_JSON_FIELD, EVOLUTION_TYPE); @@ -105,4 +155,15 @@ public class PluginStateEvolutionObjectNode { return objectNode; } + + public static PluginStateEvolution getPluginStateEvolution(JsonNode jsonNode) + throws InvalidPluginStateEvolutionException{ + UUID uuid = UUID.fromString(jsonNode.get(UUID_FIELD).asText()); + int iteration = jsonNode.get(ITERATION_FIELD).asInt(); + long timestamp = jsonNode.get(TIMESTAMP_FIELD).asInt(); + PluginDeclaration pluginDeclaration = getPluginDeclaration(jsonNode.get(PLUGIN_DECLARATION_FIELD)); + PluginState pluginState = PluginState.valueOf(jsonNode.get(STATE_FIELD).asText()); + int percentage = jsonNode.get(PERCENTAGE).asInt(); + return new PluginStateEvolution(uuid, iteration, timestamp, pluginDeclaration, pluginState, percentage); + } } diff --git a/src/main/java/org/gcube/vremanagement/executor/pluginmanager/PercentageSetterImpl.java b/src/main/java/org/gcube/vremanagement/executor/pluginmanager/PercentageSetterImpl.java new file mode 100644 index 0000000..ca46aad --- /dev/null +++ b/src/main/java/org/gcube/vremanagement/executor/pluginmanager/PercentageSetterImpl.java @@ -0,0 +1,34 @@ +/** + * + */ +package org.gcube.vremanagement.executor.pluginmanager; + +import org.gcube.vremanagement.executor.exception.InvalidPluginStateEvolutionException; +import org.gcube.vremanagement.executor.plugin.PercentageSetter; +import org.gcube.vremanagement.executor.plugin.Plugin; +import org.gcube.vremanagement.executor.plugin.PluginDeclaration; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class PercentageSetterImpl> implements PercentageSetter { + + private final RunnablePlugin runnablePlugin; + + public PercentageSetterImpl(RunnablePlugin runnablePlugin){ + this.runnablePlugin = runnablePlugin; + } + + public void setPercentageEvolution(Integer percentage){ + try { + if(percentage<0 || percentage>100){ + throw new InvalidPluginStateEvolutionException("Percentage must be beetween 0 and 100"); + } + this.runnablePlugin.setPercentage(percentage); + } catch(Exception e){ + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/org/gcube/vremanagement/executor/pluginmanager/PluginManager.java b/src/main/java/org/gcube/vremanagement/executor/pluginmanager/PluginManager.java index b5849aa..9fe8a87 100644 --- a/src/main/java/org/gcube/vremanagement/executor/pluginmanager/PluginManager.java +++ b/src/main/java/org/gcube/vremanagement/executor/pluginmanager/PluginManager.java @@ -69,7 +69,7 @@ public class PluginManager { "The class which will run the execution will be %s", plugin.getName())); - // Retrieve the Constructor of Plugin to instantiate itPLUGIN + // Retrieve the Constructor of Plugin to instantiate it @SuppressWarnings("rawtypes") Class[] argTypes = { pluginDeclaration.getClass()}; @@ -77,7 +77,7 @@ public class PluginManager { Object[] arguments = { pluginDeclaration}; - // logger.debug(String.format("Plugin named %s once instatiated will be identified by the UUID %s", + // logger.debug(String.format("Plugin named %s once instantiated will be identified by the UUID %s", // name, executionIdentifier)); Constructor> executorPluginConstructor; try { diff --git a/src/main/java/org/gcube/vremanagement/executor/pluginmanager/RunnablePlugin.java b/src/main/java/org/gcube/vremanagement/executor/pluginmanager/RunnablePlugin.java index 39f27d1..a45ace1 100644 --- a/src/main/java/org/gcube/vremanagement/executor/pluginmanager/RunnablePlugin.java +++ b/src/main/java/org/gcube/vremanagement/executor/pluginmanager/RunnablePlugin.java @@ -3,12 +3,13 @@ */ package org.gcube.vremanagement.executor.pluginmanager; -import java.util.Date; +import java.util.Calendar; import java.util.List; import java.util.Map; import java.util.UUID; import org.gcube.vremanagement.executor.exception.AlreadyInFinalStateException; +import org.gcube.vremanagement.executor.exception.InvalidPluginStateEvolutionException; import org.gcube.vremanagement.executor.plugin.Plugin; import org.gcube.vremanagement.executor.plugin.PluginDeclaration; import org.gcube.vremanagement.executor.plugin.PluginState; @@ -40,18 +41,19 @@ public class RunnablePlugin> imple protected final int iterationNumber; protected final List pluginStateNotifications; - protected PluginState actualState; + protected PluginStateEvolution actualStateEvolution; public RunnablePlugin(T plugin, Map inputs, UUID uuid, int iterationNumber, List pluginStateNotifications){ this.plugin = plugin; + this.plugin.setPercentageSetter(new PercentageSetterImpl(this)); this.inputs = inputs; this.uuid = uuid; this.iterationNumber = iterationNumber; this.pluginStateNotifications = pluginStateNotifications; try { setState(PluginState.CREATED); - } catch (AlreadyInFinalStateException e) { + } catch (AlreadyInFinalStateException | InvalidPluginStateEvolutionException e) { logger.error(" --- You should not be here. Seem that the {} is suspended before the istance is created. This is really STRANGE.", uuid); throw new RuntimeException(e); @@ -64,6 +66,7 @@ public class RunnablePlugin> imple public void run(){ try { setState(PluginState.RUNNING); + plugin.launch(inputs); setState(PluginState.DONE); } catch (AlreadyInFinalStateException e1) { @@ -71,12 +74,12 @@ public class RunnablePlugin> imple } catch(Exception e) { logger.trace(String.format("Thread %s failed", this.toString()),e); try { - setState(PluginState.FAILED); - } catch (AlreadyInFinalStateException e1) { + setState(PluginState.FAILED, e); + } catch (AlreadyInFinalStateException | InvalidPluginStateEvolutionException e1) { return; } throw new RuntimeException(e); - } + } } /** @@ -93,32 +96,66 @@ public class RunnablePlugin> imple return inputs; } + protected synchronized void setPercentage(Integer percentage) throws AlreadyInFinalStateException, InvalidPluginStateEvolutionException { + PluginState pluginState = actualStateEvolution.getPluginState(); + if(pluginState != PluginState.RUNNING){ + throw new InvalidPluginStateEvolutionException("Percentage can be set only for runnign plugin"); + } + setState(pluginState, percentage, null); + } + + public synchronized void setState(PluginState pluginState) throws AlreadyInFinalStateException, InvalidPluginStateEvolutionException { + Integer percentage = 0; + if(actualStateEvolution!=null){ + percentage = actualStateEvolution.getPercentage(); + } + + if(pluginState==PluginState.DONE){ + percentage = 100; + } + setState(pluginState, percentage, null); + } + + public synchronized void setState(PluginState pluginState, Exception e) throws AlreadyInFinalStateException, InvalidPluginStateEvolutionException { + Integer percentage = 0; + if(actualStateEvolution!=null){ + percentage = actualStateEvolution.getPercentage(); + } + + Exception exception = null; + if(pluginState == PluginState.FAILED){ + exception = new Exception(e); + } + + setState(pluginState, percentage, exception); + } /** * It is up to the plugin update the State of the Running Plugin using * this facilities function. * @param pluginState * @throws Exception */ - public synchronized void setState(PluginState pluginState) throws AlreadyInFinalStateException { - long timestamp = new Date().getTime(); - if(actualState!=null && actualState.isFinalState()){ + protected void setState(PluginState pluginState, Integer percentage, Exception exception) throws AlreadyInFinalStateException, InvalidPluginStateEvolutionException { + long timestamp = Calendar.getInstance().getTimeInMillis(); + if(actualStateEvolution!=null && actualStateEvolution.getPluginState().isFinalState()){ logger.trace("At {} Trying to set {} in {} state, but it was already in the final state {}", timestamp, - uuid, pluginState.toString(), actualState.toString()); + uuid, pluginState.toString(), actualStateEvolution.toString()); throw new AlreadyInFinalStateException(); } + + PluginStateEvolution pluginStateEvolution = new PluginStateEvolution(uuid, iterationNumber, timestamp, plugin.getPluginDeclaration(), pluginState, percentage); - actualState = pluginState; for(PluginStateNotification pluginStateNotification : pluginStateNotifications){ String pluginStateNotificationName = pluginStateNotification.getClass().getSimpleName(); - PluginStateEvolution pluginStateEvolution = new PluginStateEvolution(uuid, iterationNumber, timestamp, plugin.getPluginDeclaration(), pluginState); try { - logger.debug("Adding Plugin State Evolution {} with {}.", pluginStateEvolution, pluginStateNotificationName); - pluginStateNotification.pluginStateEvolution(pluginStateEvolution); + logger.debug("Notifing Plugin State Evolution {} to {}.", pluginStateEvolution, pluginStateNotificationName); + pluginStateNotification.pluginStateEvolution(pluginStateEvolution, exception); } catch(Exception e) { - logger.error("Unable to Persist Plugin State Evolution {} with {}.", + logger.error("Unable to Notify Plugin State Evolution {} to {}.", pluginStateEvolution, pluginStateNotificationName); } } + actualStateEvolution = pluginStateEvolution; } @Override diff --git a/src/main/java/org/gcube/vremanagement/executor/scheduler/JobCompletedNotification.java b/src/main/java/org/gcube/vremanagement/executor/scheduler/JobCompletedNotification.java index 70ee6ec..5ed9449 100644 --- a/src/main/java/org/gcube/vremanagement/executor/scheduler/JobCompletedNotification.java +++ b/src/main/java/org/gcube/vremanagement/executor/scheduler/JobCompletedNotification.java @@ -3,6 +3,7 @@ */ package org.gcube.vremanagement.executor.scheduler; +import java.util.HashMap; import java.util.Map; import org.gcube.vremanagement.executor.plugin.PluginState; @@ -18,7 +19,7 @@ import org.gcube.vremanagement.executor.plugin.PluginStateNotification; * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ */ @Deprecated -public class JobCompletedNotification implements PluginStateNotification { +public class JobCompletedNotification extends PluginStateNotification { /** * Maintain the Execution State @@ -27,11 +28,12 @@ public class JobCompletedNotification implements PluginStateNotification { protected final Map executionsState; public JobCompletedNotification(Map executionsState){ + super(new HashMap()); this.executionsState = executionsState; } @Override - public void pluginStateEvolution(PluginStateEvolution pluginStateEvolution) throws Exception { + public void pluginStateEvolution(PluginStateEvolution pluginStateEvolution, Exception e) throws Exception { executionsState.put(pluginStateEvolution.getIteration(), pluginStateEvolution.getPluginState()); } diff --git a/src/main/java/org/gcube/vremanagement/executor/scheduler/SmartExecutorScheduler.java b/src/main/java/org/gcube/vremanagement/executor/scheduler/SmartExecutorScheduler.java index 75af07f..425bb95 100644 --- a/src/main/java/org/gcube/vremanagement/executor/scheduler/SmartExecutorScheduler.java +++ b/src/main/java/org/gcube/vremanagement/executor/scheduler/SmartExecutorScheduler.java @@ -12,8 +12,7 @@ import java.util.Map; import java.util.UUID; import org.gcube.common.resources.gcore.GCoreEndpoint; -import org.gcube.vremanagement.executor.SmartExecutorImpl; -//import org.gcube.smartgears.ContextProvider; +import org.gcube.smartgears.ContextProvider; import org.gcube.vremanagement.executor.api.types.LaunchParameter; import org.gcube.vremanagement.executor.api.types.Scheduling; import org.gcube.vremanagement.executor.configuration.ScheduledTaskConfiguration; @@ -151,8 +150,7 @@ public class SmartExecutorScheduler { } try { - //String runningInstanceID = ContextProvider.get().profile(GCoreEndpoint.class).id(); - String runningInstanceID = SmartExecutorImpl.getCtx().profile(GCoreEndpoint.class).id(); + String runningInstanceID = ContextProvider.get().profile(GCoreEndpoint.class).id(); logger.debug("Going to persist Scheduled Task {} which will be assigned to Running Instance {}. LaunchParameters : {} ", uuid.toString(), runningInstanceID, parameter); ScheduledTaskConfiguration stc = ScheduledTaskConfigurationFactory.getLaunchConfiguration(); @@ -227,17 +225,21 @@ public class SmartExecutorScheduler { logger.debug("No SmartExecutor Task {} was found. That's all folk.", uuid); throw new SchedulerNotFoundException("Scheduler Not Found"); } + boolean interrupted = scheduler.interrupt(jobKey); if (interrupted) { logger.debug("SmartExecutor Task {} interrupted successfully.", uuid); } else { - logger.debug("SmartExecutor Task {} was not interrupted.", uuid); - throw new UnableToInterruptTaskException(uuid); + List list = getCurrentlyExecutingJobs(scheduler); + if(list!=null && list.size()>0){ + logger.debug("SmartExecutor Task {} was not interrupted.", uuid); + throw new UnableToInterruptTaskException(uuid); + } } } catch (UnableToInterruptTaskException e) { throw e; - } catch(Exception e1){ - throw new UnableToInterruptTaskException(uuid, e1); + } catch(Exception e){ + throw new UnableToInterruptTaskException(uuid, e); } } @@ -272,9 +274,6 @@ public class SmartExecutorScheduler { protected List getCurrentlyExecutingJobs(Scheduler scheduler) throws SchedulerException{ logger.trace("Getting {} list", JobExecutionContext.class.getSimpleName()); List cej = scheduler.getCurrentlyExecutingJobs(); - while (cej.isEmpty()){ - cej = scheduler.getCurrentlyExecutingJobs(); - } logger.trace("{} list got {}", JobExecutionContext.class.getSimpleName(), cej); return cej; } @@ -286,6 +285,28 @@ public class SmartExecutorScheduler { } + protected void removeFromPersistence(boolean global, UUID uuid, boolean remove) throws SchedulePersistenceException{ + try { + ScheduledTaskConfiguration stc = ScheduledTaskConfigurationFactory.getLaunchConfiguration(); + if(remove){ + logger.debug("Going to remove the SmartExecutor Scheduled Task {} from global scheduling", uuid); + stc.removeScheduledTask(uuid); + }else{ + if(global){ + logger.debug("Going to release the SmartExecutor Scheduled Task {}. The Task can be take in charge from another SmartExecutor instance", uuid); + stc.releaseScheduledTask(uuid); + }else{ + logger.debug("Going to remove the SmartExecutor Scheduled Task {} from local scheduling", uuid); + stc.removeScheduledTask(uuid); + } + } + }catch(Exception e){ + throw new SchedulePersistenceException( + String.format("Unable to Remove Scheduled Task %s from global scheduling", + uuid.toString()), e); + } + } + /** * Stop the execution of the Task identified by UUID * @param uuid which identify the Task @@ -306,67 +327,37 @@ public class SmartExecutorScheduler { Scheduler scheduler = activeSchedulers.get(uuid); if(scheduler==null){ logger.debug("No SmartExecutor Task {} was found. That's all folk.", uuid); + removeFromPersistence(true, uuid, remove); return; } JobKey jobKey = new JobKey(uuid.toString()); boolean exist = scheduler.checkExists(jobKey); if(!exist){ - logger.trace("SmartExecutor Task {} does not have any instaces associated. Cleaning the envoronment. That's all folk.", uuid); + logger.trace("SmartExecutor Task {} does not have any instaces associated. Cleaning the environment. That's all folk.", uuid); activeSchedulers.remove(uuid); return; }else{ - logger.trace("SmartExecutor Task {} exist", uuid); + logger.trace("SmartExecutor Task {} to stop exist", uuid); } - // TODO Check if this call is needed - //getCurrentlyExecutingJobs(scheduler); - - stopLastcurrentExecution(scheduler, uuid); - LaunchParameter launchParameter = getLaunchParameter(scheduler, jobKey); Scheduling scheduling = launchParameter.getScheduling(); boolean scheduled = launchParameter.getScheduling() != null ? true : false; - - if(stopOnly){ - - - /* - * When the Task was not Scheduled, also the quartz scheduler - * must be removed. - * If the Task was scheduled, the inputs argument request to stop - * only the last running execution, so that the quartz scheduler - * must be keep alive to run the next execution. - */ - if(scheduled){ - deleteScheduler(scheduler, uuid); - } - - logger.debug("The request was only to stop the last execution (if any). That's all folk."); - return; - } + stopLastcurrentExecution(scheduler, uuid); try { - if(scheduled){ - ScheduledTaskConfiguration stc = ScheduledTaskConfigurationFactory.getLaunchConfiguration(); - if(remove){ - logger.debug("Going to remove the SmartExecutor Scheduled Task {} from global scheduling", uuid); - stc.removeScheduledTask(uuid); - }else{ - if(scheduling.getGlobal()){ - logger.debug("Going to release the SmartExecutor Scheduled Task {}. The Task can be take in charge from another SmartExecutor instance", uuid); - stc.releaseScheduledTask(uuid); - }else{ - logger.debug("Going to remove the SmartExecutor Scheduled Task {} from local scheduling", uuid); - stc.removeScheduledTask(uuid); - } - } + if(stopOnly ^ scheduled){ + deleteScheduler(scheduler, uuid); } }catch(Exception e){ - throw new SchedulePersistenceException(e.getCause()); + throw e; } finally { - deleteScheduler(scheduler, uuid); + if(!stopOnly && scheduled){ + /* Removing scheduling from persistence */ + removeFromPersistence(scheduling.getGlobal(), uuid, remove); + } } } diff --git a/src/main/java/org/gcube/vremanagement/executor/scheduler/SmartExecutorTask.java b/src/main/java/org/gcube/vremanagement/executor/scheduler/SmartExecutorTask.java index 8e42914..0e70fd0 100644 --- a/src/main/java/org/gcube/vremanagement/executor/scheduler/SmartExecutorTask.java +++ b/src/main/java/org/gcube/vremanagement/executor/scheduler/SmartExecutorTask.java @@ -3,6 +3,7 @@ */ package org.gcube.vremanagement.executor.scheduler; +import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -13,10 +14,12 @@ import org.gcube.vremanagement.executor.api.types.LaunchParameter; import org.gcube.vremanagement.executor.api.types.Scheduling; import org.gcube.vremanagement.executor.exception.AlreadyInFinalStateException; import org.gcube.vremanagement.executor.exception.InputsNullException; +import org.gcube.vremanagement.executor.exception.InvalidPluginStateEvolutionException; import org.gcube.vremanagement.executor.exception.PluginNotFoundException; import org.gcube.vremanagement.executor.exception.SchedulePersistenceException; import org.gcube.vremanagement.executor.exception.SchedulerRemoveException; import org.gcube.vremanagement.executor.exception.UnableToInterruptTaskException; +import org.gcube.vremanagement.executor.persistence.SmartExecutorPersistenceConnector; import org.gcube.vremanagement.executor.persistence.SmartExecutorPersistenceFactory; import org.gcube.vremanagement.executor.plugin.Plugin; import org.gcube.vremanagement.executor.plugin.PluginDeclaration; @@ -80,7 +83,7 @@ public class SmartExecutorTask implements InterruptableJob { protected int maxExecutionNumber; /**/ - @SuppressWarnings("deprecation") + @SuppressWarnings({ "deprecation", "unchecked" }) protected void init(JobDataMap jobDataMap) throws JobExecutionException{ uuid = (UUID) jobDataMap.get(UUID); launchParameter = (LaunchParameter) jobDataMap.get(LAUNCH_PARAMETER); @@ -98,6 +101,7 @@ public class SmartExecutorTask implements InterruptableJob { Scheduling scheduling = launchParameter.getScheduling(); if(scheduling!=null){ mustPreviousExecutionsCompleted = scheduling.mustPreviousExecutionsCompleted(); + if(mustPreviousExecutionsCompleted){ Map executionState; if(executionsState.containsKey(uuid)){ @@ -107,16 +111,39 @@ public class SmartExecutorTask implements InterruptableJob { executionsState.put(uuid, executionState); executionState.put(0, PluginState.DONE); } - - // TODO Insert code to dynamically discover notification to - // attach and attach the requested ones. - // The following line of code is just a placeholder and must be - // removed when the previous TO DO has done. pluginStateNotifications.add(new JobCompletedNotification(executionState)); } maxExecutionNumber = scheduling.getSchedulingTimes(); + // TODO Insert code to dynamically discover notification to + // attach and attach the requested ones. + // pluginStateNotifications.add(...); + } + + Map> pluginStateNotificationWithInputs = launchParameter.getPluginStateNotifications(); + for(String pluginStateNotificationsClassName : pluginStateNotificationWithInputs.keySet()){ + if(pluginStateNotificationsClassName.compareTo(SmartExecutorPersistenceConnector.class.getName())==0) { + logger.warn("{} is for internal use only. It will be skypped", pluginStateNotificationsClassName); + continue; + } + if(pluginStateNotificationsClassName.compareTo(JobCompletedNotification.class.getName())==0){ + logger.warn("{} is for internal use only. It will be skypped", pluginStateNotificationsClassName); + continue; + } + Class clazz; + try { + logger.trace("Trying to instantiate {}", pluginStateNotificationsClassName); + clazz = (Class) Class.forName(pluginStateNotificationsClassName); + Constructor constructor = clazz.getConstructor(Map.class); + Map notificationInputs = pluginStateNotificationWithInputs.get(pluginStateNotificationsClassName); + PluginStateNotification pluginStateNotification = (PluginStateNotification) constructor.newInstance(notificationInputs); + logger.trace("{} succesfully instantiated : {}", pluginStateNotificationsClassName, pluginStateNotification); + pluginStateNotifications.add(pluginStateNotification); + } catch (Exception e) { + logger.error("Error instantiating {} : {}. It will be ignored", pluginStateNotificationsClassName, e.getMessage()); + } + } initialized = true; @@ -128,8 +155,8 @@ public class SmartExecutorTask implements InterruptableJob { public SmartExecutorTask() throws Exception { this.interrupted = false; this.initialized = false; - pluginStateNotifications = new ArrayList(); - pluginStateNotifications.add(SmartExecutorPersistenceFactory.getPersistenceConnector()); + this.pluginStateNotifications = new ArrayList(); + this.pluginStateNotifications.add(SmartExecutorPersistenceFactory.getPersistenceConnector()); } /** @@ -217,7 +244,7 @@ public class SmartExecutorTask implements InterruptableJob { notTerminatedExecutionNumber, executionCount); try { runnablePlugin.setState(PluginState.DISCARDED); - } catch (AlreadyInFinalStateException e) { } + } catch (AlreadyInFinalStateException | InvalidPluginStateEvolutionException e) { } } }else{ runnablePlugin.run(); diff --git a/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.application.ApplicationHandler b/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.application.ApplicationHandler deleted file mode 100644 index 874ac97..0000000 --- a/src/main/resources/META-INF/services/org.gcube.smartgears.handlers.application.ApplicationHandler +++ /dev/null @@ -1 +0,0 @@ -org.gcube.vremanagement.executor.SmartExecutorInitializator \ No newline at end of file diff --git a/src/test/java/org/gcube/vremanagement/executor/TokenBasedTests.java b/src/test/java/org/gcube/vremanagement/executor/TokenBasedTests.java new file mode 100644 index 0000000..4b60f6c --- /dev/null +++ b/src/test/java/org/gcube/vremanagement/executor/TokenBasedTests.java @@ -0,0 +1,22 @@ +/** + * + */ +package org.gcube.vremanagement.executor; + +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.scope.api.ScopeProvider; +import org.junit.Before; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class TokenBasedTests { + + @Before + public void before(){ + SecurityTokenProvider.instance.set("7c66c94c-7f6e-49cd-9a34-909cd3832f3e-98187548"); + ScopeProvider.instance.set("/gcube/devNext/NextNext"); + } + +} diff --git a/src/test/java/org/gcube/vremanagement/executor/configuration/ConfiguredTasksTest.java b/src/test/java/org/gcube/vremanagement/executor/configuration/ConfiguredTasksTest.java index ed29ec8..0e0f423 100644 --- a/src/test/java/org/gcube/vremanagement/executor/configuration/ConfiguredTasksTest.java +++ b/src/test/java/org/gcube/vremanagement/executor/configuration/ConfiguredTasksTest.java @@ -12,6 +12,7 @@ import java.util.Map; import org.acme.HelloWorldPlugin; import org.acme.HelloWorldPluginDeclaration; +import org.gcube.vremanagement.executor.TokenBasedTests; import org.gcube.vremanagement.executor.api.types.LaunchParameter; import org.gcube.vremanagement.executor.api.types.Scheduling; import org.gcube.vremanagement.executor.configuration.jsonbased.FileScheduledTaskConfiguration; @@ -27,12 +28,13 @@ import org.slf4j.LoggerFactory; * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ -public class ConfiguredTasksTest { +public class ConfiguredTasksTest extends TokenBasedTests { private static Logger logger = LoggerFactory.getLogger(ConfiguredTasksTest.class); public static final String TEST = "test"; + public void checkOriginal(FileScheduledTaskConfiguration parser, int size){ List configuredTasks = parser.getConfiguredTasks(); Assert.assertEquals(size, configuredTasks.size()); diff --git a/src/test/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConnectorTest.java b/src/test/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConnectorTest.java index e686c48..1d2fe57 100644 --- a/src/test/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConnectorTest.java +++ b/src/test/java/org/gcube/vremanagement/executor/persistence/SmartExecutorPersistenceConnectorTest.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.UUID; import org.acme.HelloWorldPluginDeclaration; +import org.gcube.vremanagement.executor.TokenBasedTests; import org.gcube.vremanagement.executor.api.types.LaunchParameter; import org.gcube.vremanagement.executor.configuration.ScheduledTaskConfiguration; import org.gcube.vremanagement.executor.configuration.ScheduledTaskConfigurationFactory; @@ -24,7 +25,7 @@ import org.slf4j.LoggerFactory; * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ -public class SmartExecutorPersistenceConnectorTest { +public class SmartExecutorPersistenceConnectorTest extends TokenBasedTests { private static Logger logger = LoggerFactory.getLogger(SmartExecutorPersistenceConnectorTest.class); @@ -45,8 +46,8 @@ public class SmartExecutorPersistenceConnectorTest { for(int i=0; i