2021-09-20 16:47:35 +02:00
package org.gcube.application.geoportal.service.engine.mongo ;
2021-12-01 11:13:34 +01:00
import com.fasterxml.jackson.core.JsonProcessingException ;
import com.mongodb.client.MongoDatabase ;
2021-12-07 16:12:43 +01:00
import lombok.Synchronized ;
2021-12-01 11:13:34 +01:00
import lombok.extern.slf4j.Slf4j ;
import org.bson.Document ;
import org.bson.types.ObjectId ;
2021-12-07 16:12:43 +01:00
import org.gcube.application.cms.plugins.LifecycleManager ;
2021-12-07 16:42:39 +01:00
import org.gcube.application.cms.plugins.faults.StepException ;
2022-01-12 18:42:22 +01:00
import org.gcube.application.cms.plugins.model.PluginDescriptor ;
2021-12-15 19:10:19 +01:00
import org.gcube.application.cms.plugins.reports.ExecutionReport ;
2021-12-07 16:42:39 +01:00
import org.gcube.application.cms.plugins.requests.StepExecutionRequest ;
import org.gcube.application.geoportal.common.model.document.* ;
2021-12-01 11:13:34 +01:00
import org.gcube.application.geoportal.common.model.legacy.Concessione ;
import org.gcube.application.geoportal.common.model.legacy.report.ValidationReport ;
2022-01-12 18:42:22 +01:00
import org.gcube.application.geoportal.common.model.profile.HandlerDeclaration ;
2021-12-07 13:05:08 +01:00
import org.gcube.application.geoportal.common.model.profile.Profile ;
2021-12-01 11:13:34 +01:00
import org.gcube.application.geoportal.common.model.rest.QueryRequest ;
2021-12-07 13:05:08 +01:00
import org.gcube.application.geoportal.service.engine.ImplementationProvider ;
2022-01-12 18:42:22 +01:00
import org.gcube.application.geoportal.service.engine.providers.PluginManager ;
2021-12-01 11:13:34 +01:00
import org.gcube.application.geoportal.service.model.internal.faults.ConfigurationException ;
import org.gcube.application.geoportal.service.model.internal.faults.DeletionException ;
import org.gcube.application.geoportal.service.utils.Serialization ;
2021-12-07 16:12:43 +01:00
import org.gcube.application.geoportal.service.utils.UserUtils ;
2021-09-20 16:47:35 +02:00
2021-12-07 11:16:26 +01:00
import javax.ws.rs.WebApplicationException ;
import javax.ws.rs.core.Response ;
2021-12-01 11:13:34 +01:00
import java.io.IOException ;
2021-12-07 11:16:26 +01:00
import java.security.InvalidParameterException ;
2022-01-12 18:42:22 +01:00
import java.util.List ;
2021-12-07 13:05:08 +01:00
import java.util.Map ;
2021-12-01 11:13:34 +01:00
import java.util.concurrent.LinkedBlockingQueue ;
import java.util.function.Consumer ;
import static org.gcube.application.geoportal.service.engine.mongo.ConcessioniMongoManager.asConcessione ;
@Slf4j
public class ProfiledMongoManager extends MongoManager implements MongoManagerI < ProfiledDocument > {
2021-12-07 13:05:08 +01:00
Profile profile ;
2021-12-07 16:12:43 +01:00
MongoDatabase db = null ;
LifecycleManager lfManager ;
2021-12-07 11:16:26 +01:00
public ProfiledMongoManager ( String profileId ) throws ConfigurationException {
2022-01-14 12:31:11 +01:00
// Check Profile ID
2021-12-07 16:12:43 +01:00
log . info ( " Loading profile ID {} " , profileId ) ;
2021-12-07 11:16:26 +01:00
if ( profileId = = null ) throw new InvalidParameterException ( " Profile ID cannot be null " ) ;
2021-12-07 13:05:08 +01:00
Map < String , Profile > profiles = ImplementationProvider . get ( ) . getProfiles ( ) . getObject ( ) ;
2021-12-07 16:12:43 +01:00
if ( ! profiles . containsKey ( profileId ) ) {
log . debug ( " Asked profile {} not found. Available ones are {} " , profileId , profiles . keySet ( ) ) ;
throw new WebApplicationException ( " Profile " + profileId + " not registered " , Response . Status . NOT_FOUND ) ;
}
profile = profiles . get ( profileId ) ;
log . debug ( " Loaded Profile {} " , profile ) ;
2022-01-12 18:42:22 +01:00
2022-01-14 12:31:11 +01:00
//Getting Lifecycle Manager declaration from Profile
2022-01-12 18:42:22 +01:00
List < HandlerDeclaration > handlerDeclarations = profile . getHandlersMap ( ) . get ( PluginDescriptor . BaseTypes . LIFECYCLE_MANAGER ) ;
if ( handlerDeclarations = = null | | handlerDeclarations . isEmpty ( ) ) throw new ConfigurationException ( " No Lifecycle Handler defined for profile ID " + profileId ) ;
if ( handlerDeclarations . size ( ) > 1 ) throw new ConfigurationException ( " Too many Lifecycle Handlers defined ( " + handlerDeclarations + " ) in profile ID " + profileId ) ;
HandlerDeclaration lcHandlerDeclaration = handlerDeclarations . get ( 0 ) ;
2022-01-14 12:31:11 +01:00
// Loading Lifecycle Manager
2022-01-12 18:42:22 +01:00
log . debug ( " Looking for handler {} " , lcHandlerDeclaration ) ;
try {
lfManager = ( LifecycleManager ) ImplementationProvider . get ( ) . getPluginManager ( ) . getObject ( ) . get ( lcHandlerDeclaration . getId ( ) ) ;
if ( lfManager = = null ) throw new ConfigurationException ( " Unable to find Lifecycle Manager Plugin. ID " + lcHandlerDeclaration . getId ( ) ) ;
} catch ( ClassCastException e ) {
throw new ConfigurationException ( " Unable to use " + lcHandlerDeclaration . getId ( ) + " as Lifecycle Manager " ) ;
}
2022-01-14 12:31:11 +01:00
// Connect to DB
String toUseDB = super . client . getConnection ( ) . getDatabase ( ) ;
log . info ( " Connecting to DB {} " , toUseDB ) ;
// TODO MAP OF DATABASES?
db = client . getTheClient ( ) . getDatabase ( toUseDB ) ;
2021-12-01 11:13:34 +01:00
}
2021-12-07 16:12:43 +01:00
2021-12-07 16:42:39 +01:00
private ProfiledDocument onUpdate ( ProfiledDocument updatedDocument ) throws StepException {
2021-12-07 16:12:43 +01:00
UserUtils . AuthenticatedUser u = UserUtils . getCurrent ( ) ;
updatedDocument . getInfo ( ) . setLastEditInfo ( u . asInfo ( ) ) ;
2021-12-15 19:10:19 +01:00
return step ( updatedDocument , StepExecutionRequest . Steps . ON_UPDATE_DOCUMENT ) . getResult ( ) ;
2021-12-01 11:13:34 +01:00
}
private Document asDocument ( ProfiledDocument d ) throws JsonProcessingException {
return Document . parse ( Serialization . write ( d ) ) ;
}
private ProfiledDocument asProfiledDocument ( Document d ) throws IOException {
return Serialization . read ( d . toJson ( ) , ProfiledDocument . class ) ;
}
private String getCollectionName ( ) {
2021-12-07 16:42:39 +01:00
// TODO Profile can directly specify, use ID only as default
2022-01-14 12:31:11 +01:00
2021-12-07 16:12:43 +01:00
return profile . getId ( ) ;
2021-12-01 11:13:34 +01:00
}
@Override
2021-12-07 16:12:43 +01:00
public MongoDatabase getDatabase ( ) {
return db ;
2021-12-01 11:13:34 +01:00
}
@Override
2021-12-07 16:42:39 +01:00
public ProfiledDocument registerNew ( Document toRegisterDoc ) throws IOException , StepException {
log . info ( " Registering new document in {} " , profile . getId ( ) ) ;
log . debug ( " Going to register {} " , toRegisterDoc . toJson ( ) ) ;
2021-12-07 11:16:26 +01:00
ProfiledDocument toRegister = new ProfiledDocument ( ) ;
toRegister . setTheDocument ( toRegisterDoc ) ;
2021-12-07 16:42:39 +01:00
PublicationInfo pubInfo = new PublicationInfo ( ) ;
pubInfo . setCreationInfo ( UserUtils . getCurrent ( ) . asInfo ( ) ) ;
// TODO Set Access From Profile
Access access = new Access ( ) ;
access . setLicense ( " " ) ;
access . setPolicy ( AccessPolicy . OPEN ) ;
pubInfo . setAccess ( access ) ;
toRegister . setInfo ( pubInfo ) ;
2021-12-01 11:13:34 +01:00
2021-12-07 16:42:39 +01:00
toRegister . setProfileID ( profile . getId ( ) ) ;
toRegister . setProfileVersion ( profile . getVersion ( ) ) ;
toRegister . setVersion ( new ComparableVersion ( " 1.0.0 " ) ) ;
2021-12-01 11:13:34 +01:00
2021-12-15 19:10:19 +01:00
// Apply Lifecycle
2021-12-01 11:13:34 +01:00
2021-12-15 19:10:19 +01:00
toRegister = step ( toRegister , StepExecutionRequest . Steps . ON_INIT_DOCUMENT ) . getResult ( ) ;
2021-12-07 16:42:39 +01:00
log . debug ( " Going to register {} " , toRegister ) ;
2021-12-01 11:13:34 +01:00
2021-12-15 19:10:19 +01:00
// Insert object
2021-12-07 16:12:43 +01:00
ObjectId id = insert ( asDocument ( toRegister ) , getCollectionName ( ) ) ;
2021-12-07 16:42:39 +01:00
log . info ( " Obtained id {} " , id ) ;
2021-12-07 16:12:43 +01:00
return getByID ( id . toHexString ( ) ) ;
2021-12-01 11:13:34 +01:00
}
@Override
2021-12-07 16:42:39 +01:00
public ProfiledDocument update ( String id , ProfiledDocument toSet ) throws IOException , StepException {
2021-12-01 11:13:34 +01:00
log . trace ( " Replacing {} " , toSet ) ;
toSet = onUpdate ( toSet ) ;
return asProfiledDocument ( replace ( asDocument ( toSet ) , getCollectionName ( ) ) ) ;
}
@Override
public void delete ( String id , boolean force ) throws DeletionException {
log . debug ( " Deleting by ID {}, force {} " , id , force ) ;
try {
ProfiledDocument doc = getByID ( id ) ;
2021-12-07 16:12:43 +01:00
// TODO INVOKE LIFECYCLE
2021-12-01 11:13:34 +01:00
//if(!force&&isPublished(id)) throw new Exception("Cannot delete published documents. Unpublish it or use force = true");
try {
// TODO CHECK PHASE AND STATUS
// DEINDEX
// DEMATERIALIZE
// DELETE CONTENT
// DELETE ENTRY
throw new DeletionException ( " IMPLEMENT THIS " ) ;
// delete(asId(id), getCollectionName());
} catch ( DeletionException e ) {
//storing updated - partially deleted
// concessione=onUpdate(concessione);
// replace(asDocument(concessione), collectionName);
throw e ;
}
} catch ( Throwable t ) {
throw new DeletionException ( " Unable to delete " + id , t ) ;
}
}
@Override
public ProfiledDocument getByID ( String id ) throws IOException {
return asProfiledDocument ( super . getById ( asId ( id ) , getCollectionName ( ) ) ) ;
}
@Override
2021-12-07 11:16:26 +01:00
public Iterable < Document > query ( QueryRequest queryRequest ) {
log . info ( " Querying {} " , queryRequest ) ;
LinkedBlockingQueue queue = new LinkedBlockingQueue < Concessione > ( ) ;
query ( queryRequest , getCollectionName ( ) ) . forEach (
( Consumer < ? super Document > ) ( Document d ) - > { try {
queue . put ( d ) ;
} catch ( Throwable t ) { log . warn ( " Unable to translate " + d ) ; } } ) ;
log . info ( " Returned {} elements " , queue . size ( ) ) ;
return queue ;
}
@Override
public Iterable < ProfiledDocument > filter ( QueryRequest queryRequest ) {
2021-12-01 11:13:34 +01:00
log . info ( " Searching concessione for filter {} " , queryRequest ) ;
LinkedBlockingQueue queue = new LinkedBlockingQueue < Concessione > ( ) ;
query ( queryRequest , getCollectionName ( ) ) . forEach (
( Consumer < ? super Document > ) ( Document d ) - > { try {
queue . put ( d ) ;
} catch ( Throwable t ) { log . warn ( " Unable to translate " + d ) ; } } ) ;
log . info ( " Returned {} elements " , queue . size ( ) ) ;
return queue ;
}
@Override
public ProfiledDocument materialize ( String id ) {
throw new RuntimeException ( " TO IMPLEMENT " ) ;
}
@Override
public ProfiledDocument dematerialize ( String id ) {
throw new RuntimeException ( " TO IMPLEMENT " ) ;
}
@Override
public ProfiledDocument index ( String id ) {
throw new RuntimeException ( " TO IMPLEMENT " ) ;
}
@Override
public ProfiledDocument deIndex ( String id ) {
throw new RuntimeException ( " TO IMPLEMENT " ) ;
}
@Override
public ProfiledDocument performStep ( String id , String step , Document options ) {
throw new RuntimeException ( " TO IMPLEMENT " ) ;
}
2021-12-15 19:10:19 +01:00
private ExecutionReport step ( ProfiledDocument theDocument , String step ) throws StepException {
log . info ( " [Profile {} ] Invoking Step {} on " , profile . getId ( ) , step , lfManager . getDescriptor ( ) ) ;
StepExecutionRequest request = new StepExecutionRequest ( ) ;
request . setDocument ( theDocument ) ;
request . setProfile ( profile ) ;
request . setStep ( StepExecutionRequest . Steps . ON_INIT_DOCUMENT ) ;
log . debug ( " Requesting Step Execution {} " , request ) ;
return lfManager . performStep ( request ) ;
}
2021-09-20 16:47:35 +02:00
}