Compare commits

...

16 Commits

Author SHA1 Message Date
Luca Frosini 74dae88836 Upgraded gcube-smartgears-bom version 2024-05-08 17:55:10 +02:00
Luca Frosini 93457fe823 Trying different solution 2024-05-07 16:50:51 +02:00
Luca Frosini 81002fccd1 Added log 2024-05-07 16:38:53 +02:00
Luca Frosini 940d0cba9d Downgraded gcube-smartgears-bom 2024-05-07 14:32:02 +02:00
Luca Frosini 85a92bac67 Fixed changelog 2024-05-07 11:58:30 +02:00
Luca Frosini cecc27920c Fixed changelog 2024-05-07 11:56:36 +02:00
Luca Frosini 40166c4116 updated gcube-smartgears-bom version 2024-05-07 11:55:22 +02:00
Luca Frosini 5bad218e6e Resolving bug #24116 2024-05-07 11:45:33 +02:00
Luca Frosini 840bd00275 Resolving bug #27319 2024-05-07 11:45:16 +02:00
luca.frosini e664ac8388 Removed -SNAPSHOT to release the component 2023-09-12 14:47:24 +02:00
luca.frosini 6ce80b4abe Restored guava explicit version 2023-09-08 11:22:57 +02:00
luca.frosini 2a5ef59c53 Commented explicit guava version 2023-09-08 11:10:54 +02:00
luca.frosini af41a518cf Improving service 2023-09-07 16:40:10 +02:00
luca.frosini b3efedeb1f using -SNAPSHOT version of bom 2023-09-06 15:59:19 +02:00
luca.frosini f037dd4761 Fixed code 2023-09-06 15:05:18 +02:00
luca.frosini ae7a628829 Ignored MacOs File 2023-06-21 11:46:17 +02:00
17 changed files with 1595 additions and 35 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
target
.classpath
.project
/.DS_Store
/bin/

View File

