Fixed Register FileSet

This commit is contained in:
Fabio Sinibaldi 2022-02-16 14:54:48 +01:00
parent 5b2bbf94c2
commit 06a2f83030
2 changed files with 103 additions and 82 deletions

View File

@ -25,8 +25,9 @@ public class RegisterFileSetRequest {
REPLACE_EXISTING,MERGE_EXISTING, APPEND
}
private String fieldPath;
private String destinationPath;
private String fieldDefinitionPath;
private String parentPath;
private String fieldName;
private List<TempFile> streams;
private Document attributes;

View File

@ -1,6 +1,7 @@
package org.gcube.application.geoportal.service.engine.mongo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.jayway.jsonpath.JsonPath;
import com.mongodb.client.MongoDatabase;
import com.vdurmont.semver4j.Semver;
import lombok.Getter;
@ -284,81 +285,67 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
*/
@Override
public ProfiledDocument registerFileSet(String id,RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException {
log.info("Registering Fileset for {} [profile ID {}], Request is {} ",id,profile.getId(),request);
List<TempFile> files=request.getStreams();
Document attributes =request.getAttributes();
log.info("Registering Fileset for {}, Request is {} ",id,request);
ProfiledDocument doc=getByID(id);
WorkspaceManager ws=new WorkspaceManager();
StorageUtils storage=ImplementationProvider.get().getStorageProvider().getObject();
log.debug("Checking {}  path against profile {}",request.getFieldPath(),profile.getId());
JSONPathWrapper schemaWrapper= new JSONPathWrapper(profile.getSchema().toJson());
log.debug("Checking field {} definition in {}",request.getFieldDefinitionPath(),profile.getId());
Field fieldDefinition=getFieldDefinition(profile,request.getFieldDefinitionPath());
List<Field> fieldDefinitions=schemaWrapper.getByPath(request.getFieldPath(),Field.class);
if(fieldDefinitions==null || fieldDefinitions.isEmpty())
throw new WebApplicationException("No Field found in schema "+profile.getId()+" at "+request.getFieldPath(), Response.Status.BAD_REQUEST);
if(fieldDefinitions.size()>1)
throw new WebApplicationException("Multiple field definitions ("+fieldDefinitions.size()+") found in "+profile.getId()+" for "+request.getFieldPath(),Response.Status.BAD_REQUEST);
Field fieldDefinition=Serialization.convert(fieldDefinitions.get(0),Field.class);
if(fieldDefinition==null)
throw new WebApplicationException("Found field is null ["+profile.getId()+" for "+request.getFieldPath()+"]",Response.Status.BAD_REQUEST);
log.debug("Field definition is {}",fieldDefinition);
JSONPathWrapper docWrapper=new JSONPathWrapper(doc.getTheDocument().toJson());
List<Object> matchingPaths = docWrapper.getMatchingPaths(request.getDestinationPath());
if(matchingPaths.size()>1&&!request.getClashOption().equals(RegisterFileSetRequest.ClashOptions.APPEND))
System.out.println();
List<String> matchingPaths = docWrapper.getMatchingPaths(request.getParentPath());
if(matchingPaths.size()>1) throw new WebApplicationException("Multiple Destination matching parent path "+request.getParentPath(),Response.Status.BAD_REQUEST);
if(matchingPaths.isEmpty()) throw new WebApplicationException("PArent path not found at "+request.getParentPath(),Response.Status.BAD_REQUEST);
String parentMatchingPath = matchingPaths.get(0);
Document parent = Serialization.asDocument(docWrapper.getByPath(parentMatchingPath).get(0));
// PREPARE REGISTERED FS
List<RegisteredFileSet> found=docWrapper.getByPath(request.getDestinationPath(),RegisteredFileSet.class);
Object toSet=null;
Document toSetAttributes=attributes;
// Manage clash options
if(!found.isEmpty())
// MANAGE CLASH
switch (request.getClashOption()){
case REPLACE_EXISTING: {
if(found.size()>1)
throw new WebApplicationException("Cannot replace multiple items at "+request.getDestinationPath()+".",Response.Status.BAD_REQUEST);
deleteFileSetRoutine(doc,request.getDestinationPath(),false,ws);
break;
}case MERGE_EXISTING: {
if(found.size()>1)
throw new WebApplicationException("Cannot merge multiple items at "+request.getDestinationPath()+".",Response.Status.BAD_REQUEST);
toSetAttributes=Serialization.asDocument(found.get(0));
if(attributes!=null) toSetAttributes.putAll(attributes);
deleteFileSetRoutine(doc,request.getDestinationPath(),false,ws);
break;
}case APPEND: {
if(fieldDefinition.isCollection())
throw new WebApplicationException("Cannot replace repeatable field "+request.getFieldDefinitionPath()+".",Response.Status.BAD_REQUEST);
// DELETE EXISTING AND PUT
RegisteredFileSet toDelete = Serialization.convert(parent.get(request.getFieldName()),RegisteredFileSet.class);
if(!(toDelete == null)&&!(toDelete.isEmpty()))
deleteFileSetRoutine(toDelete,false,ws);
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(),doc.get_id(),profile.getId(), request.getAttributes(),files,storage,ws);
log.debug("Registered Fileset for [ID {} profile {}] is {} ",fs,doc.get_id(),doc.getProfileID());
docWrapper.putElement(parentMatchingPath,request.getFieldName(),fs);
break;}
case MERGE_EXISTING: {
if(fieldDefinition.isCollection())
throw new WebApplicationException("Cannot merge repeatable field "+request.getFieldDefinitionPath()+".",Response.Status.BAD_REQUEST);
RegisteredFileSet original = Serialization.convert(parent.get(request.getFieldName()),RegisteredFileSet.class);
// MERGE ATTRIBUTES AND PUT
Document toUseAttributes=request.getAttributes();
if(original!=null) toUseAttributes.putAll(original);
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(),doc.get_id(),profile.getId(), toUseAttributes,files,storage,ws);
log.debug("Registered Fileset for [ID {} profile {}] is {} ",fs,doc.get_id(),doc.getProfileID());
docWrapper.putElement(parentMatchingPath,request.getFieldName(),fs);
break;}
case APPEND: {
if(!fieldDefinition.isCollection())
throw new WebApplicationException("Cannot append to "+request.getDestinationPath()+" : field "+request.getFieldPath()+" is not collection.",
Response.Status.BAD_REQUEST);
break;
}
throw new WebApplicationException("Cannot add to single field "+request.getFieldDefinitionPath()+".",Response.Status.BAD_REQUEST);
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(),doc.get_id(),profile.getId(), request.getAttributes(),files,storage,ws);
log.debug("Registered Fileset for [ID {} profile {}] is {} ",fs,doc.get_id(),doc.getProfileID());
docWrapper.addElementToArray(String.format("%1ds['%2$s']",parentMatchingPath,request.getFieldName()),fs);
break;}
default: {throw new WebApplicationException("Unexpected clash policy "+request.getClashOption(),Response.Status.BAD_REQUEST);}
}
// Actually register Files
RegisteredFileSet registeredFileSet = prepareRegisteredFileSet(doc,profile,request.getDestinationPath(),
toSetAttributes,files,storage,ws);
if(fieldDefinition.isCollection()&&(request.getClashOption().equals(RegisterFileSetRequest.ClashOptions.APPEND))){
List<RegisteredFileSet> actualList= found.isEmpty()?new ArrayList<>():(List<RegisteredFileSet>)found.get(0);
actualList.add(registeredFileSet);
toSet=actualList;
}else toSet = registeredFileSet;
docWrapper.set(request.getDestinationPath(),toSet);
log.debug("Setting result on profiled document");
doc.setTheDocument(Document.parse(docWrapper.getValueCTX().jsonString()));
@ -368,9 +355,19 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
}
@Override
public ProfiledDocument deleteFileSet(String id, String destination, Boolean force) throws ConfigurationException, StorageHubException, JsonProcessingException, DeletionException, EventException {
public ProfiledDocument deleteFileSet(String id, String path, Boolean force) throws ConfigurationException, StorageHubException, JsonProcessingException, DeletionException, EventException {
log.info("Deleting Fileset for {} [profile ID {}], at {} [force {} ]",id,profile.getId(),path,force);
ProfiledDocument doc = getByID(id);
doc=deleteFileSetRoutine(doc,destination,force,new WorkspaceManager());
JSONPathWrapper wrapper = new JSONPathWrapper(doc.getTheDocument().toJson());
List<String> matchingPaths=wrapper.getMatchingPaths(path);
if(matchingPaths.isEmpty()) throw new WebApplicationException("No Registered FileSet found at "+path,Response.Status.BAD_REQUEST);
if(matchingPaths.size()>1) throw new WebApplicationException("Multiple Fileset ("+matchingPaths.size()+") matching "+path,Response.Status.BAD_REQUEST);
RegisteredFileSet fs = Serialization.convert(wrapper.getByPath(path),RegisteredFileSet.class);
log.debug("Going to delete {}",fs);
deleteFileSetRoutine(fs,force,new WorkspaceManager());
log.debug("Removing FS from document [ID : ] by path {}",id,path);
wrapper.setElement(path,null);
doc=onUpdate(doc);
return convert(replace(asDocumentWithId(doc),new ObjectId(id),getCollectionName()),ProfiledDocument.class);
}
@ -415,24 +412,35 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
}
private static final RegisteredFileSet prepareRegisteredFileSet(ProfiledDocument doc, Profile profile,String destination,
private static final RegisteredFileSet prepareRegisteredFileSet(PublicationInfo defaultPublicationInfo,String docID, String profileID,
Document attributes,List<TempFile> files, StorageUtils storage,WorkspaceManager ws) throws StorageHubException, StorageException {
log.debug("Preparing Registered FileSet..");
RegisteredFileSet toReturn = new RegisteredFileSet();
if(attributes!=null) toReturn.putAll(attributes);
toReturn.put(RegisteredFileSet.UUID, UUID.randomUUID().toString());
toReturn.put(RegisteredFileSet.CREATION_INFO,UserUtils.getCurrent().asInfo());
toReturn.putIfAbsent(RegisteredFileSet.ACCESS,doc.getInfo().getAccess());
FolderContainer base=ws.createFolder(new WorkspaceManager.FolderOptions(
doc.get_id(),"Base Folder for profiled document. Profile "+profile.getId(),null));
String uuid = UUID.randomUUID().toString();
toReturn.putIfAbsent(RegisteredFileSet.UUID, uuid);
toReturn.putIfAbsent(RegisteredFileSet.CREATION_INFO,UserUtils.getCurrent().asInfo());
toReturn.putIfAbsent(RegisteredFileSet.ACCESS,defaultPublicationInfo.getAccess());
FolderContainer sectionFolder=ws.createFolder(new WorkspaceManager.FolderOptions(
doc.get_id()+destination,"Registered Fileset at path "+destination,base));
toReturn.put(RegisteredFileSet.FOLDER_ID,sectionFolder.getId());
// FOLDER
String folderID=toReturn.getFolderId();
log.trace("Folder ID is {} ",folderID);
FolderContainer sectionFolder=null;
if(folderID==null || folderID.isEmpty()) {
FolderContainer base = ws.createFolder(new WorkspaceManager.FolderOptions(
docID, "Base Folder for profiled document. Profile " + profileID, null));
sectionFolder = ws.createFolder(new WorkspaceManager.FolderOptions(
docID + "_" + uuid, "Registered Fileset uuid " + uuid, base));
toReturn.put(RegisteredFileSet.FOLDER_ID, sectionFolder.getId());
}else {
sectionFolder = ws.getFolderById(folderID);
}
ArrayList<RegisteredFile> registeredFiles=new ArrayList<>();
if(toReturn.containsKey(RegisteredFileSet.PAYLOADS))
registeredFiles.addAll(toReturn.getPayloads());
for (TempFile f : files) {
InputStream is=null;
try{
@ -452,25 +460,37 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
}
}
toReturn.put(RegisteredFileSet.PAYLOADS,registeredFiles);
toReturn.remove(RegisteredFileSet.MATERIALIZATIONS);
// TODO MERGE
//toReturn.remove(RegisteredFileSet.MATERIALIZATIONS);
return toReturn;
}
private static ProfiledDocument deleteFileSetRoutine(ProfiledDocument doc,String fileSetPath, Boolean force, WorkspaceManager ws) throws DeletionException, StorageHubException {
log.info("Document ID {} : deleting fileset at {} [force : {}]",doc.get_id(),fileSetPath,force);
JSONPathWrapper wrapper =new JSONPathWrapper(doc.getTheDocument().toJson());
RegisteredFileSet toDelete = Serialization.convert(wrapper.getByPath(fileSetPath).get(0),RegisteredFileSet.class);
if(toDelete.getMaterializations()!=null && !toDelete.getMaterializations().isEmpty()){
if(!force) throw new DeletionException("Fileset (Document ID "+doc.get_id()+", path "+fileSetPath+") already materialized. Use force = true");
private static void deleteFileSetRoutine(RegisteredFileSet fs, Boolean force, WorkspaceManager ws) throws DeletionException, StorageHubException {
log.debug("Deleting Registered FS {}");
if(fs.getMaterializations()!=null && !fs.getMaterializations().isEmpty()){
if(!force) throw new DeletionException("Fileset (uuid "+fs.getUUID()+") already materialized. Use force = true");
else throw new RuntimeException("Implement this");
// TODO manager force deletion
// NB handlers for materialization types
}
log.debug("Document ID {} : deleting ws folder {}",doc.get_id(),toDelete.getFolderId());
if(toDelete.getPayloads()!=null)
ws.deleteItem(toDelete.getFolderId());
doc.setTheDocument(Document.parse(wrapper.set(fileSetPath,null).getValueCTX().jsonString()));
return doc;
log.trace("FileSet ID {} : deleting ws folder {}",fs.getUUID(),fs.getFolderId());
if(fs.getPayloads()!=null)
ws.deleteItem(fs.getFolderId());
}
private static Field getFieldDefinition(Profile profile,String fieldPath)throws WebApplicationException{
JSONPathWrapper schemaWrapper= new JSONPathWrapper(profile.getSchema().toJson());
List<Field> fieldDefinitions=schemaWrapper.getByPath(fieldPath,Field.class);
if(fieldDefinitions==null || fieldDefinitions.isEmpty())
throw new WebApplicationException("No Field found in schema "+profile.getId()+" at "+fieldPath, Response.Status.BAD_REQUEST);
if(fieldDefinitions.size()>1)
throw new WebApplicationException("Multiple field definitions ("+fieldDefinitions.size()+") found in "+profile.getId()+" for "+fieldPath,Response.Status.BAD_REQUEST);
Field fieldDefinition=Serialization.convert(fieldDefinitions.get(0),Field.class);
if(fieldDefinition==null)
throw new WebApplicationException("Found field is null ["+profile.getId()+" for "+fieldPath+"]",Response.Status.BAD_REQUEST);
log.trace("Field definition is {}",fieldDefinition);
return fieldDefinition;
}
}