Base Implementations refactoring

This commit is contained in:
Fabio Sinibaldi 2022-04-01 19:11:11 +02:00
parent 085074740a
commit 9921dec9ed
44 changed files with 755 additions and 445 deletions

View File

@ -1,6 +1,6 @@
package org.gcube.application.cms.plugins;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
public interface Plugin {

View File

@ -5,7 +5,11 @@ import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.PluginManagerInterface;
import org.gcube.application.cms.plugins.faults.*;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.cms.plugins.implementations.executions.GuardedEventManager;
import org.gcube.application.cms.plugins.implementations.executions.GuardedStepExecution;
import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
import org.gcube.application.cms.plugins.reports.*;
import org.gcube.application.cms.plugins.requests.BaseRequest;
import org.gcube.application.cms.plugins.requests.EventExecutionRequest;
@ -24,34 +28,34 @@ import java.util.Map;
@Slf4j
public abstract class AbstractLifeCycleManager extends AbstractPlugin implements LifecycleManager {
protected static class Events{
public static final OperationDescriptor INIT=new OperationDescriptor(EventExecutionRequest.Events.ON_INIT_DOCUMENT,"Sets defaults and validate");
public static final OperationDescriptor UPDATE=new OperationDescriptor(EventExecutionRequest.Events.ON_UPDATE_DOCUMENT,"Sets defaults and validate");
public static final OperationDescriptor DELETE=new OperationDescriptor(EventExecutionRequest.Events.ON_DELETE_DOCUMENT,"No op");
public static final OperationDescriptor DELETE_FS=new OperationDescriptor(EventExecutionRequest.Events.ON_DELETE_FILESET,"No op");
}
@Setter
protected PluginManagerInterface pluginManager;
private Map<String,GuardedStepExecution> registeredSteps=new HashMap<>();
private Map<String,GuardedEventManager> registeredEvent=new HashMap<>();
private Map<String, GuardedStepExecution> registeredSteps=new HashMap<>();
private Map<String, GuardedEventManager> registeredEvent=new HashMap<>();
protected void setEvent(String event,GuardedEventManager m){registeredEvent.put(event,m);}
protected void setStep(String step,GuardedStepExecution e){registeredSteps.put(step,e);}
private GuardedEventManager defaultUpdateManager= new GuardedEventManager() {
@Override
protected EventExecutionReport run() throws Exception {
theReport = validate(theReport);
theReport = setDefault(theReport);
return theReport;
protected void setEvent(GuardedEventManager m){
OperationDescriptor op= m.getOp();
DESCRIPTOR.getSupportedEvents().put(op.getId(),op);
registeredEvent.put(op.getDescription(),m);
}
};
private GuardedEventManager noOp = new GuardedEventManager() {
@Override
protected EventExecutionReport run() throws Exception {
return theReport;
protected void setStep(GuardedStepExecution e){
OperationDescriptor op= e.getOp();
DESCRIPTOR.getSupportedSteps().put(op.getId(),op);
registeredSteps.put(op.getDescription(),e);
}
};
public AbstractLifeCycleManager() {
DESCRIPTOR.setSupportedSteps(new HashMap<>());
DESCRIPTOR.setSupportedEvents(new HashMap<>());
registerEvents();
registerSteps();
}
@ -72,25 +76,25 @@ public abstract class AbstractLifeCycleManager extends AbstractPlugin implements
protected void registerEvents(){
setEvent(EventExecutionRequest.Events.ON_INIT_DOCUMENT, new GuardedEventManager() {
setEvent(new GuardedEventManager(Events.INIT) {
@Override
protected EventExecutionReport run() throws Exception {
return onInitDocument(theReport);
}
});
setEvent(EventExecutionRequest.Events.ON_UPDATE_DOCUMENT, new GuardedEventManager() {
setEvent(new GuardedEventManager(Events.UPDATE) {
@Override
protected EventExecutionReport run() throws Exception {
return onUpdateDocument(theReport);
}
});
setEvent(EventExecutionRequest.Events.ON_DELETE_DOCUMENT, new GuardedEventManager() {
setEvent(new GuardedEventManager(Events.DELETE) {
@Override
protected EventExecutionReport run() throws Exception {
return onDeleteDocument(theReport);
}
});
setEvent(EventExecutionRequest.Events.ON_DELETE_FILESET, new GuardedEventManager() {
setEvent(new GuardedEventManager(Events.DELETE_FS) {
@Override
protected EventExecutionReport run() throws Exception {
return onDeleteFileSet(theReport);
@ -100,7 +104,7 @@ public abstract class AbstractLifeCycleManager extends AbstractPlugin implements
protected void registerSteps(){}
protected PluginDescriptor DESCRIPTOR=new PluginDescriptor(";;;", PluginDescriptor.BaseTypes.LIFECYCLE_MANAGER);
protected LifecycleManagerDescriptor DESCRIPTOR=new LifecycleManagerDescriptor(";;;");
@Override

View File

@ -1,23 +1,23 @@
package org.gcube.application.cms.plugins.implementations;
import com.vdurmont.semver4j.Semver;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.gcube.application.cms.plugins.IndexerPluginInterface;
import org.gcube.application.cms.plugins.MaterializationPlugin;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.faults.*;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.cms.plugins.implementations.executions.GuardedStepExecution;
import org.gcube.application.cms.plugins.reports.*;
import org.gcube.application.cms.plugins.requests.*;
import org.gcube.application.cms.plugins.model.ComparableVersion;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.configuration.Index;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.document.lifecycle.TriggeredEvents;
import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.utils.Files;
import java.util.ArrayList;
import java.util.Collections;
@Slf4j
public class Default3PhaseManager extends SimpleLifeCycleManager implements LifecycleManager {
@ -29,15 +29,22 @@ public class Default3PhaseManager extends SimpleLifeCycleManager implements Life
}
private static class STEPS{
public static final String SUBMIT="SUBMIT-FOR-REVIEW";
public static final String REJECT="REJECT-DRAFT";
public static final String APPROVE="APPROVE-SUBMITTED";
public static final OperationDescriptor SUBMIT=new OperationDescriptor("SUBMIT-FOR-REVIEW","Submits the Draft for reviewing");
public static final OperationDescriptor REJECT=new OperationDescriptor("REJECT-DRAFT","Rejects the submitted Draft");
public static final OperationDescriptor APPROVE=new OperationDescriptor("APPROVE-SUBMITTED","Approves the submitted Draft");
static {
SUBMIT.setAppliableToPhases(Collections.singletonList(LifecycleInformation.CommonPhases.DRAFT_PHASE));
REJECT.setAppliableToPhases(Collections.singletonList(Phases.PENDING_APPROVAL));
APPROVE.setAppliableToPhases(Collections.singletonList(Phases.PENDING_APPROVAL));
}
}
private static class PARAMETERS{
public static final String NOTES="notes";
}
@Override
protected EventExecutionReport onDeleteDocument(EventExecutionReport report) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException {
report = super.onDeleteDocument(report);
@ -58,11 +65,9 @@ public class Default3PhaseManager extends SimpleLifeCycleManager implements Life
@Override
protected void registerSteps() {
// register steps
setStep(STEPS.SUBMIT, new GuardedStepExecution() {
setStep(new GuardedStepExecution(STEPS.SUBMIT) {
@Override
protected StepExecutionReport run() throws Exception {
if(!theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(LifecycleInformation.CommonPhases.DRAFT_PHASE))
throw new StepException("Document is not in "+LifecycleInformation.CommonPhases.DRAFT_PHASE+" phase");
// Materialize
theReport = materializeDocument(theReport,getMaterializer(),getMaterializationParameters(theReport.getTheRequest()));
if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)){
@ -78,12 +83,9 @@ public class Default3PhaseManager extends SimpleLifeCycleManager implements Life
});
setStep(STEPS.APPROVE, new GuardedStepExecution() {
setStep(new GuardedStepExecution(STEPS.APPROVE) {
@Override
protected StepExecutionReport run() throws Exception {
if(!theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(Phases.PENDING_APPROVAL))
throw new StepException("Document is not in "+Phases.PENDING_APPROVAL+" phase");
// Index
theReport = index(theReport,getIndexer(),
getPublicIndexParams(theReport.getTheRequest()));
@ -94,11 +96,9 @@ public class Default3PhaseManager extends SimpleLifeCycleManager implements Life
}
});
setStep(STEPS.REJECT, new GuardedStepExecution() {
setStep(new GuardedStepExecution(STEPS.REJECT) {
@Override
protected StepExecutionReport run() throws Exception {
if(!theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(Phases.PENDING_APPROVAL))
throw new StepException("Document is not in "+Phases.PENDING_APPROVAL+" phase");
if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK))
theReport.getToSetLifecycleInformation().setPhase(LifecycleInformation.CommonPhases.DRAFT_PHASE);
return theReport;
@ -107,8 +107,10 @@ public class Default3PhaseManager extends SimpleLifeCycleManager implements Life
}
public Default3PhaseManager() {
DESCRIPTOR.setId("DEFAULT-3PHASE");
DESCRIPTOR.setDescription("Default 3-phase lifecycle manager. This plugin supports a simple moderated publication lifecycle.");
DESCRIPTOR.setVersion(new ComparableVersion("1.0.0"));
DESCRIPTOR.setVersion(new Semver("1.0.0"));
DESCRIPTOR.setLabel("Default 3-Phase");
}

View File

@ -1,35 +0,0 @@
package org.gcube.application.cms.plugins.implementations;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.plugins.reports.DocumentHandlingReport;
import org.gcube.application.cms.plugins.requests.BaseExecutionRequest;
@Slf4j
public abstract class GuardedExecution<R extends BaseExecutionRequest,T extends DocumentHandlingReport> {
@Getter
protected T result = null;
protected T theReport;
public T execute() throws Exception {
log.trace("Executing {} ",theReport.getTheRequest());
if(theReport==null) throw new RuntimeException("Unexpected state : request cannot be null");
result = run();
log.trace("Report is {} ",theReport);
return result;
}
public T getResult() {
return result;
}
protected abstract T run() throws Exception;
public GuardedExecution<R, T> setTheReport(T theReport) {
this.theReport = theReport;
return this;
}
}

View File

@ -1,7 +0,0 @@
package org.gcube.application.cms.plugins.implementations;
import org.gcube.application.cms.plugins.reports.StepExecutionReport;
import org.gcube.application.cms.plugins.requests.StepExecutionRequest;
public abstract class GuardedStepExecution extends GuardedExecution<StepExecutionRequest, StepExecutionReport>{
}

View File

@ -6,6 +6,8 @@ import org.gcube.application.cms.plugins.IndexerPluginInterface;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.MaterializationPlugin;
import org.gcube.application.cms.plugins.faults.*;
import org.gcube.application.cms.plugins.implementations.executions.GuardedEventManager;
import org.gcube.application.cms.plugins.implementations.executions.GuardedStepExecution;
import org.gcube.application.cms.plugins.reports.*;
import org.gcube.application.cms.plugins.requests.*;
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
@ -13,14 +15,31 @@ import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.configuration.Index;
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.utils.Files;
import java.util.ArrayList;
import java.util.Collections;
@Slf4j
public class SimpleLifeCycleManager extends AbstractLifeCycleManager implements LifecycleManager {
public SimpleLifeCycleManager() {
DESCRIPTOR.setId("DEFAULT-SINGLE-PHASE");
}
private static class Steps {
public static final OperationDescriptor PUBLISH = new OperationDescriptor("PUBLISH","Materialize & index project");
static{
PUBLISH.setAppliableToPhases(Collections.singletonList(LifecycleInformation.CommonPhases.DRAFT_PHASE));
}
}
@Override
public Configuration getCurrentConfiguration(BaseRequest req) throws ConfigurationException {
Configuration toReturn = super.getCurrentConfiguration(req);
@ -63,7 +82,7 @@ public class SimpleLifeCycleManager extends AbstractLifeCycleManager implements
@Override
protected void registerSteps() {
setStep("PUBLISH", new GuardedStepExecution() {
setStep(new GuardedStepExecution(Steps.PUBLISH) {
@Override
protected StepExecutionReport run() throws Exception {
if(!theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(LifecycleInformation.CommonPhases.DRAFT_PHASE))
@ -87,7 +106,11 @@ public class SimpleLifeCycleManager extends AbstractLifeCycleManager implements
}
protected void blockNonDraft(EventExecutionReport report) throws InvalidPluginRequestException {
Boolean force = Boolean.parseBoolean(report.getTheRequest().getMandatory("force"));
Boolean force = false;
try {
force = Boolean.parseBoolean(report.getTheRequest().getCallParameters().get("force").toString());
}catch(Throwable t){}
if(!report.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(LifecycleInformation.CommonPhases.DRAFT_PHASE) && ! force)
throw new InvalidPluginRequestException("Document is not in "+LifecycleInformation.CommonPhases.DRAFT_PHASE+" phase");
}
@ -136,19 +159,6 @@ public class SimpleLifeCycleManager extends AbstractLifeCycleManager implements
@Override
protected void registerEvents() {
super.registerEvents();
// register events
setEvent(EventExecutionRequest.Events.ON_DELETE_DOCUMENT, new GuardedEventManager() {
@Override
protected EventExecutionReport run() throws Exception {
return onDeleteDocument(theReport);
}
});
setEvent(EventExecutionRequest.Events.ON_DELETE_FILESET, new GuardedEventManager() {
@Override
protected EventExecutionReport run() throws Exception {
return onDeleteFileSet(theReport);
}
});
}

View File

@ -1,15 +1,16 @@
package org.gcube.application.cms.plugins.implementations;
package org.gcube.application.cms.plugins.implementations.executions;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.plugins.faults.EventException;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.reports.EventExecutionReport;
import org.gcube.application.cms.plugins.requests.EventExecutionRequest;
import javax.ws.rs.WebApplicationException;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
@Slf4j
public abstract class GuardedEventManager extends GuardedExecution<EventExecutionRequest,EventExecutionReport>{
public GuardedEventManager(@NonNull OperationDescriptor op) {
super(op);
}
}

View File

@ -0,0 +1,71 @@
package org.gcube.application.cms.plugins.implementations.executions;
import com.sun.xml.internal.ws.client.HandlerConfiguration;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.plugins.faults.InsufficientPrivileges;
import org.gcube.application.cms.plugins.faults.StepException;
import org.gcube.application.cms.plugins.implementations.RoleManager;
import org.gcube.application.cms.plugins.reports.DocumentHandlingReport;
import org.gcube.application.cms.plugins.requests.BaseExecutionRequest;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration;
@Slf4j
@RequiredArgsConstructor
public abstract class GuardedExecution<R extends BaseExecutionRequest,T extends DocumentHandlingReport> {
@Getter
protected T result = null;
@NonNull
@Getter
private OperationDescriptor op;
protected T theReport;
protected void checks() throws ConfigurationException, InsufficientPrivileges {
if(theReport.getTheRequest()==null) throw new RuntimeException("Unexpected state : request cannot be null");
// Check document phase
if(op.getAppliableToPhases()!=null&&!op.getAppliableToPhases().isEmpty()) {
String currentPhase = theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase();
if(!op.getAppliableToPhases().contains(currentPhase))
new StepException("Document must be in one of the following phases : "+ op.getAppliableToPhases());
}
}
public T execute() throws Exception {
log.trace("Executing {} ",theReport.getTheRequest());
checks();
result = run();
log.trace("Report is {} ",theReport);
return result;
}
public T getResult() {
return result;
}
protected abstract T run() throws Exception;
public GuardedExecution<R, T> setTheReport(T theReport) {
this.theReport = theReport;
return this;
}
protected HandlerDeclaration config=null;
public void setHandlerConfiguration(HandlerDeclaration config){
this.config=config;
}
}

View File

@ -0,0 +1,29 @@
package org.gcube.application.cms.plugins.implementations.executions;
import lombok.NonNull;
import org.gcube.application.cms.plugins.faults.InsufficientPrivileges;
import org.gcube.application.cms.plugins.implementations.RoleManager;
import org.gcube.application.cms.plugins.reports.StepExecutionReport;
import org.gcube.application.cms.plugins.requests.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
import java.util.Map;
public abstract class GuardedStepExecution extends GuardedExecution<StepExecutionRequest, StepExecutionReport>{
public GuardedStepExecution(@NonNull OperationDescriptor op) {
super(op);
}
@Override
protected void checks() throws ConfigurationException, InsufficientPrivileges {
super.checks();
RoleManager r = new RoleManager(config);
if(!r.canInvokeStep(theReport.getTheRequest().getStep(),theReport.getTheRequest().getCaller()))
throw new InsufficientPrivileges("User is not allowed to execute "+theReport.getTheRequest().getStep());
}
}

View File

@ -1,28 +0,0 @@
package org.gcube.application.cms.plugins.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@Data
@RequiredArgsConstructor
@AllArgsConstructor
public class PluginDescriptor {
public static class BaseTypes{
public static final String LIFECYCLE_MANAGER="LifecycleManagement";
public static final String MATERIALIZER="Materializer";
public static final String INDEXER="Indexer";
}
@NonNull
private String id;
@NonNull
private String type;
private String label;
private String description;
private ComparableVersion version;
}

View File

@ -31,6 +31,7 @@ public class DocumentHandlingReport<T extends BaseExecutionRequest> extends Repo
public DocumentHandlingReport(@NonNull T theRequest) throws InvalidPluginRequestException {
theRequest.validate();
this.theRequest = theRequest;
this.setStatus(Status.OK);
toSetLifecycleInformation=theRequest.getDocument().getLifecycleInformation();
resultingDocument = theRequest.getDocument().getTheDocument();
}

View File

@ -1,86 +0,0 @@
package org.gcube.application.cms.tests;
import org.gcube.application.cms.implementations.ISInterface;
import org.gcube.application.cms.implementations.ImplementationProvider;
import org.gcube.application.cms.plugins.InitializablePlugin;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.Plugin;
import org.gcube.application.cms.plugins.PluginsReflections;
import org.gcube.application.cms.plugins.faults.InitializationException;
import org.gcube.application.cms.plugins.faults.PluginExecutionException;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.*;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assume.assumeTrue;
public class BasicPluginTest {
protected User getTestUser(){
User toReturn = new User();
toReturn.setUsername("test-user");
return toReturn;
}
protected Context getTestContext(){
Context toReturn = new Context();
String contextId =GCubeTest.getContext();
toReturn.setId(contextId);
toReturn.setName(contextId.substring(contextId.lastIndexOf("/")));
return toReturn;
}
protected static Map<String,Plugin> plugins=new HashMap<>();
@BeforeClass
public static void checkPluginRegistration() {
plugins.putAll(PluginsReflections.load());
plugins.forEach((s,p) -> System.out.println(s+" "+p.getDescriptor()));
Assert.assertFalse(plugins.isEmpty());
plugins.forEach((s,p)->{
System.out.println("INIT Plugin "+p.getClass());
Assert.assertNotNull(p.getDescriptor());
Assert.assertNotNull(p.getDescriptor().getId());
Assert.assertNotNull(p.getDescriptor().getType());
Assert.assertNotNull(p.getDescriptor().getVersion());
if(p instanceof InitializablePlugin){
InitializablePlugin ip=(InitializablePlugin)p;
try {
ip.init().validate();
if(GCubeTest.isTestInfrastructureEnabled()){
TokenSetter.set(GCubeTest.getContext());
ip.initInContext().validate();
}
} catch (Exception e) {
e.printStackTrace(System.err);
Assert.fail("Unable to Init "+p.getDescriptor().getId());
}
}
});
System.out.println("Plugin Loading OK");
}
@Before
public void initContext(){
assumeTrue(GCubeTest.isTestInfrastructureEnabled());
TokenSetter.set(GCubeTest.getContext());
}
}

View File

@ -0,0 +1,151 @@
package org.gcube.application.cms.tests.model;
import com.vdurmont.semver4j.Semver;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.access.AccessPolicy;
import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.geoportal.common.model.document.accounting.PublicationInfo;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.DataAccessPolicy;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import javax.jws.soap.SOAPBinding;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.UUID;
import static junit.framework.TestCase.assertTrue;
public class BasicTests {
protected User getCurrentUser(){
User u= new User();
u.setUsername("fake-user");
return u;
}
protected UseCaseDescriptor getUCD(){
return initUCD(getContext(),getCurrentUser());
}
protected Document getBasicDocument(){
return new Document();
}
protected Project getBasicProject(){
return initProject(getBasicDocument(),getUCD(), getCurrentUser(), getContext());
}
protected Context getContext(){
Context toReturn = new Context();
toReturn.setName("My Fake Vre");
toReturn.setId("FAKE-VRE");
return toReturn;
}
protected PublicationInfo getCurrentInfo(){
return initPublicationInfo(getUCD(),getContext(),getCurrentUser());
}
protected static PublicationInfo initPublicationInfo(UseCaseDescriptor ucd, Context ctx, User user){
PublicationInfo toReturn = new PublicationInfo();
// TODO Set Access From UseCaseDescriptor
Access access=new Access();
access.setLicense("");
access.setPolicy(AccessPolicy.OPEN);
toReturn.setAccess(access);
toReturn.setCreationInfo(initAccountingInfo(ctx,user));
return toReturn;
}
protected static AccountingInfo initAccountingInfo(Context ctx, User user){
AccountingInfo accInfo = new AccountingInfo();
accInfo.setInstant(LocalDateTime.now());
accInfo.setContext(ctx);
accInfo.setUser(user);
return accInfo;
}
protected static Project initProject(Document doc, UseCaseDescriptor ucd,User user, Context ctx){
Project p = new Project();
p.setId(UUID.randomUUID().toString());
p.setInfo(initPublicationInfo(ucd,ctx,user));
p.setProfileID(ucd.getId());
p.setProfileVersion(ucd.getVersion());
p.setVersion(new Semver("1.0.0"));
LifecycleInformation draftInfo=new LifecycleInformation().cleanState();
draftInfo.setPhase(LifecycleInformation.CommonPhases.DRAFT_PHASE);
draftInfo.setLastOperationStatus(LifecycleInformation.Status.OK);
p.setLifecycleInformation(draftInfo);
return p;
}
protected static UseCaseDescriptor initUCD(Context ctx, User u){
UseCaseDescriptor ucd = new UseCaseDescriptor();
ucd.setName("Test UCD");
ucd.setId("test-ucd");
ucd.setDescription("Just a test dummy profile");
ucd.setCreationInfo(initAccountingInfo(ctx,u));
ucd.setVersion(new Semver("1.0.0"));
HandlerDeclaration h= new HandlerDeclaration();
h.setType(LifecycleManagerDescriptor.LIFECYCLE_MANAGER_TYPE);
h.setId(UUID.randomUUID().toString());
ucd.setHandlers(Collections.singletonList(h));
DataAccessPolicy p =new DataAccessPolicy();
p.setPolicy(new DataAccessPolicy.Policy());
p.getPolicy().setRead(DataAccessPolicy.Policy.Type.any);
p.getPolicy().setWrite(DataAccessPolicy.Policy.Type.any);
ucd.setDataAccessPolicies(Collections.singletonList(p));
return ucd;
}
public static void validate (Project doc){
assertTrue(doc!=null);
assertTrue(doc.getId()!=null);
assertTrue(doc.getLifecycleInformation().getPhase()!=null);
assertTrue(doc.getLifecycleInformation().getLastOperationStatus()!=null);
if(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.ERROR))
assertTrue(doc.getLifecycleInformation().getErrorMessages().size()>0);
if(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.WARNING))
assertTrue(doc.getLifecycleInformation().getWarningMessages().size()>0);
if(doc.getLifecycleInformation().getTriggeredEvents()!=null)
doc.getLifecycleInformation().getTriggeredEvents().forEach(triggeredEvents -> {
assertTrue(triggeredEvents.getEvent()!=null);
assertTrue(triggeredEvents.getLastOperationStatus()!=null);
if(triggeredEvents.getLastOperationStatus().equals(LifecycleInformation.Status.ERROR))
assertTrue(triggeredEvents.getErrorMessages().size()>0);
if(triggeredEvents.getLastOperationStatus().equals(LifecycleInformation.Status.WARNING))
assertTrue(triggeredEvents.getWarningMessages().size()>0);
});
assertTrue(doc.getInfo()!=null);
assertTrue(doc.getInfo().getCreationInfo()!=null);
assertTrue(doc.getInfo().getCreationInfo().getContext()!=null);
assertTrue(doc.getInfo().getCreationInfo().getContext().getId()!=null);
assertTrue(doc.getInfo().getCreationInfo().getContext().getName()!=null);
assertTrue(doc.getInfo().getCreationInfo().getInstant()!=null);
assertTrue(doc.getInfo().getCreationInfo().getInstant()!=null);
assertTrue(doc.getInfo().getCreationInfo().getUser()!=null);
assertTrue(doc.getInfo().getCreationInfo().getUser().getUsername()!=null);
assertTrue(doc.getTheDocument()!=null);
}
}

View File

@ -1,19 +1,18 @@
package org.gcube.application.cms.tests.model;
import org.bson.Document;
import com.vdurmont.semver4j.Semver;
import org.gcube.application.cms.plugins.IndexerPluginInterface;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.MaterializationPlugin;
import org.gcube.application.cms.plugins.PluginManagerInterface;
import org.gcube.application.cms.plugins.faults.*;
import org.gcube.application.cms.plugins.model.ComparableVersion;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
import org.gcube.application.cms.plugins.reports.*;
import org.gcube.application.cms.plugins.requests.*;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.configuration.Index;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
public class DummyPlugin implements LifecycleManager, IndexerPluginInterface, MaterializationPlugin {
@ -81,6 +80,6 @@ public class DummyPlugin implements LifecycleManager, IndexerPluginInterface, Ma
@Override
public PluginDescriptor getDescriptor() {
return new PluginDescriptor("DUMMY-PLUGIN","DUMMY-TYPE","Dummy","No op plugin", new ComparableVersion("1.0.0"));
return new PluginDescriptor("DUMMY-PLUGIN","DUMMY-TYPE","Dummy","No op plugin", new Semver("1.0.0"));
}
}

View File

@ -0,0 +1,83 @@
package org.gcube.application.cms.tests.plugins;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.Plugin;
import org.gcube.application.cms.plugins.faults.*;
import org.gcube.application.cms.plugins.reports.EventExecutionReport;
import org.gcube.application.cms.plugins.reports.StepExecutionReport;
import org.gcube.application.cms.plugins.requests.EventExecutionRequest;
import org.gcube.application.cms.plugins.requests.StepExecutionRequest;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Assert;
import org.junit.Test;
import java.util.Map;
@Slf4j
public class BasicLCPluginTest extends BasicPluginTest{
@Test
public void testLifeCycle(){
for (Map.Entry<String, Plugin> entry : plugins.entrySet()) {
String s = entry.getKey();
Plugin p = entry.getValue();
if (p.getDescriptor().getType().equals(LifecycleManagerDescriptor.LIFECYCLE_MANAGER_TYPE)) {
System.out.println("Testing LC Manager " + p.getDescriptor());
LifecycleManager ip = (LifecycleManager) p;
try {
LifecycleManagerDescriptor descriptor =(LifecycleManagerDescriptor)p.getDescriptor();
log.info("EVENTS ARE {}",descriptor.getSupportedEvents());
for(Map.Entry<String, OperationDescriptor> e : descriptor.getSupportedEvents().entrySet()){
EventExecutionRequest req = prepareEventRequest(e.getKey());
log.info("Launching request {} ",req);
EventExecutionReport rep = testEvent(ip,req);
log.info("Report is {} ",rep);
}
if(descriptor.getSupportedSteps()!=null) {
log.info("STEPS ARE {}", descriptor.getSupportedEvents());
for (Map.Entry<String, OperationDescriptor> e : descriptor.getSupportedSteps().entrySet()) {
StepExecutionRequest req = prepareStepRequest(e.getKey());
log.info("Launching request {} ", req);
StepExecutionReport rep = testStep(ip, req);
log.info("Report is {} ", rep);
}
}
ip.init().validate();
if (GCubeTest.isTestInfrastructureEnabled()) {
TokenSetter.set(GCubeTest.getContext());
ip.initInContext().validate();
}
} catch (Exception e) {
e.printStackTrace(System.err);
Assert.fail("Unable to Init " + p.getDescriptor().getId());
}
}
}
}
protected StepExecutionRequest prepareStepRequest(String stepId){
return new StepExecutionRequest(getUCD(),getCurrentUser(),getContext(),getBasicProject(),stepId);
};
protected EventExecutionRequest prepareEventRequest(String event){
return new EventExecutionRequest(getUCD(),getCurrentUser(),getContext(),getBasicProject(),event);
};
protected EventExecutionReport testEvent(LifecycleManager lc, EventExecutionRequest r) throws InvalidPluginRequestException, EventException {
return lc.onEvent(r);
}
protected StepExecutionReport testStep(LifecycleManager lc, StepExecutionRequest r) throws InvalidPluginRequestException, StepException, InvalidProfileException, StepException, ConfigurationException, InsufficientPrivileges {
return lc.performStep(r);
}
}

View File

@ -0,0 +1,52 @@
package org.gcube.application.cms.tests.plugins;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.gcube.application.cms.plugins.InitializablePlugin;
import org.gcube.application.cms.plugins.Plugin;
import org.gcube.application.cms.plugins.PluginsReflections;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.common.model.document.accounting.Context;
import org.gcube.application.cms.tests.model.BasicTests;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.*;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assume.assumeTrue;
@Slf4j
public abstract class BasicPluginTest extends BasicTests {
protected Context getTestContext(){
Context toReturn = new Context();
String contextId =GCubeTest.getContext();
toReturn.setId(contextId);
toReturn.setName(contextId.substring(contextId.lastIndexOf("/")));
return toReturn;
}
protected static Map<String,Plugin> plugins=new HashMap<>();
@BeforeClass
public static void checkPluginRegistration() {
plugins.putAll(PluginsReflections.load());
plugins.forEach((s,p) -> System.out.println(s+" "+p.getDescriptor()));
Assert.assertFalse(plugins.isEmpty());
plugins.forEach(PluginCheks.descriptor);
plugins.forEach(PluginCheks.init);
System.out.println("Plugin Loading OK");
}
@Before
public void initContext(){
assumeTrue(GCubeTest.isTestInfrastructureEnabled());
TokenSetter.set(GCubeTest.getContext());
}
}

View File

@ -0,0 +1,57 @@
package org.gcube.application.cms.tests.plugins;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.plugins.*;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.common.model.plugins.IndexerPluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor;
import org.gcube.application.geoportal.common.model.plugins.MaterializerPluginDescriptor;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Assert;
import java.util.function.BiConsumer;
import static junit.framework.TestCase.assertTrue;
@Slf4j
public class PluginCheks {
static BiConsumer<String, Plugin> init= (s,p)->{
if(p instanceof InitializablePlugin){
log.info("INIT Plugin "+p.getDescriptor());
InitializablePlugin ip=(InitializablePlugin)p;
try {
ip.init().validate();
if(GCubeTest.isTestInfrastructureEnabled()){
log.info("INIT Plugin "+p.getDescriptor()+" under "+GCubeTest.getContext());
TokenSetter.set(GCubeTest.getContext());
ip.initInContext().validate();
}
} catch (Exception e) {
log.error("Unable to init {} ",p,e);
Assert.fail("Unable to Init "+p.getDescriptor().getId());
}
}
};
static BiConsumer<String, Plugin> descriptor= (s,p)->{
log.info("Checking Plugin Descriptor "+p.getClass());
Assert.assertNotNull(p.getDescriptor());
Assert.assertNotNull(p.getDescriptor().getId());
Assert.assertNotNull(p.getDescriptor().getType());
switch(p.getDescriptor().getType()){
case LifecycleManagerDescriptor.LIFECYCLE_MANAGER_TYPE:{
assertTrue(p instanceof LifecycleManager);
break; }
case MaterializerPluginDescriptor.MATERIALIZER:{
assertTrue(p instanceof MaterializationPlugin);
break; }
case IndexerPluginDescriptor.INDEXER:{
assertTrue(p instanceof IndexerPluginInterface);
break; }
default:{}
}
};
}

View File

@ -1,6 +1,6 @@
package org.gcube.application.cms.commons.model;
import org.gcube.application.cms.tests.BasicPluginTest;
import org.gcube.application.cms.tests.plugins.BasicPluginTest;
import org.junit.Test;
public class DummyTest extends BasicPluginTest {

View File

@ -1,28 +1,21 @@
package org.gcube.application.cms.concessioni.plugins;
import com.vdurmont.semver4j.Semver;
import lombok.extern.slf4j.Slf4j;
import org.bson.BsonDocument;
import org.bson.BsonString;
import org.bson.BsonValue;
import org.bson.Document;
import org.gcube.application.cms.plugins.*;
import org.gcube.application.cms.plugins.faults.*;
import org.gcube.application.cms.plugins.implementations.Default3PhaseManager;
import org.gcube.application.cms.plugins.model.ComparableVersion;
import org.gcube.application.cms.plugins.reports.*;
import org.gcube.application.cms.plugins.requests.*;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.cms.custom.gna.concessioni.model.ProfiledConcessione;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.geoportal.common.model.document.*;
import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.access.AccessPolicy;
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.document.lifecycle.TriggeredEvents;
import org.gcube.application.geoportal.common.model.legacy.report.ConstraintCheck;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.utils.Files;
@Slf4j
/** Overrides 3 Phases lifecycle with override of default values
@ -33,9 +26,8 @@ public class ConcessioniLifeCycleManager extends Default3PhaseManager implements
public ConcessioniLifeCycleManager() {
DESCRIPTOR.setId("GNA-CONCESSIONI-LC");
DESCRIPTOR.setDescription("GNA Concessioni. This plugin supports custom lifecycle management for the GNA Concessioni UseCase.");
DESCRIPTOR.setVersion(new ComparableVersion("1.0.0"));
DESCRIPTOR.setVersion(new Semver("1.0.0"));
}

View File

@ -1,6 +1,6 @@
package org.gcube.application.cms.concessioni.plugins;
import org.gcube.application.cms.tests.BasicPluginTest;
import org.gcube.application.cms.tests.plugins.BasicPluginTest;
import org.junit.Assert;
import org.junit.Test;

View File

@ -0,0 +1,8 @@
package org.gcube.application.geoportal.common.model.plugins;
public class IndexerPluginDescriptor extends PluginDescriptor{
public static final String INDEXER="Indexer";
}

View File

@ -0,0 +1,27 @@
package org.gcube.application.geoportal.common.model.plugins;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
@XmlRootElement
@Slf4j
public class LifecycleManagerDescriptor extends PluginDescriptor{
public static final String LIFECYCLE_MANAGER_TYPE="LifecycleManagement";
public LifecycleManagerDescriptor(String id) {
super(id,LIFECYCLE_MANAGER_TYPE);
}
private Map<String, OperationDescriptor> supportedSteps;
private Map<String, OperationDescriptor> supportedEvents;
}

View File

@ -0,0 +1,7 @@
package org.gcube.application.geoportal.common.model.plugins;
public class MaterializerPluginDescriptor extends PluginDescriptor{
public static final String MATERIALIZER="Materializer";
}

View File

@ -0,0 +1,33 @@
package org.gcube.application.geoportal.common.model.plugins;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
@XmlRootElement
public class OperationDescriptor {
public OperationDescriptor(String id) {
this.id = id;
}
public OperationDescriptor(String id, String description) {
this.id = id;
this.description = description;
}
private String id;
private Map<String, Field> parameters;
private String description;
private List<String> appliableToPhases;
}

View File

@ -0,0 +1,26 @@
package org.gcube.application.geoportal.common.model.plugins;
import com.vdurmont.semver4j.Semver;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
@XmlRootElement
public class PluginDescriptor {
public PluginDescriptor(String id, String type) {
this.id = id;
this.type = type;
}
private String id;
private String type;
private String label;
private String description;
private Semver version;
}

View File

@ -30,7 +30,7 @@ public class DataAccessPolicy {
public static final String READ="_read";
public static enum Type{
OWN,NONE,ANY
own, none, any
}
@JsonProperty(WRITE)
@ -48,7 +48,13 @@ public class DataAccessPolicy {
public static class PolicyEnforcer {
public static final String FILTER="_filter";
@JsonProperty(FILTER)
private Document filter;
private String filter;
@JsonIgnore
public Document getFilterDocument(){
if(filter!=null) return Document.parse(filter);
else return new Document();
}
}
@ -62,9 +68,9 @@ public class DataAccessPolicy {
@JsonIgnore
public boolean canRead(Project p, User u){
switch(getPolicy().getRead()){
case OWN: return p.getInfo().getCreationInfo().getUser().equals(u);
case ANY: return true;
case NONE:
case own: return p.getInfo().getCreationInfo().getUser().equals(u);
case any: return true;
case none:
default : return false;
}
}
@ -72,9 +78,9 @@ public class DataAccessPolicy {
@JsonIgnore
public boolean canWrite(Project p, User u){
switch(getPolicy().getWrite()){
case OWN: return p.getInfo().getCreationInfo().getUser().equals(u);
case ANY: return true;
case NONE:
case own: return p.getInfo().getCreationInfo().getUser().equals(u);
case any: return true;
case none:
default : return false;
}
}

View File

@ -1,5 +1,7 @@
package org.gcube.application.geoportal.common.utils.tests;
import org.gcube.application.geoportal.common.model.document.Project;
public class GCubeTest {
public static String getContext() {
@ -26,5 +28,4 @@ public class GCubeTest {
}
}

View File

@ -44,7 +44,7 @@ public abstract class MongoManager {
protected void init(String collectionName){
String toUseDB=client.getConnection().getDatabase();
log.info("Opening collection {} : {} ",toUseDB);
log.info("Opening collection {} : {} ",toUseDB,collectionName);
collection=client.getTheClient().getDatabase(toUseDB).getCollection(collectionName);
}

View File

@ -19,7 +19,7 @@ public interface MongoManagerI<T> {
// create
public T registerNew(Document toRegister) throws IOException, StepException, EventException;
public T registerNew(Document toRegister) throws IOException, StepException, EventException, InvalidUserRoleException;
// update
public T update(String id,Document toSetDocument) throws IOException, StepException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess;

View File

@ -6,7 +6,6 @@ import com.mongodb.client.model.FindOneAndReplaceOptions;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import com.vdurmont.semver4j.Semver;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
@ -16,9 +15,9 @@ import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.faults.EventException;
import org.gcube.application.cms.plugins.faults.InsufficientPrivileges;
import org.gcube.application.cms.plugins.faults.StepException;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
import org.gcube.application.cms.plugins.reports.DocumentHandlingReport;
import org.gcube.application.cms.plugins.reports.EventExecutionReport;
import org.gcube.application.cms.plugins.reports.StepExecutionReport;
import org.gcube.application.cms.plugins.requests.BaseRequest;
import org.gcube.application.cms.plugins.requests.EventExecutionRequest;
@ -174,7 +173,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
try{
LifecycleManager toReturn=null;
//Getting Lifecycle Manager declaration from UseCaseDescriptor
List<HandlerDeclaration> handlerDeclarations= useCaseDescriptor.getHandlersMapByType().get(PluginDescriptor.BaseTypes.LIFECYCLE_MANAGER);
List<HandlerDeclaration> handlerDeclarations= useCaseDescriptor.getHandlersMapByType().get(LifecycleManagerDescriptor.LIFECYCLE_MANAGER_TYPE);
if(handlerDeclarations==null || handlerDeclarations.isEmpty()) throw new ConfigurationException("No Lifecycle Handler defined for useCaseDescriptor ID "+ useCaseDescriptor.getId());
if(handlerDeclarations.size()>1) throw new ConfigurationException("Too many Lifecycle Handlers defined ("+handlerDeclarations+") in useCaseDescriptor ID "+ useCaseDescriptor.getId());
@ -195,9 +194,23 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
@Override
public Project registerNew(Document toRegisterDoc) throws IOException, StepException, EventException {
public Project registerNew(Document toRegisterDoc) throws IOException, StepException, EventException, InvalidUserRoleException {
log.info("Registering new document in {} ", useCaseDescriptor.getId());
log.debug("Going to register {}",toRegisterDoc.toJson());
log.trace("Going to register {}",toRegisterDoc.toJson());
User u = UserUtils.getCurrent().asInfo().getUser();
final DataAccessPolicy policy = useCaseDescriptor.getMatching(u);
log.trace("Access policy for user {} is {} ",u,policy);
if(policy == null) {
log.warn("No policy found for {}. Returning empty ", u);
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
}
if(policy.getPolicy().getWrite().equals(DataAccessPolicy.Policy.Type.none))
throw new InvalidUserRoleException("User doesn't have write privileges " + u.getRoles());
Project toRegister = new Project();
toRegister.setTheDocument(toRegisterDoc);
@ -322,7 +335,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
}
Document doc=getDocById(asId(id),
policy==null?null:policy.getEnforcer().getFilter());
(policy==null||policy.getEnforcer()==null)?null:policy.getEnforcer().getFilterDocument());
if(doc==null) throw new ProjectNotFoundException("No document with ID "+id);
Project p = convert(doc, Project.class);
@ -341,7 +354,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
log.warn("No policy found for {}. Returning empty ", u);
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
}
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.NONE)) {
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.none)) {
log.info("Read is NONE : Returning empty collection");
return queue;
}
@ -350,10 +363,9 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
Document finalFilter=new Document();
if(queryRequest.getFilter()!=null)
finalFilter.putAll(queryRequest.getFilter());
Document enforcerFilter =policy.getEnforcer().getFilter();
if(enforcerFilter != null)
finalFilter.putAll(enforcerFilter);
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.OWN))
if(policy.getEnforcer() != null)
finalFilter.putAll(policy.getEnforcer().getFilterDocument());
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.own))
finalFilter.put(Project.INFO+"."+PublicationInfo.CREATION_INFO+"."+AccountingInfo.USER+"."+User.USERNAME,u.getUsername());
queryRequest.setFilter(finalFilter);
@ -378,7 +390,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
log.warn("No policy found for {}. Returning empty ", u);
throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles());
}
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.NONE)) {
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.none)) {
log.info("Read is NONE : Returning empty collection");
return queue;
}
@ -387,10 +399,9 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
Document finalFilter=new Document();
if(queryRequest.getFilter()!=null)
finalFilter.putAll(queryRequest.getFilter());
Document enforcerFilter =policy.getEnforcer().getFilter();
if(enforcerFilter != null)
finalFilter.putAll(enforcerFilter);
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.OWN))
if(policy.getEnforcer() != null)
finalFilter.putAll(policy.getEnforcer().getFilterDocument());
if(policy.getPolicy().getRead().equals(DataAccessPolicy.Policy.Type.own))
finalFilter.put(Project.INFO+"."+PublicationInfo.CREATION_INFO+"."+AccountingInfo.USER+"."+User.USERNAME,u.getUsername());
queryRequest.setFilter(finalFilter);

View File

@ -27,6 +27,11 @@ public class UCDMongoManager extends MongoManager implements UCDManagerI{
init("UCD_"+ContextUtils.getCurrentScope().replaceAll("/","_"));
}
public long deleteAll(){
return getCollection().deleteMany(new Document()).getDeletedCount();
}
@Override
protected String mongoIDFieldName() {
return UseCaseDescriptor.MONGO_ID;

View File

@ -46,7 +46,9 @@ public class LocalFolderProfileMapCache extends AbstractScopedMap<ProfileMap> {
File baseFolder = new File (folderPath);
for (File file : baseFolder.listFiles(pathname -> pathname.getName().endsWith(".json"))) {
try {
UseCaseDescriptor p = Serialization.read(Files.readFileAsString(file.getAbsolutePath(), Charset.defaultCharset()), UseCaseDescriptor.class);
String jsonString = Files.readFileAsString(file.getAbsolutePath(), Charset.defaultCharset());
log.trace("JSON IS {}",jsonString);
UseCaseDescriptor p = Serialization.read(jsonString, UseCaseDescriptor.class);
toReturn.put(p.getId(),p);
} catch (JsonProcessingException e) {
e.printStackTrace();

View File

@ -14,6 +14,7 @@ import org.gcube.application.geoportal.service.model.internal.faults.Registratio
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Slf4j
@ -26,7 +27,6 @@ public class UCDManager extends AbstractScopedMap<UCDManagerI> implements UCDMan
}
@Override
public Iterable<UseCaseDescriptor> query(QueryRequest queryRequest) throws ConfigurationException {
return getMongoManager().query(queryRequest);
@ -95,10 +95,13 @@ public class UCDManager extends AbstractScopedMap<UCDManagerI> implements UCDMan
}
ConcurrentHashMap<String,Boolean> cleanedCaches= new ConcurrentHashMap<>();
private void forceUpdateCache() throws ConfigurationException {
log.info("UPDATING PROFILE CACHE..");
final UCDMongoManager manager = getMongoManager();
manager.deleteAll();
final AtomicLong counter= new AtomicLong(0l);
ProfileMap liveMap=getLiveMap();
log.debug("LiveMap size is {} ",liveMap.size());

View File

@ -13,14 +13,13 @@ import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.scope.api.ScopeProvider;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
@Slf4j
public class UserUtils {
public static List<String> DEFAULT_ROLES=new ArrayList<>();
public static AuthenticatedUser getCurrent() throws SecurityException {
String context=ScopeProvider.instance.get();
if(context==null) throw new SecurityException("Cannot determine context");
@ -87,7 +86,7 @@ public class UserUtils {
log.warn("Unable to determine user id, using FAKE");
user.setUsername("FAKE");
user.setRoles(new HashSet<>());
user.getRoles().addAll(Arrays.asList(new String[] {"FakeUser","FakeAdmin","FakeEditor"}));
user.getRoles().addAll(DEFAULT_ROLES);
}
info.setUser(user);

View File

@ -16,6 +16,7 @@ import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.gcube.application.geoportal.service.BasicServiceTestUnit;
import org.gcube.application.geoportal.service.model.internal.faults.*;
import org.gcube.application.geoportal.service.utils.UserUtils;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
import org.geotoolkit.referencing.operation.provider.PolarStereographic;
import org.junit.Before;
@ -37,6 +38,9 @@ public class LockTests extends BasicServiceTestUnit {
assumeTrue(GCubeTest.isTestInfrastructureEnabled());
TokenSetter.set(GCubeTest.getContext());
manager = new ProfiledMongoManager(profileID);
UserUtils.DEFAULT_ROLES.add("FakeAdmin");
}
@Test

View File

@ -3,15 +3,16 @@ package org.gcube.application.geoportal.service.engine.providers.ucd;
import org.gcube.application.cms.tests.TestProfiles;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.xml.bind.JAXBException;
import java.util.Arrays;
import java.util.Map;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static junit.framework.TestCase.*;
import static org.junit.Assume.assumeTrue;
public class UCDLoadingTest {
@ -44,6 +45,14 @@ public class UCDLoadingTest {
@Test
public void testLocalLoading() throws ConfigurationException {
assertTrue(new LocalFolderProfileMapCache(TestProfiles.BASE_FOLDER.getAbsolutePath()).getObject().size()>0);
Map<String, UseCaseDescriptor> liveMap=new LocalFolderProfileMapCache(TestProfiles.BASE_FOLDER.getAbsolutePath()).retrieveObject(null);
assertTrue(liveMap.size()>0);
liveMap.forEach((s, useCaseDescriptor) -> {
System.out.println("Checking "+s);
assertNotNull(useCaseDescriptor);
assertNotNull(useCaseDescriptor.getId());
assertNotNull(useCaseDescriptor.getDataAccessPolicies());
assertNotNull(useCaseDescriptor.getHandlers());
});
}
}

View File

@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import org.bson.Document;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.cms.tests.model.BasicTests;
import org.gcube.application.cms.tests.model.concessioni.TestConcessioniModel;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
@ -92,50 +93,18 @@ public abstract class AbstractProfiledDocumentsTests extends BasicServiceTestUni
protected Project createNew(Document content) throws Exception {
Project doc =check(baseTarget().request(MediaType.APPLICATION_JSON).
post(Entity.entity(content, MediaType.APPLICATION_JSON)), Project.class);
validate(doc);
BasicTests.validate(doc);
assertTrue(doc.getLifecycleInformation().getPhase().equals(LifecycleInformation.CommonPhases.DRAFT_PHASE));
return doc;
}
protected void validate (Project doc){
assertTrue(doc!=null);
assertTrue(doc.getId()!=null);
assertTrue(doc.getLifecycleInformation().getPhase()!=null);
assertTrue(doc.getLifecycleInformation().getLastOperationStatus()!=null);
if(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.ERROR))
assertTrue(doc.getLifecycleInformation().getErrorMessages().size()>0);
if(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.WARNING))
assertTrue(doc.getLifecycleInformation().getWarningMessages().size()>0);
if(doc.getLifecycleInformation().getTriggeredEvents()!=null)
doc.getLifecycleInformation().getTriggeredEvents().forEach(triggeredEvents -> {
assertTrue(triggeredEvents.getEvent()!=null);
assertTrue(triggeredEvents.getLastOperationStatus()!=null);
if(triggeredEvents.getLastOperationStatus().equals(LifecycleInformation.Status.ERROR))
assertTrue(triggeredEvents.getErrorMessages().size()>0);
if(triggeredEvents.getLastOperationStatus().equals(LifecycleInformation.Status.WARNING))
assertTrue(triggeredEvents.getWarningMessages().size()>0);
});
assertTrue(doc.getInfo()!=null);
assertTrue(doc.getInfo().getCreationInfo()!=null);
assertTrue(doc.getInfo().getCreationInfo().getContext()!=null);
assertTrue(doc.getInfo().getCreationInfo().getContext().getId()!=null);
assertTrue(doc.getInfo().getCreationInfo().getContext().getName()!=null);
assertTrue(doc.getInfo().getCreationInfo().getInstant()!=null);
assertTrue(doc.getInfo().getCreationInfo().getInstant()!=null);
assertTrue(doc.getInfo().getCreationInfo().getUser()!=null);
assertTrue(doc.getInfo().getCreationInfo().getUser().getUsername()!=null);
assertTrue(doc.getTheDocument()!=null);
}
protected Project update(String id, Document newContent)throws Exception {
Project doc = check(baseTarget().path(id).request(MediaType.APPLICATION_JSON).
put(Entity.entity(newContent, MediaType.APPLICATION_JSON)), Project.class);
validate(doc);
BasicTests.validate(doc);
return doc;
}
@ -157,7 +126,7 @@ public abstract class AbstractProfiledDocumentsTests extends BasicServiceTestUni
Project doc = check(baseTarget().path(InterfaceConstants.Methods.REGISTER_FILES_PATH).path(id).request(MediaType.APPLICATION_JSON).
post(Entity.entity(Serialization.write(builder.getTheRequest()),
MediaType.APPLICATION_JSON)), Project.class);
validate(doc);
BasicTests.validate(doc);
return doc;
}
@ -167,7 +136,7 @@ public abstract class AbstractProfiledDocumentsTests extends BasicServiceTestUni
path(InterfaceConstants.Methods.STEP).path(id).request(MediaType.APPLICATION_JSON).
post(Entity.entity(Serialization.write(request),
MediaType.APPLICATION_JSON)), Project.class);
validate(toReturn);
BasicTests.validate(toReturn);
assertTrue(toReturn.getLifecycleInformation().getLastInvokedStep().equals(request.getStepID()));
return toReturn;
}

View File

@ -7,7 +7,7 @@
</encoder>
</appender>
<logger name="org.gcube.application" level="DEBUG">
<logger name="org.gcube.application" level="TRACE">
</logger>
<root level="ERROR">

View File

@ -1,5 +1,6 @@
package org.gcube.application.cms.sdi.plugins;
import com.vdurmont.semver4j.Semver;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
@ -9,7 +10,8 @@ import org.gcube.application.cms.plugins.faults.InitializationException;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.faults.InvalidProfileException;
import org.gcube.application.cms.plugins.model.ComparableVersion;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.IndexerPluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
import org.gcube.application.cms.plugins.reports.IndexDocumentReport;
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.Report;
@ -52,12 +54,12 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin
static final PluginDescriptor DESCRIPTOR=new PluginDescriptor("SDI-Indexer-Plugin",
PluginDescriptor.BaseTypes.INDEXER);
IndexerPluginDescriptor.INDEXER);
static {
DESCRIPTOR.setDescription("SDI Indexer. " +
"Manage Centroids layers.");
DESCRIPTOR.setVersion(new ComparableVersion("1.0.0"));
DESCRIPTOR.setVersion(new Semver("1.0.0"));
}
@Override

View File

@ -1,5 +1,6 @@
package org.gcube.application.cms.sdi.plugins;
import com.vdurmont.semver4j.Semver;
import lombok.Data;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
@ -11,7 +12,8 @@ import org.gcube.application.cms.plugins.faults.MaterializationException;
import org.gcube.application.cms.plugins.faults.ShutDownException;
import org.gcube.application.cms.plugins.implementations.AbstractPlugin;
import org.gcube.application.cms.plugins.model.ComparableVersion;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.MaterializerPluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.MaterializationReport;
import org.gcube.application.cms.plugins.reports.Report;
@ -204,11 +206,11 @@ public class SDIMaterializerPlugin extends AbstractPlugin implements Materializa
}
}
private static final PluginDescriptor DESCRIPTOR=new PluginDescriptor("SDI-Default-Materializer", PluginDescriptor.BaseTypes.MATERIALIZER);
private static final PluginDescriptor DESCRIPTOR=new PluginDescriptor("SDI-Default-Materializer", MaterializerPluginDescriptor.MATERIALIZER);
static {
DESCRIPTOR.setDescription("SDI Materializer. " +
"This plugin materialize FileSets in gCube SDI.");
DESCRIPTOR.setVersion(new ComparableVersion("1.0.0"));
DESCRIPTOR.setVersion(new Semver("1.0.0"));
}
@Override

View File

@ -9,9 +9,8 @@ import org.gcube.application.cms.plugins.reports.Report;
import org.gcube.application.cms.plugins.requests.BaseRequest;
import org.gcube.application.cms.plugins.requests.IndexDocumentRequest;
import org.gcube.application.cms.sdi.engine.PostgisIndexer;
import org.gcube.application.cms.sdi.model.GCubeSDILayerBuilder;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.cms.tests.BasicPluginTest;
import org.gcube.application.cms.tests.plugins.BasicPluginTest;
import org.gcube.application.cms.tests.TestDocuments;
import org.gcube.application.cms.tests.TestProfiles;
import org.gcube.application.geoportal.common.model.configuration.Index;
@ -36,7 +35,7 @@ public class IndexerTest extends BasicPluginTest {
Project doc= TestDocuments.documentMap.get("profiledConcessioniExample.json");
IndexDocumentRequest request=new IndexDocumentRequest(TestProfiles.profiles.get(doc.getProfileID()),
getTestUser(),getTestContext(),doc);
getCurrentUser(),getTestContext(),doc);
Document parameters = new Document();
parameters.put("workspace", "testing_workspace");
@ -61,7 +60,7 @@ public class IndexerTest extends BasicPluginTest {
IndexerPluginInterface plugin = (IndexerPluginInterface) plugins.get(SDIIndexerPlugin.DESCRIPTOR.getId());
UseCaseDescriptor descriptor=TestProfiles.profiles.get("profiledConcessioni");
Index index = plugin.getIndex(new BaseRequest(descriptor,getTestUser(),getTestContext())
Index index = plugin.getIndex(new BaseRequest(descriptor,getCurrentUser(),getTestContext())
.setParameter("workspace", Files.fixFilename(GCubeTest.getContext()+"_test-ws"))
.setParameter("indexName",Files.fixFilename(GCubeTest.getContext()+"test_index")));
System.out.println("Test Index Is "+index);

View File

@ -1,140 +1,31 @@
{
"_id" : "profiledConcessioni",
"_id" : "basic",
"_version" : "1.0.0",
"_name" : "Concessione",
"_schema" : {
"relazioneScavo" : { "_max" : 1, "_min" : 1,
"_children" : [
{"fileset" :{"_type" : "RegisteredFileSet"}},
{"title" : {"_max" : 1, "_min" : 1}}
]
},
"abstractRelazione" : { "_max" : 1, "_min" : 1,
"_children" : [
{"filesetIta" :{"_type" : "RegisteredFileSet"}},
{"filesetEng" :{"_type" : "RegisteredFileSet"}},
{"title" : {"_max" : 1, "_min" : 1}}
]
},
"immagini" : {
"_max" : -1,
"_children" : [
{"fileset" :{"_type" : "RegisteredFileSet"}},
{"title" : {"_max" : 1, "_min" : 1}}
]
},
"posizionamentoScavo" : { "_max" : 1, "_min" : 1,
"_children" : [
{"fileset" :{"_type" : "RegisteredFileSet"}},
{"title" : {"_max" : 1, "_min" : 1}}
]
}
},
"_schema" : {},
"_description" : "Embedded profile for concessioni [mibac] management",
"_description" : "Simple testing UCD",
"_creationInfo": {
"_user" : {
"_username": "fabio.sinibaldi"
}
},
"_data_access_policy" : [
{"_policy" : {"_read" : "own", "_write" : "own"}, "_roles":[]},
{"_policy" : {"_read" : "any", "_write" : "none"}, "_roles":["Guest"],
"_enforcer": {"_filter" : {"lifecycleInformation.phase" : {"$eq" : "Published"}}}},
{"_policy" : {"_read" : "any", "_write" : "none"}, "_roles":["Admin"]},
{"_policy" : {"_read" : "any", "_write" : "any"}, "_roles":["Data-Manager"]}
"_dataAccessPolicies" : [
{"_policy" : {"_read" : "own", "_write" : "own"}, "_roles":[]}
],
"_handlers" : [
{
"_id" : "GNA-CONCESSIONI-LC",
"_id" : "DEFAULT-SINGLE-PHASE",
"_type" : "LifecycleManagement",
"_configuration" : {
"step_access" : [
{"STEP" : "PUBLISH", "roles" :[ "DataManager"]}
{"STEP" : "PUBLISH", "roles" :[ "FakeAdmin"]}
]
}
},
{
"_id" : "SDI-Default-Materializer",
"_type" : "Materializer",
"_configuration" : {
"registeredFileSetPaths" : [
{"schemaField" : "pianteFineScavo","documentPath" : "pianteFineScavo[*]"},
{"schemaField" : "posizionamentoScavo","documentPath" : "posizionamentoScavo"}
]
}
},
{
"_id" : "SDI-Indexer-Plugin",
"_type" : "Indexer",
"_configuration" : {
"bboxEvaluation" : ["$..posizionamentoScavo.._bbox"],
"explicitFieldMapping" : [
{"name" : "titolo", "path" : "$.theDocument.title","type" : "TEXT"}
],
"jslt" : {},
"additionalLayers" : [
{"source" : {"url" : "..."},"toSetTitle":""}
]
}
},
{
"_id" : "org.gcube....geoportal-data-entry-portlet",
"_type" : "DATA_ENTRY_GUI",
"_case" : "",
"_configuration" : {
"gcubeProfiles" : [
{
"gcubeCategory" : "",
"gcubeName" : "",
"order" : "",
"sectionName": "",
"sectionTitle" : "",
"cardinality" : "",
"parentName" : "",
"filePaths" : [
{"field" : "field id from XML gcube Profile",
"path" : "$.abstract.associatedFiles" }
]
}
]
}
},
{
"_id" : "org.gcube....geoportal-data-list",
"_type" : "DATA_LIST_GUI",
"_case" : "smallList",
"_configuration" : {
"projection" : {"nome" : 1, "lifecycleInformation.phase" : 1},
"orderPaths":[
{"label" : "author", "path" : "info.creationInfo.user.username"}],
"searchPaths":[
{"label" : "author", "path" : "info.creationInfo.user.username"}],
"actions" :[
{ "status" : "OK",
"phase" : "VALIDATE_DRAFT",
"butoonsDefintion" : [
{"id" : "report_forward","action" : "STEP", "label" : "Sottometti"},
{"id" : "list_back_workflow", "action" : "STEP" , "label" : "Rifiuta"},
{"id" : "report_backward", "action" : "STEP" , "label" : "Rifiuta"}
]}
],
"implicit_filter":{"nome" : {"$eq" : "ciao" }}
}
}
]
}

View File

@ -46,10 +46,10 @@
}
},
"_data_access_policy" : [
"_dataAccessPolicies" : [
{"_policy" : {"_read" : "own", "_write" : "own"}, "_roles":[]},
{"_policy" : {"_read" : "any", "_write" : "none"}, "_roles":["Guest"],
"_enforcer": {"_filter" : {"_lifecycleInformation._phase" : {"$eq" : "Published"}}}},
"_enforcer": {"_filter" : "{\"_lifecycleInformation._phase\" : {\"$eq\" : \"Published\"}}"}},
{"_policy" : {"_read" : "any", "_write" : "none"}, "_roles":["Admin"]},
{"_policy" : {"_read" : "any", "_write" : "any"}, "_roles":["Data-Manager"]}
],

View File

@ -9,12 +9,22 @@
"_username": "fabio.sinibaldi"
}
},
"_data_access_policy" : [
"_dataAccessPolicies" : [
{"_policy" : {"_read" : "own", "_write" : "own"}, "_roles":[]},
{"_policy" : {"_read" : "any", "_write" : "none"}, "_roles":["FakeUser"],
"_enforcer": {"_filter" : {"_lifecycleInformation._phase" : {"$eq" : "Published"}}}},
"_enforcer": {"_filter" : "{\"_lifecycleInformation._phase\" : {\"$eq\" : \"Published\"}}"}},
{"_policy" : {"_read" : "any", "_write" : "none"}, "_roles":["FakeEditor"]},
{"_policy" : {"_read" : "any", "_write" : "any"}, "_roles":["FakeAdmin"]}
],
"_handlers" : []
"_handlers" : [
{
"_id" : "DEFAULT-SINGLE-PHASE",
"_type" : "LifecycleManagement",
"_configuration" : {
"step_access" : [
{"STEP" : "PUBLISH", "roles" :[ "FakeAdmin"]}
]
}
}
]
}