@ -2,10 +2,24 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
# Changelog for Smart Executor Service
## [v3.2.1-SNAPSHOT]
- Fixed bug on concurrent attempt to enter in a session while trying to schedule a second task #27319
- Fixed bug on concurrent attempt to enter in a session while trying to execute another task #24116
## [v3.2.0]
- Fixed RequestFilter to avoid to remove info to Smartgears
- Migrated code to reorganized E/R format [#24992]
- Force guava version to 23.6-jre to meet requirements of new plugins
## [v3.1.0]
- Ported service to authorization-utils [#22871]
## [v3.0.0]
- Switched smart-executor JSON management to gcube-jackson [#19647]
@ -13,6 +27,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Redesigned HTTP APIs to comply with RESTful architectural style [#12997]
- Added API to retrieve scheduled tasks [#10780]
## [v2.0.0]
- Removed SOAP APIs

1
docs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/_build/

20
docs/Makefile Normal file
View File

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

54
docs/conf.py Normal file
View File

@ -0,0 +1,54 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'Smart Executor Service'
copyright = '2012, Luca Frosini (ISTI-CNR)'
author = 'Luca Frosini (ISTI-CNR)'
# The full version, including alpha/beta/rc tags
release = '3.2.0'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinxdoc'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

103
docs/index.rst Normal file
View File

@ -0,0 +1,103 @@
***********************************************************
Welcome to Smart Executor Service documentation
***********************************************************
Smart Executor is a RESTful application which exposes operations via REST-API.
See the available `REST-API docs <../api-docs/index.html>`_.
Authorization
=============
D4Science adopts state-of-the-art industry standards for authentication and authorization.
Specifically, the implementation fully adopts `OIDC (OpenID Connect) <https://openid.net/connect>`_ for authentication and UMA 2 (User-Managed Authorization) for authorization flows.
`JSON Web Token (JWT) Access token <https://jwt.io/>`_ are used for both authentication and authorization.
Obtain your Bearer token here: https://dev.d4science.org/how-to-access-resources
Service
=======
You can call the methods of the Web Service by writing your own REST client application or using existing REST client plugins.
HTTP Statuses
-------------
Any successful operation returns *200 OK* HTTP status code.
The create operation returns *201 Created*.
Any Background operation returns *202 Accepted*.
Any operation which does not provide any content return *204 No Content*.
The most common error status a client can obtain are:
* **400 Bad Request** used to indicate a clients error `<https://tools.ietf.org/html/rfc7231#section-6.5.1>`_;
* **401 Unauthorized** used to indicate that the client does not provide the authorization token in the HTTP Header or the client has not enough right to perform such request `<https://tools.ietf.org/html/rfc7235#section-3.1>`_;
* **404 Not Found** used to indicate that the requested instance does not exist `<https://tools.ietf.org/html/rfc7231#section-6.5.4>`_;
* **405 Method Not Allowed** the used HTTP method is not supported for the requested URL `<https://tools.ietf.org/html/rfc7231#section-6.5.5>`_.
The response contains the *Allow* HTTP Header indicating the supported HTTP method for such URL `<https://tools.ietf.org/html/rfc7231#section-7.4.1>`_;
* **409 Conflict** the request could not be completed due to a conflict with the current state of the target resource (e.g. the name of the resource already exists) `<https://tools.ietf.org/html/rfc7231#section-6.5.8>`_;
* **500 Internal Server Error** indicate a server failure `<https://tools.ietf.org/html/rfc7231#section-6.6.1>`_.
You can find a complete list of HTTP Status at `<https://httpstatuses.com/>`_
If you get a *500 Internal Server Error*, please report it in the `gCube ticketing system <https://support.d4science.org>`_.
Please use this checklist before reporting an error:
* Replicate the request;
* The failure could be temporal due to network error, server issue and many other temporal issues. For this reason, please retry the request after a certain amount of time before reporting the issue;
* indicate how to replicate the error;
* indicate the time when the error occurred (this simplifies identifying the issue).
HTTP Methods
------------
Smart Executor is a pure RESTful service.
Service Discovery on IS
=======================
The service can be discovered in the gCore IS as gCore Endpoint with the following parameter:
.. code:: xml
<ServiceClass>org.gcube.vremanagement</ServiceClass>
<ServiceName>smart-executor</ServiceName>
The service can be discovered in the Facet Based IS as EService with the following json query:
.. code:: json
{
"@class": "EService",
"consistsOf": [
{
"@class": "IsIdentifiedBy",
"target": {
"@class": "SoftwareFacet",
"group": "org.gcube.vremanagement",
"name": "smart-executor"
}
}
]
}
Service Maven Coordinates
=========================
The maven coordinates of gCat service are:
.. code:: xml
<groupId>org.gcube.vremanagement</groupId>
<artifactId>smart-executor</artifactId>

35
docs/make.bat Normal file
View File

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

View File

@ -5,4 +5,6 @@
<group>${project.groupId}</group>
<version>${project.version}</version>
<description>${project.description}</description>
<exclude>/api-docs.*</exclude>
<exclude>/docs.*</exclude>
</application>

135
pom.xml
View File

@ -11,7 +11,7 @@
<groupId>org.gcube.vremanagement</groupId>
<artifactId>smart-executor</artifactId>
<version>3.1.0</version>
<version>3.2.1-SNAPSHOT</version>
<name>SmartExecutor</name>
<description>Smart Executor Service allows to launch recurrent tasks such as task for infrastructure management, healthy monitoring etc.</description>
<packaging>war</packaging>
@ -20,6 +20,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<webappDirectory>${project.basedir}${file.separator}src${file.separator}main${file.separator}webapp${file.separator}WEB-INF</webappDirectory>
<orientdb.version>3.1.12</orientdb.version>
<enunciate.version>2.14.0</enunciate.version>
</properties>
<scm>
@ -33,7 +34,7 @@
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-smartgears-bom</artifactId>
<version>2.2.0</version>
<version>2.5.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -104,29 +105,63 @@
<artifactId>smart-executor-client</artifactId>
<version>[3.0.0, 4.0.0-SNAPSHOT)</version>
</dependency>
<!-- Jersey -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.6-jre</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</dependency>
<!-- Added to support Java 11 JDK -->
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- END Jersey -->
<!-- END Added to support Java 11 JDK -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- Required for Enunciate plugin -->
<dependency>
<groupId>com.webcohesion.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
<version>${enunciate.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.webcohesion.enunciate</groupId>
<artifactId>enunciate-rt-util</artifactId>
<version>${enunciate.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- END Required for Enunciate plugin -->
<!-- Tests -->
<dependency>
<groupId>junit</groupId>
@ -141,4 +176,80 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Sphinx plugin' -->
<plugin>
<groupId>kr.motd.maven</groupId>
<artifactId>sphinx-maven-plugin</artifactId>
<version>2.10.0</version>
<configuration>
<outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/docs</outputDirectory>
<builder>html</builder>
<configDirectory>${basedir}/docs</configDirectory>
<sourceDirectory>${basedir}/docs</sourceDirectory>
</configuration>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Enunciate Maven plugin -->
<plugin>
<groupId>com.webcohesion.enunciate</groupId>
<artifactId>enunciate-maven-plugin</artifactId>
<version>${enunciate.version}</version>
<executions>
<execution>
<id>assemble</id>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Copy Enunciate Documentation from your-application/api-docs into your war -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-enunciate-docs</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target</outputDirectory>
<resources>
<resource>
<targetPath>${project.build.directory}/${project.artifactId}-${project.version}/api-docs</targetPath>
<directory>${project.build.directory}/api-docs</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -148,24 +148,27 @@ public class SmartExecutorInitializator implements ApplicationManager {
Secret secret = SecretUtility.getSecretByTokenString(scheduledTasktoken);
SecretManager secretManager = SecretManagerProvider.instance.get();
try {
secretManager.startSession(secret);
SmartExecutorScheduler smartExecutorScheduler = SmartExecutorSchedulerFactory.getSmartExecutorScheduler();
// A new Scheduled Task will be persisted due to launch. Removing it
smartExecutorPersistenceConnector.removeScheduledTask(scheduledTask);
smartExecutorScheduler.schedule(launchParameter, scheduledTask.getUUID());
} catch (Exception e) {
logger.error("({}) Error while trying to relaunch scheduled task.", context, e);
synchronized (secretManager) {
try {
smartExecutorPersistenceConnector.addScheduledTask(scheduledTask);
} catch (Exception ex) {
logger.error("({}) Unable to add back scheduled task {}", context, taskAsString);
logger.trace("Starting a Secret Manager session (synchronized block)...");
secretManager.startSession(secret);
SmartExecutorScheduler smartExecutorScheduler = SmartExecutorSchedulerFactory.getSmartExecutorScheduler();
// A new Scheduled Task will be persisted due to launch. Removing it
smartExecutorPersistenceConnector.removeScheduledTask(scheduledTask);
smartExecutorScheduler.schedule(launchParameter, scheduledTask.getUUID());
} catch (Exception e) {
logger.error("({}) Error while trying to relaunch scheduled task.", context, e);
try {
smartExecutorPersistenceConnector.addScheduledTask(scheduledTask);
} catch (Exception ex) {
logger.error("({}) Unable to add back scheduled task {}", context, taskAsString);
}
}finally {
secretManager.endSession();
logger.trace("Secret Manager session terminated (synchronized block).");
}
}finally {
secretManager.endSession();
}
}
};

View File

@ -9,7 +9,6 @@ import java.util.Map;
import java.util.UUID;
import org.gcube.informationsystem.base.reference.Direction;
import org.gcube.informationsystem.model.impl.properties.HeaderImpl;
import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl;
import org.gcube.informationsystem.model.reference.entities.Facet;
import org.gcube.informationsystem.model.reference.entities.Resource;
@ -151,7 +150,7 @@ public class RestISPublisher extends ISPublisher {
protected RunningPlugin publishRunningPluginWithRelations(Plugin plugin, UUID pluginUUID) throws Exception {
RunningPlugin runningPlugin = new RunningPluginImpl();
runningPlugin.setHeader(new HeaderImpl(pluginUUID));
runningPlugin.setID(pluginUUID);
SoftwareFacet softwareFacet = new SoftwareFacetImpl();
softwareFacet.setGroup(plugin.getGroup());
@ -240,7 +239,7 @@ public class RestISPublisher extends ISPublisher {
runningPlugin = publishRunningPluginWithRelations(plugin, pluginUUID);
} catch (AvailableInAnotherContextException e) {
runningPlugin = new RunningPluginImpl();
runningPlugin.setHeader(new HeaderImpl(pluginUUID));
runningPlugin.setID(pluginUUID);
resourceRegistryPublisher.addToCurrentContext(runningPlugin, false);
} catch (ResourceRegistryException e) {
throw e;

View File

@ -75,7 +75,7 @@ public class RunnablePlugin<T extends Plugin> implements Runnable {
@Override
public void run(){
public synchronized void run(){
String pluginName = plugin.getName();
logger.info("{} : {} is going to be launched (UUID={}, iterationNumber={}) with the following inputs {}",
@ -85,10 +85,10 @@ public class RunnablePlugin<T extends Plugin> implements Runnable {
JobUsageRecord jobUsageRecord = new JobUsageRecord();
long startTime = actualStateEvolution.getTimestamp();
Secret secret = SecretUtility.getSecretByTokenString(token);
SecretManager secretManager = SecretManagerProvider.instance.get();
try {
Secret secret = SecretUtility.getSecretByTokenString(token);
secretManager.startSession(secret);
setState(PluginState.RUNNING);

View File

@ -32,7 +32,7 @@ public class RequestFilter implements ContainerRequestFilter, ContainerResponseF
public void filter(ContainerRequestContext requestContext) throws IOException {
logger.trace("PreMatching RequestFilter");
SecretManagerProvider.instance.reset();
SecretManagerProvider.instance.remove();
SecretManager secretManager = new SecretManager();
String token = AccessTokenProvider.instance.get();
@ -48,14 +48,13 @@ public class RequestFilter implements ContainerRequestFilter, ContainerResponseF
}
SecretManagerProvider.instance.set(secretManager);
}
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
logger.trace("ResponseFilter");
SecretManagerProvider.instance.reset();
SecretManagerProvider.instance.remove();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,14 @@
<servlet>
<servlet-name>org.gcube.vremanagement.executor.ResourceInitializer</servlet-name>
</servlet>
<servlet-mapping>
2 <servlet-name>default</servlet-name>
3 <url-pattern>/docs/*</url-pattern>
4 </servlet-mapping>
<servlet-mapping>
2 <servlet-name>default</servlet-name>
3 <url-pattern>/api-docs/*</url-pattern>
4 </servlet-mapping>
<servlet-mapping>
<servlet-name>org.gcube.vremanagement.executor.ResourceInitializer</servlet-name>
<url-pattern>/*</url-pattern>

View File

@ -0,0 +1,25 @@
.d4science_intro {
top: 0;
z-index: 2000;
position: fixed;
display: block ruby;
padding: 10px;
background: white;
width: 100%;
}
.navbar-fixed-top {
top: 100px !important;
}
.sidebar {
top: 160px !important;
}
.navbar {
margin-bottom: 40px !important;
}
.main {
top: 90px;
}

View File

@ -6,7 +6,7 @@ import java.util.UUID;
import javax.servlet.ServletContext;
import org.gcube.common.events.Hub;
import org.gcube.informationsystem.utils.ElementMapper;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.gcube.resourcemanagement.model.impl.entities.facets.AccessPointFacetImpl;
import org.gcube.resourcemanagement.model.reference.entities.facets.AccessPointFacet;
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;