380 lines
14 KiB
Java
380 lines
14 KiB
Java
package org.gcube.data.access.storagehub.services;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
|
|
import javax.enterprise.context.RequestScoped;
|
|
import javax.inject.Inject;
|
|
import javax.jcr.Node;
|
|
import javax.jcr.NodeIterator;
|
|
import javax.jcr.Session;
|
|
import javax.jcr.SimpleCredentials;
|
|
import javax.jcr.query.Query;
|
|
import javax.jcr.query.QueryResult;
|
|
import javax.ws.rs.GET;
|
|
import javax.ws.rs.Path;
|
|
import javax.ws.rs.Produces;
|
|
import javax.ws.rs.QueryParam;
|
|
import javax.ws.rs.WebApplicationException;
|
|
import javax.ws.rs.core.MediaType;
|
|
import javax.xml.ws.WebServiceException;
|
|
|
|
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.Paths;
|
|
import org.gcube.common.storagehub.model.expressions.Expression;
|
|
import org.gcube.common.storagehub.model.expressions.logical.And;
|
|
import org.gcube.common.storagehub.model.expressions.logical.ISDescendant;
|
|
import org.gcube.common.storagehub.model.items.Item;
|
|
import org.gcube.common.storagehub.model.service.ItemList;
|
|
import org.gcube.common.storagehub.model.service.ItemWrapper;
|
|
import org.gcube.data.access.storagehub.Constants;
|
|
import org.gcube.data.access.storagehub.Range;
|
|
import org.gcube.data.access.storagehub.Utils;
|
|
import org.gcube.data.access.storagehub.handlers.ItemHandler;
|
|
import org.gcube.data.access.storagehub.query.sql2.evaluators.Evaluators;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
|
@Path("")
|
|
public class WorkspaceManager {
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(WorkspaceManager.class);
|
|
|
|
@Inject
|
|
RepositoryInitializer repository;
|
|
|
|
@Inject
|
|
Evaluators evaluator;
|
|
|
|
@RequestScoped
|
|
@QueryParam("exclude")
|
|
private List<String> excludes = Collections.emptyList();
|
|
|
|
@Path("")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getWorkspace(){
|
|
Session ses = null;
|
|
org.gcube.common.storagehub.model.Path absolutePath = Utils.getHomePath();
|
|
Item toReturn = null;
|
|
try{
|
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
long start = System.currentTimeMillis();
|
|
ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray()));
|
|
log.info("time to connect to repo {}",(System.currentTimeMillis()-start));
|
|
toReturn = ItemHandler.getItem(ses.getNode(absolutePath.toPath()), excludes);
|
|
}catch(Throwable e){
|
|
log.error("error reading the node children of {}",absolutePath,e);
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemWrapper<Item>(toReturn);
|
|
}
|
|
|
|
|
|
@Path("vrefolder")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getVreRootFolder(){
|
|
Session ses = null;
|
|
|
|
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
|
|
|
try{
|
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
|
|
if (!bean.is(Type.VRE)) throw new Exception("the current scope is not a VRE");
|
|
long start = System.currentTimeMillis();
|
|
ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray()));
|
|
log.info("time to connect to repo {}",(System.currentTimeMillis()-start));
|
|
|
|
String entireScopename= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-");
|
|
|
|
String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s'", entireScopename);
|
|
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE);
|
|
NodeIterator it = jcrQuery.execute().getNodes();
|
|
|
|
if (!it.hasNext()) throw new Exception("vre folder not found for context "+bean.toString());
|
|
|
|
Node folder = it.nextNode();
|
|
Item item = ItemHandler.getItem(folder, excludes);
|
|
|
|
return new ItemWrapper<Item>(item);
|
|
}catch(Throwable e){
|
|
log.error("error reading node {}",vrePath,e);
|
|
throw new WebApplicationException("error retrieving vre folder",e);
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
}
|
|
|
|
@Path("trash")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getTrashRootFolder(){
|
|
Session ses = null;
|
|
|
|
org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getHomePath(), Constants.TRASH_ROOT_FOLDER_NAME);
|
|
|
|
try{
|
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
long start = System.currentTimeMillis();
|
|
ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray()));
|
|
log.info("time to connect to repo {}",(System.currentTimeMillis()-start));
|
|
|
|
|
|
|
|
Node folder = ses.getNode(trashPath.toPath());
|
|
Item item = ItemHandler.getItem(folder, excludes);
|
|
|
|
return new ItemWrapper<Item>(item);
|
|
}catch(Throwable e){
|
|
log.error("error reading the node {}",trashPath,e);
|
|
throw new WebApplicationException("error retrieving trash folder",e);
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
}
|
|
|
|
@Path("vrefolders")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList getVreFolders(){
|
|
Session ses = null;
|
|
|
|
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
|
List<? extends Item> toReturn = null;
|
|
try{
|
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray()));
|
|
toReturn = Utils.getItemList(ses.getNode(vrePath.toPath()) , excludes, null, false);
|
|
}catch(Throwable e){
|
|
log.error("error reading the node children of {}",vrePath,e);
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemList(toReturn);
|
|
}
|
|
|
|
@Path("vrefolders/paged")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList getVreFoldersPaged(@QueryParam("start") Integer start, @QueryParam("limit") Integer limit){
|
|
Session ses = null;
|
|
|
|
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
|
List<? extends Item> toReturn = null;
|
|
try{
|
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray()));
|
|
toReturn = Utils.getItemList(ses.getNode(vrePath.toPath()) , excludes, new Range(start, limit), false);
|
|
}catch(Throwable e){
|
|
log.error("error reading the node children of {}",vrePath,e);
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemList(toReturn);
|
|
}
|
|
|
|
@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){
|
|
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(Utils.getHomePath()), expression));
|
|
//ADD ALSO LIMIT AND OFFSET
|
|
|
|
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);
|
|
|
|
|
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray()));
|
|
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(ItemHandler.getItem(it.nextNode(), excludes));
|
|
|
|
}catch(Throwable e){
|
|
log.error("error executing the query",e);
|
|
throw new WebServiceException("error executing the query", e);
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemList(toReturn);
|
|
}
|
|
|
|
|
|
/*
|
|
@POST
|
|
@Path("create")
|
|
@Consumes({MediaType.MULTIPART_FORM_DATA})
|
|
public Response create(@FormDataParam("item") ItemWrapper itemWrapper, @FormDataParam("file") InputStream stream , @FormDataParam("file") FormDataBodyPart fileDetail, @QueryParam("path") String path){
|
|
Session ses = null;
|
|
log.debug("method create called");
|
|
org.gcube.common.storagehub.model.Path absolutePath = Paths.append(Utils.getHomePath(), Paths.getPath(path));
|
|
try{
|
|
final String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
//long start = System.currentTimeMillis();
|
|
ses = repository.getRepository().login(new SimpleCredentials("workspacerep.imarine","gcube2010*onan".toCharArray()));
|
|
log.debug("session retrieved");
|
|
ItemHandler handler = new ItemHandler();
|
|
Node parentNode = ses.getNode(absolutePath.toPath());
|
|
Item item = itemWrapper.getItem();
|
|
|
|
if (item instanceof AbstractFileItem){
|
|
if (stream==null)
|
|
throw new Exception("invalid item: file without an input stream is not accepted");
|
|
fulfillContent((AbstractFileItem)item, stream, fileDetail, absolutePath.toPath());
|
|
}
|
|
|
|
|
|
Calendar now = Calendar.getInstance();
|
|
item.setCreationTime(now);
|
|
item.setHidden(false);
|
|
item.setLastAction(ItemAction.CREATED);
|
|
item.setLastModificationTime(now);
|
|
item.setLastModifiedBy(login);
|
|
item.setOwner(login);
|
|
|
|
handler.createNodeFromItem(ses, parentNode, item, stream);
|
|
ses.save();
|
|
}catch(Throwable e){
|
|
log.error("error creating file",e);
|
|
return Response.serverError().build();
|
|
} finally{
|
|
if (ses!=null) ses.logout();
|
|
}
|
|
return Response.ok().build();
|
|
}
|
|
|
|
private void fulfillContent(AbstractFileItem item, InputStream stream , FormDataBodyPart fileDetail, String path) {
|
|
if (item instanceof GenericFileItem){
|
|
Content content = new Content();
|
|
String remotePath= path+"/"+fileDetail.getContentDisposition().getFileName();
|
|
content.setData("jcr:content");
|
|
content.setRemotePath(remotePath);
|
|
content.setSize(fileDetail.getContentDisposition().getSize());
|
|
content.setMimeType(fileDetail.getMediaType().toString());
|
|
String storageId = Utils.getStorageClient(AuthorizationProvider.instance.get().getClient().getId()).getClient().put(true).LFile(stream).RFile(remotePath);
|
|
content.setStorageId(storageId);
|
|
((GenericFileItem) item).setContent(content);
|
|
} else throw new RuntimeException("type file error");
|
|
}
|
|
|
|
@PUT
|
|
@Path("{id}/move")
|
|
public Response move(@QueryParam("path") String path, @PathParam("id") String identifier){
|
|
Session ses = null;
|
|
try{
|
|
final String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
long start = System.currentTimeMillis();
|
|
//ses = RepositoryInitializer.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray()));
|
|
//TODO check if it is possible to change all the ACL on a workspace
|
|
ses = repository.getRepository().login(new SimpleCredentials("workspacerep.imarine","gcube2010*onan".toCharArray()));
|
|
|
|
log.info("time to connect to repo {}",(System.currentTimeMillis()-start));
|
|
final Node nodeToMove = ses.getNodeByIdentifier(identifier);
|
|
final Node destination = ses.getNode(path);
|
|
Item destinationItem = ItemHandler.getItem(destination,null);
|
|
//TODO for now only owner of the destination folder can move file
|
|
if (!destinationItem.getOwner().equals(login)){
|
|
/*AccessControlManager accessControlManager = ses.getAccessControlManager();
|
|
boolean canWrite = accessControlManager.hasPrivileges(path, new Privilege[] {
|
|
accessControlManager.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES)});*/
|
|
//if (!canWrite)
|
|
/*
|
|
throw new IllegalAccessException("Insufficent Provileges to write in "+path);
|
|
}
|
|
final Item item = ItemHandler.getItem(nodeToMove, null);
|
|
if (item instanceof SharedFolder){
|
|
throw new Exception("shared item cannot be moved");
|
|
}else if (item instanceof FolderItem){
|
|
if (hasSharedChildren((FolderItem) item, ses)) throw new Exception("folder item with shared children cannot be moved");
|
|
ses.getWorkspace().move(nodeToMove.getPath(), destination.getPath()+"/"+nodeToMove.getName());
|
|
}else {
|
|
item.setParentId(destinationItem.getId());
|
|
ses.getWorkspace().move(nodeToMove.getPath(), destination.getPath()+"/"+nodeToMove.getName());
|
|
}
|
|
ses.save();
|
|
}catch(Exception e){
|
|
log.error("error moving item with id {} in path {}",identifier, path,e);
|
|
return Response.serverError().build();
|
|
} finally{
|
|
if (ses!=null) ses.logout();
|
|
}
|
|
return Response.ok().build();
|
|
}
|
|
|
|
private boolean hasSharedChildren(FolderItem folder, Session session) throws Exception{
|
|
Node currentNode = session.getNodeByIdentifier(folder.getId());
|
|
for (Item item : Utils.getItemList(currentNode,null)){
|
|
if (item instanceof FolderItem)
|
|
return (item instanceof SharedFolder) || hasSharedChildren((FolderItem)item, session);
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
@PUT
|
|
@Path("{id}/rename")
|
|
public Response rename(@QueryParam("newname") String newName, @PathParam("id") String identifier){
|
|
Session ses = null;
|
|
try{
|
|
final String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
long start = System.currentTimeMillis();
|
|
ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray()));
|
|
log.info("time to connect to repo {}",(System.currentTimeMillis()-start));
|
|
}catch(Exception e){
|
|
|
|
}
|
|
return Response.ok().build();
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
}
|