Compare commits
12 Commits
master
...
feature/28
Author | SHA1 | Date |
---|---|---|
Biagio Peccerillo | 2b54a98760 | |
Biagio Peccerillo | 3f45dce6f7 | |
Biagio Peccerillo | 589e38cd55 | |
Biagio Peccerillo | 868dbabcff | |
Biagio Peccerillo | bf55883511 | |
Biagio Peccerillo | a34eef4617 | |
Biagio Peccerillo | 0ee16386f0 | |
Biagio Peccerillo | d0fac83c50 | |
Biagio Peccerillo | 1d3cc6c073 | |
Biagio Peccerillo | 65b9f611dc | |
Biagio Peccerillo | deb1d315de | |
Biagio Peccerillo | eedf6ef667 |
|
@ -1,3 +1,3 @@
|
||||||
FROM d4science/smartgears-distribution:4.0.1-SNAPSHOT-java17-tomcat10.1.19
|
FROM harbor.d4science.org/gcube/smartgears-distribution:4.0.1-SNAPSHOT-java17-tomcat10.1.19
|
||||||
COPY ./target/storagehub.war /tomcat/webapps/
|
COPY ./target/storagehub.war /tomcat/webapps/
|
||||||
COPY ./docker/storagehub.xml /tomcat/conf/Catalina/localhost/
|
COPY ./docker/storagehub.xml /tomcat/conf/Catalina/localhost/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM d4science/smartgears-distribution:4.0.0-SNAPSHOT-java17-tomcat10.1.19
|
FROM harbor.d4science.org/gcube/smartgears-distribution:4.0.0-SNAPSHOT-java17-tomcat10.1.19
|
||||||
|
|
||||||
#install unzip
|
#install unzip
|
||||||
RUN apt-get update && apt-get install unzip
|
RUN apt-get update && apt-get install unzip
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM smartgears-distribution:4.0.0-java17-tomcat10.1.19
|
FROM harbor.d4science.org/gcube/smartgears-distribution:4.0.0-SNAPSHOT-java17-tomcat10.1.19
|
||||||
COPY ./target/storagehub.war /tomcat/webapps/
|
COPY ./target/storagehub.war /tomcat/webapps/
|
||||||
COPY ./docker/jackrabbit /app/jackrabbit
|
COPY ./docker/jackrabbit /app/jackrabbit
|
||||||
COPY ./docker/storagehub.xml /tomcat/conf/Catalina/localhost/
|
COPY ./docker/storagehub.xml /tomcat/conf/Catalina/localhost/
|
||||||
|
|
|
@ -1,24 +1,41 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<enunciate
|
<enunciate
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:noNamespaceSchemaLocation="http://enunciate.webcohesion.com/schemas/enunciate-2.14.0.xsd">
|
xsi:noNamespaceSchemaLocation="http://enunciate.webcohesion.com/schemas/enunciate-2.18.0.xsd">
|
||||||
<api-classes>
|
<description>
|
||||||
<!-- Use patterns to exclude classes... e.g. for URI-Resolver <exclude
|
<![CDATA[
|
||||||
pattern="org.gcube.datatransfer.resolver.services.DocsGenerator" /> -->
|
<h1>StorageHUB</h1>
|
||||||
</api-classes>
|
<p>StorageHUB is the service implementing the gCube Workspace feature.</p>
|
||||||
|
<p>It provides an intermediate layer between the storage and the services
|
||||||
|
willing to access it.</p>
|
||||||
|
]]>
|
||||||
|
</description>
|
||||||
|
<code-license>This project is licensed under the EUPL V.1.1 License - see the LICENSE.md file for details.</code-license>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<gwt-json-overlay disabled="true" />
|
<gwt-json-overlay disabled="true" />
|
||||||
<php-json-client disabled="true" />
|
<php-json-client disabled="true" />
|
||||||
<ruby-json-client disabled="true" />
|
<ruby-json-client disabled="true" />
|
||||||
<java-json-client disabled="true" />
|
<java-json-client disabled="true" />
|
||||||
<javascript-client disabled="true" />
|
<javascript-client disabled="true" />
|
||||||
<docs docsDir="${project.build.directory}" docsSubdir="api-docs" />
|
<java-xml-client disabled="true" />
|
||||||
|
<jaxb disabled="true" />
|
||||||
|
<jaxws disabled="true" />
|
||||||
|
|
||||||
|
<c-xml-client disabled="true" />
|
||||||
|
<csharp-xml-client disabled="true" />
|
||||||
|
<obj-c-xml-client disabled="true" />
|
||||||
|
<php-xml-client disabled="true" />
|
||||||
|
<spring-webnt disabled="true" />
|
||||||
|
|
||||||
|
<jaxrs groupBy="class" disableExamples="false" path-sort-strategy="depth_first" />
|
||||||
|
<swagger basePath="/workspace" />
|
||||||
|
|
||||||
|
<docs docsDir="${project.build.directory}" docsSubdir="api-docs" />
|
||||||
<docs
|
<docs
|
||||||
freemarkerTemplate="${project.basedir}/src/main/resources/META-INF/enunciate/d4science_docs.fmt">
|
freemarkerTemplate="${project.basedir}/src/main/resources/META-INF/enunciate/d4science_docs.fmt">
|
||||||
<additional-css
|
<additional-css file="css/d4science_enunciate_custom.css" />
|
||||||
file="css/d4science_enunciate_custom.css" />
|
|
||||||
</docs>
|
</docs>
|
||||||
<swagger basePath="/workspace" />
|
|
||||||
</modules>
|
</modules>
|
||||||
</enunciate>
|
</enunciate>
|
31
pom.xml
31
pom.xml
|
@ -32,7 +32,7 @@
|
||||||
<warname>storagehub</warname>
|
<warname>storagehub</warname>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<enunciate.version>2.17.1</enunciate.version>
|
<enunciate.version>2.18.1</enunciate.version>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
<java_version>17</java_version>
|
<java_version>17</java_version>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.distribution</groupId>
|
<groupId>org.gcube.distribution</groupId>
|
||||||
<artifactId>gcube-smartgears-bom</artifactId>
|
<artifactId>gcube-smartgears-bom</artifactId>
|
||||||
<version>4.0.0</version>
|
<version>4.0.1-SNAPSHOT</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -428,7 +428,32 @@
|
||||||
<groupId>com.webcohesion.enunciate</groupId>
|
<groupId>com.webcohesion.enunciate</groupId>
|
||||||
<artifactId>enunciate-maven-plugin</artifactId>
|
<artifactId>enunciate-maven-plugin</artifactId>
|
||||||
<version>${enunciate.version}</version>
|
<version>${enunciate.version}</version>
|
||||||
<configuration></configuration>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.webcohesion.enunciate</groupId>
|
||||||
|
<artifactId>enunciate-lombok</artifactId>
|
||||||
|
<version>2.9.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<configuration>
|
||||||
|
<sourcepath-includes>
|
||||||
|
<!-- Include storagehub classes -->
|
||||||
|
<sourcepath-include>
|
||||||
|
<groupId>org.gcube.common</groupId>
|
||||||
|
<artifactId>storagehub</artifactId>
|
||||||
|
</sourcepath-include>
|
||||||
|
<!-- Include storagehub-model classes -->
|
||||||
|
<sourcepath-include>
|
||||||
|
<groupId>org.gcube.common</groupId>
|
||||||
|
<artifactId>storagehub-model</artifactId>
|
||||||
|
</sourcepath-include>
|
||||||
|
<!-- Include jersey media classes -->
|
||||||
|
<sourcepath-include>
|
||||||
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
|
<artifactId>jersey-media-multipart</artifactId>
|
||||||
|
</sourcepath-include>
|
||||||
|
</sourcepath-includes>
|
||||||
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>assemble</id>
|
<id>assemble</id>
|
||||||
|
|
|
@ -35,14 +35,19 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.DocumentationExample;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceMethodSignature;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
import jakarta.enterprise.context.RequestScoped;
|
import jakarta.enterprise.context.RequestScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
import jakarta.ws.rs.DELETE;
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.FormParam;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.PUT;
|
import jakarta.ws.rs.PUT;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
|
@ -53,10 +58,13 @@ import jakarta.ws.rs.core.Context;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage the Access Control List of shared folders
|
||||||
|
*/
|
||||||
@Path("items")
|
@Path("items")
|
||||||
@ManagedBy(StorageHubApplicationManager.class)
|
@ManagedBy(StorageHubApplicationManager.class)
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"),
|
||||||
})
|
})
|
||||||
public class ACLManager extends Impersonable {
|
public class ACLManager extends Impersonable {
|
||||||
|
|
||||||
|
@ -91,9 +99,13 @@ public class ACLManager extends Impersonable {
|
||||||
/**
|
/**
|
||||||
* returns the AccessType for all the users in a shared folder
|
* returns the AccessType for all the users in a shared folder
|
||||||
*
|
*
|
||||||
* @exception {@link RepositoryException} when a generic jcr error occurs
|
* @param id id of the shared folder
|
||||||
* @exception {@link UserNotAuthorizedException} when the caller is not authorized to access to the shared folder
|
|
||||||
*/
|
*/
|
||||||
|
@ResourceMethodSignature(output = ACLList.class, pathParams = { @PathParam("id") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Shared folder found."),
|
||||||
|
@ResponseCode ( code = 500, condition = "This item does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/acls")
|
@Path("{id}/acls")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -122,15 +134,26 @@ public class ACLManager extends Impersonable {
|
||||||
/**
|
/**
|
||||||
* Set a new AccessType for a user in a shared folder or VRE folder
|
* Set a new AccessType for a user in a shared folder or VRE folder
|
||||||
*
|
*
|
||||||
*
|
* @param id id of the shared folder
|
||||||
* @param String user
|
* @param user user id
|
||||||
* @param accessType accessType
|
* @param access access type<br>
|
||||||
*
|
* <strong>Possible values:</strong> <code>READ_ONLY</code>, <code>WRITE_OWNER</code>, <code>WRITE_ALL</code>, <code>ADMINISTRATOR</code>
|
||||||
* @exception {@link RepositoryException} when a generic jcr error occurs
|
|
||||||
* @exception {@link UserNotAuthorizedException} when the caller is not ADMINISTRATOR of the shared folder
|
|
||||||
* @exception {@link InvalidCallParameters} when the folder is not shared with the specified user
|
|
||||||
* @exception {@link InvalidItemException} when the folder is not share
|
|
||||||
*/
|
*/
|
||||||
|
@ResourceMethodSignature(output = void.class, pathParams = { @PathParam("id") }, formParams = {
|
||||||
|
@FormParam("user"), @FormParam("access") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 204, condition = "Access type updated."),
|
||||||
|
@ResponseCode ( code = 400, condition = "User does not exist."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
@ResponseCode ( code = 500, condition = "This shared item does not exist or wrong access type."),
|
||||||
|
})
|
||||||
|
@DocumentationExample(value = "...\n\n--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"user\"\n\n" +
|
||||||
|
"user2\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"accessType\"\n\n" +
|
||||||
|
"WRITE_OWNER\n" +
|
||||||
|
"--------boundaryString--")
|
||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
@Path("{id}/acls")
|
@Path("{id}/acls")
|
||||||
|
@ -186,18 +209,17 @@ public class ACLManager extends Impersonable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove right for a user only on Shared folder
|
* Remove a user from the shared folder
|
||||||
*
|
*
|
||||||
*
|
* @param id id of the shared folder
|
||||||
* @param String user
|
* @param user user id
|
||||||
*
|
|
||||||
*
|
|
||||||
* @exception {@link RepositoryException} when a generic jcr error occurs
|
|
||||||
* @exception {@link UserNotAuthorizedException} when the caller is not ADMINISTRATOR of the shared folder
|
|
||||||
* @exception {@link InvalidCallParameters} when the folder is not shared with the specified user
|
|
||||||
* @exception {@link InvalidItemException} when the folder is not share
|
|
||||||
*/
|
*/
|
||||||
//TODO: is this method correct? can ACL be removed, is correct that this means an unshare operation?
|
@ResourceMethodSignature(output = void.class, pathParams = { @PathParam("id"), @PathParam("user") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 204, condition = "User removed."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
@ResponseCode ( code = 500, condition = "This shared item does not exist."),
|
||||||
|
})
|
||||||
@DELETE
|
@DELETE
|
||||||
@Consumes(MediaType.TEXT_PLAIN)
|
@Consumes(MediaType.TEXT_PLAIN)
|
||||||
@Path("{id}/acls/{user}")
|
@Path("{id}/acls/{user}")
|
||||||
|
@ -233,7 +255,20 @@ public class ACLManager extends Impersonable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the current user can write on the shared folder
|
||||||
|
*
|
||||||
|
* @param id id of the shared folder
|
||||||
|
* @return true if the current user can write on the shared folder, false otherwise
|
||||||
|
* @responseExample text/plain true
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = Boolean.class, pathParams = { @PathParam("id") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Shared folder found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "This shared folder does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@Path("{id}/acls/write")
|
@Path("{id}/acls/write")
|
||||||
public Boolean canWriteInto() {
|
public Boolean canWriteInto() {
|
||||||
InnerMethodName.set("canWriteIntoFolder");
|
InnerMethodName.set("canWriteIntoFolder");
|
||||||
|
|
|
@ -14,11 +14,14 @@ import jakarta.ws.rs.core.Response.Status;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.Ignore;
|
||||||
|
|
||||||
@Path("api-docs")
|
@Path("api-docs")
|
||||||
public class DocsGenerator {
|
public class DocsGenerator {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(DocsGenerator.class);
|
private static Logger logger = LoggerFactory.getLogger(DocsGenerator.class);
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@GET
|
@GET
|
||||||
@Path("/{any: .*}")
|
@Path("/{any: .*}")
|
||||||
public InputStream toDoc(@Context HttpServletRequest req) throws WebApplicationException {
|
public InputStream toDoc(@Context HttpServletRequest req) throws WebApplicationException {
|
||||||
|
|
|
@ -28,8 +28,12 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.DocumentationExample;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceMethodSignature;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
|
@ -46,11 +50,14 @@ import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages groups
|
||||||
|
*/
|
||||||
@Path("groups")
|
@Path("groups")
|
||||||
@Singleton
|
@Singleton
|
||||||
@ManagedBy(StorageHubApplicationManager.class)
|
@ManagedBy(StorageHubApplicationManager.class)
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"),
|
||||||
})
|
})
|
||||||
public class GroupManager {
|
public class GroupManager {
|
||||||
|
|
||||||
|
@ -66,6 +73,15 @@ public class GroupManager {
|
||||||
PathUtil pathUtil;
|
PathUtil pathUtil;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of the groups for the current user
|
||||||
|
*
|
||||||
|
* @return list of groups
|
||||||
|
* @responseExample text/plain ["group1", "group2", "group3"]
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("")
|
@Path("")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -87,9 +103,44 @@ public class GroupManager {
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new group <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param group group name
|
||||||
|
* @param accessType access type<br> <strong>Possible values:</strong> <code>READ_ONLY</code>, <code>WRITE_OWNER</code>, <code>WRITE_ALL</code>, <code>ADMINISTRATOR</code>
|
||||||
|
* @param folderOwner folder owner
|
||||||
|
* @param useDefaultStorage use default storage if true<br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code><br>
|
||||||
|
* <strong>Optional</strong> default: <code>true</code>
|
||||||
|
* @return group name
|
||||||
|
* @responseExample text/plain "group"
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, formParams = {
|
||||||
|
@FormParam("group"), @FormParam("accessType"), @FormParam("folderOwner"), @FormParam("useDefaultStorage") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to create groups."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Error creating group."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
|
@DocumentationExample(value = "...\n\n--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"group\"\n\n" +
|
||||||
|
"my_group\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"accessType\"\n\n" +
|
||||||
|
"ADMINISTRATOR\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"folderOwner\"\n\n" +
|
||||||
|
"user1\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"useDefaultStorage\"\n\n" +
|
||||||
|
"true\n" +
|
||||||
|
"--------boundaryString--")
|
||||||
@POST
|
@POST
|
||||||
@Path("")
|
@Path("")
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE})
|
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE})
|
||||||
public String createGroup(@FormDataParam("group") String group, @FormDataParam("accessType") AccessType accessType, @FormDataParam("folderOwner") String folderOwner, @FormDataParam("useDefaultStorage") @DefaultValue("true") boolean useDefaultStorage){
|
public String createGroup(@FormDataParam("group") String group, @FormDataParam("accessType") AccessType accessType, @FormDataParam("folderOwner") String folderOwner, @FormDataParam("useDefaultStorage") @DefaultValue("true") boolean useDefaultStorage){
|
||||||
|
|
||||||
|
@ -112,8 +163,22 @@ public class GroupManager {
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a group <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param group group name
|
||||||
|
* @return group name
|
||||||
|
* @responseExample text/plain "group"
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to delete groups."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Error deleting group."),
|
||||||
|
})
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{group}")
|
@Path("{group}")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE})
|
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE})
|
||||||
public String deleteGroup(@PathParam("group") String group){
|
public String deleteGroup(@PathParam("group") String group){
|
||||||
|
|
||||||
|
@ -138,6 +203,18 @@ public class GroupManager {
|
||||||
|
|
||||||
public boolean isVREManager() { return SecretManagerProvider.get().getOwner().getRoles().contains(VREMANAGER_ROLE); }
|
public boolean isVREManager() { return SecretManagerProvider.get().getOwner().getRoles().contains(VREMANAGER_ROLE); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an administrator to a group
|
||||||
|
*
|
||||||
|
* @param id group name
|
||||||
|
* @param userId user name
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 204, condition = "Success."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Error adding an admin."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id")}, formParams = { @FormParam("userId") })
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/admins")
|
@Path("{id}/admins")
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
@ -175,9 +252,20 @@ public class GroupManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an administrator from a group. The removed admin remains in the group as a <em>normal</em> user.
|
||||||
|
*
|
||||||
|
* @param id group name
|
||||||
|
* @param userId user name
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 204, condition = "Success."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Error removing an admin."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
|
@ResourceMethodSignature(output = void.class, pathParams = { @PathParam("id")}, formParams = { @FormParam("userId") })
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{id}/admins/{userId}")
|
@Path("{id}/admins/{userId}")
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
|
||||||
public void removeAdmin(@PathParam("id") String groupId, @PathParam("userId") String userId){
|
public void removeAdmin(@PathParam("id") String groupId, @PathParam("userId") String userId){
|
||||||
|
|
||||||
InnerMethodName.set("removeAdmin");
|
InnerMethodName.set("removeAdmin");
|
||||||
|
@ -210,6 +298,16 @@ public class GroupManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of administrators of a group
|
||||||
|
*
|
||||||
|
* @param groupId group name
|
||||||
|
* @return list of administrators
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
@ResponseCode ( code = 406, condition = "This group does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{groupId}/admins")
|
@Path("{groupId}/admins")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -236,6 +334,23 @@ public class GroupManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a user to a group <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> or <code>VRE-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param id group name
|
||||||
|
* @param userId user name
|
||||||
|
* @return true if the user has been added to the group
|
||||||
|
* @responseExample text/plain true
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to add users to groups."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Group or user does not exist."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
|
@ResourceMethodSignature(output = boolean.class, pathParams = { @PathParam("id")}, formParams = { @FormParam("userId") })
|
||||||
|
@DocumentationExample(value = "...\n\nuserId=user1\n")
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/users")
|
@Path("{id}/users")
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
@ -271,6 +386,19 @@ public class GroupManager {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a user from a group <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> or <code>VRE-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param groupId group name
|
||||||
|
* @param userId user name
|
||||||
|
* @return true if the user has been removed from the group
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to add users to groups."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Group or user does not exist."),
|
||||||
|
})
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{groupId}/users/{userId}")
|
@Path("{groupId}/users/{userId}")
|
||||||
@AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE})
|
@AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE})
|
||||||
|
@ -304,6 +432,17 @@ public class GroupManager {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of users of a group <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> or <code>VRE-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param groupId group name
|
||||||
|
* @return list of users
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Group does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{groupId}/users")
|
@Path("{groupId}/users")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
|
|
@ -42,13 +42,17 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.DocumentationExample;
|
||||||
|
import com.webcohesion.enunciate.metadata.Ignore;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceMethodSignature;
|
||||||
|
|
||||||
import jakarta.enterprise.context.RequestScoped;
|
import jakarta.enterprise.context.RequestScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.FormParam;
|
import jakarta.ws.rs.FormParam;
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.PUT;
|
import jakarta.ws.rs.PUT;
|
||||||
|
@ -59,10 +63,12 @@ import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage item sharing.
|
||||||
|
*/
|
||||||
@Path("items")
|
@Path("items")
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"),
|
||||||
})
|
})
|
||||||
public class ItemSharing extends Impersonable{
|
public class ItemSharing extends Impersonable{
|
||||||
|
|
||||||
|
@ -92,10 +98,12 @@ public class ItemSharing extends Impersonable{
|
||||||
@Inject Node2ItemConverter node2Item;
|
@Inject Node2ItemConverter node2Item;
|
||||||
@Inject Item2NodeConverter item2Node;
|
@Inject Item2NodeConverter item2Node;
|
||||||
|
|
||||||
|
// TODO: Remove this method - not used by anyone
|
||||||
|
@Ignore
|
||||||
|
@POST
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@POST
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@Path("{id}/share")
|
@Path("{id}/share")
|
||||||
public String shareWithMap(@FormParam("mapUserPermission") String mapUserPermissionString, @FormParam("defaultAccessType") String defaultAccessTypeString){
|
public String shareWithMap(@FormParam("mapUserPermission") String mapUserPermissionString, @FormParam("defaultAccessType") String defaultAccessTypeString){
|
||||||
InnerMethodName.set("shareFolder");
|
InnerMethodName.set("shareFolder");
|
||||||
|
@ -197,9 +205,32 @@ public class ItemSharing extends Impersonable{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Share an item with some users and set its access type.
|
||||||
|
*
|
||||||
|
* @param id id of the item
|
||||||
|
* @param users set of users
|
||||||
|
* @param defaultAccessType default access type<br>
|
||||||
|
* <strong>Possible values:</strong> <code>READ_ONLY</code>, <code>WRITE_OWNER</code>, <code>WRITE_ALL</code>, <code>ADMINISTRATOR</code>
|
||||||
|
* @return id of the shared item
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") }, formParams = {
|
||||||
|
@FormParam("users"), @FormParam("defaultAccessType") })
|
||||||
|
@DocumentationExample("...\n\n--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"users\"\n\n" +
|
||||||
|
"user1\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"users\"\n\n" +
|
||||||
|
"user2\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"defaultAccessType\"\n\n" +
|
||||||
|
"READ_ONLY\n" +
|
||||||
|
"------boundaryString--")
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/share")
|
@Path("{id}/share")
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
public String share(@FormDataParam("users") Set<String> users, @FormDataParam("defaultAccessType") AccessType accessType){
|
public String share(@FormDataParam("users") Set<String> users, @FormDataParam("defaultAccessType") AccessType accessType){
|
||||||
InnerMethodName.set("shareFolder");
|
InnerMethodName.set("shareFolder");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
|
@ -339,9 +370,24 @@ public class ItemSharing extends Impersonable{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unshare an item with some users.
|
||||||
|
*
|
||||||
|
* @param id id of the item
|
||||||
|
* @param users set of users
|
||||||
|
* @return id of the unshared item
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") }, formParams = {
|
||||||
|
@FormParam("users") })
|
||||||
|
@DocumentationExample("...\n\n--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"users\"\n\n" +
|
||||||
|
"user1,user2,user3\n" +
|
||||||
|
"--------boundaryString--")
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/unshare")
|
@Path("{id}/unshare")
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
public String unshare(@FormDataParam("users") Set<String> users){
|
public String unshare(@FormDataParam("users") Set<String> users){
|
||||||
InnerMethodName.set("unshareFolder");
|
InnerMethodName.set("unshareFolder");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
|
|
|
@ -39,8 +39,13 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.DocumentationExample;
|
||||||
|
import com.webcohesion.enunciate.metadata.Ignore;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceMethodSignature;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
|
@ -50,17 +55,20 @@ import jakarta.ws.rs.FormParam;
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.core.Context;
|
import jakarta.ws.rs.core.Context;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage item creation.
|
||||||
|
*/
|
||||||
@Path("items")
|
@Path("items")
|
||||||
@ManagedBy(StorageHubApplicationManager.class)
|
@ManagedBy(StorageHubApplicationManager.class)
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
@RequestHeader(name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>")
|
||||||
})
|
})
|
||||||
public class ItemsCreator extends Impersonable{
|
public class ItemsCreator extends Impersonable {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ItemsCreator.class);
|
private static final Logger log = LoggerFactory.getLogger(ItemsCreator.class);
|
||||||
|
|
||||||
|
@ -72,8 +80,29 @@ public class ItemsCreator extends Impersonable{
|
||||||
@Inject
|
@Inject
|
||||||
ItemHandler itemHandler;
|
ItemHandler itemHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a folder.
|
||||||
|
*
|
||||||
|
* @param id destination parent folder id
|
||||||
|
* @param name destination folder name
|
||||||
|
* @param description description meta-info for the created folder
|
||||||
|
* @param hidden hidden folder if true<br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code> <br>
|
||||||
|
* <strong>Optional</strong> default: <code>false</code>
|
||||||
|
* @return id of the created folder
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") }, formParams = {
|
||||||
|
@FormParam("name"), @FormParam("description"), @FormParam("hidden") })
|
||||||
|
@DocumentationExample(" ...\n\nname=sampleFolder&description=This+is+a+sample+folder&hidden=false")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Folder created."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Wrong set of parameters."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@Path("/{id}/create/FOLDER")
|
@Path("/{id}/create/FOLDER")
|
||||||
public Response createFolder(@PathParam("id") String id, @FormParam("name") String name,
|
public Response createFolder(@PathParam("id") String id, @FormParam("name") String name,
|
||||||
@FormParam("description") String description, @FormParam("hidden") boolean hidden) {
|
@FormParam("description") String description, @FormParam("hidden") boolean hidden) {
|
||||||
|
@ -81,29 +110,31 @@ public class ItemsCreator extends Impersonable{
|
||||||
log.info("create folder item called");
|
log.info("create folder item called");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
try{
|
try {
|
||||||
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
||||||
ItemsParameterBuilder<FolderCreationParameters> builder = FolderCreationParameters.builder().name(name).description(description).hidden(hidden).on(id).with(ses).author(currentUser);
|
ItemsParameterBuilder<FolderCreationParameters> builder = FolderCreationParameters.builder().name(name)
|
||||||
|
.description(description).hidden(hidden).on(id).with(ses).author(currentUser);
|
||||||
toReturn = itemHandler.create(builder.build());
|
toReturn = itemHandler.create(builder.build());
|
||||||
}catch(StorageHubException she ){
|
} catch (StorageHubException she) {
|
||||||
log.error(she.getErrorMessage(), she);
|
log.error(she.getErrorMessage(), she);
|
||||||
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
||||||
}catch(RepositoryException re ){
|
} catch (RepositoryException re) {
|
||||||
log.error("jcr error creating item", re);
|
log.error("jcr error creating item", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
|
||||||
}catch(Throwable e ){
|
} catch (Throwable e) {
|
||||||
log.error("unexpected error", e);
|
log.error("unexpected error", e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
}finally{
|
} finally {
|
||||||
if (ses!=null)
|
if (ses != null)
|
||||||
ses.logout();
|
ses.logout();
|
||||||
|
|
||||||
}
|
}
|
||||||
return Response.ok(toReturn).build();
|
return Response.ok(toReturn).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@POST
|
@POST
|
||||||
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE})
|
@AuthorizationControl(allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE })
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/{id}/create/EXTERNALFOLDER")
|
@Path("/{id}/create/EXTERNALFOLDER")
|
||||||
public Response createExternalFolder(@PathParam("id") String id, @FormParam("name") String name,
|
public Response createExternalFolder(@PathParam("id") String id, @FormParam("name") String name,
|
||||||
|
@ -114,7 +145,7 @@ public class ItemsCreator extends Impersonable{
|
||||||
log.info("create folder item called");
|
log.info("create folder item called");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
try{
|
try {
|
||||||
Iterator<String> paramIt = request.getParameterNames().asIterator();
|
Iterator<String> paramIt = request.getParameterNames().asIterator();
|
||||||
Iterable<String> iterable = () -> paramIt;
|
Iterable<String> iterable = () -> paramIt;
|
||||||
Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false);
|
Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false);
|
||||||
|
@ -124,60 +155,81 @@ public class ItemsCreator extends Impersonable{
|
||||||
targetStream.filter(v -> v.startsWith("plugin."))
|
targetStream.filter(v -> v.startsWith("plugin."))
|
||||||
.forEach(v -> pluginParams.add(v.replace("plugin.", ""), request.getParameter(v)));
|
.forEach(v -> pluginParams.add(v.replace("plugin.", ""), request.getParameter(v)));
|
||||||
|
|
||||||
log.debug("parameters for external folder with plugin {} are {}",pluginName, pluginParams.toString());
|
log.debug("parameters for external folder with plugin {} are {}", pluginName, pluginParams.toString());
|
||||||
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
||||||
ItemsParameterBuilder<FolderCreationParameters> builder = FolderCreationParameters.builder().name(name)
|
ItemsParameterBuilder<FolderCreationParameters> builder = FolderCreationParameters.builder().name(name)
|
||||||
.description(description).onRepository(pluginName).withParameters(pluginParams.getParameters()).hidden(hidden).on(id).with(ses).author(currentUser);
|
.description(description).onRepository(pluginName).withParameters(pluginParams.getParameters())
|
||||||
|
.hidden(hidden).on(id).with(ses).author(currentUser);
|
||||||
toReturn = itemHandler.create(builder.build());
|
toReturn = itemHandler.create(builder.build());
|
||||||
}catch(StorageHubException she ){
|
} catch (StorageHubException she) {
|
||||||
log.error(she.getErrorMessage(), she);
|
log.error(she.getErrorMessage(), she);
|
||||||
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
||||||
}catch(RepositoryException re ){
|
} catch (RepositoryException re) {
|
||||||
log.error("jcr error creating item", re);
|
log.error("jcr error creating item", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
|
||||||
}catch(Throwable e ){
|
} catch (Throwable e) {
|
||||||
log.error("unexpected error", e);
|
log.error("unexpected error", e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
}finally{
|
} finally {
|
||||||
if (ses!=null)
|
if (ses != null)
|
||||||
ses.logout();
|
ses.logout();
|
||||||
|
|
||||||
}
|
}
|
||||||
return Response.ok(toReturn).build();
|
return Response.ok(toReturn).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a URL.
|
||||||
|
*
|
||||||
|
* @param id destination parent folder id
|
||||||
|
* @param name destination URL name
|
||||||
|
* @param description description meta-info for the created URL
|
||||||
|
* @param value URL address
|
||||||
|
* @return id of the created URL
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@DocumentationExample(" ...\n\nname=d4science&description=D4Science+URL&value=www.d4science.org")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "URL created."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Wrong set of parameters."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Unable to create URL."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@Path("/{id}/create/URL")
|
@Path("/{id}/create/URL")
|
||||||
public Response createURL(@PathParam("id") String id, @FormParam("name") String name, @FormParam("description") String description, @FormParam("value") URL value) {
|
public Response createURL(@PathParam("id") String id, @FormParam("name") String name,
|
||||||
|
@FormParam("description") String description, @FormParam("value") URL value) {
|
||||||
InnerMethodName.set("createItem(URL)");
|
InnerMethodName.set("createItem(URL)");
|
||||||
log.info("create url called");
|
log.info("create url called");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
try{
|
try {
|
||||||
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
||||||
|
|
||||||
ItemsParameterBuilder<URLCreationParameters> builder = URLCreationParameters.builder().name(name).description(description).url(value).on(id).with(ses).author(currentUser);
|
ItemsParameterBuilder<URLCreationParameters> builder = URLCreationParameters.builder().name(name)
|
||||||
|
.description(description).url(value).on(id).with(ses).author(currentUser);
|
||||||
|
|
||||||
toReturn = itemHandler.create(builder.build());
|
toReturn = itemHandler.create(builder.build());
|
||||||
}catch(StorageHubException she ){
|
} catch (StorageHubException she) {
|
||||||
log.error(she.getErrorMessage(), she);
|
log.error(she.getErrorMessage(), she);
|
||||||
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
||||||
}catch(RepositoryException re ){
|
} catch (RepositoryException re) {
|
||||||
log.error("jcr error creating item", re);
|
log.error("jcr error creating item", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
|
||||||
}catch(Throwable e ){
|
} catch (Throwable e) {
|
||||||
log.error("unexpected error", e);
|
log.error("unexpected error", e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
}finally{
|
} finally {
|
||||||
if (ses!=null)
|
if (ses != null)
|
||||||
ses.logout();
|
ses.logout();
|
||||||
|
|
||||||
}
|
}
|
||||||
return Response.ok(toReturn).build();
|
return Response.ok(toReturn).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Path("/{id}/create/GCUBEITEM")
|
@Path("/{id}/create/GCUBEITEM")
|
||||||
|
@ -187,39 +239,57 @@ public class ItemsCreator extends Impersonable{
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
|
|
||||||
try{
|
try {
|
||||||
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
||||||
ItemsParameterBuilder<GCubeItemCreationParameters> builder = GCubeItemCreationParameters.builder().item(item).on(id).with(ses).author(currentUser);
|
ItemsParameterBuilder<GCubeItemCreationParameters> builder = GCubeItemCreationParameters.builder()
|
||||||
|
.item(item).on(id).with(ses).author(currentUser);
|
||||||
|
|
||||||
toReturn = itemHandler.create(builder.build());
|
toReturn = itemHandler.create(builder.build());
|
||||||
}catch(StorageHubException she ){
|
} catch (StorageHubException she) {
|
||||||
log.error(she.getErrorMessage(), she);
|
log.error(she.getErrorMessage(), she);
|
||||||
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
||||||
}catch(RepositoryException re ){
|
} catch (RepositoryException re) {
|
||||||
log.error("jcr error creating item", re);
|
log.error("jcr error creating item", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
|
||||||
}catch(Throwable e ){
|
} catch (Throwable e) {
|
||||||
log.error("unexpected error", e);
|
log.error("unexpected error", e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
}finally{
|
} finally {
|
||||||
if (ses!=null)
|
if (ses != null)
|
||||||
ses.logout();
|
ses.logout();
|
||||||
}
|
}
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a file retrieved from the provided url.
|
||||||
|
*
|
||||||
|
* @param id destination folder id
|
||||||
|
* @param name destination file name
|
||||||
|
* @param description description meta-info for the created file
|
||||||
|
* @param url address of the file to be uploaded
|
||||||
|
* @return id of the created file
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@DocumentationExample(" ...\n\nname=d4science_logo.png&description=D4Science+logo&url=\"https://www.d4science.org/image/layout_set_logo?img_id=12630&t=1720538711657\"")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "File created."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Wrong set of parameters."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Unable to create file."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@Path("/{id}/create/FILE")
|
@Path("/{id}/create/FILE")
|
||||||
public String createFileItemFromUrl(@PathParam("id") String id, @FormParam("name") String name,
|
public String createFileItemFromUrl(@PathParam("id") String id, @FormParam("name") String name,
|
||||||
@FormParam("description") String description,
|
@FormParam("description") String description,
|
||||||
@FormParam("url") String url){
|
@FormParam("url") String url) {
|
||||||
InnerMethodName.set("createItem(FILEFromUrl)");
|
InnerMethodName.set("createItem(FILEFromUrl)");
|
||||||
|
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
try{
|
try {
|
||||||
|
|
||||||
log.debug("UPLOAD: call started");
|
log.debug("UPLOAD: call started");
|
||||||
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
||||||
|
@ -228,24 +298,25 @@ public class ItemsCreator extends Impersonable{
|
||||||
|
|
||||||
long fileLength = connectionURL.getContentLengthLong();
|
long fileLength = connectionURL.getContentLengthLong();
|
||||||
|
|
||||||
try(InputStream stream = connectionURL.getInputStream()){
|
try (InputStream stream = connectionURL.getInputStream()) {
|
||||||
ItemsParameterBuilder<FileCreationParameters> builder = FileCreationParameters.builder().name(name).fileDetails(FormDataContentDisposition.name(name).size(fileLength).build())
|
ItemsParameterBuilder<FileCreationParameters> builder = FileCreationParameters.builder().name(name)
|
||||||
|
.fileDetails(FormDataContentDisposition.name(name).size(fileLength).build())
|
||||||
.description(description).stream(stream)
|
.description(description).stream(stream)
|
||||||
.on(id).with(ses).author(currentUser);
|
.on(id).with(ses).author(currentUser);
|
||||||
toReturn = itemHandler.create(builder.build());
|
toReturn = itemHandler.create(builder.build());
|
||||||
}
|
}
|
||||||
log.debug("UPLOAD: call finished");
|
log.debug("UPLOAD: call finished");
|
||||||
}catch(RepositoryException re ){
|
} catch (RepositoryException re) {
|
||||||
log.error("jcr error creating file item", re);
|
log.error("jcr error creating file item", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating file item", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating file item", re));
|
||||||
}catch(StorageHubException she ){
|
} catch (StorageHubException she) {
|
||||||
log.error(she.getErrorMessage(), she);
|
log.error(she.getErrorMessage(), she);
|
||||||
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
||||||
}catch(Throwable e ){
|
} catch (Throwable e) {
|
||||||
log.error("unexpected error", e);
|
log.error("unexpected error", e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
}finally{
|
} finally {
|
||||||
if (ses!=null && ses.isLive()) {
|
if (ses != null && ses.isLive()) {
|
||||||
log.info("session closed");
|
log.info("session closed");
|
||||||
ses.logout();
|
ses.logout();
|
||||||
}
|
}
|
||||||
|
@ -254,39 +325,71 @@ public class ItemsCreator extends Impersonable{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload the provided file.
|
||||||
|
*
|
||||||
|
* @param id destination folder id
|
||||||
|
* @param name destination file name
|
||||||
|
* @param description description meta-info for the created file
|
||||||
|
* @param file multipart/form-data file parameter, with optional
|
||||||
|
* 'filename' and 'size' (see example below)
|
||||||
|
* @return id of the created file
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") }, formParams = {
|
||||||
|
@FormParam("name"), @FormParam("description"), @FormParam("file") })
|
||||||
|
@DocumentationExample(value = "...\n\n--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"file\"; filename=\"doc.pdf\"; size=426018;\n" +
|
||||||
|
"Content-Type: application/pdf\n\n" +
|
||||||
|
"(data)\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"name\"\n\n" +
|
||||||
|
"doc.pdf\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"description\"\n\n" +
|
||||||
|
"\"This is just a sample PDF file\"\n" +
|
||||||
|
"--------boundaryString--")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "File created."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Wrong set of parameters."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Unable to create file."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@Path("/{id}/create/FILE")
|
@Path("/{id}/create/FILE")
|
||||||
public String createFileItem(@PathParam("id") String id, @FormDataParam("name") String name,
|
public String createFileItem(@PathParam("id") String id, @FormDataParam("name") String name,
|
||||||
@FormDataParam("description") String description,
|
@FormDataParam("description") String description,
|
||||||
@FormDataParam("file") InputStream file,
|
@FormDataParam("file") InputStream file,
|
||||||
@FormDataParam("file") FormDataContentDisposition fileDetail){
|
@FormDataParam("file") FormDataContentDisposition fileDetail) {
|
||||||
InnerMethodName.set("createItem(FILE)");
|
InnerMethodName.set("createItem(FILE)");
|
||||||
|
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
try(InputStream is = new BufferedInputStream(file)){
|
try (InputStream is = new BufferedInputStream(file)) {
|
||||||
|
|
||||||
long size = fileDetail.getSize();
|
long size = fileDetail.getSize();
|
||||||
|
|
||||||
log.info("UPLOAD: call started with file size {}",size);
|
log.info("UPLOAD: call started with file size {}", size);
|
||||||
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
||||||
ItemsParameterBuilder<FileCreationParameters> builder = FileCreationParameters.builder().name(name).description(description).stream(file).fileDetails(fileDetail)
|
ItemsParameterBuilder<FileCreationParameters> builder = FileCreationParameters.builder().name(name)
|
||||||
|
.description(description).stream(file).fileDetails(fileDetail)
|
||||||
.on(id).with(ses).author(currentUser);
|
.on(id).with(ses).author(currentUser);
|
||||||
log.debug("UPLOAD: item prepared");
|
log.debug("UPLOAD: item prepared");
|
||||||
toReturn = itemHandler.create(builder.build());
|
toReturn = itemHandler.create(builder.build());
|
||||||
log.debug("UPLOAD: call finished");
|
log.debug("UPLOAD: call finished");
|
||||||
}catch(RepositoryException re ){
|
} catch (RepositoryException re) {
|
||||||
log.error("jcr error creating file item", re);
|
log.error("jcr error creating file item", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating file item", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating file item", re));
|
||||||
}catch(StorageHubException she ){
|
} catch (StorageHubException she) {
|
||||||
log.error(she.getErrorMessage(), she);
|
log.error(she.getErrorMessage(), she);
|
||||||
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
||||||
}catch(Throwable e ){
|
} catch (Throwable e) {
|
||||||
log.error("unexpected error", e);
|
log.error("unexpected error", e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
}finally{
|
} finally {
|
||||||
if (ses!=null && ses.isLive()) {
|
if (ses != null && ses.isLive()) {
|
||||||
log.info("session closed");
|
log.info("session closed");
|
||||||
ses.logout();
|
ses.logout();
|
||||||
}
|
}
|
||||||
|
@ -295,79 +398,123 @@ public class ItemsCreator extends Impersonable{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload an archive from the provided url and extract its content on-the-fly in a new folder.
|
||||||
|
*
|
||||||
|
* @param id destination folder id
|
||||||
|
* @param parentFolderName name of the newly-created folder containing extracted
|
||||||
|
* files
|
||||||
|
* @param url address of the archive to be uploaded
|
||||||
|
* @return id of the created folder containing extracted files
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@DocumentationExample(" ...\n\nname=sampleZip.zip&description=This+is+a+sample+zip&url=\"https://getsamplefiles.com/download/zip/sample-1.zip\"")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Archive extracted."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Wrong set of parameters."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Unable to extract archive."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@Path("/{id}/create/ARCHIVE")
|
@Path("/{id}/create/ARCHIVE")
|
||||||
public String uploadArchiveFromURL(@PathParam("id") String id, @FormParam("parentFolderName") String parentFolderName,
|
public String uploadArchiveFromURL(@PathParam("id") String id,
|
||||||
@FormParam("url") String url){
|
@FormParam("parentFolderName") String parentFolderName,
|
||||||
|
@FormParam("url") String url) {
|
||||||
InnerMethodName.set("createItem(ARCHIVEFromURL)");
|
InnerMethodName.set("createItem(ARCHIVEFromURL)");
|
||||||
|
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
try{
|
try {
|
||||||
|
|
||||||
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
||||||
try(InputStream stream = new URI(url).toURL().openStream()){
|
try (InputStream stream = new URI(url).toURL().openStream()) {
|
||||||
ItemsParameterBuilder<ArchiveStructureCreationParameter> builder = ArchiveStructureCreationParameter.builder().parentName(parentFolderName).stream(stream)
|
ItemsParameterBuilder<ArchiveStructureCreationParameter> builder = ArchiveStructureCreationParameter
|
||||||
|
.builder().parentName(parentFolderName).stream(stream)
|
||||||
.on(id).with(ses).author(currentUser);
|
.on(id).with(ses).author(currentUser);
|
||||||
toReturn = itemHandler.create(builder.build());
|
toReturn = itemHandler.create(builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch(RepositoryException | ArchiveException | IOException re){
|
} catch (RepositoryException | ArchiveException | IOException re) {
|
||||||
log.error("jcr error extracting archive", re);
|
log.error("jcr error extracting archive", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error extracting archive", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error extracting archive", re));
|
||||||
}catch(StorageHubException she ){
|
} catch (StorageHubException she) {
|
||||||
log.error(she.getErrorMessage(), she);
|
log.error(she.getErrorMessage(), she);
|
||||||
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
||||||
}catch(Throwable e ){
|
} catch (Throwable e) {
|
||||||
log.error("unexpected error", e);
|
log.error("unexpected error", e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
} finally{
|
} finally {
|
||||||
if (ses!=null)
|
if (ses != null)
|
||||||
ses.logout();
|
ses.logout();
|
||||||
|
|
||||||
}
|
}
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload the provided archive and extract its content on-the-fly in a new folder.
|
||||||
|
*
|
||||||
|
* @param id destination folder id
|
||||||
|
* @param parentFolderName name of the newly-created folder containing extracted
|
||||||
|
* files
|
||||||
|
* @param file multipart/form-data file parameter, with optional
|
||||||
|
* 'filename' and 'size' (see example below)
|
||||||
|
* @return id of the created folder containing extracted files
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") }, formParams = {
|
||||||
|
@FormParam("parentFolderName"), @FormParam("file") })
|
||||||
|
@DocumentationExample(value = "...\n\n--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"file\"; filename=\"archive.zip\"; size=1560238;\n" +
|
||||||
|
"Content-Type: application/zip\n\n" +
|
||||||
|
"(compressed data)\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"parentFolderName=\"\n\n" +
|
||||||
|
"my documents\n" +
|
||||||
|
"--------boundaryString--")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Archive extracted."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Wrong set of parameters."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Unable to extract archive."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@Path("/{id}/create/ARCHIVE")
|
@Path("/{id}/create/ARCHIVE")
|
||||||
public String uploadArchive(@PathParam("id") String id, @FormDataParam("parentFolderName") String parentFolderName,
|
public String uploadArchive(@PathParam("id") String id, @FormDataParam("parentFolderName") String parentFolderName,
|
||||||
@FormDataParam("file") InputStream stream,
|
@FormDataParam("file") InputStream file,
|
||||||
@FormDataParam("file") FormDataContentDisposition fileDetail){
|
@FormDataParam("file") FormDataContentDisposition fileDetail) {
|
||||||
InnerMethodName.set("createItem(ARCHIVE)");
|
InnerMethodName.set("createItem(ARCHIVE)");
|
||||||
|
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
try(InputStream is = new BufferedInputStream(stream)){
|
try (InputStream is = new BufferedInputStream(file)) {
|
||||||
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
||||||
|
|
||||||
ItemsParameterBuilder<ArchiveStructureCreationParameter> builder = ArchiveStructureCreationParameter.builder().parentName(parentFolderName).stream(is).fileDetails(fileDetail)
|
ItemsParameterBuilder<ArchiveStructureCreationParameter> builder = ArchiveStructureCreationParameter
|
||||||
|
.builder().parentName(parentFolderName).stream(is).fileDetails(fileDetail)
|
||||||
.on(id).with(ses).author(currentUser);
|
.on(id).with(ses).author(currentUser);
|
||||||
|
|
||||||
toReturn = itemHandler.create(builder.build());
|
toReturn = itemHandler.create(builder.build());
|
||||||
|
|
||||||
}catch(RepositoryException | ArchiveException | IOException re){
|
} catch (RepositoryException | ArchiveException | IOException re) {
|
||||||
log.error("jcr error extracting archive", re);
|
log.error("jcr error extracting archive", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error extracting archive", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error extracting archive", re));
|
||||||
}catch(StorageHubException she ){
|
} catch (StorageHubException she) {
|
||||||
log.error(she.getErrorMessage(), she);
|
log.error(she.getErrorMessage(), she);
|
||||||
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
||||||
}catch(Throwable e ){
|
} catch (Throwable e) {
|
||||||
log.error("unexpected error", e);
|
log.error("unexpected error", e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
} finally{
|
} finally {
|
||||||
if (ses!=null)
|
if (ses != null)
|
||||||
ses.logout();
|
ses.logout();
|
||||||
|
|
||||||
}
|
}
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,13 @@ import org.gcube.smartgears.utils.InnerMethodName;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.DocumentationExample;
|
||||||
|
import com.webcohesion.enunciate.metadata.Ignore;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceMethodSignature;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
|
@ -82,11 +87,13 @@ import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import jakarta.ws.rs.core.Response.Status;
|
import jakarta.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage item retrieval, deletion, and update.
|
||||||
|
*/
|
||||||
@Path("items")
|
@Path("items")
|
||||||
@ManagedBy(StorageHubApplicationManager.class)
|
@ManagedBy(StorageHubApplicationManager.class)
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"),
|
||||||
})
|
})
|
||||||
public class ItemsManager extends Impersonable{
|
public class ItemsManager extends Impersonable{
|
||||||
|
|
||||||
|
@ -130,7 +137,22 @@ public class ItemsManager extends Impersonable{
|
||||||
PublicLinkHandler publicLinkHandler;
|
PublicLinkHandler publicLinkHandler;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an item by its id.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return a JSON representation of the item
|
||||||
|
* @pathExample /{id}?exclude=content
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemWrapper.class, pathParams = @PathParam("id"), queryParams = @QueryParam("exclude"))
|
||||||
@GET
|
@GET
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Unable to find this item."),
|
||||||
|
})
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public ItemWrapper<Item> getById(@QueryParam("exclude") List<String> excludes){
|
public ItemWrapper<Item> getById(@QueryParam("exclude") List<String> excludes){
|
||||||
|
@ -159,6 +181,18 @@ public class ItemsManager extends Impersonable{
|
||||||
return new ItemWrapper<Item>(toReturn);
|
return new ItemWrapper<Item>(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an item by its relative path.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param path the relative path of the item to retrieve
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return a JSON representation of the item
|
||||||
|
* @pathExample /{id}/path?path=folder1&exclude=content
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemWrapper.class, pathParams = @PathParam("id"), queryParams = {@QueryParam("path"), @QueryParam("exclude")})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/path")
|
@Path("{id}/path")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -220,6 +254,7 @@ public class ItemsManager extends Impersonable{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/items/{name}")
|
@Path("{id}/items/{name}")
|
||||||
|
@ -229,6 +264,22 @@ public class ItemsManager extends Impersonable{
|
||||||
return _findChildrenByNamePattern(excludes, name);
|
return _findChildrenByNamePattern(excludes, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a child item by its name.
|
||||||
|
*
|
||||||
|
* @param id parent item id
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @param name the name of the child item to retrieve
|
||||||
|
* @return a JSON representation of the item list
|
||||||
|
* @pathExample /{id}/items?name=doc.pdf&exclude=content
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") }, queryParams = { @QueryParam("exclude"), @QueryParam("name") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Parent item does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/items")
|
@Path("{id}/items")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -278,9 +329,26 @@ public class ItemsManager extends Impersonable{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a child item by its name.
|
||||||
|
*
|
||||||
|
* @param id parent item id
|
||||||
|
* @param showHidden if true, hidden items are shown<br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code> <br>
|
||||||
|
* <strong>Optional</strong> default: <code>false</code>
|
||||||
|
* @param onlyType only items of the specified type are counted <br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return the number of children
|
||||||
|
* @pathExample /{id}/children/count?showHidden=true&onlyType=File
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = Long.class, pathParams = @PathParam("id"), queryParams = {@QueryParam("showHidden"), @QueryParam("onlyType")})
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Parent item does not exist"),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/children/count")
|
@Path("{id}/children/count")
|
||||||
public Long countById(@QueryParam("showHidden") Boolean showHidden, @QueryParam("exclude") List<String> excludes, @QueryParam("onlyType") String nodeType){
|
public Long countById(@QueryParam("showHidden") Boolean showHidden, @QueryParam("onlyType") String nodeType){
|
||||||
InnerMethodName.set("countById");
|
InnerMethodName.set("countById");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
Long toReturn = null;
|
Long toReturn = null;
|
||||||
|
@ -307,6 +375,26 @@ public class ItemsManager extends Impersonable{
|
||||||
return toReturn ;
|
return toReturn ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a list of children items.
|
||||||
|
*
|
||||||
|
* @param id parent item id
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @param showHidden if true, hidden items are shown<br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code> <br>
|
||||||
|
* <strong>Optional</strong> default: <code>false</code>
|
||||||
|
* @param onlyType only items of the specified type are counted <br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return a JSON representation of the item list
|
||||||
|
* @pathExample /{id}/children?showHidden=true&onlyType=File&exclude=content
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemList.class, pathParams = @PathParam("id"), queryParams = {@QueryParam("showHidden"), @QueryParam("exclude"), @QueryParam("onlyType")})
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Parent item does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/children")
|
@Path("{id}/children")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -337,6 +425,9 @@ public class ItemsManager extends Impersonable{
|
||||||
return new ItemList(toReturn);
|
return new ItemList(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// tipo di nodo ROOT - per ora non funziona
|
||||||
|
@Ignore
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/search")
|
@Path("{id}/search")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -369,6 +460,32 @@ public class ItemsManager extends Impersonable{
|
||||||
return new ItemList(toReturn);
|
return new ItemList(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a paged list of children items.
|
||||||
|
*
|
||||||
|
* @param id parent item id
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @param showHidden if true, hidden items are shown<br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code> <br>
|
||||||
|
* <strong>Optional</strong> default: <code>false</code>
|
||||||
|
* @param onlyType only items of the specified type are counted <br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @param start start index, counting from 0 <br>
|
||||||
|
* <strong>Possible values:</strong> integers
|
||||||
|
* @param limit maximum number of items returned <br>
|
||||||
|
* <strong>Possible values:</strong> integers
|
||||||
|
* @return a JSON representation of the item list
|
||||||
|
* @pathExample /{id}/children/paged?start=1&limit=100&showHidden=true&onlyType=File&exclude=content
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemList.class, pathParams = @PathParam("id"),
|
||||||
|
queryParams = {@QueryParam("showHidden"), @QueryParam("exclude"), @QueryParam("onlyType"), @QueryParam("start"), @QueryParam("limit")})
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Parent item does not exist."),
|
||||||
|
@ResponseCode ( code = 500, condition = "Missing 'start' or 'limit' parameter."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/children/paged")
|
@Path("{id}/children/paged")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -399,6 +516,7 @@ public class ItemsManager extends Impersonable{
|
||||||
return new ItemList(toReturn);
|
return new ItemList(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@GET
|
@GET
|
||||||
@Path("publiclink/{id}")
|
@Path("publiclink/{id}")
|
||||||
@AuthorizationControl(allowedUsers={"URIResolver"})
|
@AuthorizationControl(allowedUsers={"URIResolver"})
|
||||||
|
@ -434,6 +552,21 @@ public class ItemsManager extends Impersonable{
|
||||||
return Response.serverError().build();
|
return Response.serverError().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the public link for a specified item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param version version of the item for which the public link is requested <br>
|
||||||
|
* <strong>Optional</strong> default: <em>last version</em>
|
||||||
|
* @return URL of the public link for the specified item
|
||||||
|
* @pathExample /{id}/publiclink?version=1.0
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = URL.class, pathParams = @PathParam("id"), queryParams = @QueryParam("version"))
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 400, condition = "This item is not a file."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("{id}/publiclink")
|
@Path("{id}/publiclink")
|
||||||
|
@ -497,6 +630,21 @@ public class ItemsManager extends Impersonable{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the access level of the specified folder.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param publish if true, the folder is made public <br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code>
|
||||||
|
* @return the id of the folder
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = @PathParam("id"), formParams = @FormParam("publish"))
|
||||||
|
@DocumentationExample("...\n\npublish=true")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 400, condition = "This item is not a file."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/publish")
|
@Path("{id}/publish")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -533,6 +681,21 @@ public class ItemsManager extends Impersonable{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the root shared folder for the specified item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return the id of the root folder
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 400, condition = "This item is not a shared."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
|
@ResourceMethodSignature(output = ItemWrapper.class, pathParams = @PathParam("id"), queryParams = @QueryParam("exclude"))
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/rootSharedFolder")
|
@Path("{id}/rootSharedFolder")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -576,6 +739,17 @@ public class ItemsManager extends Impersonable{
|
||||||
return currentNode;
|
return currentNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of versions for the specified item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @return the version list
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
|
@ResourceMethodSignature(output = VersionList.class, pathParams = @PathParam("id"))
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/versions")
|
@Path("{id}/versions")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -613,6 +787,20 @@ public class ItemsManager extends Impersonable{
|
||||||
return new VersionList(versions);
|
return new VersionList(versions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download a specific version of a given item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param version the requested version
|
||||||
|
* @return download the item
|
||||||
|
* @pathExample /{id}/versions/1.0/download
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
@ResponseCode ( code = 500, condition = "Invalid version."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/versions/{version}/download")
|
@Path("{id}/versions/{version}/download")
|
||||||
public Response downloadVersion(@PathParam("version") String versionName){
|
public Response downloadVersion(@PathParam("version") String versionName){
|
||||||
|
@ -641,6 +829,21 @@ public class ItemsManager extends Impersonable{
|
||||||
return Response.serverError().build();
|
return Response.serverError().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a specific version of a given item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param version the requested version
|
||||||
|
* @return download the item
|
||||||
|
* @pathExample /{id}/versions/1.0
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = void.class, pathParams = { @PathParam("id"), @PathParam("version") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item deleted."),
|
||||||
|
@ResponseCode ( code = 400, condition = "This item's version cannot be removed."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
@ResponseCode ( code = 500, condition = "Invalid version."),
|
||||||
|
})
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{id}/versions/{version}")
|
@Path("{id}/versions/{version}")
|
||||||
public void deleteVersion(@PathParam("version") String versionName){
|
public void deleteVersion(@PathParam("version") String versionName){
|
||||||
|
@ -684,6 +887,21 @@ public class ItemsManager extends Impersonable{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the anchestors of a given item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param exclude a list of fields to exclude from the returned item list<br>
|
||||||
|
* <strong>Multivalued</strong> <br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return the list of anchestors
|
||||||
|
* @pathExample /{id}/anchestors?exclude=content
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemList.class, pathParams = { @PathParam("id")}, queryParams = { @QueryParam("exclude")})
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/anchestors")
|
@Path("{id}/anchestors")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -741,9 +959,21 @@ public class ItemsManager extends Impersonable{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download a given item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @return download the item
|
||||||
|
* @pathExample /{id}/download
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = Response.class, pathParams = { @PathParam("id")})
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/download")
|
@Path("{id}/download")
|
||||||
public Response download(@QueryParam("exclude") List<String> excludes){
|
public Response download(){
|
||||||
InnerMethodName.set("downloadById");
|
InnerMethodName.set("downloadById");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
try{
|
try{
|
||||||
|
@ -770,6 +1000,22 @@ public class ItemsManager extends Impersonable{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move a given item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param destinationId destination folder id
|
||||||
|
* @return id of the moved item
|
||||||
|
* @pathExample /{id}/move
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") }, formParams = { @FormParam("destinationId")})
|
||||||
|
@DocumentationExample("...\n\ndestinationId=19863b4e-b33f- ... -5b6d2e0e1eee")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item moved."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Source or destination item does not exist."),
|
||||||
|
@ResponseCode ( code = 409, condition = "Source and destination are the same item."),
|
||||||
|
})
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/move")
|
@Path("{id}/move")
|
||||||
public String move(@FormParam("destinationId") String destinationId){
|
public String move(@FormParam("destinationId") String destinationId){
|
||||||
|
@ -848,6 +1094,23 @@ public class ItemsManager extends Impersonable{
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy a given item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param destinationId destination folder id
|
||||||
|
* @param fileName name of the copied item
|
||||||
|
* @return id of the copied item
|
||||||
|
* @pathExample /{id}/copy
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = @PathParam("id"),
|
||||||
|
formParams = { @FormParam("destinationId"), @FormParam("fileName")})
|
||||||
|
@DocumentationExample("...\n\ndestinationId=19863b4e-b33f- ... -5b6d2e0e1eee&fileName=myCopy.jpg")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item copied."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Source or destination item does not exist."),
|
||||||
|
})
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/copy")
|
@Path("{id}/copy")
|
||||||
public String copy(@FormParam("destinationId") String destinationId, @FormParam("fileName") String newFileName){
|
public String copy(@FormParam("destinationId") String destinationId, @FormParam("fileName") String newFileName){
|
||||||
|
@ -923,6 +1186,21 @@ public class ItemsManager extends Impersonable{
|
||||||
return newFileIdentifier;
|
return newFileIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rename a given item.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param newName new name for the item
|
||||||
|
* @return id of the renamed item
|
||||||
|
* @pathExample /{id}/rename
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = @PathParam("id"), formParams = @FormParam("newName"))
|
||||||
|
@DocumentationExample("...\n\nnewName=newFileName.txt")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item renamed."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/rename")
|
@Path("{id}/rename")
|
||||||
public Response rename(@FormParam("newName") String newName){
|
public Response rename(@FormParam("newName") String newName){
|
||||||
|
@ -979,9 +1257,25 @@ public class ItemsManager extends Impersonable{
|
||||||
return Response.ok(id).build();
|
return Response.ok(id).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: transform this and setMetadata in a generic method for all properties
|
/**
|
||||||
|
* Set the item as hidden or visible. The body request is interpreted as the boolean
|
||||||
|
* value for the visibility.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @return id of the item
|
||||||
|
* @pathExample /{id}/hidden
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") })
|
||||||
|
@DocumentationExample("...\n\ntrue")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item visibility set."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Unable to parse request body."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@Path("/{id}/hidden")
|
@Path("/{id}/hidden")
|
||||||
public Response setItemAsHidden(Boolean hidden){
|
public Response setItemAsHidden(Boolean hidden){
|
||||||
InnerMethodName.set("setHidden");
|
InnerMethodName.set("setHidden");
|
||||||
|
@ -1024,9 +1318,24 @@ public class ItemsManager extends Impersonable{
|
||||||
return Response.ok(id).build();
|
return Response.ok(id).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: transform this and setMetadata in a generic method for all properties
|
/**
|
||||||
|
* Set description for the specified item. The body request is interpreted as the description string.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @return id of the item
|
||||||
|
* @pathExample /{id}/description
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") })
|
||||||
|
@DocumentationExample("...\n\nThis is a sample description")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item description set."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Unable to parse request body."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@Path("/{id}/description")
|
@Path("/{id}/description")
|
||||||
public Response setDescription(String description){
|
public Response setDescription(String description){
|
||||||
InnerMethodName.set("setDescription");
|
InnerMethodName.set("setDescription");
|
||||||
|
@ -1069,8 +1378,29 @@ public class ItemsManager extends Impersonable{
|
||||||
return Response.ok(id).build();
|
return Response.ok(id).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set metadata for the specified item. The body request is interpreted as the metadata JSON.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @return id of the item
|
||||||
|
* @pathExample /{id}/metadata
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") })
|
||||||
|
@DocumentationExample("...\n\n{\n" +
|
||||||
|
" \"map\": {\n" +
|
||||||
|
" \"meta1\": \"value1\",\n" +
|
||||||
|
" \"meta2\": \"value2\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item metadata set."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Unable to parse request body."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item does not exist."),
|
||||||
|
})
|
||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@Path("/{id}/metadata")
|
@Path("/{id}/metadata")
|
||||||
public Response setMetadata(org.gcube.common.storagehub.model.Metadata metadata){
|
public Response setMetadata(org.gcube.common.storagehub.model.Metadata metadata){
|
||||||
InnerMethodName.set("updateMetadata");
|
InnerMethodName.set("updateMetadata");
|
||||||
|
@ -1115,7 +1445,22 @@ public class ItemsManager extends Impersonable{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the specified item to the trash or delete it permanently if it is already trashed.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @param force permanently delete <br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code> <br>
|
||||||
|
* <strong>Optional</strong> default: <code>false</code>
|
||||||
|
* @pathExample /{id}?force=true
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature (output = String.class, pathParams = { @PathParam("id") }, queryParams = { @QueryParam("force") })
|
||||||
@DELETE
|
@DELETE
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item deleted."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Unable to find this item."),
|
||||||
|
@ResponseCode ( code = 500, condition = "Unable to delete this item."),
|
||||||
|
})
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
public Response deleteItem(@QueryParam("force") boolean force){
|
public Response deleteItem(@QueryParam("force") boolean force){
|
||||||
InnerMethodName.set("deleteItem("+force+")");
|
InnerMethodName.set("deleteItem("+force+")");
|
||||||
|
@ -1163,6 +1508,18 @@ public class ItemsManager extends Impersonable{
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info of the specified folder.
|
||||||
|
*
|
||||||
|
* @param id item id
|
||||||
|
* @return folder info
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, pathParams = { @PathParam("id") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item found."),
|
||||||
|
@ResponseCode ( code = 400, condition = "This item is not a folder."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Unable to find this folder."),
|
||||||
|
})
|
||||||
@Path("{id}/info")
|
@Path("{id}/info")
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
|
|
@ -52,6 +52,7 @@ import org.gcube.smartgears.utils.InnerMethodName;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.Ignore;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
|
||||||
|
@ -71,10 +72,11 @@ import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import jakarta.ws.rs.core.Response.Status;
|
import jakarta.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@Path("messages")
|
@Path("messages")
|
||||||
@ManagedBy(StorageHubApplicationManager.class)
|
@ManagedBy(StorageHubApplicationManager.class)
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"),
|
||||||
})
|
})
|
||||||
public class MessageManager extends Impersonable{
|
public class MessageManager extends Impersonable{
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ import org.gcube.smartgears.utils.InnerMethodName;
|
||||||
|
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
|
@ -18,17 +20,28 @@ import jakarta.ws.rs.Path;
|
||||||
import jakarta.ws.rs.Produces;
|
import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage underlying storage backends.
|
||||||
|
*/
|
||||||
@Path("storages")
|
@Path("storages")
|
||||||
@ManagedBy(StorageHubApplicationManager.class)
|
@ManagedBy(StorageHubApplicationManager.class)
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"),
|
||||||
})
|
})
|
||||||
public class StorageManager {
|
public class StorageManager {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
StorageBackendHandler storageBackendHandler;
|
StorageBackendHandler storageBackendHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of available storages
|
||||||
|
*
|
||||||
|
* @return list of available storages
|
||||||
|
*/
|
||||||
@GET
|
@GET
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
})
|
||||||
@Path("/")
|
@Path("/")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public List<StorageDescriptor> getStorages(){
|
public List<StorageDescriptor> getStorages(){
|
||||||
|
|
|
@ -22,8 +22,11 @@ import org.gcube.smartgears.utils.InnerMethodName;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.DocumentationExample;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
|
@ -38,10 +41,13 @@ import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage users
|
||||||
|
*/
|
||||||
@Path("users")
|
@Path("users")
|
||||||
@ManagedBy(StorageHubApplicationManager.class)
|
@ManagedBy(StorageHubApplicationManager.class)
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader(name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), })
|
@RequestHeader(name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"), })
|
||||||
public class UserManager {
|
public class UserManager {
|
||||||
|
|
||||||
private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager";
|
private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager";
|
||||||
|
@ -53,7 +59,15 @@ public class UserManager {
|
||||||
@Inject
|
@Inject
|
||||||
UserManagerDelegate userHandler;
|
UserManagerDelegate userHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of users
|
||||||
|
*
|
||||||
|
* @return list of users
|
||||||
|
*/
|
||||||
@GET
|
@GET
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
})
|
||||||
@Path("")
|
@Path("")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public UsersList getUsers() {
|
public UsersList getUsers() {
|
||||||
|
@ -72,7 +86,17 @@ public class UserManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user details
|
||||||
|
*
|
||||||
|
* @param user user name
|
||||||
|
* @return user detail
|
||||||
|
*/
|
||||||
@GET
|
@GET
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "User found."),
|
||||||
|
@ResponseCode ( code = 406, condition = "User does not exist."),
|
||||||
|
})
|
||||||
@Path("{user}")
|
@Path("{user}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public SHUBUser getUser(@PathParam("user") String user) {
|
public SHUBUser getUser(@PathParam("user") String user) {
|
||||||
|
@ -100,9 +124,26 @@ public class UserManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new user <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param user user name
|
||||||
|
* @param password user password
|
||||||
|
* @return user name
|
||||||
|
* @responseExample name.surname
|
||||||
|
*/
|
||||||
|
@DocumentationExample(" ...\n\nuser=nome.utente&password=passw0rd")
|
||||||
@POST
|
@POST
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "User created."),
|
||||||
|
@ResponseCode ( code = 400, condition = "Wrong set of parameters."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to create users."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@Path("")
|
@Path("")
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@AuthorizationControl(allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE })
|
@AuthorizationControl(allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE })
|
||||||
public String createUser(@FormParam("user") String user, @FormParam("password") String password) {
|
public String createUser(@FormParam("user") String user, @FormParam("password") String password) {
|
||||||
|
|
||||||
|
@ -130,9 +171,21 @@ public class UserManager {
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update user to the last 'home' version <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param user user name
|
||||||
|
* @return user id
|
||||||
|
*/
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{user}")
|
@Path("{user}")
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Home update done."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to create users."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@AuthorizationControl(allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE })
|
@AuthorizationControl(allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE })
|
||||||
public String updateHomeUserToLatestVersion(@PathParam("user") String user) {
|
public String updateHomeUserToLatestVersion(@PathParam("user") String user) {
|
||||||
|
|
||||||
|
@ -160,8 +213,21 @@ public class UserManager {
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a user <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param user user name
|
||||||
|
* @return user name
|
||||||
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "User deleted."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to delete users."),
|
||||||
|
@ResponseCode ( code = 406, condition = "User does not exist."),
|
||||||
|
})
|
||||||
@Path("{user}")
|
@Path("{user}")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@AuthorizationControl(allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE })
|
@AuthorizationControl(allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE })
|
||||||
public String deleteUser(@PathParam("user") final String user) {
|
public String deleteUser(@PathParam("user") final String user) {
|
||||||
|
|
||||||
|
@ -189,7 +255,17 @@ public class UserManager {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of groups for the specified user
|
||||||
|
*
|
||||||
|
* @param user user name
|
||||||
|
* @return List of groups
|
||||||
|
*/
|
||||||
@GET
|
@GET
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "User found."),
|
||||||
|
@ResponseCode ( code = 500, condition = "User does not exist."),
|
||||||
|
})
|
||||||
@Path("{user}/groups")
|
@Path("{user}/groups")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public List<String> getGroupsPerUser(@PathParam("user") final String user) {
|
public List<String> getGroupsPerUser(@PathParam("user") final String user) {
|
||||||
|
|
|
@ -56,8 +56,13 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.DocumentationExample;
|
||||||
|
import com.webcohesion.enunciate.metadata.Ignore;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceMethodSignature;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
import jakarta.enterprise.context.RequestScoped;
|
import jakarta.enterprise.context.RequestScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
@ -75,10 +80,13 @@ import jakarta.ws.rs.core.Context;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage the workspace
|
||||||
|
*/
|
||||||
@Path("/")
|
@Path("/")
|
||||||
@ManagedBy(StorageHubApplicationManager.class)
|
@ManagedBy(StorageHubApplicationManager.class)
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader(name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), })
|
@RequestHeader(name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"), })
|
||||||
public class WorkspaceManager extends Impersonable {
|
public class WorkspaceManager extends Impersonable {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(WorkspaceManager.class);
|
private static final Logger log = LoggerFactory.getLogger(WorkspaceManager.class);
|
||||||
|
@ -121,6 +129,21 @@ public class WorkspaceManager extends Impersonable {
|
||||||
@Inject
|
@Inject
|
||||||
Item2NodeConverter item2Node;
|
Item2NodeConverter item2Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info of an item referred through its path
|
||||||
|
*
|
||||||
|
* @param relPath relative path
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return workspace item
|
||||||
|
* @pathExample /?relPath=folder1/folder2/file.txt&exclude=owner
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item retrieved."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Item not found."),
|
||||||
|
})
|
||||||
|
@ResourceMethodSignature(output = ItemWrapper.class, queryParams = { @QueryParam("relPath"), @QueryParam("exclude") })
|
||||||
@Path("/")
|
@Path("/")
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -164,19 +187,33 @@ public class WorkspaceManager extends Impersonable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads a file in the volatile area returning a public link
|
* Upload a file in the volatile area
|
||||||
*
|
*
|
||||||
* @param id
|
* @param file multipart/form-data file parameter, with optional
|
||||||
* @param name
|
* 'filename' and 'size' (see example below)
|
||||||
* @param description
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
* @param stream
|
* <strong>Multivalued</strong><br>
|
||||||
* @param fileDetail
|
* <strong>Optional</strong>
|
||||||
* @return
|
* @return public link to the created file
|
||||||
|
* @responseExample https://data.dev.d4science.org/shub/VLT_V1...9PQ==
|
||||||
*/
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, formParams = { @FormParam("file") }, queryParams = { @QueryParam("exclude") })
|
||||||
|
@DocumentationExample(value = "...\n\n--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"file\"; filename=\"doc.pdf\"; size=426018;\n" +
|
||||||
|
"Content-Type: application/pdf\n\n" +
|
||||||
|
"(data)\n" +
|
||||||
|
"--------boundaryString--")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "File created."),
|
||||||
|
@ResponseCode ( code = 400, condition = "File not provided."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
@ResponseCode ( code = 500, condition = "Wrong set of parameters."),
|
||||||
|
})
|
||||||
@Path("volatile")
|
@Path("volatile")
|
||||||
public String uploadVolatileFile(@FormDataParam("file") InputStream stream,
|
public String uploadVolatileFile(@FormDataParam("file") InputStream file,
|
||||||
@FormDataParam("file") FormDataContentDisposition fileDetail) {
|
@FormDataParam("file") FormDataContentDisposition fileDetail) {
|
||||||
InnerMethodName.set("uploadToVolatileArea");
|
InnerMethodName.set("uploadToVolatileArea");
|
||||||
|
|
||||||
|
@ -193,7 +230,7 @@ public class WorkspaceManager extends Impersonable {
|
||||||
StorageBackend sb = sbf.create(payloadBackend);
|
StorageBackend sb = sbf.create(payloadBackend);
|
||||||
|
|
||||||
log.info("UPLOAD: call started with file size {}", size);
|
log.info("UPLOAD: call started with file size {}", size);
|
||||||
MetaInfo info = sb.upload(stream, null, fileDetail.getFileName(), currentUser);
|
MetaInfo info = sb.upload(file, null, fileDetail.getFileName(), currentUser);
|
||||||
log.debug("UPLOAD: call finished");
|
log.debug("UPLOAD: call finished");
|
||||||
|
|
||||||
toReturn = publicLinkHandler.getForVolatile(info.getStorageId(), GCubeVolatileStorageBackendFactory.NAME,
|
toReturn = publicLinkHandler.getForVolatile(info.getStorageId(), GCubeVolatileStorageBackendFactory.NAME,
|
||||||
|
@ -208,11 +245,23 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info on the VRE folder associated to the current token
|
||||||
|
*
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return VRE folder info
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemWrapper.class, queryParams = { @QueryParam("exclude") })
|
||||||
@Path("vrefolder")
|
@Path("vrefolder")
|
||||||
@GET
|
@GET
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
})
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public ItemWrapper<Item> getVreRootFolder() {
|
public ItemWrapper<Item> getCurrentVreFolder() {
|
||||||
InnerMethodName.set("getVreRootFolder");
|
InnerMethodName.set("getCurrentVreFolder");
|
||||||
JackrabbitSession ses = null;
|
JackrabbitSession ses = null;
|
||||||
Item vreItem = null;
|
Item vreItem = null;
|
||||||
try {
|
try {
|
||||||
|
@ -239,6 +288,18 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return new ItemWrapper<Item>(vreItem);
|
return new ItemWrapper<Item>(vreItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of recent documents from VRE folders
|
||||||
|
*
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return list of recent documents
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemList.class, queryParams = { @QueryParam("exclude") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
})
|
||||||
@Path("vrefolder/recents")
|
@Path("vrefolder/recents")
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -277,6 +338,18 @@ public class WorkspaceManager extends Impersonable {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info on the trash folder
|
||||||
|
*
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return info on the trash folder
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemWrapper.class, queryParams = { @QueryParam("exclude") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Success."),
|
||||||
|
})
|
||||||
@Path("trash")
|
@Path("trash")
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -307,7 +380,21 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return new ItemWrapper<Item>(item);
|
return new ItemWrapper<Item>(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty the trash folder
|
||||||
|
*
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return trash folder id
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, queryParams = { @QueryParam("exclude") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Trash emptied."),
|
||||||
|
})
|
||||||
@Path("trash/empty")
|
@Path("trash/empty")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@DELETE
|
@DELETE
|
||||||
public String emptyTrash() {
|
public String emptyTrash() {
|
||||||
InnerMethodName.set("emptyTrash");
|
InnerMethodName.set("emptyTrash");
|
||||||
|
@ -334,6 +421,25 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore a trashed item.
|
||||||
|
*
|
||||||
|
* @param trashedItemId item id
|
||||||
|
* @param destinationId destination folder id
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return id of the restored item
|
||||||
|
* @responseExample text/plain 5f4b3b4e-4b3b- ... -4b3b4e4b3b4e
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = String.class, queryParams = { @QueryParam("exclude")}, formParams = { @FormParam("trashedItemId"), @FormParam("destinationId") })
|
||||||
|
@DocumentationExample("...\n\ntrashedId=17dae181-f33c- ... - 3fa22198dd30&destinationId=19863b4e-b33f- ... -5b6d2e0e1eee")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Item restored."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Source or destination item does not exist."),
|
||||||
|
@ResponseCode ( code = 409, condition = "Source and destination are the same item."),
|
||||||
|
@ResponseCode ( code = 415, condition = "Wrong content type."),
|
||||||
|
})
|
||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("trash/restore")
|
@Path("trash/restore")
|
||||||
|
@ -383,6 +489,15 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of VRE folders for which the user is member
|
||||||
|
*
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return list of VRE folders
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemList.class, queryParams = { @QueryParam("exclude") })
|
||||||
@Path("vrefolders")
|
@Path("vrefolders")
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -411,6 +526,20 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return new ItemList(toReturn);
|
return new ItemList(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a paged list of VRE folders for which the user is member
|
||||||
|
*
|
||||||
|
* @param start start index, counting from 0 <br>
|
||||||
|
* <strong>Possible values:</strong> integers
|
||||||
|
* @param limit maximum number of items returned <br>
|
||||||
|
* <strong>Possible values:</strong> integers
|
||||||
|
* @param exclude a list of fields to exclude from the returned item<br>
|
||||||
|
* <strong>Multivalued</strong><br>
|
||||||
|
* <strong>Optional</strong>
|
||||||
|
* @return list of VRE folders
|
||||||
|
* @pathExample /vrefolders/paged?start=0&limit=10
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ItemList.class, queryParams = { @QueryParam("start"), @QueryParam("limit"), @QueryParam("exclude") })
|
||||||
@Path("vrefolders/paged")
|
@Path("vrefolders/paged")
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -437,30 +566,13 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return new ItemList(toReturn);
|
return new ItemList(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @Path("shared-by-me")
|
|
||||||
*
|
|
||||||
* @GET
|
|
||||||
*
|
|
||||||
* @Produces(MediaType.APPLICATION_JSON) public ItemList getMySharedFolders(){
|
|
||||||
* InnerMethodName.set("getMySharedFolders"); Session ses = null; List<? extends
|
|
||||||
* Item> toReturn = null; org.gcube.common.storagehub.model.Path sharedPath =
|
|
||||||
* null; try{ ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
||||||
* sharedPath = pathUtil.getMySharedPath(currentUser);
|
|
||||||
* log.info("my shared folder path is folder path is {}",sharedPath.toPath());
|
|
||||||
*
|
|
||||||
* toReturn = Utils.getItemList(ses.getNode(sharedPath.toPath()) , excludes,
|
|
||||||
* null, false, SharedFolder.class); }catch(RepositoryException re ){
|
|
||||||
* log.error("error reading my shared folder ({})",sharedPath, re);
|
|
||||||
* GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
||||||
* }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she);
|
|
||||||
* GXOutboundErrorResponse.throwException(she,
|
|
||||||
* Response.Status.fromStatusCode(she.getStatus())); }finally{ if (ses!=null)
|
|
||||||
* ses.logout(); }
|
|
||||||
*
|
|
||||||
* return new ItemList(toReturn); }
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// TODO: boh! Sviluppo a metà. Valutare se finirlo o ammazzarlo male
|
||||||
|
@Ignore
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "List retrieved."),
|
||||||
|
@ResponseCode ( code = 406, condition = "Error retrieving shared-with-me folder."),
|
||||||
|
})
|
||||||
@Path("shared-with-me")
|
@Path("shared-with-me")
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -489,6 +601,7 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return new ItemList(toReturn);
|
return new ItemList(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@Path("count")
|
@Path("count")
|
||||||
@GET
|
@GET
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@ -513,6 +626,7 @@ public class WorkspaceManager extends Impersonable {
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@Path("size")
|
@Path("size")
|
||||||
@GET
|
@GET
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|
|
@ -41,12 +41,17 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.webcohesion.enunciate.metadata.DocumentationExample;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceMethodSignature;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
import jakarta.ws.rs.DefaultValue;
|
import jakarta.ws.rs.DefaultValue;
|
||||||
|
import jakarta.ws.rs.FormParam;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
|
@ -55,9 +60,12 @@ import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.WebApplicationException;
|
import jakarta.ws.rs.WebApplicationException;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage "script" classes
|
||||||
|
*/
|
||||||
@Path("admin/script")
|
@Path("admin/script")
|
||||||
@RequestHeaders({
|
@RequestHeaders({
|
||||||
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>"),
|
||||||
})
|
})
|
||||||
public class ScriptManager {
|
public class ScriptManager {
|
||||||
|
|
||||||
|
@ -84,21 +92,62 @@ public class ScriptManager {
|
||||||
|
|
||||||
protected static HashMap<String, ScriptStatus> scriptStatusMap = new HashMap<String, ScriptStatus>();
|
protected static HashMap<String, ScriptStatus> scriptStatusMap = new HashMap<String, ScriptStatus>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a "script" class <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param name name of the script
|
||||||
|
* @param asynch if true, execute script asynchronously <br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code> <br>
|
||||||
|
* <strong>Optional</strong> default: <code>false</code>
|
||||||
|
* @param writeResult if true, write the result in the workspace <br>
|
||||||
|
* <strong>Possible values:</strong> <code>true</code>, <code>false</code> <br>
|
||||||
|
* <strong>Optional</strong> default: <code>false</code>
|
||||||
|
* @param destinationFolderId id of the destination folder
|
||||||
|
* @param file multipart/form-data file parameter, with optional
|
||||||
|
* 'filename' and 'size' (see example below)
|
||||||
|
* @return outcome of the script execution
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ScriptStatus.class, formParams = { @FormParam("name"),
|
||||||
|
@FormParam("asynch"), @FormParam("writeResult"), @FormParam("destinationFolderId"),
|
||||||
|
@FormParam("file") })
|
||||||
|
@DocumentationExample(value = "...\n\n--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"file\"; filename=\"MoveFiles.class\"; size=171018;\n" +
|
||||||
|
"Content-Type: application/octet-stream\n\n" +
|
||||||
|
"(binary data)\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"name\"\n\n" +
|
||||||
|
"MoveFile\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"async\"\n\n" +
|
||||||
|
"false\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"writeResult\"\n\n" +
|
||||||
|
"true\n" +
|
||||||
|
"--------boundaryString\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"destinationFolderId=\"\n\n" +
|
||||||
|
"5f4b3b4e-4b3b- ... -4b3b4e4b3b4e\n" +
|
||||||
|
"--------boundaryString--")
|
||||||
@POST
|
@POST
|
||||||
@Path("execute")
|
@Path("execute")
|
||||||
@AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE})
|
@AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE})
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Script correctly loaded."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to run scripts."),
|
||||||
|
@ResponseCode ( code = 500, condition = "Error loading the script."),
|
||||||
|
})
|
||||||
public ScriptStatus run( @FormDataParam("name") String name,
|
public ScriptStatus run( @FormDataParam("name") String name,
|
||||||
@FormDataParam("asynch") @DefaultValue("false") Boolean asynch,
|
@FormDataParam("asynch") @DefaultValue("false") Boolean asynch,
|
||||||
@FormDataParam("writeResult") @DefaultValue("false") Boolean writeResult ,
|
@FormDataParam("writeResult") @DefaultValue("false") Boolean writeResult ,
|
||||||
@FormDataParam("destinationFolderId") String destinationFolderId,
|
@FormDataParam("destinationFolderId") String destinationFolderId,
|
||||||
@FormDataParam("file") InputStream stream,
|
@FormDataParam("file") InputStream file,
|
||||||
@FormDataParam("file") FormDataContentDisposition fileDetail) {
|
@FormDataParam("file") FormDataContentDisposition fileDetail) {
|
||||||
try {
|
try {
|
||||||
InnerMethodName.set("executeScript");
|
InnerMethodName.set("executeScript");
|
||||||
ScriptClassLoader scriptClassLoader = new ScriptClassLoader(Thread.currentThread().getContextClassLoader());
|
ScriptClassLoader scriptClassLoader = new ScriptClassLoader(Thread.currentThread().getContextClassLoader());
|
||||||
Class<?> scriptClass = uploadClass(stream, scriptClassLoader, fileDetail.getFileName().replace(".class", ""));
|
Class<?> scriptClass = uploadClass(file, scriptClassLoader, fileDetail.getFileName().replace(".class", ""));
|
||||||
return internalRun(scriptClass, name, destinationFolderId, asynch, writeResult);
|
return internalRun(scriptClass, name, destinationFolderId, asynch, writeResult);
|
||||||
}catch(Throwable e) {
|
}catch(Throwable e) {
|
||||||
log.error("error executing script {}", name,e);
|
log.error("error executing script {}", name,e);
|
||||||
|
@ -106,6 +155,19 @@ public class ScriptManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status of a script <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @param id id of the script
|
||||||
|
* @return outcome of the script execution
|
||||||
|
*/
|
||||||
|
@ResourceMethodSignature(output = ScriptStatus.class, pathParams = { @PathParam("id") })
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Script status retrieved."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to inquire script status."),
|
||||||
|
@ResponseCode ( code = 404, condition = "Script not found."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/status")
|
@Path("{id}/status")
|
||||||
@AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE})
|
@AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE})
|
||||||
|
@ -123,6 +185,17 @@ public class ScriptManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export the data <br>
|
||||||
|
* <strong>Only users with <code>Infrastructure-Manager</code> role allowed</strong>
|
||||||
|
*
|
||||||
|
* @return outcome of the export
|
||||||
|
*/
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode ( code = 200, condition = "Script status retrieved."),
|
||||||
|
@ResponseCode ( code = 403, condition = "You're not allowed to inquire script status."),
|
||||||
|
@ResponseCode ( code = 404, condition = "Script not found."),
|
||||||
|
})
|
||||||
@GET
|
@GET
|
||||||
@Path("export")
|
@Path("export")
|
||||||
@AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE})
|
@AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE})
|
||||||
|
|
Loading…
Reference in New Issue