git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/branches/data-transfer/data-transfer-service/2.0@148792 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
commit
6db6c31cbe
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
|
</classpath>
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>data-transfer-service</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||||
|
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||||
|
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||||
|
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src/main/webapp"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="hide" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
|
||||||
|
<classpathentry kind="output" path=""/>
|
||||||
|
</classpath>
|
|
@ -0,0 +1,6 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding//src/main/java=UTF-8
|
||||||
|
encoding//src/main/resources=UTF-8
|
||||||
|
encoding//src/test/java=UTF-8
|
||||||
|
encoding//src/test/resources=UTF-8
|
||||||
|
encoding/<project>=UTF-8
|
|
@ -0,0 +1,8 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.7
|
|
@ -0,0 +1,4 @@
|
||||||
|
activeProfiles=
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
resolveWorkspaceProjects=false
|
||||||
|
version=1
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||||
|
<wb-module deploy-name="data-transfer-service">
|
||||||
|
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
|
||||||
|
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
||||||
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||||
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||||
|
<property name="context-root" value="data-transfer-service"/>
|
||||||
|
<property name="java-output-path" value="/data-transfer-service/target/classes"/>
|
||||||
|
</wb-module>
|
||||||
|
</project-modules>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<root>
|
||||||
|
<facet id="jst.jaxrs">
|
||||||
|
<node name="libprov">
|
||||||
|
<attribute name="provider-id" value="jaxrs-no-op-library-provider"/>
|
||||||
|
</node>
|
||||||
|
</facet>
|
||||||
|
</root>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<faceted-project>
|
||||||
|
<fixed facet="wst.jsdt.web"/>
|
||||||
|
<installed facet="java" version="1.7"/>
|
||||||
|
<installed facet="wst.jsdt.web" version="1.0"/>
|
||||||
|
<installed facet="jst.web" version="3.0"/>
|
||||||
|
<installed facet="jst.jaxrs" version="2.0"/>
|
||||||
|
</faceted-project>
|
|
@ -0,0 +1 @@
|
||||||
|
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
|
|
@ -0,0 +1 @@
|
||||||
|
Window
|
|
@ -0,0 +1,2 @@
|
||||||
|
disabled=06target
|
||||||
|
eclipse.preferences.version=1
|
|
@ -0,0 +1 @@
|
||||||
|
${gcube.license}
|
|
@ -0,0 +1,65 @@
|
||||||
|
The gCube System - ${name}
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
${description}
|
||||||
|
|
||||||
|
|
||||||
|
${gcube.description}
|
||||||
|
|
||||||
|
${gcube.funding}
|
||||||
|
|
||||||
|
|
||||||
|
Version
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
${version} (${buildDate})
|
||||||
|
|
||||||
|
Please see the file named "changelog.xml" in this directory for the release notes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Authors
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
* Fabio Sinibaldi (fabio.sinibaldi-AT-isti.cnr.it) Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||||
|
|
||||||
|
Maintainers
|
||||||
|
-----------
|
||||||
|
|
||||||
|
* Fabio Sinibaldi (fabio.sinibaldi-AT-isti.cnr.it) Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||||
|
|
||||||
|
|
||||||
|
Download information
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Source code is available from SVN:
|
||||||
|
${scm.url}
|
||||||
|
|
||||||
|
Binaries can be downloaded from the gCube website:
|
||||||
|
${gcube.website}
|
||||||
|
|
||||||
|
Installation
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Installation documentation is available on-line in the gCube Wiki:
|
||||||
|
${gcube.wikiRoot}/Data_Transfer_2
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Documentation is available on-line in the gCube Wiki:
|
||||||
|
${gcube.wikiRoot}/Data_Transfer_2
|
||||||
|
${gcube.wikiRoot}/How_to_use_Data_Transfer_2
|
||||||
|
|
||||||
|
|
||||||
|
Support
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Bugs and support requests can be reported in the gCube issue tracking tool:
|
||||||
|
${gcube.issueTracking}
|
||||||
|
|
||||||
|
|
||||||
|
Licensing
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
This software is licensed under the terms you may find in the file named "LICENSE" in this directory.
|
|
@ -0,0 +1,13 @@
|
||||||
|
<ReleaseNotes>
|
||||||
|
<Changeset component="data-transfer-service-1.0.0" date="2016-02-22">
|
||||||
|
<Change>First Release</Change>
|
||||||
|
</Changeset>
|
||||||
|
<Changeset component="data-transfer-service-1.1.0" date="2016-09-09">
|
||||||
|
<Change>Added Destination</Change>
|
||||||
|
<Change>Added Plugin</Change>
|
||||||
|
</Changeset>
|
||||||
|
<Changeset component="data-transfer-service-1.2.0" date="2016-10-29">
|
||||||
|
<Change>Improved plugin management</Change>
|
||||||
|
<Change>Endorsed decompress-plugin</Change>
|
||||||
|
</Changeset>
|
||||||
|
</ReleaseNotes>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<id>servicearchive</id>
|
||||||
|
<formats>
|
||||||
|
<format>tar.gz</format>
|
||||||
|
</formats>
|
||||||
|
<baseDirectory>/</baseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>${distroDirectory}</directory>
|
||||||
|
<outputDirectory>/</outputDirectory>
|
||||||
|
<useDefaultExcludes>true</useDefaultExcludes>
|
||||||
|
<includes>
|
||||||
|
<include>README</include>
|
||||||
|
<include>LICENSE</include>
|
||||||
|
<include>changelog.xml</include>
|
||||||
|
</includes>
|
||||||
|
<fileMode>755</fileMode>
|
||||||
|
<filtered>true</filtered>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
<files>
|
||||||
|
<file>
|
||||||
|
<source>target/${build.finalName}.${project.packaging}</source>
|
||||||
|
<outputDirectory>/${artifactId}</outputDirectory>
|
||||||
|
</file>
|
||||||
|
</files>
|
||||||
|
</assembly>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<application mode='online'>
|
||||||
|
<name>data-transfer-service</name>
|
||||||
|
<group>DataTransfer</group>
|
||||||
|
<version>${version}</version>
|
||||||
|
<description>Data Tansfer Service</description>
|
||||||
|
<!-- <servlets>
|
||||||
|
<servlet name="org.gcube.data.analysis.rconnector.RConnector" entryPointName="connector"/>
|
||||||
|
</servlets> -->
|
||||||
|
<local-persistence location='target' />
|
||||||
|
</application>
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<ID />
|
||||||
|
<Type>Service</Type>
|
||||||
|
<Profile>
|
||||||
|
<Description>${description}</Description>
|
||||||
|
<Class>DataTransfer</Class>
|
||||||
|
<Name>${artifactId}</Name>
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
<Packages>
|
||||||
|
<Software>
|
||||||
|
<Name>${artifactId}</Name>
|
||||||
|
<Version>${version}</Version>
|
||||||
|
<MavenCoordinates>
|
||||||
|
<groupId>${groupId}</groupId>
|
||||||
|
<artifactId>${artifactId}</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</MavenCoordinates>
|
||||||
|
<Files>
|
||||||
|
<File>${build.finalName}.jar</File>
|
||||||
|
</Files>
|
||||||
|
</Software>
|
||||||
|
</Packages>
|
||||||
|
</Profile>
|
||||||
|
</Resource>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,245 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.gcube.tools</groupId>
|
||||||
|
<artifactId>maven-parent</artifactId>
|
||||||
|
<version>LATEST</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.gcube.data.transfer</groupId>
|
||||||
|
<artifactId>data-transfer-service</artifactId>
|
||||||
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>DataTransferService</name>
|
||||||
|
<scm>
|
||||||
|
<url>https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-transfer/${project.artifactId}</url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<webappDirectory>${project.basedir}/src/main/webapp/WEB-INF</webappDirectory>
|
||||||
|
<distroDirectory>${project.basedir}/distro</distroDirectory>
|
||||||
|
<jersey-version>2.14</jersey-version>
|
||||||
|
<jersey-cdi-version>2.14</jersey-cdi-version>
|
||||||
|
<weld-version>2.2.4.Final</weld-version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.distribution</groupId>
|
||||||
|
<artifactId>maven-smartgears-bom</artifactId>
|
||||||
|
<version>LATEST</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.data.transfer</groupId>
|
||||||
|
<artifactId>data-transfer-plugin-framework</artifactId>
|
||||||
|
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- PLUGINS -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.data.transfer</groupId>
|
||||||
|
<artifactId>decompress-archive-plugin</artifactId>
|
||||||
|
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- SMARTGEARS -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.core</groupId>
|
||||||
|
<artifactId>common-smartgears-app</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.core</groupId>
|
||||||
|
<artifactId>common-smartgears</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- jersey -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.ws.rs</groupId>
|
||||||
|
<artifactId>javax.ws.rs-api</artifactId>
|
||||||
|
<version>2.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.containers</groupId>
|
||||||
|
<artifactId>jersey-container-servlet</artifactId>
|
||||||
|
<version>${jersey-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.containers.glassfish</groupId>
|
||||||
|
<artifactId>jersey-gf-cdi</artifactId>
|
||||||
|
<version>${jersey-cdi-version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.transaction</groupId>
|
||||||
|
<artifactId>javax.transaction-api</artifactId>
|
||||||
|
<version>1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>3.0.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
|
<artifactId>jersey-media-json-jackson</artifactId>
|
||||||
|
<version>${jersey-version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <dependency> -->
|
||||||
|
<!-- <groupId>org.glassfish.jersey.media</groupId> -->
|
||||||
|
<!-- <artifactId>jersey-media-moxy</artifactId> -->
|
||||||
|
<!-- <version>2.25.1</version> -->
|
||||||
|
<!-- </dependency> -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
|
<artifactId>jersey-media-multipart</artifactId>
|
||||||
|
<version>${jersey-version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.bundles</groupId>
|
||||||
|
<artifactId>jaxrs-ri</artifactId>
|
||||||
|
<version>${jersey-version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.core</groupId>
|
||||||
|
<artifactId>jersey-common</artifactId>
|
||||||
|
<version>${jersey-version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- weld -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.enterprise</groupId>
|
||||||
|
<artifactId>cdi-api</artifactId>
|
||||||
|
<version>1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.weld.servlet</groupId>
|
||||||
|
<artifactId>weld-servlet</artifactId>
|
||||||
|
<version>${weld-version}</version> <!-- 2.0.4 doesn't find implementations. 2.2.4 doesn't find CDI... -->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss</groupId>
|
||||||
|
<artifactId>jandex</artifactId>
|
||||||
|
<version>1.2.2.Final</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.0.13</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
|
||||||
|
<artifactId>jersey-test-framework-provider-simple</artifactId>
|
||||||
|
<version>${jersey-version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>2.3.2</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.7</source>
|
||||||
|
<target>1.7</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
<configuration>
|
||||||
|
<warName>data-transfer-service</warName>
|
||||||
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>2.6</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-profile</id>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<phase>process-resources</phase>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${webappDirectory}</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${distroDirectory}</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>${distroDirectory}/descriptor.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>servicearchive</id>
|
||||||
|
<phase>install</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<description>Service used to receive data from other hosting nodes</description>
|
||||||
|
</project>
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import javax.ws.rs.ApplicationPath;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.ServiceConstants;
|
||||||
|
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
|
||||||
|
@ApplicationPath(ServiceConstants.APPLICATION_PATH)
|
||||||
|
public class DTService extends ResourceConfig{
|
||||||
|
|
||||||
|
public DTService() {
|
||||||
|
super();
|
||||||
|
packages("org.gcube.data.transfer.service.transfers");
|
||||||
|
packages("org.glassfish.jersey.media.multipart");
|
||||||
|
packages("org.glassfish.jersey.media.multipart.internal");
|
||||||
|
// register(ProviderLoggingListener.class);
|
||||||
|
register(MultiPartFeature.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.RequestManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.TicketManager;
|
||||||
|
import org.gcube.smartgears.ApplicationManager;
|
||||||
|
import org.gcube.smartgears.ContextProvider;
|
||||||
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class DTServiceAppManager implements ApplicationManager {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RequestManager requests;
|
||||||
|
@Inject
|
||||||
|
TicketManager tickets;
|
||||||
|
|
||||||
|
ApplicationContext ctx = ContextProvider.get();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInit() {
|
||||||
|
log.info("DT Application init");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onShutdown() {
|
||||||
|
log.info("DT Application shutdown");
|
||||||
|
log.debug("Shutting down request manager ...");
|
||||||
|
requests.shutdown();
|
||||||
|
log.debug("Shutting down ticket manager");
|
||||||
|
tickets.shutdown();
|
||||||
|
log.info("Done");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
import org.glassfish.jersey.server.model.ResourceModel;
|
||||||
|
import org.glassfish.jersey.server.monitoring.ApplicationEvent;
|
||||||
|
import org.glassfish.jersey.server.monitoring.ApplicationEventListener;
|
||||||
|
import org.glassfish.jersey.server.monitoring.RequestEvent;
|
||||||
|
import org.glassfish.jersey.server.monitoring.RequestEventListener;
|
||||||
|
|
||||||
|
@Provider
|
||||||
|
public class ProviderLoggingListener implements ApplicationEventListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEvent(ApplicationEvent event) {
|
||||||
|
switch (event.getType()) {
|
||||||
|
case INITIALIZATION_FINISHED: {
|
||||||
|
System.out.println("*************** LISTING PROVIDERS ******************");
|
||||||
|
|
||||||
|
for(Class c: event.getProviders()){
|
||||||
|
System.out.println(c.getCanonicalName()+" \t "+ c);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("*************** RESOURCE CONFIG ******************");
|
||||||
|
System.out.println(event.getResourceConfig());
|
||||||
|
System.out.println("*************** RESOURCE MODEL ******************");
|
||||||
|
System.out.println(event.getResourceModel());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestEventListener onRequest(RequestEvent requestEvent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.ServiceConstants;
|
||||||
|
import org.gcube.data.transfer.model.TransferCapabilities;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.CapabilitiesProvider;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Path(ServiceConstants.CAPABILTIES_SERVLET_NAME)
|
||||||
|
public class Capabilities {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CapabilitiesProvider provider;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public TransferCapabilities getCapabilities(){
|
||||||
|
log.debug("Serving get capabilities");
|
||||||
|
try{
|
||||||
|
TransferCapabilities toReturn=provider.get();
|
||||||
|
log.debug("No exceptions here.. returning "+toReturn);
|
||||||
|
return toReturn;
|
||||||
|
}catch(Exception e){
|
||||||
|
log.debug("Unable to return capabilities.",e);
|
||||||
|
throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.Destination;
|
||||||
|
import org.gcube.data.transfer.model.DestinationClashPolicy;
|
||||||
|
import org.gcube.data.transfer.model.ServiceConstants;
|
||||||
|
import org.gcube.data.transfer.model.TransferRequest;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.model.options.FileUploadOptions;
|
||||||
|
import org.gcube.data.transfer.model.options.HttpDownloadOptions;
|
||||||
|
import org.gcube.data.transfer.model.options.TransferOptions.TransferMethod;
|
||||||
|
import org.gcube.data.transfer.model.settings.FileUploadSettings;
|
||||||
|
import org.gcube.data.transfer.model.settings.HttpDownloadSettings;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.RequestManager;
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Path(ServiceConstants.REST_SERVLET_NAME)
|
||||||
|
@Slf4j
|
||||||
|
public class REST {
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RequestManager requests;
|
||||||
|
|
||||||
|
|
||||||
|
// @Inject
|
||||||
|
// PersistenceProvider persistenceProvider;
|
||||||
|
// @Inject
|
||||||
|
// PluginManager pluginManager;
|
||||||
|
//
|
||||||
|
|
||||||
|
@QueryParam(ServiceConstants.DESTINATION_FILE_NAME) String destinationFileName;
|
||||||
|
@QueryParam(ServiceConstants.CREATE_DIRS) @DefaultValue("true") Boolean createDirs;
|
||||||
|
@QueryParam(ServiceConstants.ON_EXISTING_FILE) @DefaultValue("ADD_SUFFIX") DestinationClashPolicy onExistingFile;
|
||||||
|
@QueryParam(ServiceConstants.ON_EXISTING_DIR) @DefaultValue("APPEND") DestinationClashPolicy onExistingDirectory;
|
||||||
|
@QueryParam(ServiceConstants.SOURCE_ID) String sourceID;
|
||||||
|
@FormDataParam(ServiceConstants.MULTIPART_FILE) InputStream uploadedFile;
|
||||||
|
@FormDataParam(ServiceConstants.MULTIPART_FILE) FormDataContentDisposition uploadedFileDetails;
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{method}/{destinationId}/{subPath: .*}")
|
||||||
|
@Consumes(MediaType.WILDCARD)
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Object serveFileUpload(@PathParam("method") String methodString,
|
||||||
|
@PathParam("destinationId") String destinationID, @PathParam("subPath") String subPath){
|
||||||
|
try{
|
||||||
|
|
||||||
|
TransferRequest request=formRequestFromREST(methodString, destinationID, subPath);
|
||||||
|
log.info("Received REST Request {} ",request);
|
||||||
|
|
||||||
|
|
||||||
|
TransferTicket ticket=requests.put(request);
|
||||||
|
|
||||||
|
if(ticket.getSettings().getOptions().getMethod().equals(TransferMethod.FileUpload))
|
||||||
|
try {
|
||||||
|
return Response.created(new URI(ticket.getDestinationFileName())).build();
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new WebApplicationException("Internal ERROR "+e.getMessage(),e);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
}catch(WebApplicationException e){
|
||||||
|
log.error("Unable to serve request",e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private TransferRequest formRequestFromREST(String methodString,String destinationID,String subPath){
|
||||||
|
log.info("Creating TransferRequest from REST invocation method : {}, dest ID {}, sub Path {} ",methodString,destinationID,subPath);
|
||||||
|
TransferMethod method=null;
|
||||||
|
try{
|
||||||
|
method=TransferMethod.valueOf(methodString);
|
||||||
|
}catch (Throwable t) {
|
||||||
|
throw new WebApplicationException("Invalid selected method "+methodString,Status.BAD_REQUEST);}
|
||||||
|
|
||||||
|
Destination destination=new Destination();
|
||||||
|
destination.setCreateSubfolders(createDirs);
|
||||||
|
destination.setPersistenceId(destinationID);
|
||||||
|
destination.setSubFolder(subPath);
|
||||||
|
destination.setOnExistingSubFolder(onExistingDirectory);
|
||||||
|
|
||||||
|
TransferRequest resultingRequest=new TransferRequest();
|
||||||
|
resultingRequest.setDestinationSettings(destination);
|
||||||
|
|
||||||
|
switch(method){
|
||||||
|
case FileUpload : {
|
||||||
|
// if(destinationFileName==null) throw new WebApplicationException("Parameter "+ServiceConstants.DESTINATION_FILE_NAME+" is mandatory.",Status.BAD_REQUEST);
|
||||||
|
if(uploadedFileDetails==null) throw new WebApplicationException("Missing multipart "+ServiceConstants.MULTIPART_FILE+" details.",Status.BAD_REQUEST);
|
||||||
|
if(uploadedFile==null) throw new WebApplicationException("Missing multipart "+ServiceConstants.MULTIPART_FILE+" stream.",Status.BAD_REQUEST);
|
||||||
|
destination.setDestinationFileName(destinationFileName!=null?destinationFileName:uploadedFileDetails.getFileName());
|
||||||
|
FileUploadSettings uploadSettings=new FileUploadSettings(uploadedFile,new FileUploadOptions());
|
||||||
|
resultingRequest.setSettings(uploadSettings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DirectTransfer :{
|
||||||
|
throw new WebApplicationException("Unsupported selected method "+methodString,Status.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
case HTTPDownload :{
|
||||||
|
if(sourceID==null) throw new WebApplicationException("Parameter "+ServiceConstants.SOURCE_ID+" is mandatory.",Status.BAD_REQUEST);
|
||||||
|
destination.setDestinationFileName(destinationFileName==null?sourceID:destinationFileName);
|
||||||
|
try{
|
||||||
|
HttpDownloadSettings settings=new HttpDownloadSettings(new URL(sourceID), new HttpDownloadOptions());
|
||||||
|
resultingRequest.setSettings(settings);
|
||||||
|
break;
|
||||||
|
}catch(MalformedURLException e){
|
||||||
|
throw new WebApplicationException("Source "+sourceID+" is not a valid URL.",Status.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: throw new WebApplicationException("Unsupported selected method "+methodString,Status.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
return resultingRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.ServiceConstants;
|
||||||
|
import org.gcube.data.transfer.model.TransferRequest;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.RequestManager;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
@Path(ServiceConstants.REQUESTS_SERVLET_NAME)
|
||||||
|
@Slf4j
|
||||||
|
public class Requests {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RequestManager requests;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//********************* INJECT PARAMS
|
||||||
|
@POST
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public TransferTicket submitRequest(@NotNull TransferRequest theRequest){
|
||||||
|
log.info("Received transfer request : "+theRequest);
|
||||||
|
|
||||||
|
return requests.put(theRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// @PUT
|
||||||
|
// @Path("/{method}/{destinationId}/{subPath: .*}")
|
||||||
|
// @Produces(MediaType.APPLICATION_JSON)
|
||||||
|
// public TransferTicket submitRESTRequest(@PathParam("method") String methodString,
|
||||||
|
// @PathParam("destinationId") String destinationID, @PathParam("subPath") String subPath){
|
||||||
|
// return handleRequest(formRequestFromREST(methodString, destinationID, subPath));
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// private TransferTicket handleRequest(TransferRequest toHandle){
|
||||||
|
//
|
||||||
|
// toHandle.setId(UUID.randomUUID().toString());
|
||||||
|
// boolean inserted=requests.put(toHandle);
|
||||||
|
//
|
||||||
|
// log.debug("Successfully inserted "+inserted);
|
||||||
|
//
|
||||||
|
// if(!inserted) throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
|
||||||
|
// else
|
||||||
|
// try {
|
||||||
|
// return tickets.get(toHandle.getId());
|
||||||
|
// } catch (TicketNotFoundException e) {
|
||||||
|
// throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.InternalServerErrorException;
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.ServiceConstants;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.TicketManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.TicketNotFoundException;
|
||||||
|
|
||||||
|
@Path(ServiceConstants.STATUS_SERVLET_NAME)
|
||||||
|
@Slf4j
|
||||||
|
public class TransferStatus {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TicketManager manager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{"+ServiceConstants.TRANSFER_ID+"}")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public TransferTicket getTicket(@PathParam(ServiceConstants.TRANSFER_ID)@NotNull String requestId){
|
||||||
|
try{
|
||||||
|
log.debug("Returning status for id "+requestId);
|
||||||
|
return manager.get(requestId);
|
||||||
|
}catch(TicketNotFoundException e){
|
||||||
|
throw new NotFoundException();
|
||||||
|
}catch(Throwable t){
|
||||||
|
log.error("Unexpected exception ",t);
|
||||||
|
throw new InternalServerErrorException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.TransferCapabilities;
|
||||||
|
|
||||||
|
public interface CapabilitiesProvider {
|
||||||
|
|
||||||
|
public TransferCapabilities get();
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.Destination;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.DestinationAccessException;
|
||||||
|
|
||||||
|
public interface PersistenceProvider {
|
||||||
|
|
||||||
|
public File getPersistenceFolderById(String persistenceId) throws DestinationAccessException;
|
||||||
|
|
||||||
|
public Set<String> getAvaileblContextIds();
|
||||||
|
|
||||||
|
File prepareDestination(Destination dest) throws DestinationAccessException;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.PluginDescription;
|
||||||
|
import org.gcube.data.transfer.model.PluginInvocation;
|
||||||
|
import org.gcube.data.transfer.plugin.ExecutionReport;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.PluginExecutionException;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.PluginNotFoundException;
|
||||||
|
|
||||||
|
public interface PluginManager {
|
||||||
|
|
||||||
|
public Map<String,PluginDescription> getInstalledPlugins();
|
||||||
|
public ExecutionReport execute(PluginInvocation invocation)throws PluginNotFoundException,PluginExecutionException;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.TransferRequest;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
|
||||||
|
public interface RequestManager {
|
||||||
|
|
||||||
|
public TransferTicket put(TransferRequest request);
|
||||||
|
|
||||||
|
public void shutdown();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.TicketNotFoundException;
|
||||||
|
|
||||||
|
public interface TicketManager {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns true if new
|
||||||
|
*
|
||||||
|
* @param toInsert
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean insertUpdate(TransferTicket toInsert);
|
||||||
|
|
||||||
|
public TransferTicket get(String ticketId) throws TicketNotFoundException;
|
||||||
|
|
||||||
|
public void shutdown();
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.faults;
|
||||||
|
|
||||||
|
public class DestinationAccessException extends ManagedException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 4968214602073818019L;
|
||||||
|
|
||||||
|
public DestinationAccessException() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public DestinationAccessException(String message) {
|
||||||
|
super(message);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public DestinationAccessException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public DestinationAccessException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public DestinationAccessException(String message, Throwable cause, boolean enableSuppression,
|
||||||
|
boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.faults;
|
||||||
|
|
||||||
|
public class ManagedException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public ManagedException() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManagedException(String message) {
|
||||||
|
super(message);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManagedException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManagedException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManagedException(String message, Throwable cause,
|
||||||
|
boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.faults;
|
||||||
|
|
||||||
|
public class NotSupportedMethodException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public NotSupportedMethodException() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotSupportedMethodException(String message) {
|
||||||
|
super(message);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotSupportedMethodException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotSupportedMethodException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotSupportedMethodException(String message, Throwable cause,
|
||||||
|
boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.faults;
|
||||||
|
|
||||||
|
public class PluginExecutionException extends ManagedException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 2681096696757651730L;
|
||||||
|
|
||||||
|
public PluginExecutionException() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginExecutionException(String message) {
|
||||||
|
super(message);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginExecutionException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginExecutionException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginExecutionException(String message, Throwable cause, boolean enableSuppression,
|
||||||
|
boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.faults;
|
||||||
|
|
||||||
|
public class PluginNotFoundException extends ManagedException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -5169583804790487322L;
|
||||||
|
|
||||||
|
public PluginNotFoundException() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginNotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginNotFoundException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginNotFoundException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginNotFoundException(String message, Throwable cause, boolean enableSuppression,
|
||||||
|
boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.faults;
|
||||||
|
|
||||||
|
public class TicketNotFoundException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -5761719004322780267L;
|
||||||
|
|
||||||
|
public TicketNotFoundException() {
|
||||||
|
super();
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public TicketNotFoundException(String message, Throwable cause,
|
||||||
|
boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public TicketNotFoundException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public TicketNotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public TicketNotFoundException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.impl;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.gcube.data.transfer.model.PluginInvocation;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket.Status;
|
||||||
|
import org.gcube.data.transfer.model.options.TransferOptions.TransferMethod;
|
||||||
|
import org.gcube.data.transfer.model.settings.FileUploadSettings;
|
||||||
|
import org.gcube.data.transfer.model.settings.HttpDownloadSettings;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PersistenceProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PluginManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.ManagedException;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.NotSupportedMethodException;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public abstract class AbstractTicketHandler {
|
||||||
|
|
||||||
|
private TransferTicket ticket;
|
||||||
|
|
||||||
|
PersistenceProvider persistenceProvider;
|
||||||
|
PluginManager pluginManager;
|
||||||
|
|
||||||
|
|
||||||
|
public AbstractTicketHandler(PersistenceProvider persProv,PluginManager plugMan, TransferTicket ticket) {
|
||||||
|
this.persistenceProvider=persProv;
|
||||||
|
this.pluginManager=plugMan;
|
||||||
|
this.ticket=ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onStep(String msg,double progress,Status status,long transferredBytes){
|
||||||
|
ticket.setStatus(status);
|
||||||
|
ticket.setMessage(msg);
|
||||||
|
ticket.setPercent(progress);
|
||||||
|
ticket.setTransferredBytes(transferredBytes);
|
||||||
|
try{
|
||||||
|
long elapsedTime=System.currentTimeMillis()-ticket.getSubmissionTime().getValue().getTimeInMillis();
|
||||||
|
long average=(transferredBytes/((elapsedTime==0?1:elapsedTime)))*1000;
|
||||||
|
ticket.setAverageTransferSpeed(average);
|
||||||
|
}catch(Exception e){
|
||||||
|
log.warn("Unable to evaluate average ",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected void onError(String message){
|
||||||
|
onStep(message,ticket.getPercent(),Status.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onStep(String msg,double progress,Status status){
|
||||||
|
onStep(msg,progress,status,ticket.getTransferredBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransferTicket getTicket(){
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void handle(){
|
||||||
|
|
||||||
|
InputStream is=null;
|
||||||
|
BufferedOutputStream out=null;
|
||||||
|
Boolean completedTransfer=false;
|
||||||
|
File destination=null;
|
||||||
|
|
||||||
|
try{
|
||||||
|
if(ticket.getSettings().getOptions().getMethod().equals(TransferMethod.DirectTransfer))
|
||||||
|
throw new NotSupportedMethodException("Unable to manage request [ID "+ticket.getId()+"]. Method not supported : "+ticket.getSettings().getOptions().getMethod());
|
||||||
|
|
||||||
|
|
||||||
|
log.trace("Request handling started. Ticket is "+ticket);
|
||||||
|
|
||||||
|
onStep("Checking destination",0d,Status.TRANSFERRING,0l);
|
||||||
|
destination =persistenceProvider.prepareDestination(ticket.getDestinationSettings());
|
||||||
|
ticket.setDestinationFileName(destination.getAbsolutePath());
|
||||||
|
onStep("Opening input stream",0d,Status.TRANSFERRING,0l);
|
||||||
|
|
||||||
|
|
||||||
|
is=getInputStream();
|
||||||
|
|
||||||
|
|
||||||
|
try{
|
||||||
|
out=new BufferedOutputStream(new FileOutputStream(destination));
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("Unable to create destination file.",e);
|
||||||
|
throw new ManagedException("Cannot save file in host");
|
||||||
|
}
|
||||||
|
|
||||||
|
transferStream(is, out);
|
||||||
|
completedTransfer=true;
|
||||||
|
// IF TRANSFER FAILS, EXCEPTIONS AR THROWN
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Plugin execution
|
||||||
|
if(ticket.getPluginInvocations()!=null){
|
||||||
|
for(PluginInvocation invocation:ticket.getPluginInvocations()){
|
||||||
|
log.debug("Execution {}",invocation);
|
||||||
|
if(invocation.getParameters().containsValue(PluginInvocation.DESTINATION_FILE_PATH)){
|
||||||
|
log.debug("Checking for param value : "+PluginInvocation.DESTINATION_FILE_PATH);
|
||||||
|
for(Entry<String,String> param:invocation.getParameters().entrySet())
|
||||||
|
if(param.getValue().equals(PluginInvocation.DESTINATION_FILE_PATH)){
|
||||||
|
log.debug("Setting {} = {} ",param.getKey(),ticket.getDestinationFileName());
|
||||||
|
param.setValue(ticket.getDestinationFileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
onStep("Executing invocation "+invocation.getPluginId(),1d,Status.PLUGIN_EXECUTION);
|
||||||
|
pluginManager.execute(invocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onStep("Completed transfer",1d,Status.SUCCESS);
|
||||||
|
}catch(NotSupportedMethodException e){
|
||||||
|
onError(e.getMessage());
|
||||||
|
}catch(ManagedException e){
|
||||||
|
onError(e.getMessage());
|
||||||
|
}catch(Throwable t){
|
||||||
|
onError("Unexpected error while downloading : "+t.getMessage());
|
||||||
|
log.error("Unexpected error occurred",t);
|
||||||
|
}finally{
|
||||||
|
log.debug("Finalizing transfer, ticket ID {} ",ticket.getId());
|
||||||
|
if(out!=null)IOUtils.closeQuietly(out);
|
||||||
|
if(is!=null)IOUtils.closeQuietly(is);
|
||||||
|
|
||||||
|
if((!completedTransfer)&& (destination!=null) && (destination.exists())) {
|
||||||
|
log.debug("Removing incomplete transfer..");
|
||||||
|
try{
|
||||||
|
FileUtils.forceDelete(destination);
|
||||||
|
}catch(Exception e){
|
||||||
|
log.warn("Unable to clean {} ",destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void transferStream(InputStream in, OutputStream out) throws ManagedException{
|
||||||
|
|
||||||
|
long receivedTotal=0l;
|
||||||
|
|
||||||
|
try{
|
||||||
|
byte[] internalBuf=new byte[1024];
|
||||||
|
int received=0;
|
||||||
|
while ((received=in.read(internalBuf))!=-1){
|
||||||
|
out.write(internalBuf,0,received);
|
||||||
|
receivedTotal+=received;
|
||||||
|
onStep("Transferring",0d,Status.TRANSFERRING,receivedTotal);
|
||||||
|
}
|
||||||
|
out.flush();
|
||||||
|
}catch(IOException e){
|
||||||
|
log.debug("Unable to read from source",e);
|
||||||
|
throw new ManagedException("Unable to read from source.");
|
||||||
|
}
|
||||||
|
log.debug("Completed transfer phase for ticket ID {}. Transferred {} bytes. ",ticket.getId(),receivedTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream getInputStream() throws ManagedException{
|
||||||
|
switch(ticket.getSettings().getOptions().getMethod()){
|
||||||
|
case HTTPDownload:{
|
||||||
|
try{
|
||||||
|
HttpDownloadSettings options=(HttpDownloadSettings) (ticket.getSettings());
|
||||||
|
return new BufferedInputStream(options.getSource().openStream());
|
||||||
|
}catch(Exception e){
|
||||||
|
log.debug("Unable to open connection ",e);
|
||||||
|
throw new ManagedException("Cannot open connection to source");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case FileUpload :{
|
||||||
|
try{
|
||||||
|
FileUploadSettings options=(FileUploadSettings) (ticket.getSettings());
|
||||||
|
return new BufferedInputStream(options.getPassedStream());
|
||||||
|
}catch(Exception e){
|
||||||
|
log.debug("Unable to open connection ",e);
|
||||||
|
throw new ManagedException("Cannot open connection to source");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new ManagedException(ticket.getSettings().getOptions().getMethod()+" cannot be managed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.impl;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.gcube.common.resources.gcore.GCoreEndpoint;
|
||||||
|
import org.gcube.data.transfer.model.PluginDescription;
|
||||||
|
import org.gcube.data.transfer.model.TransferCapabilities;
|
||||||
|
import org.gcube.data.transfer.model.options.HttpDownloadOptions;
|
||||||
|
import org.gcube.data.transfer.model.options.TransferOptions;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.CapabilitiesProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PersistenceProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PluginManager;
|
||||||
|
import org.gcube.smartgears.ContextProvider;
|
||||||
|
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
||||||
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
|
|
||||||
|
import lombok.Synchronized;
|
||||||
|
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class CapabilitiesProviderImpl implements CapabilitiesProvider {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private TransferCapabilities capabilities=null;
|
||||||
|
|
||||||
|
private PersistenceProvider persistenceProvider;
|
||||||
|
private PluginManager pluginManager;
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public CapabilitiesProviderImpl(PersistenceProvider persistenceProvider,PluginManager pluginManager) {
|
||||||
|
this.persistenceProvider = persistenceProvider;
|
||||||
|
this.pluginManager=pluginManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @Synchronized
|
||||||
|
public TransferCapabilities get() {
|
||||||
|
if(capabilities==null)capabilities=getCapabilities();
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TransferCapabilities getCapabilities(){
|
||||||
|
ApplicationContext context=ContextProvider.get();
|
||||||
|
ContainerConfiguration configuration=context.container().configuration();
|
||||||
|
|
||||||
|
String hostName=configuration.hostname();
|
||||||
|
String id=context.profile(GCoreEndpoint.class).id();
|
||||||
|
Integer port=configuration.port();
|
||||||
|
|
||||||
|
HashSet<TransferOptions> meansOfTransfer=new HashSet<TransferOptions>();
|
||||||
|
meansOfTransfer.add(HttpDownloadOptions.DEFAULT);
|
||||||
|
|
||||||
|
|
||||||
|
HashSet<PluginDescription> plugins=new HashSet<PluginDescription>(pluginManager.getInstalledPlugins().values());
|
||||||
|
|
||||||
|
|
||||||
|
return new TransferCapabilities(id,hostName,port,meansOfTransfer,plugins,persistenceProvider.getAvaileblContextIds());
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static String getHostname() throws Exception {
|
||||||
|
// String OS = System.getProperty("os.name").toLowerCase();
|
||||||
|
// log.debug("Getting hostname..");
|
||||||
|
// String hostName=null;
|
||||||
|
// if (OS.indexOf("win") >= 0) {
|
||||||
|
// log.debug("Detected windows..");
|
||||||
|
// hostName=System.getenv("COMPUTERNAME");
|
||||||
|
// if(hostName==null || hostName.equals("")){
|
||||||
|
// log.debug("System env not found, trying via hostname command..");
|
||||||
|
// hostName=execReadToString("hostname");
|
||||||
|
// }
|
||||||
|
// } else
|
||||||
|
// if (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0) {
|
||||||
|
// log.debug("Detected linux..");
|
||||||
|
// hostName= System.getenv("HOSTNAME");
|
||||||
|
// if(hostName==null || hostName.equals("")){
|
||||||
|
// log.debug("System env not found, trying via hostname command..");
|
||||||
|
// hostName=execReadToString("hostname -f");
|
||||||
|
// }
|
||||||
|
// if(hostName==null || hostName.equals("")){
|
||||||
|
// log.debug("Hostname command didn't work, trying via hostname file..");
|
||||||
|
// hostName=execReadToString("cat /etc/hostname");
|
||||||
|
// }
|
||||||
|
// }else throw new Exception("OS not detected");
|
||||||
|
// return hostName;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// public static String execReadToString(String execCommand) throws IOException {
|
||||||
|
// Process proc = Runtime.getRuntime().exec(execCommand);
|
||||||
|
// try (InputStream stream = proc.getInputStream()) {
|
||||||
|
// try (Scanner s = new Scanner(stream).useDelimiter("\\A")) {
|
||||||
|
// return s.hasNext() ? s.next() : "";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.impl;
|
||||||
|
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PersistenceProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PluginManager;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class LocalRequestHandler extends AbstractTicketHandler{
|
||||||
|
|
||||||
|
public LocalRequestHandler(PersistenceProvider persProv, PluginManager plugMan, TransferTicket ticket) {
|
||||||
|
super(persProv, plugMan, ticket);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStep(String msg, double progress, org.gcube.data.transfer.model.TransferTicket.Status status,
|
||||||
|
long transferredBytes) {
|
||||||
|
super.onStep(msg, progress, status, transferredBytes);
|
||||||
|
log.trace("Stepping upload. Relative Ticket {} ",getTicket());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onError(String message) {
|
||||||
|
log.error("Unable to manage upload request ticket {} MSG {} ",getTicket(),message);
|
||||||
|
throw new WebApplicationException("Internal ERROR "+message,Status.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.impl;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.Destination;
|
||||||
|
import org.gcube.data.transfer.model.DestinationClashPolicy;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PersistenceProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.DestinationAccessException;
|
||||||
|
import org.gcube.smartgears.ContextProvider;
|
||||||
|
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
||||||
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Singleton
|
||||||
|
public class PersistenceProviderImpl implements PersistenceProvider {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getPersistenceFolderById(String persistenceId) throws DestinationAccessException {
|
||||||
|
File toReturn=null;
|
||||||
|
log.debug("looking for persistence ID : {}",persistenceId);
|
||||||
|
|
||||||
|
if(persistenceId.equalsIgnoreCase(Destination.DEFAULT_PERSISTENCE_ID)){
|
||||||
|
log.debug("Persistence ID is default");
|
||||||
|
ApplicationContext context=ContextProvider.get();
|
||||||
|
toReturn=new File(context.persistence().location());
|
||||||
|
}else{
|
||||||
|
for(ApplicationConfiguration config:ContextProvider.get().container().configuration().apps()){
|
||||||
|
if(config.context().equals(persistenceId)){
|
||||||
|
log.debug("Found persistence ID {}",persistenceId);
|
||||||
|
toReturn= new File(config.persistence().location());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(toReturn== null) throw new DestinationAccessException("Persistence ID "+persistenceId+" not found.");
|
||||||
|
if(!toReturn.exists()) throw new DestinationAccessException("Persistence ID "+persistenceId+", location "+toReturn.getAbsolutePath()+" location doesn't exists.");
|
||||||
|
if(!toReturn.canWrite()) throw new DestinationAccessException("Cannot write to Persistence ID "+persistenceId+", location "+toReturn.getAbsolutePath()+" .");
|
||||||
|
if(!toReturn.isDirectory()) throw new DestinationAccessException("Persistence ID "+persistenceId+", location "+toReturn.getAbsolutePath()+" is a directory.");
|
||||||
|
if(!toReturn.canWrite()) throw new DestinationAccessException("Cannot write to Persistence ID "+persistenceId+", location "+toReturn.getAbsolutePath()+" .");
|
||||||
|
return toReturn;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getAvaileblContextIds() {
|
||||||
|
HashSet<String> toReturn=new HashSet<>();
|
||||||
|
for(ApplicationConfiguration config:ContextProvider.get().container().configuration().apps()){
|
||||||
|
String toAddID=config.context();
|
||||||
|
if(toAddID.startsWith("/")) toAddID=toAddID.substring(1);
|
||||||
|
toReturn.add(toAddID);
|
||||||
|
}
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File prepareDestination(Destination dest) throws DestinationAccessException{
|
||||||
|
File persistenceFolder=getPersistenceFolderById(dest.getPersistenceId());
|
||||||
|
if(!persistenceFolder.canWrite()) throw new DestinationAccessException("Cannot write to selecte persistenceFolder [ID :"+dest.getPersistenceId()+"]");
|
||||||
|
log.debug("Got Persistence folder ID {}, PATH {}",persistenceFolder.getAbsolutePath(),dest.getPersistenceId());
|
||||||
|
String subFolderName=dest.getSubFolder();
|
||||||
|
File subFolder=persistenceFolder;
|
||||||
|
if(subFolderName!=null){
|
||||||
|
log.debug("Looking for subFolder : "+subFolder);
|
||||||
|
if(subFolderName.startsWith(File.pathSeparator)) throw new DestinationAccessException("SubFolder cannot be absolute.");
|
||||||
|
// String[] pathItems=subFolderName.split(File.pathSeparator);
|
||||||
|
// for(String subPath:pathItems){
|
||||||
|
//// Set<String> existingFiles=new HashSet<String>(Arrays.asList(subFolder.list()));
|
||||||
|
// subFolder=new File(subFolder,subPath);
|
||||||
|
// if(subFolder.exists()){
|
||||||
|
// if(!subFolder.canRead()) throw new DestinationAccessException("Cannot write to "+subFolder.getAbsolutePath());
|
||||||
|
// }else if(dest.getCreateSubfolders()) subFolder.mkdir();
|
||||||
|
// else throw new DestinationAccessException("Destination subfolder {} not found. Set createSubFolder=true to create intermediary directories.");
|
||||||
|
// }
|
||||||
|
|
||||||
|
subFolder=new File(persistenceFolder,subFolderName);
|
||||||
|
if(subFolder.exists()){
|
||||||
|
if(!subFolder.canRead()) throw new DestinationAccessException("Cannot write to "+subFolder.getAbsolutePath());
|
||||||
|
manageClash(dest.getOnExistingSubFolder(),subFolder);
|
||||||
|
}else if(dest.getCreateSubfolders()) subFolder.mkdirs();
|
||||||
|
else throw new DestinationAccessException("SubFolder not found. Use createSubFolders=true to create it.");
|
||||||
|
}
|
||||||
|
|
||||||
|
File destination=new File(subFolder,dest.getDestinationFileName());
|
||||||
|
if(destination.exists()) return manageClash(dest.getOnExistingFileName(),destination);
|
||||||
|
else {
|
||||||
|
try{
|
||||||
|
destination.createNewFile();
|
||||||
|
return destination;
|
||||||
|
}catch(IOException e){
|
||||||
|
throw new DestinationAccessException("Unable to create file ",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final File manageClash(DestinationClashPolicy policy, File clashing ) throws DestinationAccessException{
|
||||||
|
log.debug("Managing clash for {}, policy is {} ",clashing.getAbsolutePath(),policy);
|
||||||
|
boolean dir=clashing.isDirectory();
|
||||||
|
try{
|
||||||
|
switch(policy){
|
||||||
|
case ADD_SUFFIX : {
|
||||||
|
String clashingBaseName=clashing.getName();
|
||||||
|
|
||||||
|
int counter=1;
|
||||||
|
while(clashing.exists()){
|
||||||
|
clashing=new File(clashing.getParentFile(),clashingBaseName+"("+counter+")");
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
if(dir)clashing.mkdirs();
|
||||||
|
else clashing.createNewFile();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FAIL: throw new DestinationAccessException("Found existing "+clashing.getAbsolutePath()+"policy is "+policy);
|
||||||
|
case REWRITE : {
|
||||||
|
Files.deleteIfExists(Paths.get(clashing.getAbsolutePath()));
|
||||||
|
if(dir)clashing.mkdirs();
|
||||||
|
else clashing.createNewFile();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(IOException e){
|
||||||
|
throw new DestinationAccessException("Unable to rewrite existing destination",e);
|
||||||
|
}
|
||||||
|
return clashing;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.impl;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.PluginDescription;
|
||||||
|
import org.gcube.data.transfer.model.PluginInvocation;
|
||||||
|
import org.gcube.data.transfer.plugin.AbstractPlugin;
|
||||||
|
import org.gcube.data.transfer.plugin.AbstractPluginFactory;
|
||||||
|
import org.gcube.data.transfer.plugin.ExecutionReport;
|
||||||
|
import org.gcube.data.transfer.plugin.fails.PluginException;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PluginManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.PluginExecutionException;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.PluginNotFoundException;
|
||||||
|
|
||||||
|
import lombok.Synchronized;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Singleton
|
||||||
|
public class PluginManagerImpl implements PluginManager {
|
||||||
|
|
||||||
|
private static ServiceLoader<AbstractPluginFactory> abstractFactoryLoader = null;
|
||||||
|
|
||||||
|
private static Map<String,PluginDescription> installedPlugins=null;
|
||||||
|
|
||||||
|
|
||||||
|
static{
|
||||||
|
abstractFactoryLoader=ServiceLoader.load(AbstractPluginFactory.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, PluginDescription> getInstalledPlugins() {
|
||||||
|
return init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private static Map<String, PluginDescription> init() {
|
||||||
|
if(installedPlugins==null){
|
||||||
|
Map<String,PluginDescription> toSet=new HashMap<String,PluginDescription>();
|
||||||
|
log.trace("Loading plugins descriptors..");
|
||||||
|
for(AbstractPluginFactory factory:abstractFactoryLoader){
|
||||||
|
log.debug("loading {}, {} ",factory.getID(),factory.getDescription());
|
||||||
|
toSet.put(factory.getID(), new PluginDescription(factory.getID(), factory.getDescription(), factory.getParameters()));
|
||||||
|
}
|
||||||
|
installedPlugins=toSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
return installedPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecutionReport execute(PluginInvocation invocation)
|
||||||
|
throws PluginNotFoundException, PluginExecutionException {
|
||||||
|
log.debug("Executing invocation {} ",invocation);
|
||||||
|
|
||||||
|
AbstractPluginFactory factory=getFactory(invocation.getPluginId());
|
||||||
|
log.debug("Loaded factory {} ",factory.getClass());
|
||||||
|
log.debug("Checkign invocation .. ");
|
||||||
|
try{
|
||||||
|
factory.checkInvocation(invocation);
|
||||||
|
AbstractPlugin plugin=factory.createWorker(invocation);
|
||||||
|
return plugin.execute();
|
||||||
|
}catch(PluginException e){
|
||||||
|
throw new PluginExecutionException(e.getMessage(),e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private AbstractPluginFactory getFactory(String pluginId) throws PluginNotFoundException{
|
||||||
|
for(AbstractPluginFactory factory:abstractFactoryLoader){
|
||||||
|
if(factory.getID().equals(pluginId)) return factory;
|
||||||
|
}
|
||||||
|
throw new PluginNotFoundException("Plugin with ID "+pluginId+" not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.impl;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket.Status;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PersistenceProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PluginManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.TicketManager;
|
||||||
|
|
||||||
|
public class RequestHandler extends AbstractTicketHandler implements Runnable {
|
||||||
|
|
||||||
|
|
||||||
|
TicketManager ticketManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public RequestHandler(TicketManager ticketManager,TransferTicket ticket,PersistenceProvider persProv, PluginManager plugMan) {
|
||||||
|
super(persProv, plugMan,ticket);
|
||||||
|
this.ticketManager=ticketManager;
|
||||||
|
ticketManager.insertUpdate(ticket);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStep(String msg, double progress, Status status, long transferredBytes) {
|
||||||
|
super.onStep(msg, progress, status,transferredBytes);
|
||||||
|
ticketManager.insertUpdate(getTicket());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.impl;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.TransferRequest;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.model.options.TransferOptions.TransferMethod;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PersistenceProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PluginManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.RequestManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.TicketManager;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Slf4j
|
||||||
|
public class RequestManagerImpl implements RequestManager{
|
||||||
|
|
||||||
|
ExecutorService executor;
|
||||||
|
|
||||||
|
TicketManager ticketManager;
|
||||||
|
PersistenceProvider persistenceProvider;
|
||||||
|
PluginManager pluginManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public RequestManagerImpl(TicketManager ticketManager,PersistenceProvider persistenceProvider,PluginManager pluginManager) {
|
||||||
|
executor=Executors.newCachedThreadPool();
|
||||||
|
this.persistenceProvider=persistenceProvider;
|
||||||
|
this.pluginManager=pluginManager;
|
||||||
|
this.ticketManager=ticketManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransferTicket put(TransferRequest request) {
|
||||||
|
request.setId(UUID.randomUUID().toString());
|
||||||
|
log.info("Managing request {} ",request);
|
||||||
|
TransferTicket toReturn=new TransferTicket(request);
|
||||||
|
|
||||||
|
if(request.getSettings().getOptions().getMethod().equals(TransferMethod.FileUpload)){
|
||||||
|
log.debug("Request is sync");
|
||||||
|
new LocalRequestHandler(persistenceProvider, pluginManager, toReturn).handle();
|
||||||
|
return toReturn;
|
||||||
|
}else{
|
||||||
|
log.debug("Request is async");
|
||||||
|
executor.execute(new RequestHandler(ticketManager,new TransferTicket(request),persistenceProvider,pluginManager));
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() {
|
||||||
|
log.debug("Calling shutdown..");
|
||||||
|
executor.shutdownNow();
|
||||||
|
|
||||||
|
long timeout=4;
|
||||||
|
TimeUnit unit=TimeUnit.SECONDS;
|
||||||
|
|
||||||
|
log.debug("Waiting termination.. {} {} ",timeout,unit);
|
||||||
|
boolean halted=false;
|
||||||
|
try {
|
||||||
|
halted=executor.awaitTermination(timeout, unit);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.debug("Halted threads : {} ",halted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package org.gcube.data.transfer.service.transfers.engine.impl;
|
||||||
|
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.TicketManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.TicketNotFoundException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Singleton
|
||||||
|
public class TransferTicketManagerImpl implements TicketManager{
|
||||||
|
|
||||||
|
private static ConcurrentHashMap<String, TTLContainer> theMap=new ConcurrentHashMap<>();
|
||||||
|
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||||
|
|
||||||
|
static{
|
||||||
|
scheduler.scheduleAtFixedRate(new Runnable() {
|
||||||
|
|
||||||
|
private static final long TTL =30*60*1000;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
log.debug("Running Ticket cleaner, TTL is "+TTL);
|
||||||
|
int removed=0;
|
||||||
|
for(Entry<String,TTLContainer> entry:theMap.entrySet())
|
||||||
|
if(System.currentTimeMillis()-entry.getValue().getLastUsageTime()>TTL){
|
||||||
|
theMap.remove(entry.getKey());
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
|
log.debug("Removed "+removed+" old tickets");
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 30, 30, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class TTLContainer {
|
||||||
|
|
||||||
|
private long lastUsageTime=System.currentTimeMillis();
|
||||||
|
private TransferTicket theTicket;
|
||||||
|
public TTLContainer(TransferTicket theTicket) {
|
||||||
|
this.theTicket = theTicket;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void update(){
|
||||||
|
lastUsageTime=System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransferTicket getTicket(){
|
||||||
|
update();
|
||||||
|
return theTicket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastUsageTime() {
|
||||||
|
return lastUsageTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean insertUpdate(TransferTicket toInsert) {
|
||||||
|
return (theMap.put(toInsert.getId(), new TTLContainer(toInsert))!=null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransferTicket get(String ticketId) throws TicketNotFoundException {
|
||||||
|
if(theMap.containsKey(ticketId))return theMap.get(ticketId).getTicket();
|
||||||
|
else throw new TicketNotFoundException(String.format("Ticket [%s] not found. Request is probably served and outdated",ticketId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() {
|
||||||
|
scheduler.shutdownNow();
|
||||||
|
|
||||||
|
long timeout=4;
|
||||||
|
TimeUnit unit=TimeUnit.SECONDS;
|
||||||
|
|
||||||
|
log.debug("Waiting termination.. {} {} ",timeout,unit);
|
||||||
|
boolean halted=false;
|
||||||
|
try {
|
||||||
|
halted=scheduler.awaitTermination(timeout, unit);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.debug("Halted threads : {} ",halted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||||
|
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="annotated">
|
||||||
|
</beans>
|
|
@ -0,0 +1,313 @@
|
||||||
|
European Union Public Licence V. 1.1
|
||||||
|
|
||||||
|
|
||||||
|
EUPL © the European Community 2007
|
||||||
|
|
||||||
|
|
||||||
|
This European Union Public Licence (the “EUPL”) applies to the Work or Software
|
||||||
|
(as defined below) which is provided under the terms of this Licence. Any use of
|
||||||
|
the Work, other than as authorised under this Licence is prohibited (to the
|
||||||
|
extent such use is covered by a right of the copyright holder of the Work).
|
||||||
|
|
||||||
|
The Original Work is provided under the terms of this Licence when the Licensor
|
||||||
|
(as defined below) has placed the following notice immediately following the
|
||||||
|
copyright notice for the Original Work:
|
||||||
|
|
||||||
|
Licensed under the EUPL V.1.1
|
||||||
|
|
||||||
|
or has expressed by any other mean his willingness to license under the EUPL.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. Definitions
|
||||||
|
|
||||||
|
In this Licence, the following terms have the following meaning:
|
||||||
|
|
||||||
|
- The Licence: this Licence.
|
||||||
|
|
||||||
|
- The Original Work or the Software: the software distributed and/or
|
||||||
|
communicated by the Licensor under this Licence, available as Source Code and
|
||||||
|
also as Executable Code as the case may be.
|
||||||
|
|
||||||
|
- Derivative Works: the works or software that could be created by the Licensee,
|
||||||
|
based upon the Original Work or modifications thereof. This Licence does not
|
||||||
|
define the extent of modification or dependence on the Original Work required
|
||||||
|
in order to classify a work as a Derivative Work; this extent is determined by
|
||||||
|
copyright law applicable in the country mentioned in Article 15.
|
||||||
|
|
||||||
|
- The Work: the Original Work and/or its Derivative Works.
|
||||||
|
|
||||||
|
- The Source Code: the human-readable form of the Work which is the most
|
||||||
|
convenient for people to study and modify.
|
||||||
|
|
||||||
|
- The Executable Code: any code which has generally been compiled and which is
|
||||||
|
meant to be interpreted by a computer as a program.
|
||||||
|
|
||||||
|
- The Licensor: the natural or legal person that distributes and/or communicates
|
||||||
|
the Work under the Licence.
|
||||||
|
|
||||||
|
- Contributor(s): any natural or legal person who modifies the Work under the
|
||||||
|
Licence, or otherwise contributes to the creation of a Derivative Work.
|
||||||
|
|
||||||
|
- The Licensee or “You”: any natural or legal person who makes any usage of the
|
||||||
|
Software under the terms of the Licence.
|
||||||
|
|
||||||
|
- Distribution and/or Communication: any act of selling, giving, lending,
|
||||||
|
renting, distributing, communicating, transmitting, or otherwise making
|
||||||
|
available, on-line or off-line, copies of the Work or providing access to its
|
||||||
|
essential functionalities at the disposal of any other natural or legal
|
||||||
|
person.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2. Scope of the rights granted by the Licence
|
||||||
|
|
||||||
|
The Licensor hereby grants You a world-wide, royalty-free, non-exclusive,
|
||||||
|
sub-licensable licence to do the following, for the duration of copyright vested
|
||||||
|
in the Original Work:
|
||||||
|
|
||||||
|
- use the Work in any circumstance and for all usage, reproduce the Work, modify
|
||||||
|
- the Original Work, and make Derivative Works based upon the Work, communicate
|
||||||
|
- to the public, including the right to make available or display the Work or
|
||||||
|
- copies thereof to the public and perform publicly, as the case may be, the
|
||||||
|
- Work, distribute the Work or copies thereof, lend and rent the Work or copies
|
||||||
|
- thereof, sub-license rights in the Work or copies thereof.
|
||||||
|
|
||||||
|
Those rights can be exercised on any media, supports and formats, whether now
|
||||||
|
known or later invented, as far as the applicable law permits so.
|
||||||
|
|
||||||
|
In the countries where moral rights apply, the Licensor waives his right to
|
||||||
|
exercise his moral right to the extent allowed by law in order to make effective
|
||||||
|
the licence of the economic rights here above listed.
|
||||||
|
|
||||||
|
The Licensor grants to the Licensee royalty-free, non exclusive usage rights to
|
||||||
|
any patents held by the Licensor, to the extent necessary to make use of the
|
||||||
|
rights granted on the Work under this Licence.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3. Communication of the Source Code
|
||||||
|
|
||||||
|
The Licensor may provide the Work either in its Source Code form, or as
|
||||||
|
Executable Code. If the Work is provided as Executable Code, the Licensor
|
||||||
|
provides in addition a machine-readable copy of the Source Code of the Work
|
||||||
|
along with each copy of the Work that the Licensor distributes or indicates, in
|
||||||
|
a notice following the copyright notice attached to the Work, a repository where
|
||||||
|
the Source Code is easily and freely accessible for as long as the Licensor
|
||||||
|
continues to distribute and/or communicate the Work.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4. Limitations on copyright
|
||||||
|
|
||||||
|
Nothing in this Licence is intended to deprive the Licensee of the benefits from
|
||||||
|
any exception or limitation to the exclusive rights of the rights owners in the
|
||||||
|
Original Work or Software, of the exhaustion of those rights or of other
|
||||||
|
applicable limitations thereto.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
5. Obligations of the Licensee
|
||||||
|
|
||||||
|
The grant of the rights mentioned above is subject to some restrictions and
|
||||||
|
obligations imposed on the Licensee. Those obligations are the following:
|
||||||
|
|
||||||
|
Attribution right: the Licensee shall keep intact all copyright, patent or
|
||||||
|
trademarks notices and all notices that refer to the Licence and to the
|
||||||
|
disclaimer of warranties. The Licensee must include a copy of such notices and a
|
||||||
|
copy of the Licence with every copy of the Work he/she distributes and/or
|
||||||
|
communicates. The Licensee must cause any Derivative Work to carry prominent
|
||||||
|
notices stating that the Work has been modified and the date of modification.
|
||||||
|
|
||||||
|
Copyleft clause: If the Licensee distributes and/or communicates copies of the
|
||||||
|
Original Works or Derivative Works based upon the Original Work, this
|
||||||
|
Distribution and/or Communication will be done under the terms of this Licence
|
||||||
|
or of a later version of this Licence unless the Original Work is expressly
|
||||||
|
distributed only under this version of the Licence. The Licensee (becoming
|
||||||
|
Licensor) cannot offer or impose any additional terms or conditions on the Work
|
||||||
|
or Derivative Work that alter or restrict the terms of the Licence.
|
||||||
|
|
||||||
|
Compatibility clause: If the Licensee Distributes and/or Communicates Derivative
|
||||||
|
Works or copies thereof based upon both the Original Work and another work
|
||||||
|
licensed under a Compatible Licence, this Distribution and/or Communication can
|
||||||
|
be done under the terms of this Compatible Licence. For the sake of this clause,
|
||||||
|
“Compatible Licence” refers to the licences listed in the appendix attached to
|
||||||
|
this Licence. Should the Licensee’s obligations under the Compatible Licence
|
||||||
|
conflict with his/her obligations under this Licence, the obligations of the
|
||||||
|
Compatible Licence shall prevail.
|
||||||
|
|
||||||
|
Provision of Source Code: When distributing and/or communicating copies of the
|
||||||
|
Work, the Licensee will provide a machine-readable copy of the Source Code or
|
||||||
|
indicate a repository where this Source will be easily and freely available for
|
||||||
|
as long as the Licensee continues to distribute and/or communicate the Work.
|
||||||
|
|
||||||
|
Legal Protection: This Licence does not grant permission to use the trade names,
|
||||||
|
trademarks, service marks, or names of the Licensor, except as required for
|
||||||
|
reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the copyright notice.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
6. Chain of Authorship
|
||||||
|
|
||||||
|
The original Licensor warrants that the copyright in the Original Work granted
|
||||||
|
hereunder is owned by him/her or licensed to him/her and that he/she has the
|
||||||
|
power and authority to grant the Licence.
|
||||||
|
|
||||||
|
Each Contributor warrants that the copyright in the modifications he/she brings
|
||||||
|
to the Work are owned by him/her or licensed to him/her and that he/she has the
|
||||||
|
power and authority to grant the Licence.
|
||||||
|
|
||||||
|
Each time You accept the Licence, the original Licensor and subsequent
|
||||||
|
Contributors grant You a licence to their contributions to the Work, under the
|
||||||
|
terms of this Licence.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty
|
||||||
|
|
||||||
|
The Work is a work in progress, which is continuously improved by numerous
|
||||||
|
contributors. It is not a finished work and may therefore contain defects or
|
||||||
|
“bugs” inherent to this type of software development.
|
||||||
|
|
||||||
|
For the above reason, the Work is provided under the Licence on an “as is” basis
|
||||||
|
and without warranties of any kind concerning the Work, including without
|
||||||
|
limitation merchantability, fitness for a particular purpose, absence of defects
|
||||||
|
or errors, accuracy, non-infringement of intellectual property rights other than
|
||||||
|
copyright as stated in Article 6 of this Licence.
|
||||||
|
|
||||||
|
This disclaimer of warranty is an essential part of the Licence and a condition
|
||||||
|
for the grant of any rights to the Work.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
8. Disclaimer of Liability
|
||||||
|
|
||||||
|
Except in the cases of wilful misconduct or damages directly caused to natural
|
||||||
|
persons, the Licensor will in no event be liable for any direct or indirect,
|
||||||
|
material or moral, damages of any kind, arising out of the Licence or of the use
|
||||||
|
of the Work, including without limitation, damages for loss of goodwill, work
|
||||||
|
stoppage, computer failure or malfunction, loss of data or any commercial
|
||||||
|
damage, even if the Licensor has been advised of the possibility of such
|
||||||
|
damage. However, the Licensor will be liable under statutory product liability
|
||||||
|
laws as far such laws apply to the Work.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
9. Additional agreements
|
||||||
|
|
||||||
|
While distributing the Original Work or Derivative Works, You may choose to
|
||||||
|
conclude an additional agreement to offer, and charge a fee for, acceptance of
|
||||||
|
support, warranty, indemnity, or other liability obligations and/or services
|
||||||
|
consistent with this Licence. However, in accepting such obligations, You may
|
||||||
|
act only on your own behalf and on your sole responsibility, not on behalf of
|
||||||
|
the original Licensor or any other Contributor, and only if You agree to
|
||||||
|
indemnify, defend, and hold each Contributor harmless for any liability incurred
|
||||||
|
by, or claims asserted against such Contributor by the fact You have accepted
|
||||||
|
any such warranty or additional liability.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
10. Acceptance of the Licence
|
||||||
|
|
||||||
|
The provisions of this Licence can be accepted by clicking on an icon “I agree”
|
||||||
|
placed under the bottom of a window displaying the text of this Licence or by
|
||||||
|
affirming consent in any other similar way, in accordance with the rules of
|
||||||
|
applicable law. Clicking on that icon indicates your clear and irrevocable
|
||||||
|
acceptance of this Licence and all of its terms and conditions.
|
||||||
|
|
||||||
|
Similarly, you irrevocably accept this Licence and all of its terms and
|
||||||
|
conditions by exercising any rights granted to You by Article 2 of this Licence,
|
||||||
|
such as the use of the Work, the creation by You of a Derivative Work or the
|
||||||
|
Distribution and/or Communication by You of the Work or copies thereof.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
11. Information to the public
|
||||||
|
|
||||||
|
In case of any Distribution and/or Communication of the Work by means of
|
||||||
|
electronic communication by You (for example, by offering to download the Work
|
||||||
|
from a remote location) the distribution channel or media (for example, a
|
||||||
|
website) must at least provide to the public the information requested by the
|
||||||
|
applicable law regarding the Licensor, the Licence and the way it may be
|
||||||
|
accessible, concluded, stored and reproduced by the Licensee.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
12. Termination of the Licence
|
||||||
|
|
||||||
|
The Licence and the rights granted hereunder will terminate automatically upon
|
||||||
|
any breach by the Licensee of the terms of the Licence.
|
||||||
|
|
||||||
|
Such a termination will not terminate the licences of any person who has
|
||||||
|
received the Work from the Licensee under the Licence, provided such persons
|
||||||
|
remain in full compliance with the Licence.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
13. Miscellaneous
|
||||||
|
|
||||||
|
Without prejudice of Article 9 above, the Licence represents the complete
|
||||||
|
agreement between the Parties as to the Work licensed hereunder.
|
||||||
|
|
||||||
|
If any provision of the Licence is invalid or unenforceable under applicable
|
||||||
|
law, this will not affect the validity or enforceability of the Licence as a
|
||||||
|
whole. Such provision will be construed and/or reformed so as necessary to make
|
||||||
|
it valid and enforceable.
|
||||||
|
|
||||||
|
The European Commission may publish other linguistic versions and/or new
|
||||||
|
versions of this Licence, so far this is required and reasonable, without
|
||||||
|
reducing the scope of the rights granted by the Licence. New versions of the
|
||||||
|
Licence will be published with a unique version number.
|
||||||
|
|
||||||
|
All linguistic versions of this Licence, approved by the European Commission,
|
||||||
|
have identical value. Parties can take advantage of the linguistic version of
|
||||||
|
their choice.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
14. Jurisdiction
|
||||||
|
|
||||||
|
Any litigation resulting from the interpretation of this License, arising
|
||||||
|
between the European Commission, as a Licensor, and any Licensee, will be
|
||||||
|
subject to the jurisdiction of the Court of Justice of the European Communities,
|
||||||
|
as laid down in article 238 of the Treaty establishing the European Community.
|
||||||
|
|
||||||
|
Any litigation arising between Parties, other than the European Commission, and
|
||||||
|
resulting from the interpretation of this License, will be subject to the
|
||||||
|
exclusive jurisdiction of the competent court where the Licensor resides or
|
||||||
|
conducts its primary business.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
15. Applicable Law
|
||||||
|
|
||||||
|
This Licence shall be governed by the law of the European Union country where
|
||||||
|
the Licensor resides or has his registered office.
|
||||||
|
|
||||||
|
This licence shall be governed by the Belgian law if:
|
||||||
|
|
||||||
|
- a litigation arises between the European Commission, as a Licensor, and any
|
||||||
|
- Licensee; the Licensor, other than the European Commission, has no residence
|
||||||
|
- or registered office inside a European Union country.
|
||||||
|
|
||||||
|
|
||||||
|
===
|
||||||
|
|
||||||
|
|
||||||
|
Appendix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
“Compatible Licences” according to article 5 EUPL are:
|
||||||
|
|
||||||
|
|
||||||
|
- GNU General Public License (GNU GPL) v. 2
|
||||||
|
|
||||||
|
- Open Software License (OSL) v. 2.1, v. 3.0
|
||||||
|
|
||||||
|
- Common Public License v. 1.0
|
||||||
|
|
||||||
|
- Eclipse Public License v. 1.0
|
||||||
|
|
||||||
|
- Cecill v. 2.0
|
|
@ -0,0 +1,78 @@
|
||||||
|
The gCube System - DataTransferService
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Service used to receive data from other hosting nodes
|
||||||
|
|
||||||
|
|
||||||
|
This software is part of the gCube Framework (https://www.gcube-system.org/): an
|
||||||
|
open-source software toolkit used for building and operating Hybrid Data
|
||||||
|
Infrastructures enabling the dynamic deployment of Virtual Research Environments
|
||||||
|
by favouring the realisation of reuse oriented policies.
|
||||||
|
|
||||||
|
The projects leading to this software have received funding from a series of
|
||||||
|
European Union programmes including:
|
||||||
|
* the Sixth Framework Programme for Research and Technological Development -
|
||||||
|
DILIGENT (grant no. 004260);
|
||||||
|
* the Seventh Framework Programme for research, technological development and
|
||||||
|
demonstration - D4Science (grant no. 212488), D4Science-II (grant no.
|
||||||
|
239019),ENVRI (grant no. 283465), EUBrazilOpenBio (grant no. 288754), iMarine
|
||||||
|
(grant no. 283644);
|
||||||
|
* the H2020 research and innovation programme - BlueBRIDGE (grant no. 675680),
|
||||||
|
EGIEngage (grant no. 654142), ENVRIplus (grant no. 654182), Parthenos (grant
|
||||||
|
no. 654119), SoBigData (grant no. 654024);
|
||||||
|
|
||||||
|
|
||||||
|
Version
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
2.0.0-SNAPSHOT (2017-05-17)
|
||||||
|
|
||||||
|
Please see the file named "changelog.xml" in this directory for the release notes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Authors
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
* Fabio Sinibaldi (fabio.sinibaldi-AT-isti.cnr.it) Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||||
|
|
||||||
|
Maintainers
|
||||||
|
-----------
|
||||||
|
|
||||||
|
* Fabio Sinibaldi (fabio.sinibaldi-AT-isti.cnr.it) Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||||
|
|
||||||
|
|
||||||
|
Download information
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Source code is available from SVN:
|
||||||
|
https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-transfer/data-transfer-service
|
||||||
|
|
||||||
|
Binaries can be downloaded from the gCube website:
|
||||||
|
https://www.gcube-system.org/
|
||||||
|
|
||||||
|
Installation
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Installation documentation is available on-line in the gCube Wiki:
|
||||||
|
https://wiki.gcube-system.org/gcube/index.php/Data_Transfer_2
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Documentation is available on-line in the gCube Wiki:
|
||||||
|
https://wiki.gcube-system.org/gcube/index.php/Data_Transfer_2
|
||||||
|
https://wiki.gcube-system.org/gcube/index.php/How_to_use_Data_Transfer_2
|
||||||
|
|
||||||
|
|
||||||
|
Support
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Bugs and support requests can be reported in the gCube issue tracking tool:
|
||||||
|
https://support.d4science.org/projects/gcube/
|
||||||
|
|
||||||
|
|
||||||
|
Licensing
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
This software is licensed under the terms you may find in the file named "LICENSE" in this directory.
|
|
@ -0,0 +1,13 @@
|
||||||
|
<ReleaseNotes>
|
||||||
|
<Changeset component="data-transfer-service-1.0.0" date="2016-02-22">
|
||||||
|
<Change>First Release</Change>
|
||||||
|
</Changeset>
|
||||||
|
<Changeset component="data-transfer-service-1.1.0" date="2016-09-09">
|
||||||
|
<Change>Added Destination</Change>
|
||||||
|
<Change>Added Plugin</Change>
|
||||||
|
</Changeset>
|
||||||
|
<Changeset component="data-transfer-service-1.2.0" date="2016-10-29">
|
||||||
|
<Change>Improved plugin management</Change>
|
||||||
|
<Change>Endorsed decompress-plugin</Change>
|
||||||
|
</Changeset>
|
||||||
|
</ReleaseNotes>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<id>servicearchive</id>
|
||||||
|
<formats>
|
||||||
|
<format>tar.gz</format>
|
||||||
|
</formats>
|
||||||
|
<baseDirectory>/</baseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>/home/fabio/workspaces/trunk_workspace/data-transfer-service/distro</directory>
|
||||||
|
<outputDirectory>/</outputDirectory>
|
||||||
|
<useDefaultExcludes>true</useDefaultExcludes>
|
||||||
|
<includes>
|
||||||
|
<include>README</include>
|
||||||
|
<include>LICENSE</include>
|
||||||
|
<include>changelog.xml</include>
|
||||||
|
</includes>
|
||||||
|
<fileMode>755</fileMode>
|
||||||
|
<filtered>true</filtered>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
<files>
|
||||||
|
<file>
|
||||||
|
<source>target/data-transfer-service.war</source>
|
||||||
|
<outputDirectory>/data-transfer-service</outputDirectory>
|
||||||
|
</file>
|
||||||
|
</files>
|
||||||
|
</assembly>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<application mode='online'>
|
||||||
|
<name>data-transfer-service</name>
|
||||||
|
<group>DataTransfer</group>
|
||||||
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
|
<description>Data Tansfer Service</description>
|
||||||
|
<!-- <servlets>
|
||||||
|
<servlet name="org.gcube.data.analysis.rconnector.RConnector" entryPointName="connector"/>
|
||||||
|
</servlets> -->
|
||||||
|
<local-persistence location='target' />
|
||||||
|
</application>
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<ID />
|
||||||
|
<Type>Service</Type>
|
||||||
|
<Profile>
|
||||||
|
<Description>Service used to receive data from other hosting nodes</Description>
|
||||||
|
<Class>DataTransfer</Class>
|
||||||
|
<Name>data-transfer-service</Name>
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
<Packages>
|
||||||
|
<Software>
|
||||||
|
<Name>data-transfer-service</Name>
|
||||||
|
<Version>2.0.0-SNAPSHOT</Version>
|
||||||
|
<MavenCoordinates>
|
||||||
|
<groupId>org.gcube.data.transfer</groupId>
|
||||||
|
<artifactId>data-transfer-service</artifactId>
|
||||||
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
|
</MavenCoordinates>
|
||||||
|
<Files>
|
||||||
|
<File>data-transfer-service.jar</File>
|
||||||
|
</Files>
|
||||||
|
</Software>
|
||||||
|
</Packages>
|
||||||
|
</Profile>
|
||||||
|
</Resource>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<web-app>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>org.gcube.data.transfer.service.DTService</servlet-name>
|
||||||
|
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>javax.ws.rs.Application</param-name>
|
||||||
|
<param-value>org.gcube.data.transfer.service.DTService</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>jersey.config.server.provider.classnames</param-name>
|
||||||
|
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
|
||||||
|
</init-param>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>org.gcube.data.transfer.service.DTService</servlet-name>
|
||||||
|
<url-pattern>/gcube/service/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
</web-app>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<configuration debug="true">
|
||||||
|
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<!-- encoders are assigned the type
|
||||||
|
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="debug">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.PluginDescription;
|
||||||
|
import org.gcube.data.transfer.model.TransferCapabilities;
|
||||||
|
import org.gcube.data.transfer.model.options.HttpDownloadOptions;
|
||||||
|
import org.gcube.data.transfer.model.options.TransferOptions;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.CapabilitiesProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.impl.PluginManagerImpl;
|
||||||
|
import org.glassfish.hk2.api.Factory;
|
||||||
|
|
||||||
|
public class CapabilitiesProviderFactory implements Factory<CapabilitiesProvider> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose(CapabilitiesProvider instance) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CapabilitiesProvider provide() {
|
||||||
|
return new CapabilitiesProvider(){
|
||||||
|
@Override
|
||||||
|
public TransferCapabilities get() {
|
||||||
|
return new TransferCapabilities("12345", "localhost", 80,
|
||||||
|
Collections.singleton((TransferOptions)HttpDownloadOptions.DEFAULT),
|
||||||
|
new HashSet<PluginDescription>(new PluginManagerImpl().getInstalledPlugins().values())
|
||||||
|
,Collections.<String> emptySet());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.DestinationAccessException;
|
||||||
|
|
||||||
|
public class ClashPolicyTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws DestinationAccessException {
|
||||||
|
File dir=new File ("/home/fabio/workspaces/DT_TESTS");
|
||||||
|
dir.mkdirs();
|
||||||
|
// System.out.println(RequestHandler.manageClash(DestinationClashPolicy.ADD_SUFFIX, new File(dir,"clashing.file")).getAbsolutePath());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.ext.ExceptionMapper;
|
||||||
|
import javax.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
@Provider
|
||||||
|
public class DebugExceptionMapper implements ExceptionMapper<Exception> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response toResponse(Exception exception) {
|
||||||
|
exception.printStackTrace();
|
||||||
|
Response toReturn=null;
|
||||||
|
if(exception instanceof WebApplicationException)
|
||||||
|
toReturn=((WebApplicationException)exception).getResponse();
|
||||||
|
else
|
||||||
|
toReturn=Response.serverError().entity(exception.getMessage()).build();
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.Destination;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PersistenceProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.DestinationAccessException;
|
||||||
|
import org.glassfish.hk2.api.Factory;
|
||||||
|
|
||||||
|
class PersistenceProviderFactory implements Factory<PersistenceProvider>{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PersistenceProvider provide() {
|
||||||
|
return new PersistenceProvider() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getPersistenceFolderById(String persistenceId) throws DestinationAccessException {
|
||||||
|
return new File(System.getProperty("java.io.tmpdir"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getAvaileblContextIds() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File prepareDestination(Destination dest) throws DestinationAccessException {
|
||||||
|
try {
|
||||||
|
return File.createTempFile("dest", "");
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose(PersistenceProvider arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PluginManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.impl.PluginManagerImpl;
|
||||||
|
import org.glassfish.hk2.api.Factory;
|
||||||
|
|
||||||
|
public class PluginManagerFactory implements Factory<PluginManager> {
|
||||||
|
|
||||||
|
static PluginManagerImpl impl=new PluginManagerImpl();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose(PluginManager arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PluginManager provide() {
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.RequestManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.impl.RequestManagerImpl;
|
||||||
|
import org.glassfish.hk2.api.Factory;
|
||||||
|
|
||||||
|
public class RequestManagerFactory implements Factory<RequestManager> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose(RequestManager instance) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestManager provide() {
|
||||||
|
return new RequestManagerImpl(new TicketManagerProvider().provide(),
|
||||||
|
new PersistenceProviderFactory().provide(),
|
||||||
|
new PluginManagerFactory().provide());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.client.Entity;
|
||||||
|
import javax.ws.rs.client.WebTarget;
|
||||||
|
import javax.ws.rs.core.Application;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.Destination;
|
||||||
|
import org.gcube.data.transfer.model.ServiceConstants;
|
||||||
|
import org.gcube.data.transfer.model.TransferCapabilities;
|
||||||
|
import org.gcube.data.transfer.model.TransferRequest;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket.Status;
|
||||||
|
import org.gcube.data.transfer.model.options.HttpDownloadOptions;
|
||||||
|
import org.gcube.data.transfer.model.settings.HttpDownloadSettings;
|
||||||
|
import org.gcube.data.transfer.service.transfers.Capabilities;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.CapabilitiesProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PersistenceProvider;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.PluginManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.RequestManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.TicketManager;
|
||||||
|
import org.glassfish.hk2.utilities.binding.AbstractBinder;
|
||||||
|
import org.glassfish.jersey.client.ClientConfig;
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
|
||||||
|
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
||||||
|
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
import org.glassfish.jersey.test.JerseyTest;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class TestCall extends JerseyTest {
|
||||||
|
|
||||||
|
public static class MyBinder extends AbstractBinder{
|
||||||
|
|
||||||
|
public MyBinder() {
|
||||||
|
super();
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bindFactory(TicketManagerProvider.class).to(TicketManager.class);
|
||||||
|
bindFactory(CapabilitiesProviderFactory.class).to(CapabilitiesProvider.class);
|
||||||
|
bindFactory(RequestManagerFactory.class).to(RequestManager.class);
|
||||||
|
bindFactory(PersistenceProviderFactory.class).to(PersistenceProvider.class);
|
||||||
|
bindFactory(PluginManagerFactory.class).to(PluginManager.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Application configure() {
|
||||||
|
System.out.println("Configuration for "+ServiceConstants.APPLICATION_PATH);
|
||||||
|
|
||||||
|
ResourceConfig config= new ResourceConfig(Capabilities.class,ProviderLoggingListener.class);
|
||||||
|
config.register(new MyBinder());
|
||||||
|
config.register(DebugExceptionMapper.class);
|
||||||
|
|
||||||
|
|
||||||
|
//Multipart
|
||||||
|
config.packages("org.glassfish.jersey.media.multipart");
|
||||||
|
config.packages("org.gcube.data.transfer.service.transfers");
|
||||||
|
config.register(MultiPartFeature.class);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureClient(ClientConfig config) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
super.configureClient(config);
|
||||||
|
config.register(MultiPartFeature.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void capabilities(){
|
||||||
|
WebTarget target=target(ServiceConstants.CAPABILTIES_SERVLET_NAME);
|
||||||
|
System.err.println(target.getUri());
|
||||||
|
System.out.println(target.request(MediaType.APPLICATION_JSON).get(TransferCapabilities.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotFoundException.class)
|
||||||
|
public void testTicketNotFound(){
|
||||||
|
System.out.println(getTicketById("myVeryLongestId"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void transfer() throws MalformedURLException{
|
||||||
|
TransferRequest request=new TransferRequest("", new HttpDownloadSettings(new URL("http://data.d4science.org/bm1sRTg0Y1ZZZHRraUZuNG1IUGdvOUVFMnlOcTlFRmlHbWJQNStIS0N6Yz0"), HttpDownloadOptions.DEFAULT),new Destination("something"));
|
||||||
|
TransferTicket submissionResponse=submit(request);
|
||||||
|
System.out.println("Obtained "+submissionResponse);
|
||||||
|
boolean continuePolling=true;
|
||||||
|
do{
|
||||||
|
TransferTicket ticket=getTicketById(submissionResponse.getId());
|
||||||
|
System.out.println("Status : "+ticket);
|
||||||
|
continuePolling=ticket.getStatus().equals(Status.PENDING)||ticket.getStatus().equals(Status.TRANSFERRING)||ticket.getStatus().equals(Status.WAITING);
|
||||||
|
try{
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}catch(InterruptedException e){}
|
||||||
|
}while(continuePolling);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void RESTUpload(){
|
||||||
|
FormDataMultiPart multipart = new FormDataMultiPart();
|
||||||
|
File toSend=new File("/home/fabio/life@dev2.d4science.org");
|
||||||
|
Assert.assertTrue(toSend!=null);
|
||||||
|
Assert.assertTrue(toSend.exists());
|
||||||
|
multipart.bodyPart(new FileDataBodyPart(ServiceConstants.MULTIPART_FILE, toSend));
|
||||||
|
WebTarget target=target(ServiceConstants.REST_SERVLET_NAME).path(ServiceConstants.REST_FILE_UPLOAD).path("data-transfer-service").path("my/sub/path");
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println(target.request().post(Entity.entity(multipart, multipart.getMediaType())));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private TransferTicket getTicketById(String id){
|
||||||
|
return target(ServiceConstants.STATUS_SERVLET_NAME).path(id).request(MediaType.APPLICATION_JSON).get(TransferTicket.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TransferTicket submit(TransferRequest req){
|
||||||
|
return target(ServiceConstants.REQUESTS_SERVLET_NAME).request(MediaType.APPLICATION_JSON).post(Entity.entity(req,MediaType.APPLICATION_JSON),TransferTicket.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.PluginDescription;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.impl.PluginManagerImpl;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TestPlugins {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlugins(){
|
||||||
|
Map<String,PluginDescription> plugins=new PluginManagerImpl().getInstalledPlugins();
|
||||||
|
Assert.assertNotNull(plugins);
|
||||||
|
System.out.println(plugins);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.gcube.data.transfer.service;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.gcube.data.transfer.model.TransferRequest;
|
||||||
|
import org.gcube.data.transfer.model.TransferTicket;
|
||||||
|
import org.gcube.data.transfer.model.options.HttpDownloadOptions;
|
||||||
|
import org.gcube.data.transfer.model.settings.HttpDownloadSettings;
|
||||||
|
import org.gcube.data.transfer.model.utils.DateWrapper;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.TicketManager;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.faults.TicketNotFoundException;
|
||||||
|
import org.gcube.data.transfer.service.transfers.engine.impl.TransferTicketManagerImpl;
|
||||||
|
import org.glassfish.hk2.api.Factory;
|
||||||
|
|
||||||
|
public class TicketManagerProvider implements Factory<TicketManager> {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose(TicketManager instance) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TicketManager provide() {
|
||||||
|
return new TransferTicketManagerImpl(){
|
||||||
|
// @Override
|
||||||
|
// public TransferTicket get(String ticketId)
|
||||||
|
// throws TicketNotFoundException{
|
||||||
|
// URL url=null;
|
||||||
|
// try{
|
||||||
|
// url=new URL("http://some.where.com");
|
||||||
|
// }catch(MalformedURLException e){}
|
||||||
|
// TransferRequest request=new TransferRequest(UUID.randomUUID().toString(), new HttpDownloadSettings(url,new HttpDownloadOptions()));
|
||||||
|
// return new TransferTicket(request, org.gcube.data.transfer.model.TransferTicket.Status.STOPPED, 1005467l, .57d, 123345, new DateWrapper(),"/dev/null","bona");
|
||||||
|
//// throw new TicketNotFoundException();
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<configuration debug="true">
|
||||||
|
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<!-- encoders are assigned the type
|
||||||
|
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="debug">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
Loading…
Reference in New Issue