Compare commits

...

32 Commits

Author SHA1 Message Date
Massimiliano Assante fc37ffec6f Update 'enunciate.xml' 2023-05-30 12:41:55 +02:00
lucio e0a50f2a72 added header for swagger 2023-05-29 12:17:59 +02:00
lucio b4c9cfeee6 updated 2023-05-25 15:01:40 +02:00
lucio 7920345286 theme modified 2023-05-25 15:00:10 +02:00
lucio 80704b9df2 basepath changed for swagger 2023-05-25 14:53:27 +02:00
lucio a42919ffcf enunciate updated 2023-05-24 17:13:46 +02:00
lucio 6b54bf4554 enunciate files updated 2023-05-24 17:11:14 +02:00
lucio 122cba00e4 added DocManager to jersey initialiser 2023-05-24 15:00:19 +02:00
Lucio Lelii 60d9bf570c Update 'CHANGELOG.md' 2023-05-23 14:37:19 +02:00
Lucio Lelii f9870a0190 Update 'CHANGELOG.md' 2023-05-23 14:36:56 +02:00
lucio d9a229929b enunciate documentation added 2023-05-22 11:23:32 +02:00
Lucio Lelii 0b907277cd Update 'pom.xml' 2022-11-15 11:06:55 +01:00
Lucio Lelii 500aaa3fc9 Update 'pom.xml' 2022-11-15 10:52:33 +01:00
Lucio Lelii e167aa24d9 smartgears bom updated 2022-11-15 10:23:01 +01:00
Lucio Lelii 39d73b97c4 aspectj updated for java11 2022-11-15 10:16:29 +01:00
Lucio Lelii 4dc547afd2 Update 'CHANGELOG.md' 2022-11-14 12:06:28 +01:00
Lucio Lelii 122b326203 update for release 2022-11-14 12:05:16 +01:00
Lucio Lelii 1bbd1d200f added library to manage particular jpeg 2022-11-14 12:04:29 +01:00
Lucio Lelii 647dbb651a Update 'src/main/java/org/gcube/data/access/storagehub/services/MessageManager.java'
solved Incident #22230
2021-10-15 17:06:32 +02:00
lucio.lelii 7f88e20a88 first message shown twice for new user issue solved 2021-10-13 13:48:37 +02:00
lucio.lelii 08f0160d8d changed vre recents parameter 2021-10-13 11:48:03 +02:00
lucio.lelii 2a46ac3aa2 solved error on vre recents 2021-10-13 11:35:19 +02:00
lucio.lelii 882f849e2f pom and changelog updated 2021-10-12 14:01:21 +02:00
lucio.lelii 8c934a138e Merge remote-tracking branch 'origin/vreQueryRemoval'
Conflicts:
	CHANGELOG.md
	pom.xml
2021-10-12 13:40:06 +02:00
lucio.lelii 20390e3147 incident https://support.d4science.org/issues/22184 solved 2021-10-12 13:12:02 +02:00
lucio.lelii 47bf9b57d2 pom and changelog update 2021-10-07 10:38:35 +02:00
lucio.lelii 27c6f2d3e1 scriptManager accept different names 2021-10-06 19:41:18 +02:00
lucio.lelii 586d9df939 removed a part of query to retrieve recents 2021-10-06 19:18:34 +02:00
lucio.lelii 7ebd1ae629 fix updated 2021-10-06 11:56:57 +02:00
lucio.lelii 51cbd0776a solved bug https://support.d4science.org/issues/22147 2021-10-06 11:44:23 +02:00
lucio.lelii f30029c052 - using groupHandler method to retrieve VRE
- added logs to ScriptManager error
2021-10-06 10:37:14 +02:00
Lucio Lelii 68eb65e168 removing query for retreiving VRE root Folder 2021-10-04 17:11:43 +02:00
29 changed files with 1985 additions and 631 deletions

View File

@ -18,6 +18,7 @@
@ -43,6 +44,7 @@
@ -67,6 +69,7 @@
@ -91,6 +94,7 @@
@ -115,16 +119,12 @@
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<dependent-module archiveName="storagehub-model-1.1.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/storagehub-model/storagehub-model">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="storagehub-script-utils-1.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/storagehub-scripting-util/storagehub-scripting-util">
<dependency-type>uses</dependency-type>
</dependent-module>
@ -169,6 +169,7 @@
@ -192,6 +193,7 @@
@ -216,6 +218,7 @@

View File

@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.4.2] - [2023-05-22]
- added enunciate libraries for documentation
## [v1.4.1] - [2022-11-14]
- added libraries to manage different image format
## [v1.4.0] - [2021-10-07]
- slow query removed from VRE retrieving and recents
- incident #22184 solved
## [v1.3.2] - [2021-09-28]
- fix 22087

View File

