From 6185b1563b818cb6ff076e054411148445f8ff75 Mon Sep 17 00:00:00 2001 From: Lucio Lelii Date: Thu, 12 Jul 2018 13:44:11 +0000 Subject: [PATCH] git-svn-id: https://svn.d4science-ii.research-infrastructures.eu/gcube/branches/data-access/storagehub-webapp/1.0@169762 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../storagehub/handlers/ItemHandler.java | 10 +- .../handlers/VREQueryRetriever.java | 34 ++++-- .../storagehub/handlers/VersionHandler.java | 9 +- .../storagehub/services/ItemsCreator.java | 102 ++++++++++++++++-- 4 files changed, 134 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java index 540fda7..3f2ebf5 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java @@ -29,6 +29,7 @@ import org.apache.jackrabbit.value.BooleanValue; import org.apache.jackrabbit.value.DateValue; import org.apache.jackrabbit.value.LongValue; import org.apache.jackrabbit.value.StringValue; +import org.gcube.common.storagehub.model.NodeConstants; import org.gcube.common.storagehub.model.annotations.Attribute; import org.gcube.common.storagehub.model.annotations.AttributeRootNode; import org.gcube.common.storagehub.model.annotations.ListNodes; @@ -40,6 +41,8 @@ import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.common.storagehub.model.items.TrashItem; import org.gcube.common.storagehub.model.items.nodes.Content; +import org.gcube.common.storagehub.model.types.ItemAction; +import org.gcube.common.storagehub.model.types.NodeProperty; import org.reflections.Configuration; import org.reflections.Reflections; import org.reflections.util.ConfigurationBuilder; @@ -406,9 +409,12 @@ public class ItemHandler { try { node.setPrimaryType(item.getClass().getAnnotation(RootNode.class).value()); - Node contentNode = node.getNode("jcr:content"); + Node contentNode = node.getNode(NodeConstants.CONTENT_NAME); contentNode.setPrimaryType(item.getContent().getClass().getAnnotation(AttributeRootNode.class).value()); - + + node.setProperty(NodeProperty.LAST_MODIFIED.toString(), item.getLastModificationTime()); + node.setProperty(NodeProperty.LAST_MODIFIED_BY.toString(), item.getLastModifiedBy()); + node.setProperty(NodeProperty.LAST_ACTION.toString(), ItemAction.UPDATED.name()); for (Field field : retrieveAllFields(item.getContent().getClass())){ if (field.isAnnotationPresent(Attribute.class)){ diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java b/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java index 14cf4de..fed397c 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java @@ -57,8 +57,12 @@ public class VREQueryRetriever implements Callable> { lastTimestamp = System.currentTimeMillis(); NodeIterator it = jcrQuery.execute().getNodes(); logger.trace("query for recents took {}",System.currentTimeMillis()-start); - while (it.hasNext()) - cachedList.add(ItemHandler.getItem(it.nextNode(), Arrays.asList(NodeConstants.ACCOUNTING_NAME))); + while (it.hasNext()) { + Node node = it.nextNode(); + Item item =ItemHandler.getItem(node, Arrays.asList(NodeConstants.ACCOUNTING_NAME)); + cachedList.add(item); + logger.trace("adding item {} with node {}",item.getTitle(), node.getName()); + } logger.trace("creating objects took {}",System.currentTimeMillis()-start); if (cachedList.size()<=10) return cachedList; else return cachedList.subList(0, 10); @@ -72,7 +76,7 @@ public class VREQueryRetriever implements Callable> { } } else { try { - + long timestampToUse = lastTimestamp; lastTimestamp = System.currentTimeMillis(); @@ -80,13 +84,29 @@ public class VREQueryRetriever implements Callable> { 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, vreFolder.getPath(), true, null, types); + 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); + + int events = 0; + while (journalChanged.hasNext()) { + events++; Event event = journalChanged.nextEvent(); 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 = ItemHandler.getItem(nodeAdded, Arrays.asList(NodeConstants.ACCOUNTING_NAME)); + insertItemInTheRightPlace(item); + } + } + break; + case Event.PROPERTY_CHANGED: if (ses.propertyExists(event.getPath())) { Property property = ses.getProperty(event.getPath()); @@ -127,7 +147,7 @@ public class VREQueryRetriever implements Callable> { if (cachedList.size()>CACHE_DIMENSION) cachedList.subList(51, cachedList.size()).clear(); - logger.trace("retrieving event took {}",System.currentTimeMillis()-start); + 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) { diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/VersionHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/VersionHandler.java index f49a545..d37382d 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/VersionHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/VersionHandler.java @@ -14,6 +14,7 @@ import javax.jcr.version.VersionManager; import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.core.version.VersionManagerImplBase; +import org.gcube.common.storagehub.model.NodeConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,7 +25,7 @@ public class VersionHandler { public void makeVersionableContent(Node node, Session session){ try { - Node contentNode = node.getNode("jcr:content"); + Node contentNode = node.getNode(NodeConstants.CONTENT_NAME); contentNode.addMixin(JcrConstants.MIX_VERSIONABLE); }catch(Exception e ) { logger.warn("cannot create versioned content node",e); @@ -33,7 +34,7 @@ public class VersionHandler { public void checkinContentNode(Node node, Session session){ try { - Node contentNode = node.getNode("jcr:content"); + Node contentNode = node.getNode(NodeConstants.CONTENT_NAME); VersionManager versionManager = session.getWorkspace().getVersionManager(); versionManager.checkin(contentNode.getPath()); }catch(Exception e ) { @@ -43,7 +44,7 @@ public class VersionHandler { public void checkoutContentNode(Node node, Session session){ try { - Node contentNode = node.getNode("jcr:content"); + Node contentNode = node.getNode(NodeConstants.CONTENT_NAME); VersionManager versionManager = session.getWorkspace().getVersionManager(); versionManager.checkout(contentNode.getPath()); }catch(Exception e ) { @@ -53,7 +54,7 @@ public class VersionHandler { public List getContentVersionHistory(Node node, Session session) { try { - Node contentNode = node.getNode("jcr:content"); + Node contentNode = node.getNode(NodeConstants.CONTENT_NAME); VersionManager versionManager = session.getWorkspace().getVersionManager(); VersionHistory history = versionManager.getVersionHistory(contentNode.getPath()); VersionIterator iterator = history.getAllVersions(); diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java index 1399695..be4f204 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java @@ -82,7 +82,8 @@ public class ItemsCreator { @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) - @Path("/{id}/create/{type:(?!FILE)[^/?$]*}") + //@Path("/{id}/create/{type:(?!FILE)[^/?$]*}") + @Path("/{id}/create/FOLDER") public Response createItem(@PathParam("id") String id, @PathParam("type") String type,@QueryParam("name") String name, @QueryParam("description") String description){ InnerMethodName.instance.set(String.format("createItem(%s)",type)); log.info("create generic item called"); @@ -97,7 +98,7 @@ public class ItemsCreator { //validate input parameters for Item Type - if(!type.equals("FOLDER")) throw new IllegalAccessException("invalid item type"); + //if(!type.equals("FOLDER")) throw new IllegalAccessException("invalid item type"); log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); Node destination = ses.getNodeByIdentifier(id); @@ -228,6 +229,82 @@ public class ItemsCreator { } + + /* + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @Path("/{id}/create/ARCHIVE") + public Response uploadArchive(@PathParam("id") String id, @FormDataParam("folderName") String folderName, + @FormDataParam("file") InputStream stream, + @FormDataParam("file") FormDataContentDisposition fileDetail){ + InnerMethodName.instance.set("createItem(FILE)"); + + Session ses = null; + Item destinationItem = null; + try{ + if (folderName==null) throw new Exception("new folder name is null"); + final String login = AuthorizationProvider.instance.get().getClient().getId(); + + //TODO check if it is possible to change all the ACL on a workspace + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); + + //TODO: validate input parameters for Item Type + Node destination = ses.getNodeByIdentifier(id); + + destinationItem = ItemHandler.getItem(destination,Arrays.asList(ACCOUNTING_NAME,CONTENT_NAME)); + if (!(destinationItem instanceof FolderItem)) throw new Exception("destination item is not a folder"); + + ses.getWorkspace().getLockManager().lock(destinationItem.getPath(), true, true, 0,login); + + ContentHandler handler = getContentHandler(stream , name, destinationItem.getPath()); + + AbstractFileItem item =handler.buildItem(name, description, login); + + //to inherit hidden property + //item.setHidden(destinationItem.isHidden()); + + log.debug("item prepared, fulfilling content"); + log.debug("content prepared"); + + Node newNode; + try { + newNode = ses.getNode(org.gcube.common.storagehub.model.Paths.append(org.gcube.common.storagehub.model.Paths.getPath(destinationItem.getPath()), name).toPath()); + authChecker.checkWriteAuthorizationControl(ses, newNode.getIdentifier(), false); + versionHandler.checkoutContentNode(newNode, ses); + log.trace("replacing content of class {}",item.getContent().getClass()); + ItemHandler.replaceContent(ses, newNode,item); + }catch(PathNotFoundException pnf) { + log.info("creating new node"); + authChecker.checkWriteAuthorizationControl(ses, destinationItem.getId(), true); + newNode = ItemHandler.createNodeFromItem(ses, destination, item); + versionHandler.makeVersionableContent(newNode, ses); + } + + accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), item.getContent().getMimeType(), ses, newNode, false); + + ses.save(); + versionHandler.checkinContentNode(newNode, ses); + log.info("file with id {} correctly created",newNode.getIdentifier()); + return Response.ok(newNode.getIdentifier()).build(); + }catch(Throwable e){ + log.error("error creating item", e); + return Response.serverError().build(); + } finally{ + if (ses!=null){ + if (destinationItem!=null) + try { + if (ses.getWorkspace().getLockManager().isLocked(destinationItem.getPath())) + ses.getWorkspace().getLockManager().unlock(destinationItem.getPath()); + } catch (Throwable t){ + log.warn("error unlocking {}", destinationItem.getPath(), t); + } + ses.logout(); + } + } + + } + */ private ContentHandler getContentHandler(InputStream stream , String name, String path) throws Exception { @@ -238,6 +315,8 @@ public class ItemsCreator { @Override public ContentHandler call() throws Exception { ContentHandler handler =null; + long start = System.currentTimeMillis(); + log.debug("TIMING: reading the mimetype - start"); try(BufferedInputStream is1 = new BufferedInputStream(mos.get(), 2048)){ org.apache.tika.mime.MediaType mediaType = null; TikaConfig config = TikaConfig.getDefaultConfig(); @@ -253,7 +332,7 @@ public class ItemsCreator { is1.reset(); handler.initiliseSpecificContent(is1); handler.getContent().setMimeType(mimeType); - + log.trace("TIMING: reading the mimetype - finished in {}",System.currentTimeMillis()-start); } catch (Throwable e) { log.error("error retrieving mimeType",e); throw new RuntimeException(e); @@ -268,6 +347,8 @@ public class ItemsCreator { @Override public MetaInfo call() throws Exception { try { + long start = System.currentTimeMillis(); + log.debug("TIMING: sending the content to Storage - start"); String remotePath= path+"/"+name; String storageId = Utils.getStorageClient(AuthorizationProvider.instance.get().getClient().getId()).getClient().put(true).LFile(mos.get()).RFile(remotePath); long size = Utils.getStorageClient(AuthorizationProvider.instance.get().getClient().getId()).getClient().getSize().RFileById(storageId); @@ -275,6 +356,7 @@ public class ItemsCreator { info.setSize(size); info.setStorageId(storageId); info.setRemotePath(remotePath); + log.debug("TIMING: sending the content to Storage - finished in {}",System.currentTimeMillis()-start); return info; }catch (Throwable e) { log.error("error writing content"); @@ -286,14 +368,18 @@ public class ItemsCreator { Future detectorF = executor.submit(mimeTypeDector); Future uploaderF = executor.submit(uploader); - + + long start = System.currentTimeMillis(); + log.debug("TIMING: writing the strem - start"); mos.startWriting(); - + log.debug("TIMING: writing the stream - finished in {}",System.currentTimeMillis()-start); + ContentHandler handler = detectorF.get(); + MetaInfo info = uploaderF.get(); handler.getContent().setData("jcr:content"); - handler.getContent().setStorageId(uploaderF.get().getStorageId()); - handler.getContent().setSize(uploaderF.get().getSize()); - handler.getContent().setRemotePath(uploaderF.get().getRemotePath()); + handler.getContent().setStorageId(info.getStorageId()); + handler.getContent().setSize(info.getSize()); + handler.getContent().setRemotePath(info.getRemotePath()); return handler; }