379 lines
14 KiB
Java
379 lines
14 KiB
Java
package org.gcube.data.access.storagehub.services;
|
|
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
import javax.enterprise.context.RequestScoped;
|
|
import javax.inject.Inject;
|
|
import javax.jcr.Node;
|
|
import javax.jcr.RepositoryException;
|
|
import javax.jcr.Session;
|
|
import javax.servlet.ServletContext;
|
|
import javax.ws.rs.Consumes;
|
|
import javax.ws.rs.DELETE;
|
|
import javax.ws.rs.FormParam;
|
|
import javax.ws.rs.GET;
|
|
import javax.ws.rs.PUT;
|
|
import javax.ws.rs.Path;
|
|
import javax.ws.rs.Produces;
|
|
import javax.ws.rs.QueryParam;
|
|
import javax.ws.rs.core.Context;
|
|
import javax.ws.rs.core.MediaType;
|
|
import javax.ws.rs.core.Response;
|
|
|
|
import org.apache.jackrabbit.api.JackrabbitSession;
|
|
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
|
import org.gcube.common.storagehub.model.Excludes;
|
|
import org.gcube.common.storagehub.model.Paths;
|
|
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
|
|
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.exceptions.UserNotAuthorizedException;
|
|
import org.gcube.common.storagehub.model.items.FolderItem;
|
|
import org.gcube.common.storagehub.model.items.Item;
|
|
import org.gcube.common.storagehub.model.items.TrashItem;
|
|
import org.gcube.common.storagehub.model.service.ItemList;
|
|
import org.gcube.common.storagehub.model.service.ItemWrapper;
|
|
import org.gcube.data.access.storagehub.AuthorizationChecker;
|
|
import org.gcube.data.access.storagehub.Constants;
|
|
import org.gcube.data.access.storagehub.PathUtil;
|
|
import org.gcube.data.access.storagehub.Range;
|
|
import org.gcube.data.access.storagehub.StorageHubAppllicationManager;
|
|
import org.gcube.data.access.storagehub.Utils;
|
|
import org.gcube.data.access.storagehub.handlers.CredentialHandler;
|
|
import org.gcube.data.access.storagehub.handlers.TrashHandler;
|
|
import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter;
|
|
import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter;
|
|
import org.gcube.data.access.storagehub.handlers.items.builders.FolderCreationParameters;
|
|
import org.gcube.data.access.storagehub.handlers.plugins.FolderPluginHandler;
|
|
import org.gcube.data.access.storagehub.handlers.vres.VRE;
|
|
import org.gcube.data.access.storagehub.handlers.vres.VREManager;
|
|
import org.gcube.data.access.storagehub.query.sql2.evaluators.Evaluators;
|
|
import org.gcube.smartgears.annotations.ManagedBy;
|
|
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);
|
|
|
|
RepositoryInitializer repository = StorageHubAppllicationManager.repository;
|
|
|
|
@Inject
|
|
Evaluators evaluator;
|
|
|
|
@Inject
|
|
PathUtil pathUtil;
|
|
|
|
@Inject
|
|
VREManager vreManager;
|
|
|
|
@Context
|
|
ServletContext context;
|
|
|
|
@Inject
|
|
AuthorizationChecker authChecker;
|
|
|
|
@Inject
|
|
TrashHandler trashHandler;
|
|
|
|
@RequestScoped
|
|
@QueryParam("exclude")
|
|
private List<String> excludes = Collections.emptyList();
|
|
|
|
@Inject Node2ItemConverter node2Item;
|
|
@Inject Item2NodeConverter item2Node;
|
|
|
|
@Inject
|
|
FolderPluginHandler folderHandler;
|
|
|
|
|
|
@Path("/")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getWorkspace(@QueryParam("relPath") String relPath){
|
|
InnerMethodName.instance.set("getWorkspace");
|
|
Session ses = null;
|
|
org.gcube.common.storagehub.model.Path absolutePath;
|
|
if (relPath==null)
|
|
absolutePath = pathUtil.getWorkspacePath(currentUser);
|
|
else absolutePath = Paths.append(pathUtil.getWorkspacePath(currentUser), relPath);
|
|
|
|
Item toReturn = null;
|
|
try{
|
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
|
//TODO: remove when all user will have TRASH
|
|
org.gcube.common.storagehub.model.Path trashPath = pathUtil.getTrashPath(currentUser, ses);
|
|
if (!ses.nodeExists(trashPath.toPath())) {
|
|
Node wsNode = ses.getNode(pathUtil.getWorkspacePath(currentUser).toPath());
|
|
FolderCreationParameters trashFolderParameters = FolderCreationParameters.builder().name(Constants.TRASH_ROOT_FOLDER_NAME)
|
|
.description("trash of "+currentUser)
|
|
.author(currentUser).on(wsNode.getIdentifier()).with(ses).build();
|
|
Utils.createFolderInternally(trashFolderParameters, null);
|
|
ses.save();
|
|
}
|
|
Node node = ses.getNode(absolutePath.toPath());
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, node.getIdentifier());
|
|
toReturn = node2Item.getItem(node, excludes);
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error getting workspace item", 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 ItemWrapper<Item>(toReturn);
|
|
}
|
|
|
|
|
|
@Path("vrefolder")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getVreRootFolder(){
|
|
InnerMethodName.instance.set("getVreRootFolder");
|
|
JackrabbitSession ses = null;
|
|
Item vreItem = null;
|
|
try {
|
|
ses = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
|
vreItem = vreManager.getVreFolderItem(ses, currentUser, excludes).getVreFolder();
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error getting vrefolder", 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 ItemWrapper<Item>(vreItem);
|
|
}
|
|
|
|
@Path("vrefolder/recents")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList getVreFolderRecentsDocument(){
|
|
InnerMethodName.instance.set("getVreFolderRecents");
|
|
JackrabbitSession ses = null;
|
|
List<Item> recentItems = Collections.emptyList();
|
|
try{
|
|
ses = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
|
|
|
VRE vre = vreManager.getVreFolderItem(ses, currentUser, excludes);
|
|
log.trace("VRE retrieved {}",vre.getVreFolder().getTitle());
|
|
recentItems = vre.getRecents();
|
|
log.trace("recents retrieved {}",vre.getVreFolder().getTitle());
|
|
return new ItemList(recentItems);
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error getting recents", 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(recentItems);
|
|
|
|
|
|
}
|
|
|
|
|
|
@Path("trash")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getTrashRootFolder(){
|
|
InnerMethodName.instance.set("getTrashRootFolder");
|
|
Session ses = null;
|
|
|
|
Item item = null;
|
|
try{
|
|
long start = System.currentTimeMillis();
|
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
|
org.gcube.common.storagehub.model.Path trashPath = pathUtil.getTrashPath(currentUser, ses);
|
|
log.info("time to connect to repo {}",(System.currentTimeMillis()-start));
|
|
|
|
Node folder = ses.getNode(trashPath.toPath());
|
|
item = node2Item.getItem(folder, excludes);
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error getting trash", 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 ItemWrapper<Item>(item);
|
|
}
|
|
|
|
|
|
@Path("trash/empty")
|
|
@DELETE
|
|
public String emptyTrash(){
|
|
InnerMethodName.instance.set("emptyTrash");
|
|
Session ses = null;
|
|
String toReturn = null;
|
|
try{
|
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
|
org.gcube.common.storagehub.model.Path trashPath = pathUtil.getTrashPath(currentUser, ses);
|
|
Node trashNode = ses.getNode(trashPath.toPath());
|
|
List<Item> itemsToDelete = Utils.getItemList(trashNode, Excludes.ALL, null, true, null);
|
|
trashHandler.removeNodes(ses, itemsToDelete);
|
|
toReturn = trashNode.getIdentifier();
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error emptying trash", 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 toReturn;
|
|
}
|
|
|
|
@PUT
|
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
|
@Path("trash/restore")
|
|
public String restoreItem(@FormParam("trashedItemId") String trashedItemId,@FormParam("destinationId") String destinationFolderId){
|
|
InnerMethodName.instance.set("restoreItem");
|
|
Session ses = null;
|
|
String toReturn = null;
|
|
try{
|
|
|
|
log.info("restoring node with id {}", trashedItemId);
|
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
|
|
|
final Node nodeToRestore = ses.getNodeByIdentifier(trashedItemId);
|
|
|
|
Item itemToRestore = node2Item.getItem(nodeToRestore, Excludes.ALL);
|
|
|
|
if (!(itemToRestore instanceof TrashItem))
|
|
throw new InvalidItemException("Only trash items can be restored");
|
|
|
|
org.gcube.common.storagehub.model.Path trashPath = pathUtil.getTrashPath(currentUser, ses);
|
|
if (!itemToRestore.getPath().startsWith(trashPath.toPath()))
|
|
throw new UserNotAuthorizedException("this item is not in the user "+currentUser+" trash");
|
|
|
|
Item destinationItem = null;
|
|
if (destinationFolderId!=null ) {
|
|
destinationItem = node2Item.getItem(ses.getNodeByIdentifier(destinationFolderId), Excludes.ALL);
|
|
if (!(destinationItem instanceof FolderItem))
|
|
throw new InvalidCallParameters("destintation item is not a folder");
|
|
toReturn = trashHandler.restoreItem(ses, (TrashItem)itemToRestore, (FolderItem) destinationItem, currentUser);
|
|
} else
|
|
toReturn = trashHandler.restoreItem(ses, (TrashItem)itemToRestore, null, currentUser);
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("error restoring item with id {}",trashedItemId, 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 toReturn;
|
|
}
|
|
|
|
|
|
@Path("vrefolders")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList getVreFolders(){
|
|
InnerMethodName.instance.set("getVreFolders");
|
|
Session ses = null;
|
|
List<? extends Item> toReturn = null;
|
|
org.gcube.common.storagehub.model.Path vrePath = null;
|
|
try{
|
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
|
vrePath = pathUtil.getVREsPath(currentUser, ses);
|
|
log.info("vres folder path is {}",vrePath.toPath());
|
|
|
|
toReturn = Utils.getItemList(ses.getNode(vrePath.toPath()) , excludes, null, false, null);
|
|
}catch(RepositoryException re ){
|
|
log.error("error reading the node children of {}",vrePath, 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("vrefolders/paged")
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList getVreFoldersPaged(@QueryParam("start") Integer start, @QueryParam("limit") Integer limit){
|
|
InnerMethodName.instance.set("getVreFoldersPaged");
|
|
Session ses = null;
|
|
org.gcube.common.storagehub.model.Path vrePath = null;
|
|
List<? extends Item> toReturn = null;
|
|
try{
|
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
|
vrePath = pathUtil.getVREsPath(currentUser, ses);
|
|
toReturn = Utils.getItemList(ses.getNode(vrePath.toPath()) , excludes, new Range(start, limit), false, null);
|
|
}catch(RepositoryException re ){
|
|
log.error("(paged) error reading the node children of {}",vrePath, 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
|
|
public String getTotalItemsCount(){
|
|
InnerMethodName.instance.set("getTotalItemsCount");
|
|
return folderHandler.getDefault().getStorageBackend().getTotalItemsCount();
|
|
}
|
|
|
|
|
|
@Path("size")
|
|
@GET
|
|
public String getTotalVolume(){
|
|
InnerMethodName.instance.set("getTotalSize");
|
|
return folderHandler.getDefault().getStorageBackend().getTotalSizeStored();
|
|
|
|
}
|
|
|
|
}
|