diff --git a/distro/gcube-app.xml b/distro/gcube-app.xml
index 4f0d8e1..aa6e541 100644
--- a/distro/gcube-app.xml
+++ b/distro/gcube-app.xml
@@ -1,7 +1,7 @@
StorageHub
DataAccess
- 1.0.0-SNAPSHOT
+ ${version}
Storage Hub webapp
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 474122e..ab8da1a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
4.0.0
org.gcube.data.access
storagehub
- 1.0.8
+ 1.0.9
storagehub
@@ -97,11 +97,6 @@
common-scope
-
- org.gcube.core
- common-encryption
-
-
org.gcube.common
storagehub-model
diff --git a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java
index ad792be..a294964 100644
--- a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java
+++ b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java
@@ -44,7 +44,7 @@ public class AuthorizationChecker {
Item item = node2Item.getItem(node, Excludes.ALL);
- if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to read node with id "+id+": it's not a valid StorageHub node");
+ if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id+": it's not a valid StorageHub node");
@@ -64,10 +64,10 @@ public class AuthorizationChecker {
if (!authorizable.isGroup() && entry.getPrincipal().getName().equals(login)) return;
if (authorizable.isGroup() && ((Group) authorizable).isMember(userAuthorizable)) return;
}
- throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to read node with id "+id);
+ throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id);
} else if (item.getOwner()==null || !item.getOwner().equals(login))
- throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to read node with id "+id);
+ throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id);
}
@@ -86,10 +86,10 @@ public class AuthorizationChecker {
String login = AuthorizationProvider.instance.get().getClient().getId();
- if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to write into node with id "+id+": it's not a valid StorageHub node");
+ if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+id+": it's not a valid StorageHub node");
if (Constants.WRITE_PROTECTED_FOLDER.contains(item.getName()) || Constants.WRITE_PROTECTED_FOLDER.contains(item.getTitle()))
- throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to write into node with id "+id+": it's a protected folder");
+ throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+id+": it's a protected folder");
if (item.isShared()) {
Node parentSharedNode = retrieveSharedFolderParent(node, session);
@@ -116,7 +116,7 @@ public class AuthorizationChecker {
} else
if(item.getOwner().equals(login))
return;
- throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to write into node with id "+id);
+ throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+id);
}
@@ -132,7 +132,7 @@ public class AuthorizationChecker {
//TODO: riguardare questo pezzo di codice
String login = AuthorizationProvider.instance.get().getClient().getId();
- if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+": it's not a valid StorageHub node");
+ if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+": it's not a valid StorageHub node");
Node node = session.getNodeByIdentifier(item.getId());
diff --git a/src/main/java/org/gcube/data/access/storagehub/MyApplicationListener.java b/src/main/java/org/gcube/data/access/storagehub/MyApplicationListener.java
new file mode 100644
index 0000000..0600c8d
--- /dev/null
+++ b/src/main/java/org/gcube/data/access/storagehub/MyApplicationListener.java
@@ -0,0 +1,40 @@
+package org.gcube.data.access.storagehub;
+
+import javax.inject.Inject;
+
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.gcube.data.access.storagehub.services.GroupManager;
+import org.gcube.data.access.storagehub.services.RepositoryInitializer;
+import org.glassfish.jersey.server.monitoring.ApplicationEvent;
+import org.glassfish.jersey.server.monitoring.ApplicationEventListener;
+import org.glassfish.jersey.server.monitoring.RequestEvent;
+import org.glassfish.jersey.server.monitoring.RequestEventListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MyApplicationListener implements ApplicationEventListener {
+
+ private static final Logger log = LoggerFactory.getLogger(MyApplicationListener.class);
+
+ @Inject
+ RepositoryInitializer repository;
+
+ @Override
+ public void onEvent(ApplicationEvent event) {
+ switch (event.getType()) {
+ case DESTROY_FINISHED:
+ log.info("Destroying application storageHub");
+ ((JackrabbitRepository) repository.getRepository()).shutdown();
+ log.info("Jackrabbit repository stopped");
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public RequestEventListener onRequest(RequestEvent requestEvent) {
+ return null;
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/gcube/data/access/storagehub/StorageHub.java b/src/main/java/org/gcube/data/access/storagehub/StorageHub.java
index da500a3..53ba0be 100644
--- a/src/main/java/org/gcube/data/access/storagehub/StorageHub.java
+++ b/src/main/java/org/gcube/data/access/storagehub/StorageHub.java
@@ -32,6 +32,7 @@ public class StorageHub extends Application {
classes.add(UserManager.class);
classes.add(GroupManager.class);
classes.add(SerializableErrorEntityTextWriter.class);
+ classes.add(MyApplicationListener.class);
return classes;
}
diff --git a/src/main/java/org/gcube/data/access/storagehub/Utils.java b/src/main/java/org/gcube/data/access/storagehub/Utils.java
index 62f4ec8..ed7448a 100644
--- a/src/main/java/org/gcube/data/access/storagehub/Utils.java
+++ b/src/main/java/org/gcube/data/access/storagehub/Utils.java
@@ -22,11 +22,16 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
+import javax.jcr.query.Query;
import javax.jcr.version.Version;
import org.apache.commons.io.FilenameUtils;
+import org.apache.jackrabbit.util.ISO9075;
import org.apache.jackrabbit.util.Text;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.common.scope.impl.ScopeBean;
+import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.common.storagehub.model.Excludes;
import org.gcube.common.storagehub.model.Paths;
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
@@ -39,15 +44,13 @@ import org.gcube.common.storagehub.model.items.Item;
import org.gcube.common.storagehub.model.items.SharedFolder;
import org.gcube.common.storagehub.model.types.ItemAction;
import org.gcube.common.storagehub.model.types.NodeProperty;
-import org.gcube.contentmanager.storageclient.wrapper.AccessType;
-import org.gcube.contentmanager.storageclient.wrapper.MemoryType;
-import org.gcube.contentmanager.storageclient.wrapper.StorageClient;
import org.gcube.data.access.storagehub.accounting.AccountingHandler;
import org.gcube.data.access.storagehub.handlers.Item2NodeConverter;
import org.gcube.data.access.storagehub.handlers.Node2ItemConverter;
import org.gcube.data.access.storagehub.handlers.StorageBackendHandler;
+import org.gcube.data.access.storagehub.handlers.VRE;
+import org.gcube.data.access.storagehub.handlers.VREManager;
import org.gcube.data.access.storagehub.handlers.VersionHandler;
-import org.gcube.data.access.storagehub.storage.backend.impl.GCubeStorageBackend;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -107,15 +110,30 @@ public class Utils {
}
+ public static List serachByNameOnFolder(Session ses, Node parent, List excludes, Range range, boolean showHidden, Class extends Item> nodeTypeToInclude, String nameParam) throws RepositoryException, BackendGenericError{
+ String xpath = String.format("/jcr:root%s//element(*,nthl:workspaceItem)[jcr:like(@jcr:title, '%s')]",ISO9075.encodePath(parent.getPath()), nameParam);
+
+ //String query = String.format("SELECT * FROM [nthl:workspaceLeafItem] AS node WHERE ISDESCENDANTNODE('%s') ORDER BY node.[jcr:lastModified] DESC ",vreFolder.getPath());
+ logger.trace("query for search is {}",xpath);
+
+ Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH);
+
+ NodeIterator it = jcrQuery.execute().getNodes();
+ return getItemListFromNodeIterator(it, excludes, range, showHidden, nodeTypeToInclude);
+ }
+
public static List getItemList(Node parent, List excludes, Range range, boolean showHidden, Class extends Item> nodeTypeToInclude) throws RepositoryException, BackendGenericError{
-
- logger.debug("getting children of node {}", parent.getIdentifier());
-
- List returnList = new ArrayList();
+ logger.trace("getting children of node {}", parent.getIdentifier());
long start = System.currentTimeMillis();
NodeIterator iterator = parent.getNodes();
logger.trace("time to get iterator {}",(System.currentTimeMillis()-start));
+ return getItemListFromNodeIterator(iterator, excludes, range, showHidden, nodeTypeToInclude);
+ }
+
+ private static List getItemListFromNodeIterator(NodeIterator iterator, List excludes, Range range, boolean showHidden, Class extends Item> nodeTypeToInclude) throws RepositoryException, BackendGenericError{
+ List returnList = new ArrayList();
+
logger.trace("nodeType is {}",nodeTypeToInclude);
int count =0;
logger.trace("selected range is {}", range);
@@ -123,12 +141,12 @@ public class Utils {
while (iterator.hasNext()){
Node current = iterator.nextNode();
- logger.debug("current node "+current.getName());
+ logger.trace("current node "+current.getName());
if (isToExclude(current, showHidden))
continue;
- logger.debug("current node not excluded "+current.getName());
+ logger.trace("current node not excluded "+current.getName());
if (range==null || (count>=range.getStart() && returnList.size() tempQueue = new LinkedList- ();
- logger.debug("adding directory {}",currentNode.getPath());
+ logger.trace("adding directory {}",currentNode.getPath());
for (Item item : Utils.getItemList(currentNode,Excludes.GET_ONLY_CONTENT, null, false, null)){
if (excludes.contains(item.getId())) continue;
if (item instanceof FolderItem)
tempQueue.addAll(getAllNodesForZip((FolderItem) item, session, accountingHandler, excludes));
else if (item instanceof AbstractFileItem){
- logger.debug("adding file {}",item.getPath());
+ logger.trace("adding file {}",item.getPath());
AbstractFileItem fileItem = (AbstractFileItem) item;
accountingHandler.createReadObj(fileItem.getTitle(), session, session.getNodeByIdentifier(item.getId()), false);
queue.addLast(item);
@@ -188,9 +206,9 @@ public class Utils {
Item item = queue.pop();
if (item instanceof FolderItem) {
actualPath = Paths.getPath(item.getPath());
- logger.debug("actualPath is {}",actualPath.toPath());
+ logger.trace("actualPath is {}",actualPath.toPath());
String name = Paths.remove(actualPath, originalPath).toPath().replaceFirst("/", "");
- logger.debug("writing dir {}",name);
+ logger.trace("writing dir {}",name);
if (name.isEmpty()) continue;
try {
zos.putNextEntry(new ZipEntry(name));
@@ -206,7 +224,7 @@ public class Utils {
}
try(BufferedInputStream is = new BufferedInputStream(streamToWrite)){
String name = (Paths.remove(actualPath, originalPath).toPath()+item.getName()).replaceFirst("/", "");
- logger.debug("writing file {}",name);
+ logger.trace("writing file {}",name);
zos.putNextEntry(new ZipEntry(name));
copyStream(is, zos);
}catch (Exception e) {
@@ -283,7 +301,7 @@ public class Utils {
String nameTocheck = ext.isEmpty()? String.format("%s(*)",filename): String.format("%s(*).%s",filename, ext);
- logger.debug("filename is {}, extension is {} , and name to check is {}", filename, ext, nameTocheck);
+ logger.trace("filename is {}, extension is {} , and name to check is {}", filename, ext, nameTocheck);
NodeIterator ni = destination.getNodes(nameTocheck);
int maxval = 0;
@@ -323,8 +341,10 @@ public class Utils {
//item.setHidden(destinationItem.isHidden());
Node newNode = new Item2NodeConverter().getNode(destinationNode, item);
- if (accountingHandler!=null)
- accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, newNode, false);
+ if (accountingHandler!=null) {
+ accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, destinationNode, false);
+ accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false);
+ }
return newNode;
}
@@ -349,8 +369,10 @@ public class Utils {
//item.setHidden(destinationItem.isHidden());
Node newNode = new Item2NodeConverter().getNode(destinationNode, item);
- if (accountingHandler!=null)
- accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, newNode, false);
+ if (accountingHandler!=null) {
+ accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, destinationNode, false);
+ accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false);
+ }
return newNode;
}
@@ -380,4 +402,43 @@ public class Utils {
node.setProperty(NodeProperty.LAST_MODIFIED_BY.toString(), login);
node.setProperty(NodeProperty.LAST_ACTION.toString(), action.name());
}
+
+ public static synchronized VRE getVreFolderItem(Session ses, Node2ItemConverter node2Item, VREManager vreManager, List excludes ) throws RepositoryException, BackendGenericError{
+ org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME);
+ ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
+ if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE");
+ String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-");
+ VRE vre = vreManager.getVRE(entireScopeName);
+ 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')",entireScopeName, 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 "+entireScopeName);
+
+ Node folder = it.nextNode();
+ Item vreFolder = node2Item.getItem(folder, excludes);
+ return vreManager.putVRE(vreFolder);
+ }
+
+ }
+
+ public static synchronized VRE getVreFolderItemByGroupNameAndUser(Session ses, String goupName, String userId, Node2ItemConverter node2Item, VREManager vreManager, List excludes ) throws RepositoryException, BackendGenericError{
+ org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(userId), Constants.VRE_FOLDER_PARENT_NAME);
+ VRE vre = vreManager.getVRE(goupName);
+ 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')",goupName, 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 "+goupName);
+
+ Node folder = it.nextNode();
+ Item vreFolder = node2Item.getItem(folder, excludes);
+ return vreManager.putVRE(vreFolder);
+ }
+ }
+
}
diff --git a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java
index d2986c0..d321019 100644
--- a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java
+++ b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java
@@ -70,6 +70,25 @@ public class AccountingHandler {
}
}
+ public void createEntryCreate(String title, Session ses, Node node, boolean saveHistory ) {
+ try {
+
+ if (!node.hasNode(NodeProperty.ACCOUNTING.toString())){
+ node.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString());
+ }
+
+ Node accountingNodeParent = node.getNode(NodeProperty.ACCOUNTING.toString());
+ Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.CREATE.getNodeTypeDefinition());
+ accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId());
+ accountingNode.setProperty(DATE, Calendar.getInstance());
+ accountingNode.setProperty(ITEM_NAME, title);
+
+ if (saveHistory) ses.save();
+ } catch (RepositoryException e) {
+ logger.warn("error trying to retrieve accountign node",e);
+ }
+ }
+
public void createFileUpdated(String title, Session ses, Node node, boolean saveHistory ) {
try {
@@ -107,15 +126,15 @@ public class AccountingHandler {
}
- public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, Node node, boolean saveHistory ) {
+ public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, Node parentNode, boolean saveHistory ) {
try {
- Node directoryNode = node.getParent();
- if (!directoryNode.hasNode(NodeProperty.ACCOUNTING.toString())){
- directoryNode.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString());
+
+ if (!parentNode.hasNode(NodeProperty.ACCOUNTING.toString())){
+ parentNode.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString());
}
- Node accountingNodeParent = directoryNode.getNode(NodeProperty.ACCOUNTING.toString());
+ Node accountingNodeParent = parentNode.getNode(NodeProperty.ACCOUNTING.toString());
Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.ADD.getNodeTypeDefinition());
accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId());
accountingNode.setProperty(DATE, Calendar.getInstance());
@@ -172,7 +191,7 @@ public class AccountingHandler {
}
}
- public void createUnshareFolder(String title, Session ses, Node sharedNode, boolean saveHistory ) {
+ public void createUnshareFolder(String title, String user, Session ses, Node sharedNode, boolean saveHistory ) {
try {
if (!sharedNode.hasNode(NodeProperty.ACCOUNTING.toString())){
@@ -180,8 +199,8 @@ public class AccountingHandler {
}
Node accountingNodeParent = sharedNode.getNode(NodeProperty.ACCOUNTING.toString());
- Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.SHARE.getNodeTypeDefinition());
- accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId());
+ Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.UNSHARE.getNodeTypeDefinition());
+ accountingNode.setProperty(USER, user);
accountingNode.setProperty(DATE, Calendar.getInstance());
accountingNode.setProperty(ITEM_NAME, title);
diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/Item2NodeConverter.java b/src/main/java/org/gcube/data/access/storagehub/handlers/Item2NodeConverter.java
index 1b72bd0..68e4e09 100644
--- a/src/main/java/org/gcube/data/access/storagehub/handlers/Item2NodeConverter.java
+++ b/src/main/java/org/gcube/data/access/storagehub/handlers/Item2NodeConverter.java
@@ -56,7 +56,7 @@ public class Item2NodeConverter {
field.setAccessible(true);
try{
//Class> returnType = field.getType();
- logger.debug("creating node - added field {}",field.getName());
+ logger.trace("creating node - added field {}",field.getName());
Values values = getObjectValue(field.getType(), field.get(item));
if (values.isMulti()) newNode.setProperty(attribute.value(), values.getValues());
else newNode.setProperty(attribute.value(), values.getValue());
@@ -67,7 +67,7 @@ public class Item2NodeConverter {
NodeAttribute nodeAttribute = field.getAnnotation(NodeAttribute.class);
if (nodeAttribute.isReadOnly()) continue;
String nodeName = nodeAttribute.value();
- logger.debug("retrieving field node "+field.getName());
+ logger.trace("retrieving field node "+field.getName());
field.setAccessible(true);
try{
Object obj = field.get(item);
@@ -129,7 +129,7 @@ public class Item2NodeConverter {
}
} else if (field.isAnnotationPresent(ListNodes.class)){
- logger.debug("found field {} of type annotated as ListNodes in class {} on node {}", field.getName(), object.getClass().getName(), newNode.getName());
+ logger.trace("found field {} of type annotated as ListNodes in class {} on node {}", field.getName(), object.getClass().getName(), newNode.getName());
field.setAccessible(true);
List