@ -1,7 +1,8 @@
<application mode='online'>
<name>StorageHub</name>
<group>DataAccess</group>
<version>${version}</version>
<version>1.4.2</version>
<description>Storage Hub webapp</description>
<local-persistence location='target' />
<exclude>/workspace/api-docs/*</exclude>
</application>

24
enunciate.xml Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<enunciate
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://enunciate.webcohesion.com/schemas/enunciate-2.14.0.xsd">
<api-classes>
<!-- Use patterns to exclude classes... e.g. for URI-Resolver <exclude
pattern="org.gcube.datatransfer.resolver.services.DocsGenerator" /> -->
</api-classes>
<modules>
<gwt-json-overlay disabled="true" />
<php-json-client disabled="true" />
<ruby-json-client disabled="true" />
<java-json-client disabled="true" />
<javascript-client disabled="true" />
<docs docsDir="${project.build.directory}" docsSubdir="api-docs" />
<docs
freemarkerTemplate="${project.basedir}/src/main/resources/META-INF/enunciate/d4science_docs.fmt">
<additional-css
file="css/d4science_enunciate_custom.css" />
</docs>
<swagger basePath="/workspace" />
</modules>
</enunciate>

162
pom.xml
View File

@ -1,29 +1,23 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>maven-parent</artifactId>
<groupId>org.gcube.tools</groupId>
<version>1.1.0</version>
<relativePath />
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.gcube.data.access</groupId>
<artifactId>storagehub</artifactId>
<version>1.3.2</version>
<version>1.4.2</version>
<name>storagehub</name>
<scm>
<connection>scm:git:https://code-repo.d4science.org/gCubeSystem/storagehub.git</connection>
<developerConnection>scm:git:https://code-repo.d4science.org/gCubeSystem/storagehub.git</developerConnection>
<url>https://code-repo.d4science.org/gCubeSystem/storagehub</url>
</scm>
<packaging>war</packaging>
<properties>
<webappDirectory>${project.basedir}/src/main/webapp/WEB-INF</webappDirectory>
<jackrabbit.version>2.20.2</jackrabbit.version>
@ -32,21 +26,19 @@
<tomcat.version>7.0.40</tomcat.version>
<jetty.version>6.1.26</jetty.version>
<tika.version>1.21</tika.version>
<distroDirectory>${project.basedir}/distro</distroDirectory>
<description>REST web service for Jackrabbit</description>
<warname>storagehub</warname>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<enunciate.version>2.14.0</enunciate.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-smartgears-bom</artifactId>
<version>2.0.0</version>
<version>2.1.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -57,87 +49,85 @@
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-smartgears</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-smartgears-app</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-control-library</artifactId>
<version>[1.0.0,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>common-authorization</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-encryption</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-scope-maps</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-scope</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>storagehub-model</artifactId>
<version>[1.0.0,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.data.access</groupId>
<artifactId>storagehub-script-utils</artifactId>
<version>[1.0.0-SNAPSHOT,2.0.0)</version>
<version>[1.0.0, 2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version>
</dependency>
<!-- needed to manage strange image types -->
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-bmp</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-core</artifactId>
<version>3.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.62</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>gxJRS</artifactId>
</dependency>
<!-- JCR dependencies -->
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
@ -158,74 +148,67 @@
<artifactId>jackrabbit-jcr-server</artifactId>
<version>${jackrabbit.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-parsers -->
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>1.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-core -->
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.bull.javamelody/javamelody-core -->
<dependency>
<groupId>net.bull.javamelody</groupId>
<artifactId>javamelody-core</artifactId>
<version>1.82.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<scope>provided</scope>
</dependency>
<!-- jersey & weld -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.interceptor/javax.interceptor-api -->
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>1.2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
@ -234,14 +217,12 @@
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.inject/jersey-hk2 -->
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.30.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
@ -259,87 +240,67 @@
<artifactId>weld-servlet-core</artifactId>
<version>3.1.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss/jandex -->
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jandex</artifactId>
<version>2.2.2.Final</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-common -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc4</version>
<scope>runtime</scope>
</dependency>
<!-- Storage dependencies -->
<dependency>
<groupId>org.gcube.contentmanagement</groupId>
<artifactId>storage-manager-core</artifactId>
<version>[2.0.0,3.0.0-SNAPSHOT)</version>
<version>[3.0.0-SNAPSHOT,4.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.contentmanagement</groupId>
<artifactId>storage-manager-wrapper</artifactId>
<version>[2.0.0,3.0.0-SNAPSHOT)</version>
<version>[3.0.0-SNAPSHOT,4.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-simple</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
@ -352,7 +313,6 @@
<version>10.8.2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.jeeunit</groupId>
<artifactId>jeeunit</artifactId>
@ -365,20 +325,29 @@
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vlkan.rfos</groupId>
<artifactId>rotating-fos</artifactId>
<version>0.9.2</version>
</dependency>
<!-- enunciate deps -->
<dependency>
<groupId>com.webcohesion.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
<version>${enunciate.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.webcohesion.enunciate</groupId>
<artifactId>enunciate-rt-util</artifactId>
<version>${enunciate.version}</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
<dependency>
<groupId>org.mockito</groupId>
@ -386,14 +355,11 @@
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
@ -406,19 +372,16 @@
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
@ -452,7 +415,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<version>1.14.0</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
@ -509,7 +472,46 @@
</execution>
</executions>
</plugin>
<!-- Enunciate Maven plugin -->
<plugin>
<groupId>com.webcohesion.enunciate</groupId>
<artifactId>enunciate-maven-plugin</artifactId>
<version>${enunciate.version}</version>
<configuration></configuration>
<executions>
<execution>
<id>assemble</id>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Copy Enunciate Documentation from your-application/docs to your-application.war -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-enunciate-docs</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target</outputDirectory>
<resources>
<resource>
<targetPath>${project.build.directory}/${project.artifactId}/api-docs</targetPath>
<directory>${project.build.directory}/api-docs</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -8,6 +8,7 @@ import javax.ws.rs.core.Application;
import org.gcube.common.gxrest.response.entity.SerializableErrorEntityTextWriter;
import org.gcube.data.access.storagehub.services.ACLManager;
import org.gcube.data.access.storagehub.services.DocManager;
import org.gcube.data.access.storagehub.services.GroupManager;
import org.gcube.data.access.storagehub.services.Impersonable;
import org.gcube.data.access.storagehub.services.ItemSharing;
@ -39,6 +40,7 @@ public class StorageHub extends Application {
classes.add(MultiPartFeature.class);
classes.add(SerializableErrorEntityTextWriter.class);
classes.add(MyApplicationListener.class);
classes.add(DocManager.class);
return classes;
}

View File

@ -101,16 +101,16 @@ public class Utils {
}
public static <T extends Item> List<T> serachByNameOnFolder(Session ses, String user, AuthorizationChecker authChecker, Node parent, List<String> excludes, Range range, boolean showHidden, boolean excludeTrashed, Class<? extends RootItem> nodeTypeToInclude, String nameParam) throws RepositoryException, BackendGenericError{
public static <T extends Item> List<T> searchByNameOnFolder(Session ses, String user, AuthorizationChecker authChecker, Node parent, List<String> excludes, Range range, boolean showHidden, boolean excludeTrashed, Class<? extends RootItem> nodeTypeToInclude, String nameParam) throws RepositoryException, BackendGenericError{
String xpath = String.format("/jcr:root%s//element(*,nthl:workspaceItem)[jcr:like(fn:lower-case(@jcr:title), '%s')]",ISO9075.encodePath(parent.getPath()), nameParam.toLowerCase());
//String query = String.format("SELECT * FROM [nthl:workspaceLeafItem] AS node WHERE ISDESCENDANTNODE('%s') ORDER BY node.[jcr:lastModified] DESC ",vreFolder.getPath());
logger.debug("query for search is {}",xpath);
logger.trace("query for search is {}",xpath);
long start = System.currentTimeMillis();
@SuppressWarnings("deprecation")
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH);
NodeChildrenFilterIterator iterator = new NodeChildrenFilterIterator(jcrQuery.execute().getNodes());
logger.debug("[SEARCH] real search took {} millis",(System.currentTimeMillis()-start));
logger.trace("[SEARCH] real search took {} millis",(System.currentTimeMillis()-start));
Predicate<Node> checker = new Predicate<Node>() {
@Override
@ -152,7 +152,7 @@ public class Utils {
while (iterator.hasNext()){
Node current = iterator.next();
logger.debug("[SEARCH] evaluating node {} ",current.hasProperty(NodeProperty.TITLE.toString())? current.getProperty(NodeProperty.TITLE.toString()):current.getName());
logger.trace("[SEARCH] evaluating node {} ",current.hasProperty(NodeProperty.TITLE.toString())? current.getProperty(NodeProperty.TITLE.toString()):current.getName());
//REMOVE duplicate nodes, in case the indexes are not working
if (duplicateId.contains(current.getIdentifier())) {
@ -168,7 +168,7 @@ public class Utils {
if (isToExclude(current, showHidden))
continue;
logger.debug("[SEARCH] current node not excluded {} ",current.hasProperty(NodeProperty.TITLE.toString())? current.getProperty(NodeProperty.TITLE.toString()):current.getName());
logger.trace("[SEARCH] current node not excluded {} ",current.hasProperty(NodeProperty.TITLE.toString())? current.getProperty(NodeProperty.TITLE.toString()):current.getName());
if (range==null || (count>=range.getStart() && returnList.size()<range.getLimit())) {
T item = node2Item.getFilteredItem(current, excludes, nodeTypeToInclude);

View File

@ -2,6 +2,7 @@ package org.gcube.data.access.storagehub.handlers;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
@ -11,7 +12,6 @@ import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters;
import org.gcube.common.storagehub.model.exceptions.InvalidItemException;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
import org.gcube.common.storagehub.model.types.NodeProperty;
import org.gcube.data.access.storagehub.Constants;
@ -39,7 +39,7 @@ public class GroupHandler {
//delete folder on user
String folderName = group.getPrincipal().getName();
Node folder = getVreFolderNode(session, folderName);
Node folder = getFolderNodeRelatedToGroup(session, folderName);
NodeIterator ni = folder.getSharedSet();
while (ni.hasNext()) {
@ -54,7 +54,7 @@ public class GroupHandler {
}
public Node getVreFolderNode(JackrabbitSession session, String name) throws InvalidItemException, RepositoryException {
public Node getFolderNodeRelatedToGroup(JackrabbitSession session, String name) throws ItemNotFoundException, RepositoryException {
Node sharedRootNode = session.getNode(Constants.SHARED_FOLDER_PATH);
Node vreFolder = null;
@ -64,6 +64,7 @@ public class GroupHandler {
log.debug("is an old HL VRE");
}
if (vreFolder==null) {
NodeIterator nodes = sharedRootNode.getNodes();
while (nodes.hasNext()) {
Node node = nodes.nextNode();
@ -72,8 +73,9 @@ public class GroupHandler {
break;
}
}
}
if (vreFolder==null) throw new InvalidItemException("vre folder not found");
if (vreFolder==null) throw new ItemNotFoundException("vre folder not found for group "+name);
return vreFolder;
}

View File

@ -11,12 +11,14 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.lock.LockException;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
@ -40,7 +42,6 @@ import org.gcube.common.storagehub.model.plugins.FolderManager;
import org.gcube.common.storagehub.model.storages.MetaInfo;
import org.gcube.common.storagehub.model.storages.StorageBackend;
import org.gcube.common.storagehub.model.types.ItemAction;
import org.gcube.common.storagehub.model.types.NodeProperty;
import org.gcube.data.access.storagehub.AuthorizationChecker;
import org.gcube.data.access.storagehub.MultipleOutputStream;
import org.gcube.data.access.storagehub.Utils;
@ -267,7 +268,7 @@ public class ItemHandler {
authChecker.checkWriteAuthorizationControl(ses, login, newNode.getIdentifier(), false);
AbstractFileItem item = fillItemWithContent(stream, storageBackend, name, description, relativePath,login);
item.setHidden(destinationNode.getProperty(NodeProperty.HIDDEN.toString()).getBoolean());
if (withLock) {
try {
ses.getWorkspace().getLockManager().lock(newNode.getPath(), true, true, 0,login);

View File

@ -85,6 +85,9 @@ public class Node2ItemConverter {
}
public Message getMessageItem(Node node) throws RepositoryException{
if (!(node.getPrimaryNodeType().getName().equals("nthl:itemSentRequest")
|| node.getPrimaryNodeType().getName().equals("nthl:itemSentRequestSH")))
return null;
Message msg = new Message();
try {
Node attachmentNode = node.getNode(Constants.ATTACHMENTNODE_NAME);

View File

@ -9,6 +9,7 @@ import javax.jcr.SimpleCredentials;
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
import org.gcube.common.storagehub.model.items.Item;
import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -21,11 +22,11 @@ public class VRE {
private VREQueryRetriever vreQueryRetriever;
private ExecutorService executor;
protected VRE(Item item, Repository repository, SimpleCredentials credentials, ExecutorService executor) {
protected VRE(Item item, Repository repository, SimpleCredentials credentials, Node2ItemConverter node2Item, ExecutorService executor) {
super();
this.vreFolder = item;
this.executor = executor;
vreQueryRetriever = new VREQueryRetriever(repository, credentials, vreFolder);
vreQueryRetriever = new VREQueryRetriever(repository, credentials, node2Item, vreFolder);
result = executor.submit(vreQueryRetriever);
}

View File

@ -9,11 +9,8 @@ import java.util.concurrent.Executors;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.query.Query;
import javax.servlet.ServletContext;
import org.apache.jackrabbit.api.JackrabbitSession;
@ -29,6 +26,7 @@ import org.gcube.common.storagehub.model.exceptions.StorageHubException;
import org.gcube.common.storagehub.model.items.Item;
import org.gcube.data.access.storagehub.Constants;
import org.gcube.data.access.storagehub.PathUtil;
import org.gcube.data.access.storagehub.handlers.GroupHandler;
import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter;
import org.gcube.data.access.storagehub.services.RepositoryInitializer;
import org.slf4j.Logger;
@ -50,6 +48,9 @@ public class VREManager {
@Inject
PathUtil pathUtil;
@Inject
GroupHandler groupHandler;
ExecutorService executor = Executors.newFixedThreadPool(5);
SimpleCredentials credentials;
@ -73,7 +74,7 @@ public class VREManager {
logger.trace("inserting VRE {}",vreFolder.getTitle());
if (vreMap.containsKey(vreFolder.getTitle())) throw new RuntimeException("something went wrong (vre already present in the map)");
else {
VRE toReturn = new VRE(vreFolder, repository.getRepository(), credentials, executor);
VRE toReturn = new VRE(vreFolder, repository.getRepository(), credentials, node2Item, executor);
vreMap.put(vreFolder.getTitle(), toReturn);
return toReturn;
}
@ -97,18 +98,13 @@ public class VREManager {
throw new InvalidCallParameters("error getting VRE with user "+userId+" for group "+groupName);
org.gcube.common.storagehub.model.Path vrePath = pathUtil.getVREsPath(userId, ses);
VRE vre = this.getVRE(groupName);
if (vre!=null) return vre;
else {
String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",groupName, vrePath.toPath());
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE);
NodeIterator it = jcrQuery.execute().getNodes();
if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+groupName);
Node vreFolderNode = groupHandler.getFolderNodeRelatedToGroup(ses, groupName);
Node folder = it.nextNode();
Item vreFolder = node2Item.getItem(folder, excludes);
Item vreFolder = node2Item.getItem(vreFolderNode, excludes);
return this.putVRE(vreFolder);
}
}

View File

@ -1,29 +1,30 @@
package org.gcube.data.access.storagehub.handlers.vres;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import javax.jcr.Credentials;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventJournal;
import javax.jcr.query.Query;
import org.apache.jackrabbit.util.ISO9075;
import org.gcube.common.storagehub.model.Excludes;
import org.gcube.common.storagehub.model.NodeConstants;
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
import org.gcube.common.storagehub.model.items.AbstractFileItem;
import org.gcube.common.storagehub.model.items.FolderItem;
import org.gcube.common.storagehub.model.items.Item;
import org.gcube.data.access.storagehub.NodeChildrenFilterIterator;
import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -37,92 +38,156 @@ public class VREQueryRetriever implements Callable<List<Item>> {
private Repository repository;
private Credentials credentials;
private Item vreFolder;
List<Item> cachedList = new ArrayList<>(CACHE_DIMENSION);
Map<String, Long> cachedMap = new HashMap<>(CACHE_DIMENSION);
long lastTimestamp =0;
private Node2ItemConverter node2Item = new Node2ItemConverter();
long doTime= 0;
boolean underRedo = false;
Node2ItemConverter node2Item;
private static int TIME_MEASURE = Calendar.MINUTE;
private static int VALUE_TIME_BEFORE = 30;
public VREQueryRetriever(Repository repository, Credentials credentials, Item vreFolder) {
public VREQueryRetriever(Repository repository, Credentials credentials, Node2ItemConverter node2Item, Item vreFolder) {
super();
this.repository = repository;
this.credentials = credentials;
this.vreFolder = vreFolder;
this.node2Item = node2Item;
}
public List<Item> call() {
logger.trace("executing recents task");
Session ses = null;
if (lastTimestamp==0) {
try {
long start = System.currentTimeMillis();
ses = repository.login(credentials);
Calendar now = Calendar.getInstance();
now.add(Calendar.YEAR, -1);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH);
String formattedDate = formatter.format(now.getTime());
String xpath = String.format("/jcr:root%s//element(*,nthl:workspaceLeafItem)[@jcr:lastModified>xs:dateTime('%s')] order by @jcr:lastModified descending",ISO9075.encodePath(vreFolder.getPath()),formattedDate);
//String query = String.format("SELECT * FROM [nthl:workspaceLeafItem] AS node WHERE ISDESCENDANTNODE('%s') ORDER BY node.[jcr:lastModified] DESC ",vreFolder.getPath());
logger.debug("query for recents is {}",xpath);
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH);
jcrQuery.setLimit(CACHE_DIMENSION);
lastTimestamp = System.currentTimeMillis();
NodeChildrenFilterIterator it = new NodeChildrenFilterIterator(jcrQuery.execute().getNodes());
logger.debug("query for recents took {}",System.currentTimeMillis()-start);
while (it.hasNext()) {
Node node = it.next();
Item item = node2Item.getItem(node, Excludes.EXCLUDE_ACCOUNTING);
logger.debug("RECENTS - adding item {} with timestamp {}",item.getTitle(), item.getLastModificationTime().getTimeInMillis());
cachedList.add(item);
now.add(TIME_MEASURE, -1*Math.abs(VALUE_TIME_BEFORE));
if (doTime> now.getTimeInMillis() || underRedo) {
logger.debug("executing recents task for {} (cahced result)",vreFolder.getTitle());
return correctValues(ses, cachedMap);
}else {
logger.debug("executing recents task for {} (redoing it)",vreFolder.getTitle());
List<Item> toReturn = redo(ses);
doTime = System.currentTimeMillis();
return toReturn;
}
logger.debug("creating objects took {}",System.currentTimeMillis()-start);
if (cachedList.size()<=10) return cachedList;
else return cachedList.subList(0, 10);
} catch (Exception e) {
logger.error("error querying vre {}",vreFolder.getTitle(),e);
throw new RuntimeException(e);
}catch (Exception e) {
logger.error("error preparing recents for folder {}", vreFolder.getTitle(),e);
return Collections.emptyList();
}finally{
if (ses!=null)
ses.logout();
logger.trace("recents task finished");
logger.debug("recents task finished");
}
}
} else {
try {
public synchronized List<Item> redo(Session ses) {
underRedo = true;
try {
Map<String, Long> tempCachedMap = new HashMap<>(cachedMap);
if (cachedMap.isEmpty())
init(ses, tempCachedMap);
else {
logger.debug("redoing recents for {}",vreFolder.getTitle());
update(ses, tempCachedMap);
}
cachedMap = tempCachedMap;
return correctValues(ses, tempCachedMap);
}finally{
underRedo = false;
}
}
private List<Item> correctValues(Session ses, Map<String, Long> tempCachedMap){
logger.debug("preparing returning values for {}",vreFolder.getTitle());
long start = System.currentTimeMillis();
List<Map.Entry<String, Long>> list = new LinkedList<>(tempCachedMap.entrySet());
list.sort((c1, c2) -> c1.getValue().compareTo(c2.getValue())*-1);
if (list.size()>CACHE_DIMENSION)
for (int index = CACHE_DIMENSION-1; index< list.size() ; index++)
tempCachedMap.remove(list.get(index).getKey());
List<String> cachedIds = list.stream().map(m -> m.getKey()).collect(Collectors.toList());
if (cachedIds.size()>10)
cachedIds = cachedIds.subList(0, 10);
List<Item> result = new ArrayList<>(10);
for (String id: cachedIds) {
try {
Item item = node2Item.getItem(id, ses, Excludes.EXCLUDE_ACCOUNTING);
if (item!=null)
result.add(item);
else logger.warn("item with id {} is null",id);
} catch (BackendGenericError | RepositoryException e) { }
}
logger.debug("returning values prepared in {} for {}",System.currentTimeMillis()-start,vreFolder.getTitle());
return result;
}
private void insertItemInTheRightPlace(Item item, Map<String, Long> tempCachedMap) {
long lastModifiedTime = item.getLastModificationTime().getTimeInMillis();
if (tempCachedMap.size()<CACHE_DIMENSION || lastModifiedTime>Collections.min(tempCachedMap.values()))
tempCachedMap.put(item.getId(), lastModifiedTime);
}
private void init(Session ses,Map<String, Long> tempCachedMap){
try {
long start = System.currentTimeMillis();
lastTimestamp = System.currentTimeMillis();
Node vreFolderNode = ses.getNodeByIdentifier(vreFolder.getId());
logger.debug("starting visiting children for {}",vreFolder.getTitle());
visitChildren(vreFolderNode, tempCachedMap);
logger.debug("initializing recents for {} took {}",vreFolder.getTitle(),System.currentTimeMillis()-start);
} catch (Exception e) {
logger.error("error querying vre {}",vreFolder.getTitle(),e);
throw new RuntimeException(e);
}
}
private void update(Session ses, Map<String, Long> tempCachedMap) {
try {
long timestampToUse = lastTimestamp;
lastTimestamp = System.currentTimeMillis();
long start = System.currentTimeMillis();
ses = repository.login(credentials);
final String[] types = { "nthl:workspaceLeafItem", "nthl:workspaceItem"};
EventJournal journalChanged = ses.getWorkspace().getObservationManager().getEventJournal(Event.PROPERTY_CHANGED^Event.NODE_REMOVED^Event.NODE_MOVED^Event.NODE_ADDED, vreFolder.getPath(), true, null, types);
journalChanged.skipTo(timestampToUse);
logger.trace("getting the journal took {}",System.currentTimeMillis()-start);
logger.debug("getting the journal took {}",System.currentTimeMillis()-start);
int events = 0;
//TODO: manage hidden nodes
while (journalChanged.hasNext()) {
events++;
Event event = journalChanged.nextEvent();
try {
switch(event.getType()) {
case Event.NODE_ADDED:
if (ses.nodeExists(event.getPath())) {
Node nodeAdded = ses.getNode(event.getPath());
if (nodeAdded.isNodeType("nthl:workspaceLeafItem")) {
logger.trace("node added event received with name {}", nodeAdded.getName());
Item item = node2Item.getItem(nodeAdded, Arrays.asList(NodeConstants.ACCOUNTING_NAME));
insertItemInTheRightPlace(item);
logger.debug("node added event received with name {}", nodeAdded.getName());
Item item = node2Item.getItem(nodeAdded, Excludes.ALL);
if (tempCachedMap.get(event.getIdentifier())!=null)
tempCachedMap.remove(event.getIdentifier());
if (item.isHidden())
break;
insertItemInTheRightPlace(item,tempCachedMap);
}
}
break;
@ -131,66 +196,66 @@ public class VREQueryRetriever implements Callable<List<Item>> {
if (ses.propertyExists(event.getPath())) {
Property property = ses.getProperty(event.getPath());
if (property.getName().equalsIgnoreCase("jcr:lastModified")) {
logger.trace("event property changed on {} with value {} and parent {}",property.getName(), property.getValue().getString(), property.getParent().getPath());
logger.debug("event property changed on {} with value {} and parent {}",property.getName(), property.getValue().getString(), property.getParent().getPath());
String identifier = property.getParent().getIdentifier();
cachedList.removeIf(i -> i.getId().equals(identifier));
Item item = node2Item.getItem(property.getParent(), Excludes.EXCLUDE_ACCOUNTING);
insertItemInTheRightPlace(item);
tempCachedMap.remove(identifier);
Item item = node2Item.getItem(property.getParent(), Excludes.ALL);
if (item.isHidden())
break;
insertItemInTheRightPlace(item, tempCachedMap);
}
}
break;
case Event.NODE_REMOVED:
logger.trace("node removed event received with type {}", event.getIdentifier());
cachedList.removeIf(i -> {
try {
return i.getId().equals(event.getIdentifier()) && i.getLastModificationTime().getTime().getTime()<event.getDate();
} catch (RepositoryException e) {
return false;
}
});
if (tempCachedMap.get(event.getIdentifier())!=null &&
tempCachedMap.get(event.getIdentifier())<event.getDate())
tempCachedMap.remove(event.getIdentifier());
break;
case Event.NODE_MOVED:
Node nodeMoved = ses.getNode(event.getPath());
logger.trace("node moved event received with type {}", nodeMoved.getPrimaryNodeType());
if (nodeMoved.isNodeType("nthl:workspaceLeafItem")) {
logger.trace("event node moved on {} with path {}",nodeMoved.getName(), nodeMoved.getPath());
logger.debug("event node moved on {} with path {}",nodeMoved.getName(), nodeMoved.getPath());
String identifier = nodeMoved.getIdentifier();
cachedList.removeIf(i -> i.getId().equals(identifier) && !i.getPath().startsWith(vreFolder.getPath()));
String nodePath = ses.getNode(identifier).getPath();
if (tempCachedMap.get(event.getIdentifier())!=null &&
!nodePath.startsWith(vreFolder.getPath()))
tempCachedMap.remove(event.getIdentifier());
}
break;
default:
throw new Exception("error in event handling");
break;
}
}catch (Exception e) {
logger.warn("error handling event {}",event.getType(),e);
}
}
if (cachedList.size()>CACHE_DIMENSION)
cachedList.subList(51, cachedList.size()).clear();
logger.trace("retrieving event took {} with {} events",System.currentTimeMillis()-start, events);
if (cachedList.size()<=10) return cachedList;
else return cachedList.subList(0, 10);
} catch (Exception e) {
logger.error("error getting events for vre {}",vreFolder.getTitle(),e);
throw new RuntimeException(e);
}finally{
if (ses!=null)
ses.logout();
}
}
}
private void insertItemInTheRightPlace(Item item) {
Iterator<Item> it = cachedList.iterator();
int index =0;
while (it.hasNext()) {
Item inListItem = it.next();
if (item.getLastModificationTime().getTime().getTime()>=inListItem.getLastModificationTime().getTime().getTime()) break;
index++;
private void visitChildren(Node node, Map<String, Long> tempCachedMap) throws Exception{
NodeIterator nodeIt = node.getNodes();
while(nodeIt.hasNext()) {
Node child = nodeIt.nextNode();
Item item = node2Item.getItem(child, Excludes.ALL);
if (item==null || item.isHidden()) continue;
if (item instanceof FolderItem)
visitChildren(child,tempCachedMap);
else if(item instanceof AbstractFileItem)
insertItemInTheRightPlace(item,tempCachedMap);
}
if (index<CACHE_DIMENSION)
cachedList.add(index, item);
}
/* @Override

View File

@ -47,8 +47,14 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("items")
@ManagedBy(StorageHubAppllicationManager.class)
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class ACLManager extends Impersonable {
private static final Logger log = LoggerFactory.getLogger(ACLManager.class);

View File

@ -0,0 +1,47 @@
package org.gcube.data.access.storagehub.services;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Path("api-docs")
public class DocManager {
private static Logger logger = LoggerFactory.getLogger(DocManager.class);
@GET
@Path("/{any: .*}")
public InputStream toDoc(@Context HttpServletRequest req) throws WebApplicationException {
logger.info(DocManager.class.getSimpleName() + " toDoc called");
String pathInfo = req.getPathInfo();
logger.debug("pathInfo {}", pathInfo);
try {
if (pathInfo.endsWith("/api-docs")) {
pathInfo += "index.html";
}
if (pathInfo.endsWith("/api-docs/")) {
pathInfo += "index.html";
}
logger.info("going to {}", pathInfo);
String realPath = req.getServletContext().getRealPath(pathInfo);
return new FileInputStream(new File(realPath));
} catch (Exception e) {
throw new WebApplicationException("error getting docs",e);
}
}
}

View File

@ -9,7 +9,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
@ -40,7 +39,6 @@ import org.apache.jackrabbit.api.security.user.QueryBuilder;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
import org.gcube.common.authorization.control.annotations.AuthorizationControl;
import org.gcube.common.authorization.library.AuthorizationEntry;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
import org.gcube.common.scope.api.ScopeProvider;
@ -75,8 +73,14 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("groups")
@ManagedBy(StorageHubAppllicationManager.class)
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class GroupManager {
@ -200,11 +204,11 @@ public class GroupManager {
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
Authorizable authorizable = usrManager.getAuthorizable(group);
if (authorizable.isGroup())
if (authorizable!=null && authorizable.isGroup())
authorizable.remove();
try {
Node node = groupHandler.getVreFolderNode(session, group);
Node node = groupHandler.getFolderNodeRelatedToGroup(session, group);
List<Item> workspaceItems = Utils.getItemList(node, Excludes.GET_ONLY_CONTENT, null, true, null);
trashHandler.removeOnlyNodesContent(session, workspaceItems);
node.removeSharedSet();
@ -242,7 +246,7 @@ public class GroupManager {
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
Node vreFolder = groupHandler.getVreFolderNode(session, groupId);
Node vreFolder = groupHandler.getFolderNodeRelatedToGroup(session, groupId);
String currentUser = AuthorizationProvider.instance.get().getClient().getId();
if (!isInfraManager() && !(isVREManager() && isValidGroupForContext(groupId) ))
@ -296,7 +300,7 @@ public class GroupManager {
Objects.nonNull(userId);
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
Node vreFolder = groupHandler.getVreFolderNode(session, groupId);
Node vreFolder = groupHandler.getFolderNodeRelatedToGroup(session, groupId);
String currentUser = AuthorizationProvider.instance.get().getClient().getId();
if (!isInfraManager() && !(isVREManager() && isValidGroupForContext(groupId) ))
@ -422,7 +426,7 @@ public class GroupManager {
boolean success = group.addMember(user);
session.save();
String folderName = group.getPrincipal().getName();
Node folder = groupHandler.getVreFolderNode(session, folderName);
Node folder = groupHandler.getFolderNodeRelatedToGroup(session, folderName);
String userPath = Paths.append(pathUtil.getVREsPath(user.getPrincipal().getName(), session), folderName).toPath();
log.debug("creating folder in user path {} from {}", userPath, folder.getPath() );

View File

@ -35,7 +35,6 @@ import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters;
import org.gcube.common.storagehub.model.exceptions.InvalidItemException;
import org.gcube.common.storagehub.model.exceptions.ItemLockedException;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
import org.gcube.common.storagehub.model.items.ExternalFolder;
import org.gcube.common.storagehub.model.items.FolderItem;
import org.gcube.common.storagehub.model.items.Item;
import org.gcube.common.storagehub.model.items.SharedFolder;
@ -56,9 +55,15 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("items")
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class ItemSharing extends Impersonable{
private static final Logger log = LoggerFactory.getLogger(ItemSharing.class);

View File

@ -38,10 +38,14 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("items")
@ManagedBy(StorageHubAppllicationManager.class)
public class ItemsCreator extends Impersonable{
@RequestHeaders({
@RequestHeader(name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), })
public class ItemsCreator extends Impersonable {
private static final Logger log = LoggerFactory.getLogger(ItemsCreator.class);
@ -62,21 +66,22 @@ public class ItemsCreator extends Impersonable{
log.info("create folder item called");
Session ses = null;
String toReturn = null;
try{
try {
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
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());
}catch(StorageHubException she ){
} catch (StorageHubException she) {
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(RepositoryException re ){
} catch (RepositoryException re) {
log.error("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);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
}finally{
if (ses!=null)
} finally {
if (ses != null)
ses.logout();
}
@ -88,29 +93,29 @@ public class ItemsCreator extends Impersonable{
@Path("/{id}/create/EXTERNALFOLDER")
public Response createExternalFolder(@PathParam("id") String id, @FormParam("name") String name,
@FormParam("description") String description, @FormParam("hidden") boolean hidden,
@FormParam("pluginName") String pluginName,
@FormParam("parameters") String pluginParameters) {
@FormParam("pluginName") String pluginName, @FormParam("parameters") String pluginParameters) {
InnerMethodName.instance.set("createItem(EXTERNALFOLDER)");
log.info("create folder item called");
Session ses = null;
String toReturn = null;
try{
//TODO
try {
// TODO
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
ItemsParameterBuilder<FolderCreationParameters> builder = FolderCreationParameters.builder().name(name)
.description(description).onRepository(pluginName).withParameters(null).hidden(hidden).on(id).with(ses).author(currentUser);
.description(description).onRepository(pluginName).withParameters(null).hidden(hidden).on(id)
.with(ses).author(currentUser);
toReturn = itemHandler.create(builder.build());
}catch(StorageHubException she ){
} catch (StorageHubException she) {
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(RepositoryException re ){
} catch (RepositoryException re) {
log.error("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);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
}finally{
if (ses!=null)
} finally {
if (ses != null)
ses.logout();
}
@ -120,35 +125,36 @@ public class ItemsCreator extends Impersonable{
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@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.instance.set("createItem(URL)");
log.info("create url called");
Session ses = null;
String toReturn = null;
try{
try {
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
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());
}catch(StorageHubException she ){
} catch (StorageHubException she) {
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(RepositoryException re ){
} catch (RepositoryException re) {
log.error("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);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
}finally{
if (ses!=null)
} finally {
if (ses != null)
ses.logout();
}
return Response.ok(toReturn).build();
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{id}/create/GCUBEITEM")
@ -158,58 +164,58 @@ public class ItemsCreator extends Impersonable{
Session ses = null;
String toReturn = null;
try{
try {
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
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());
}catch(StorageHubException she ){
} catch (StorageHubException she) {
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(RepositoryException re ){
} catch (RepositoryException re) {
log.error("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);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
}finally{
if (ses!=null)
} finally {
if (ses != null)
ses.logout();
}
return toReturn;
}
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/{id}/create/FILE")
public String createFileItem(@PathParam("id") String id, @FormDataParam("name") String name,
@FormDataParam("description") String description,
@FormDataParam("file") InputStream stream,
@FormDataParam("file") FormDataContentDisposition fileDetail){
@FormDataParam("description") String description, @FormDataParam("file") InputStream stream,
@FormDataParam("file") FormDataContentDisposition fileDetail) {
InnerMethodName.instance.set("createItem(FILE)");
Session ses = null;
String toReturn = null;
try{
try {
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
ItemsParameterBuilder<FileCreationParameters> builder = FileCreationParameters.builder().name(name).description(description).stream(stream).fileDetails(fileDetail)
.on(id).with(ses).author(currentUser);
ItemsParameterBuilder<FileCreationParameters> builder = FileCreationParameters.builder().name(name)
.description(description).stream(stream).fileDetails(fileDetail).on(id).with(ses)
.author(currentUser);
toReturn = itemHandler.create(builder.build());
}catch(RepositoryException re ){
} catch (RepositoryException re) {
log.error("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);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(Throwable e ){
} catch (Throwable e) {
log.error("unexpected error", e);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
}finally{
if (ses!=null && ses.isLive()) {
} finally {
if (ses != null && ses.isLive()) {
log.info("session closed");
ses.logout();
}
@ -218,47 +224,39 @@ public class ItemsCreator extends Impersonable{
}
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/{id}/create/ARCHIVE")
public String uploadArchive(@PathParam("id") String id, @FormDataParam("parentFolderName") String parentFolderName,
@FormDataParam("file") InputStream stream,
@FormDataParam("file") FormDataContentDisposition fileDetail){
@FormDataParam("file") InputStream stream, @FormDataParam("file") FormDataContentDisposition fileDetail) {
InnerMethodName.instance.set("createItem(ARCHIVE)");
Session ses = null;
String toReturn = null;
try{
try {
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
ItemsParameterBuilder<ArchiveStructureCreationParameter> builder = ArchiveStructureCreationParameter.builder().parentName(parentFolderName).stream(stream).fileDetails(fileDetail)
.on(id).with(ses).author(currentUser);
ItemsParameterBuilder<ArchiveStructureCreationParameter> builder = ArchiveStructureCreationParameter
.builder().parentName(parentFolderName).stream(stream).fileDetails(fileDetail).on(id).with(ses)
.author(currentUser);
toReturn = itemHandler.create(builder.build());
}catch(RepositoryException | ArchiveException | IOException re){
} catch (RepositoryException | ArchiveException | IOException re) {
log.error("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);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(Throwable e ){
} catch (Throwable e) {
log.error("unexpected error", e);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
} finally{
if (ses!=null)
} finally {
if (ses != null)
ses.logout();
}
return toReturn;
}
}

View File

@ -94,9 +94,15 @@ import org.gcube.smartgears.utils.InnerMethodName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("items")
@ManagedBy(StorageHubAppllicationManager.class)
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class ItemsManager extends Impersonable{
private static final Logger log = LoggerFactory.getLogger(ItemsManager.class);
@ -350,7 +356,7 @@ public class ItemsManager extends Impersonable{
log.debug("search for node {}",name);
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
toReturn = Utils.serachByNameOnFolder(ses, currentUser, authChecker, ses.getNodeByIdentifier(id), excludes, null, showHidden==null?false:showHidden,excludeTrashed==true?false:excludeTrashed , nodeType!=null ? ClassHandler.instance().get(nodeType) : null, name);
toReturn = Utils.searchByNameOnFolder(ses, currentUser, authChecker, ses.getNodeByIdentifier(id), excludes, null, showHidden==null?false:showHidden,excludeTrashed==true?false:excludeTrashed , nodeType!=null ? ClassHandler.instance().get(nodeType) : null, name);
log.debug("search retrieved {} elements",toReturn.size());
}catch (ItemNotFoundException e) {
log.error("id {} not found",id,e);

View File

@ -63,8 +63,14 @@ import org.gcube.smartgears.utils.InnerMethodName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("messages")
@ManagedBy(StorageHubAppllicationManager.class)
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class MessageManager extends Impersonable{
private static final Logger log = LoggerFactory.getLogger(MessageManager.class);
@ -345,7 +351,13 @@ public class MessageManager extends Impersonable{
NodeIterator nodeIt = node.getNodes();
while(nodeIt.hasNext()) {
Node child = nodeIt.nextNode();
log.info("message type "+child.getPrimaryNodeType().getName());
Message message = node2Item.getMessageItem(child);
if (message == null) {
log.info("message discarded");
continue;
}
if (reduceBody != null && reduceBody>0 && message.getBody().length()>reduceBody )
message.setBody(message.getBody().substring(0, reduceBody));
insertOrdered(messages, message);
@ -354,25 +366,28 @@ public class MessageManager extends Impersonable{
}
private void insertOrdered(List<Message> messages, Message toInsert) {
if (messages.isEmpty()) messages.add(toInsert);
if (messages.isEmpty())
messages.add(toInsert);
else {
int i;
for ( i=0 ; i<messages.size(); i++)
if (messages.get(i).getCreationTime().getTimeInMillis()<=toInsert.getCreationTime().getTimeInMillis())
break;
messages.add(i, toInsert);
}
}
private Node checkRights(String user, Message messageItem) throws RepositoryException, StorageHubException{
Node personalNode = null;
Node messageNode = (Node) messageItem.getRelatedNode();
if (messageNode.getPath().startsWith(pathUtil.getWorkspacePath(currentUser).toPath()))
if (messageNode.getPath().startsWith(pathUtil.getInboxPath(user).toPath()))
return messageNode;
NodeIterator nodeIt = messageNode.getSharedSet();
while (nodeIt.hasNext()) {
Node node = nodeIt.nextNode();
if (node.getPath().startsWith(pathUtil.getWorkspacePath(currentUser).toPath()))
if (node.getPath().startsWith(pathUtil.getInboxPath(user).toPath()))
personalNode = node;
}
if (personalNode == null &&

View File

@ -58,8 +58,14 @@ import org.gcube.smartgears.utils.InnerMethodName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("users")
@ManagedBy(StorageHubAppllicationManager.class)
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class UserManager {
private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager";

View File

@ -55,10 +55,16 @@ import org.gcube.smartgears.utils.InnerMethodName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("/")
@ManagedBy(StorageHubAppllicationManager.class)
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class WorkspaceManager extends Impersonable{
private static final Logger log = LoggerFactory.getLogger(WorkspaceManager.class);
@ -352,59 +358,6 @@ public class WorkspaceManager extends Impersonable{
}
/*
@Path("query")
@GET
@Produces(MediaType.APPLICATION_JSON)
public ItemList searchItems(@QueryParam("n") String node, @QueryParam("e") String jsonExpr, @QueryParam("o") List<String> orderField, @QueryParam("l") Integer limit, @QueryParam("f") Integer offset){
InnerMethodName.instance.set("searchItems");
Session ses = null;
List<? extends Item> toReturn = new ArrayList<>();
try{
ObjectMapper mapper = new ObjectMapper();
Expression<Boolean> expression = mapper.readValue(jsonExpr, Expression.class);
String stringExpression = evaluator.evaluate(new And(new ISDescendant(pathUtil.getWorkspacePath(currentUser)), expression));
String orderBy = "";
if (orderField!=null && orderField.size()>0)
orderBy= String.format("ORDER BY %s", orderField.stream().collect(Collectors.joining(",")).toString());
String sql2Query = String.format("SELECT * FROM [%s] AS node WHERE %s %s ",node, stringExpression,orderBy);
log.info("query sent is {}",sql2Query);
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(sql2Query, Constants.QUERY_LANGUAGE);
if (limit!=null && limit!=-1 )
jcrQuery.setLimit(limit);
if (offset!=null && offset!=-1 )
jcrQuery.setOffset(offset);
QueryResult result = jcrQuery.execute();
NodeIterator it = result.getNodes();
while (it.hasNext())
toReturn.add(node2Item.getItem(it.nextNode(), null));
}catch(RepositoryException | IOException re ){
log.error("error executing the query", 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);
}
*/
@Path("count")
@GET

