resource-registry/src/test/java/org/gcube/informationsystem/resourceregistry/contexts/ContextManagementTest.java

539 lines
17 KiB
Java

package org.gcube.informationsystem.resourceregistry.contexts;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.informationsystem.base.reference.IdentifiableElement;
import org.gcube.informationsystem.contexts.impl.entities.ContextImpl;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
import org.gcube.informationsystem.resourceregistry.ContextTest;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextAlreadyPresentException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException;
import org.gcube.informationsystem.resourceregistry.contexts.entities.ContextManagement;
import org.gcube.informationsystem.resourceregistry.contexts.security.ContextSecurityContext;
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext;
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode;
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.SecurityType;
import org.gcube.informationsystem.resourceregistry.utils.MetadataUtility;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.arcadedb.remote.RemoteDatabase;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ContextManagementTest extends ContextTest {
private static Logger logger = LoggerFactory.getLogger(ContextManagementTest.class);
public static final String CTX_NAME_A = "A";
public static final String CTX_NAME_B = "B";
public static final String CTX_NAME_C = "C";
public static void checkUUUIDAndMetadata(IdentifiableElement er, UUID uuid, boolean create) {
Assert.assertTrue(er.getMetadata() != null);
Assert.assertTrue(er.getID() != null);
if(uuid != null) {
Assert.assertTrue(er.getID().compareTo(uuid) == 0);
}
String user = MetadataUtility.getUser();
Assert.assertTrue(er.getMetadata().getLastUpdateBy().compareTo(user) == 0);
if(create) {
Assert.assertTrue(er.getMetadata().getCreatedBy().compareTo(user) == 0);
Assert.assertTrue(er.getMetadata().getCreationTime().compareTo(er.getMetadata().getLastUpdateTime()) == 0);
} else {
Assert.assertTrue(er.getMetadata().getCreationTime().before(er.getMetadata().getLastUpdateTime()));
}
}
protected void assertions(Context pre, Context post, boolean checkParent, boolean create)
throws ResourceRegistryException {
if(checkParent) {
if(pre.getMetadata() != null) {
checkUUUIDAndMetadata(post, pre.getID(), create);
} else {
checkUUUIDAndMetadata(post, null, create);
}
}
Assert.assertTrue(pre.getName().compareTo(post.getName()) == 0);
if(checkParent && pre.getParent() != null && post.getParent() != null) {
Context preParent = pre.getParent().getSource();
Context postParent = post.getParent().getSource();
assertions(preParent, postParent, false, false);
}
}
protected void roleUserAssertions(UUID uuid, UUID oldParentUUID, boolean deleted) throws ResourceRegistryException {
ContextSecurityContext contextSecurityContext = ContextSecurityContext.getInstance();
RemoteDatabase database = contextSecurityContext.getRemoteDatabase(PermissionMode.READER);
// OSecurity oSecurity = oDatabaseDocument.getMetadata().getSecurity();
SecurityContext securityContext = null;
if(deleted) {
securityContext = new SecurityContext(uuid);
} else {
securityContext = ContextUtility.getInstance().getSecurityContextByUUID(uuid);
}
boolean[] booleanArray = new boolean[] {false, true};
for(boolean hierarchic : booleanArray) {
for(PermissionMode permissionMode : PermissionMode.values()) {
String role = securityContext.getSecurityRoleOrUserName(permissionMode, SecurityType.ROLE, hierarchic);
Role oRole = oSecurity.getRole(role);
Assert.assertEquals(oRole == null, deleted);
String user = securityContext.getSecurityRoleOrUserName(permissionMode, SecurityType.USER, hierarchic);
User oUser = oSecurity.getUser(user);
Assert.assertEquals(oUser == null, deleted);
if(oUser != null) {
Assert.assertTrue(oUser.hasRole(oRole.getName(), false));
}
if(hierarchic) {
SecurityContext parent = null;
if(deleted) {
if(oldParentUUID != null) {
parent = ContextUtility.getInstance().getSecurityContextByUUID(oldParentUUID);
}
}
parent = securityContext.getParentSecurityContext();
while(parent != null) {
String parentUser = parent.getSecurityRoleOrUserName(permissionMode, SecurityType.USER,
hierarchic);
User parentOUser = oSecurity.getUser(parentUser);
Assert.assertTrue(parentOUser != null);
Assert.assertEquals(parentOUser.hasRole(oRole.getName(), false), !deleted);
parent = parent.getParentSecurityContext();
}
}
}
}
}
protected Context read(UUID uuid) throws ResourceRegistryException, IOException {
ContextManagement contextManagement = new ContextManagement();
contextManagement.setUUID(uuid);
String contextString = contextManagement.read().toString();
logger.debug("Read {}", contextString);
roleUserAssertions(uuid, null, false);
return ElementMapper.unmarshal(Context.class, contextString);
}
protected Context create(Context context) throws ResourceRegistryException, IOException {
ContextManagement contextManagement = new ContextManagement();
contextManagement.setJson(ElementMapper.marshal(context));
String contextString = contextManagement.create();
logger.debug("Created {}", contextString);
Context c = ElementMapper.unmarshal(Context.class, contextString);
assertions(context, c, true, true);
roleUserAssertions(c.getID(), null, false);
return c;
}
protected Context update(Context context) throws ResourceRegistryException, IOException {
ContextManagement contextManagement = new ContextManagement();
contextManagement.setJson(ElementMapper.marshal(context));
String contextString = contextManagement.update();
logger.debug("Updated {}", contextString);
Context c = ElementMapper.unmarshal(Context.class, contextString);
assertions(context, c, true, false);
roleUserAssertions(c.getID(), null, false);
return c;
}
protected void delete(UUID uuid) throws ResourceRegistryException {
ContextManagement contextManagement = new ContextManagement();
contextManagement.setUUID(uuid);
SecurityContext securityContext = ContextUtility.getInstance().getSecurityContextByUUID(uuid);
UUID oldParentUUID = null;
if(securityContext.getParentSecurityContext() != null) {
oldParentUUID = securityContext.getParentSecurityContext().getUUID();
}
contextManagement.delete();
roleUserAssertions(uuid, oldParentUUID, true);
logger.debug("Deleted {} with UUID {}", Context.NAME, uuid);
}
protected void delete(Context context) throws ResourceRegistryException {
delete(context.getID());
}
protected void invalidCreate(Context context) throws ResourceRegistryException, IOException {
try {
Context c = create(context);
throw new RuntimeException(ElementMapper.marshal(c) + " was created successfully. This is not what we expected");
} catch(ContextAlreadyPresentException e) {
logger.debug("As expected {} cannot be created.", ElementMapper.marshal(context));
}
}
protected void invalidUpdate(Context context) throws ResourceRegistryException, IOException {
try {
Context c = update(context);
throw new RuntimeException(ElementMapper.marshal(c) + " was updated successfully. This is not what we expected");
} catch(ContextAlreadyPresentException e) {
logger.debug("As expected {} cannot be updated.", ElementMapper.marshal(context));
}
}
protected void invalidDelete(Context context) throws ResourceRegistryException, JsonProcessingException {
String contextString = ElementMapper.marshal(context);
try {
delete(context);
throw new RuntimeException(contextString + " was deleted successfully. This is not what we expected");
} catch(ContextException e) {
logger.debug("As expected {} cannot be deleted.", contextString);
}
}
/*
@Test
public void createDelete() throws Exception {
Context contextA1 = new ContextImpl(CTX_NAME_A);
contextA1 = create(contextA1);
delete(contextA1);
logger.debug("The DB should be now clean");
}
*/
@Test
public void completeTest() throws Exception {
Context contextA1 = new ContextImpl(CTX_NAME_A);
contextA1 = create(contextA1);
// ________A1________
Context contextA2 = new ContextImpl(CTX_NAME_A);
contextA2.setParent(contextA1);
contextA2 = create(contextA2);
// ________A1________
// ___A2
Context contextB3 = new ContextImpl(CTX_NAME_B);
contextB3.setParent(contextA2);
contextB3 = create(contextB3);
// ________A1________
// ___A2
// B3
Context contextB4 = new ContextImpl(CTX_NAME_B);
contextB4.setParent(contextA1);
contextB4 = create(contextB4);
// ________A1________
// ___A2_______B4____
// B3
Context contextA5 = new ContextImpl(CTX_NAME_A);
contextA5.setParent(contextB4);
contextA5 = create(contextA5);
// ________A1________
// ___A2_______B4____
// B3______________A5
invalidCreate(contextA1); // Trying to recreate A1. Fails
invalidCreate(contextA2); // Trying to recreate A2. Fails
invalidCreate(contextB3); // Trying to recreate B3. Fails
invalidCreate(contextB4); // Trying to recreate B4. Fails
invalidCreate(contextA5); // Trying to recreate A5. Fails
Context nullContext = null;
// Trying to move A5 as root. It fails due to A1.
contextA5.setParent(nullContext);
invalidUpdate(contextA5);
contextA5.setParent(contextB4);
// ________A1________
// ___A2_______B4____
// B3______________A5
nullContext = null;
contextB4.setParent(nullContext);
update(contextB4);
// _____A1____B4_____
// __A2__________A5__
// B3
contextB4.setParent(contextA1);
update(contextB4);
// ________A1________
// ___A2_______B4____
// B3______________A5
// Trying to rename with the new name A. It fails due to A5.
contextB3.setName(CTX_NAME_A);
update(contextB3);
// ________A1________
// ___A2_______B4____
// A3______________A5
// After Restoring name B, trying to move B3 as child of A1. It fails due to B4.
contextB3.setName(CTX_NAME_B);
contextB3.setParent(contextA1);
invalidUpdate(contextB3);
// ________A1________
// ___A2_______B4____
// A3______________A5
// Restoring A3 (was B3) as B3 and with parent A2.OK.
contextB3.setName(CTX_NAME_B);
contextB3.setParent(contextA2);
update(contextB3);
// ________A1________
// ___A2_______B4____
// B3______________A5
// This update should not has eny effects except updating the lastUpdateTime.
contextB3.setName(CTX_NAME_B);
contextB3.setParent(contextA2);
update(contextB3);
// Trying to move A5 as child of A1. It fails due to A2.
contextA5.setParent(contextA1);
invalidUpdate(contextA5);
// Restoring A5
contextA5.setParent(contextB4);
// ________A1________
// ___A2_______B4____
// B3______________A5
// Moving B3 as child of B4. OK.
contextB3.setParent(contextB4);
update(contextB3);
// ________A1________
// ___A2_______B4____
// ________B3______A5
// Restoring the initial situation by moving B3 as child of A2. OK.
contextB3.setParent(contextA2);
update(contextB3);
// ________A1________
// ___A2_______B4____
// B3______________A5
// Renaming B3 as C3. OK.
contextB3.setName(CTX_NAME_C);
update(contextB3);
// ________A1________
// ___A2_______B4____
// C3______________A5
// Moving C3 (was B3) as child of A1. Now it is possible. OK.
contextB3.setParent(contextA1);
update(contextB3);
// ________A1________
// ___A2___C3___B4___
// ________________A5
// Trying to rename C3 (was B3) newly to B3. Fails due to B4.
contextB3.setName(CTX_NAME_B);
invalidUpdate(contextB3);
// ________A1________
// ___A2___C3___B4___
// ________________A5
// Moving back C3 (was B3) as child of A2. OK.
contextB3.setParent(contextA2);
update(contextB3);
// ________A1________
// ___A2_______B4____
// C3______________A5
// Renaming C3 (was B3) to B3. OK.
contextB3.setName(CTX_NAME_B);
update(contextB3);
// ________A1________
// ___A2_______B4____
// B3______________A5
/*
// This updates (move) has been made to test HRoles and HUsers
contextA2.setParent(contextA5);
update(contextA2);
// __A1______________
// _____B4___________
// ________A5________
// ___________A2_____
// ______________B3__
contextA5.setParent(contextA1);
update(contextA5);
// _________A1________
// ______A5_____B4____
// ___A2______________
// B3_________________
contextA5.setParent(contextB4);
update(contextA5);
// __A1______________
// _____B4___________
// ________A5________
// ___________A2_____
// ______________B3__
contextA2.setParent(contextA1);
update(contextA2);
// ________A1________
// ___A2_______B4____
// B3______________A5
*/
// The following delete are not allowed because they are not child contexts
invalidDelete(contextA1);
invalidDelete(contextA2);
invalidDelete(contextB4);
delete(contextA5);
// ________A1________
// ___A2_______B4____
// B3
try {
delete(contextA5);
} catch(ContextNotFoundException e) {
logger.debug("The context with uuid {} was not found. (Was already deleted)",
contextA5.getID());
}
delete(contextB3);
// ________A1________
// ___A2_______B4____
delete(contextB4);
// ________A1________
// ___A2
delete(contextA2);
// ________A1________
Context contextC = new ContextImpl(CTX_NAME_C);
contextC.setID(contextA1.getID());
invalidCreate(contextC);
delete(contextA1);
logger.debug("The DB should be now clean");
}
private List<Context> getAll() throws Exception {
ContextManagement contextManagement = new ContextManagement();
String allString = contextManagement.all(false);
logger.trace(allString);
List<Context> all = ElementMapper.unmarshalList(Context.class, allString);
return all;
}
/*
// @Test
public void deleteAll() throws Exception {
ContextTest.setContextByName(PARENT_DEFAULT_TEST_SCOPE);
List<Context> all = getAll();
while(all.size()>0) {
for (Context context : all) {
logger.trace(ElementMapper.marshal(context));
List<IsParentOf> children = context.getChildren();
if(children==null || children.size()==0) {
// delete(context);
}
}
all = getAll();
}
}
*/
@Test
public void testGetAll() throws Exception {
List<Context> contexts = getAll();
contexts = ServerContextCache.getInstance().getContexts();
for(Context context : contexts) {
logger.info(ElementMapper.marshal(context));
List<IsParentOf> children = context.getChildren();
for(IsParentOf child : children) {
Assert.assertTrue(child.getSource() == context);
Context childContext = child.getTarget();
Assert.assertTrue(childContext.getParent().getSource() == context);
}
roleUserAssertions(context.getID(), null, false);
}
}
// @Test
public void readContext() throws ResourceRegistryException, IOException {
Context context = read(UUID.fromString(""));
logger.debug("{}", context);
}
// @Test
public void deleteContext() throws ResourceRegistryException, IOException {
Context context = read(UUID.fromString(""));
delete(context);
}
@Test
public void testContextCache() throws Exception {
List<Context> contexts = getAll();
logger.debug("{}", contexts);
ServerContextCache contextCache = ServerContextCache.getInstance();
Map<UUID, String> uuidToContextFullName = contextCache.getUUIDToContextFullNameAssociation();
logger.debug("{}", uuidToContextFullName);
List<Context> contextsFromCache = contextCache.getContexts();
for(Context c : contextsFromCache) {
UUID uuid = c.getID();
if(c.getParent()!=null) {
IsParentOf isParentOf = c.getParent();
Context parentContext = isParentOf.getSource();
UUID parentUUID = parentContext.getID();
Assert.assertTrue(parentContext.getName().compareTo(contextCache.getContextByUUID(parentUUID).getName())==0);
List<IsParentOf> children = parentContext.getChildren();
boolean found = false;
for(IsParentOf ipo : children) {
if(ipo.equals(isParentOf)) {
found = true;
break;
}
}
Assert.assertTrue(found);
logger.debug("{} : {} (parent {} : {})", c.getID(), contextCache.getContextFullNameByUUID(uuid), parentUUID, contextCache.getContextFullNameByUUID(parentUUID));
}else {
logger.debug("{} : {}", c.getID(), contextCache.getContextFullNameByUUID(uuid));
}
}
Context currentContext = read(ContextUtility.getCurrentSecurityContext().getUUID());
logger.debug("Current context : {}", currentContext);
for(Context c : contexts) {
UUID uuid = c.getID();
Context context = read(uuid);
String fullName = ServerContextCache.getInstance().getContextFullNameByUUID(uuid);
logger.debug("{} - {} : {}", uuid, fullName, context);
}
}
}