2018-05-17 12:51:56 +02:00
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 ;
2018-06-20 16:59:41 +02:00
import javax.servlet.ServletContext ;
2018-05-17 12:51:56 +02:00
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 ;
2018-05-28 12:01:01 +02:00
import org.gcube.common.authorization.library.provider.CalledMethodProvider ;
2018-05-17 12:51:56 +02:00
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 ;
2018-06-20 16:59:41 +02:00
import org.gcube.data.access.storagehub.AuthorizationChecker ;
2018-05-17 12:51:56 +02:00
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 ;
2018-06-20 16:59:41 +02:00
import org.gcube.data.access.storagehub.handlers.VRE ;
import org.gcube.data.access.storagehub.handlers.VREManager ;
2018-05-17 12:51:56 +02:00
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 {
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
private static final Logger log = LoggerFactory . getLogger ( WorkspaceManager . class ) ;
@Inject
RepositoryInitializer repository ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
@Inject
Evaluators evaluator ;
2018-06-20 16:59:41 +02:00
@Inject
AuthorizationChecker authChecker ;
@Inject
ServletContext context ;
@Inject
VREManager vreManager ;
2018-05-17 12:51:56 +02:00
@RequestScoped
@QueryParam ( " exclude " )
private List < String > excludes = Collections . emptyList ( ) ;
2018-06-29 16:59:24 +02:00
SimpleCredentials credential = new SimpleCredentials ( context . getInitParameter ( Constants . ADMIN_PARAM_NAME ) , context . getInitParameter ( Constants . ADMIN_PARAM_PWD ) . toCharArray ( ) ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
@Path ( " " )
@GET
@Produces ( MediaType . APPLICATION_JSON )
2018-06-20 16:59:41 +02:00
public ItemWrapper < Item > getWorkspace ( @QueryParam ( " relPath " ) String relPath ) {
2018-05-28 12:01:01 +02:00
CalledMethodProvider . instance . set ( " getWorkspace " ) ;
2018-05-17 12:51:56 +02:00
Session ses = null ;
2018-06-20 16:59:41 +02:00
org . gcube . common . storagehub . model . Path absolutePath ;
if ( relPath = = null )
absolutePath = Utils . getHomePath ( ) ;
else absolutePath = Paths . append ( Utils . getHomePath ( ) , relPath ) ;
2018-05-17 12:51:56 +02:00
Item toReturn = null ;
try {
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
long start = System . currentTimeMillis ( ) ;
2018-06-29 16:59:24 +02:00
ses = repository . getRepository ( ) . login ( credential ) ;
2018-06-20 16:59:41 +02:00
log . trace ( " time to connect to repo {} " , ( System . currentTimeMillis ( ) - start ) ) ;
Node node = ses . getNode ( absolutePath . toPath ( ) ) ;
authChecker . checkReadAuthorizationControl ( ses , node . getIdentifier ( ) ) ;
toReturn = ItemHandler . getItem ( node , excludes ) ;
2018-05-17 12:51:56 +02:00
} catch ( Throwable e ) {
log . error ( " error reading the node children of {} " , absolutePath , e ) ;
2018-06-20 16:59:41 +02:00
throw new WebApplicationException ( " error getting WS folder " + absolutePath . toPath ( ) , e ) ;
2018-05-17 12:51:56 +02:00
} finally {
if ( ses ! = null )
ses . logout ( ) ;
}
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
return new ItemWrapper < Item > ( toReturn ) ;
}
2018-06-20 16:59:41 +02:00
private synchronized VRE getVreFolderItem ( Session ses ) throws Exception {
org . gcube . common . storagehub . model . Path vrePath = Paths . append ( Utils . getHomePath ( ) , Constants . VRE_FOLDER_PARENT_NAME ) ;
ScopeBean bean = new ScopeBean ( ScopeProvider . instance . get ( ) ) ;
if ( ! bean . is ( Type . VRE ) ) throw new Exception ( " 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 Exception ( " vre folder not found for context " + entireScopeName ) ;
Node folder = it . nextNode ( ) ;
Item vreFolder = ItemHandler . getItem ( folder , excludes ) ;
return vreManager . putVRE ( vreFolder ) ;
}
}
2018-05-17 12:51:56 +02:00
@Path ( " vrefolder " )
@GET
@Produces ( MediaType . APPLICATION_JSON )
public ItemWrapper < Item > getVreRootFolder ( ) {
2018-05-28 12:01:01 +02:00
CalledMethodProvider . instance . set ( " getVreRootFolder " ) ;
2018-05-17 12:51:56 +02:00
Session ses = null ;
2018-06-20 16:59:41 +02:00
try {
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
2018-06-29 16:59:24 +02:00
ses = repository . getRepository ( ) . login ( credential ) ;
2018-06-20 16:59:41 +02:00
return new ItemWrapper < Item > ( getVreFolderItem ( ses ) . getVreFolder ( ) ) ;
} catch ( Throwable e ) {
log . error ( " error reading vreNode for context {} " , ScopeProvider . instance . get ( ) , e ) ;
throw new WebApplicationException ( " error retrieving vre folder " , e ) ;
} finally {
if ( ses ! = null )
ses . logout ( ) ;
}
}
@Path ( " vrefolder/recents " )
@GET
@Produces ( MediaType . APPLICATION_JSON )
public ItemList getVreFolderRecentsDocument ( ) {
CalledMethodProvider . instance . set ( " getVreFolderRecents " ) ;
Session ses = null ;
2018-05-17 12:51:56 +02:00
try {
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
2018-06-29 16:59:24 +02:00
ses = repository . getRepository ( ) . login ( credential ) ;
2018-05-17 12:51:56 +02:00
2018-06-20 16:59:41 +02:00
VRE vre = getVreFolderItem ( ses ) ;
log . trace ( " VRE retrieved {} " , vre . getVreFolder ( ) . getTitle ( ) ) ;
List < Item > recentItems = vre . getRecents ( ) ;
log . trace ( " recents retrieved {} " , vre . getVreFolder ( ) . getTitle ( ) ) ;
return new ItemList ( recentItems ) ;
2018-05-17 12:51:56 +02:00
} catch ( Throwable e ) {
2018-06-20 16:59:41 +02:00
log . error ( " error reading recents for context {} " , ScopeProvider . instance . get ( ) , e ) ;
throw new WebApplicationException ( " error reading recents " , e ) ;
2018-05-17 12:51:56 +02:00
} finally {
if ( ses ! = null )
ses . logout ( ) ;
}
}
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
@Path ( " trash " )
@GET
@Produces ( MediaType . APPLICATION_JSON )
public ItemWrapper < Item > getTrashRootFolder ( ) {
2018-05-28 12:01:01 +02:00
CalledMethodProvider . instance . set ( " getTrashRootFolder " ) ;
2018-05-17 12:51:56 +02:00
Session ses = null ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
org . gcube . common . storagehub . model . Path trashPath = Paths . append ( Utils . getHomePath ( ) , Constants . TRASH_ROOT_FOLDER_NAME ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
try {
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
long start = System . currentTimeMillis ( ) ;
2018-06-29 16:59:24 +02:00
ses = repository . getRepository ( ) . login ( credential ) ;
2018-05-17 12:51:56 +02:00
log . info ( " time to connect to repo {} " , ( System . currentTimeMillis ( ) - start ) ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
Node folder = ses . getNode ( trashPath . toPath ( ) ) ;
Item item = ItemHandler . getItem ( folder , excludes ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
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 ( ) ;
}
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
}
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
@Path ( " vrefolders " )
@GET
@Produces ( MediaType . APPLICATION_JSON )
public ItemList getVreFolders ( ) {
2018-05-28 12:01:01 +02:00
CalledMethodProvider . instance . set ( " getVreFolders " ) ;
2018-05-17 12:51:56 +02:00
Session ses = null ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
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 ( ) ;
2018-06-29 16:59:24 +02:00
ses = repository . getRepository ( ) . login ( credential ) ;
2018-05-17 12:51:56 +02:00
toReturn = Utils . getItemList ( ses . getNode ( vrePath . toPath ( ) ) , excludes , null , false ) ;
} catch ( Throwable e ) {
log . error ( " error reading the node children of {} " , vrePath , e ) ;
2018-06-20 16:59:41 +02:00
throw new WebApplicationException ( " error reading the node children of " + vrePath . toPath ( ) , e ) ;
2018-05-17 12:51:56 +02:00
} finally {
if ( ses ! = null )
ses . logout ( ) ;
}
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
return new ItemList ( toReturn ) ;
}
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
@Path ( " vrefolders/paged " )
@GET
@Produces ( MediaType . APPLICATION_JSON )
public ItemList getVreFoldersPaged ( @QueryParam ( " start " ) Integer start , @QueryParam ( " limit " ) Integer limit ) {
2018-05-28 12:01:01 +02:00
CalledMethodProvider . instance . set ( " getVreFoldersPaged " ) ;
2018-05-17 12:51:56 +02:00
Session ses = null ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
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 ( ) ;
2018-06-29 16:59:24 +02:00
ses = repository . getRepository ( ) . login ( credential ) ;
2018-05-17 12:51:56 +02:00
toReturn = Utils . getItemList ( ses . getNode ( vrePath . toPath ( ) ) , excludes , new Range ( start , limit ) , false ) ;
} catch ( Throwable e ) {
2018-06-20 16:59:41 +02:00
log . error ( " (paged) error reading the node children of {} " , vrePath , e ) ;
throw new WebApplicationException ( " error reading the node children of " + vrePath . toPath ( ) , e ) ;
2018-05-17 12:51:56 +02:00
} finally {
if ( ses ! = null )
ses . logout ( ) ;
}
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
return new ItemList ( toReturn ) ;
}
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
@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 ) {
2018-05-28 12:01:01 +02:00
CalledMethodProvider . instance . set ( " searchItems " ) ;
2018-05-17 12:51:56 +02:00
Session ses = null ;
List < ? extends Item > toReturn = new ArrayList < > ( ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
try {
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
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
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
String orderBy = " " ;
if ( orderField ! = null & & orderField . size ( ) > 0 )
2018-06-20 16:59:41 +02:00
orderBy = String . format ( " ORDER BY %s " , orderField . stream ( ) . collect ( Collectors . joining ( " , " ) ) . toString ( ) ) ;
2018-05-17 12:51:56 +02:00
String sql2Query = String . format ( " SELECT * FROM [%s] AS node WHERE %s %s " , node , stringExpression , orderBy ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
log . info ( " query sent is {} " , sql2Query ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
2018-06-29 16:59:24 +02:00
ses = repository . getRepository ( ) . login ( credential ) ;
2018-05-17 12:51:56 +02:00
Query jcrQuery = ses . getWorkspace ( ) . getQueryManager ( ) . createQuery ( sql2Query , Constants . QUERY_LANGUAGE ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
if ( limit ! = null & & limit ! = - 1 )
jcrQuery . setLimit ( limit ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
if ( offset ! = null & & offset ! = - 1 )
jcrQuery . setOffset ( offset ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
QueryResult result = jcrQuery . execute ( ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
NodeIterator it = result . getNodes ( ) ;
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
while ( it . hasNext ( ) )
2018-06-20 16:59:41 +02:00
toReturn . add ( ItemHandler . getItem ( it . nextNode ( ) , null ) ) ;
2018-05-17 12:51:56 +02:00
2018-06-20 16:59:41 +02:00
2018-05-17 12:51:56 +02:00
} catch ( Throwable e ) {
log . error ( " error executing the query " , e ) ;
throw new WebServiceException ( " error executing the query " , e ) ;
} finally {
if ( ses ! = null )
ses . logout ( ) ;
}
2018-06-20 16:59:41 +02:00
return new ItemList ( toReturn ) ;
2018-05-17 12:51:56 +02:00
}
}