View File

@ -40,7 +40,13 @@ import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
@Path("admin/script")
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class ScriptManager {
@ -74,7 +80,7 @@ public class ScriptManager {
@FormDataParam("file") FormDataContentDisposition fileDetail) {
try {
ScriptClassLoader scriptClassLoader = new ScriptClassLoader(Thread.currentThread().getContextClassLoader());
Class<?> scriptClass = uploadClass(stream, scriptClassLoader, name);
Class<?> scriptClass = uploadClass(stream, scriptClassLoader, fileDetail.getFileName().replace(".class", ""));
return run(scriptClass, name, destinationFolderId, asynch!=null? asynch : false);
}catch(Throwable e) {
log.error("error executing script {}", name,e);
@ -168,7 +174,7 @@ public class ScriptManager {
.stream(stream).on(parentId).with(ses).author(login);
itemHandler.create(builder.build());
} catch (Throwable e) {
log.error("error saving script result {} in the Workspace",name);
log.error("error saving script result {} in the Workspace",name, e);
}
} finally {

View File

@ -10,7 +10,6 @@ import javax.jcr.RepositoryException;
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
import org.gcube.common.storagehub.model.items.Item;
import org.gcube.data.access.storagehub.Range;
import org.gcube.data.access.storagehub.Utils;
import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter;
import org.gcube.data.access.storagehub.scripting.ScriptUtil;
@ -22,7 +21,7 @@ public class ScriptUtilImpl implements ScriptUtil {
@Override
public List<Item> getChildren(Predicate<Node> checker, Node parent, List<String> excludes, boolean showHidden, Class<? extends Item> nodeTypeToInclude) throws RepositoryException, BackendGenericError {
return Utils.getItemList(checker, parent, excludes, new Range(0, 100), showHidden, nodeTypeToInclude);
return Utils.getItemList(checker, parent, excludes, null, showHidden, nodeTypeToInclude);
}
@Override

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,6 @@ European Union Public Licence V. 1.1
or has expressed by any other mean his willingness to license under the EUPL.
1. Definitions
In this Licence, the following terms have the following meaning:
@ -59,7 +58,6 @@ European Union Public Licence V. 1.1
person.
2. Scope of the rights granted by the Licence
The Licensor hereby grants You a world-wide, royalty-free, non-exclusive,
@ -85,7 +83,6 @@ European Union Public Licence V. 1.1
rights granted on the Work under this Licence.
3. Communication of the Source Code
The Licensor may provide the Work either in its Source Code form, or as
@ -97,7 +94,6 @@ European Union Public Licence V. 1.1
continues to distribute and/or communicate the Work.
4. Limitations on copyright
Nothing in this Licence is intended to deprive the Licensee of the benefits from
@ -106,7 +102,6 @@ European Union Public Licence V. 1.1
applicable limitations thereto.
5. Obligations of the Licensee
The grant of the rights mentioned above is subject to some restrictions and
@ -147,7 +142,6 @@ European Union Public Licence V. 1.1
reproducing the content of the copyright notice.
6. Chain of Authorship
The original Licensor warrants that the copyright in the Original Work granted
@ -163,7 +157,6 @@ European Union Public Licence V. 1.1
terms of this Licence.
7. Disclaimer of Warranty
The Work is a work in progress, which is continuously improved by numerous
@ -180,7 +173,6 @@ European Union Public Licence V. 1.1
for the grant of any rights to the Work.
8. Disclaimer of Liability
Except in the cases of wilful misconduct or damages directly caused to natural
@ -193,7 +185,6 @@ European Union Public Licence V. 1.1
laws as far such laws apply to the Work.
9. Additional agreements
While distributing the Original Work or Derivative Works, You may choose to
@ -207,7 +198,6 @@ European Union Public Licence V. 1.1
any such warranty or additional liability.
10. Acceptance of the Licence
The provisions of this Licence can be accepted by clicking on an icon “I agree”
@ -222,7 +212,6 @@ European Union Public Licence V. 1.1
Distribution and/or Communication by You of the Work or copies thereof.
11. Information to the public
In case of any Distribution and/or Communication of the Work by means of
@ -233,7 +222,6 @@ European Union Public Licence V. 1.1
accessible, concluded, stored and reproduced by the Licensee.
12. Termination of the Licence
The Licence and the rights granted hereunder will terminate automatically upon
@ -244,7 +232,6 @@ European Union Public Licence V. 1.1
remain in full compliance with the Licence.
13. Miscellaneous
Without prejudice of Article 9 above, the Licence represents the complete
@ -265,7 +252,6 @@ European Union Public Licence V. 1.1
their choice.
14. Jurisdiction
Any litigation resulting from the interpretation of this License, arising
@ -279,7 +265,6 @@ European Union Public Licence V. 1.1
conducts its primary business.
15. Applicable Law
This Licence shall be governed by the law of the European Union country where
@ -298,7 +283,6 @@ European Union Public Licence V. 1.1
Appendix
“Compatible Licences” according to article 5 EUPL are:

View File

@ -25,7 +25,7 @@ The projects leading to this software have received funding from a series of
Version
--------------------------------------------------
1.3.1 (20210910-085653)
1.4.2 (20230524-150450)
Please see the file named "changelog.xml" in this directory for the release notes.

View File

@ -1,7 +1,8 @@
<application mode='online'>
<name>StorageHub</name>
<group>DataAccess</group>
<version>1.3.1</version>
<version>1.4.2</version>
<description>Storage Hub webapp</description>
<local-persistence location='target' />
<exclude>/workspace/api-docs/*</exclude>
</application>

View File

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