Skip to content

Commit

Permalink
Changing closure to contain orgs only (work in progress).
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Oct 8, 2014
1 parent aacd8e7 commit b648b10
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 142 deletions.
Expand Up @@ -31,6 +31,7 @@
import com.evolveum.midpoint.prism.query.OrgFilter;
import com.evolveum.midpoint.repo.sql.BaseSQLRepoTest;
import com.evolveum.midpoint.repo.sql.data.common.ROrgClosure;
import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType;
import com.evolveum.midpoint.repo.sql.type.XMLGregorianCalendarType;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
Expand Down Expand Up @@ -260,7 +261,9 @@ protected void removeObjectParent(ObjectType object, ObjectReferenceType parentO
ItemDelta removeParent = ReferenceDelta.createModificationDelete(object.getClass(), OrgType.F_PARENT_ORG_REF, prismContext, existingValue.clone());
modifications.add(removeParent);
repositoryService.modifyObject(object.getClass(), object.getOid(), modifications, opResult);
orgGraph.removeEdge(object.getOid(), existingValue.getOid());
if (object instanceof OrgType) {
orgGraph.removeEdge(object.getOid(), existingValue.getOid());
}
}

// TODO generalzie to addObjectParent
Expand All @@ -279,7 +282,6 @@ protected void addUserParent(UserType user, ObjectReferenceType parentOrgRef, Op
ItemDelta readdParent = ReferenceDelta.createModificationAdd(UserType.class, UserType.F_PARENT_ORG_REF, prismContext, existingValue.clone());
modifications.add(readdParent);
repositoryService.modifyObject(UserType.class, user.getOid(), modifications, opResult);
orgGraph.addEdge(user.getOid(), existingValue.getOid());
}

protected void removeOrg(String oid, OperationResult opResult) throws Exception {
Expand All @@ -289,7 +291,6 @@ protected void removeOrg(String oid, OperationResult opResult) throws Exception

protected void removeUser(String oid, OperationResult opResult) throws Exception {
repositoryService.deleteObject(UserType.class, oid, opResult);
orgGraph.removeVertex(oid);
}

protected void reAddOrg(OrgType org, OperationResult opResult) throws Exception {
Expand All @@ -299,7 +300,6 @@ protected void reAddOrg(OrgType org, OperationResult opResult) throws Exception

protected void reAddUser(UserType user, OperationResult opResult) throws Exception {
repositoryService.addObject(user.asPrismObject(), null, opResult);
registerObject(user, false);
}

// parentsInLevel may be null (in that case, a simple tree is generated)
Expand Down Expand Up @@ -338,7 +338,7 @@ protected void loadOrgStructure(int level, String parentOid, String oidPrefix,
loadOrgStructure(level+1, oid, newOidPrefix, result);
}

if (parentOid != null) {
if (parentOid != null && userChildrenInLevel != null) {

List<String> usersAtThisLevel = getUsersAtThisLevelSafe(level);

Expand All @@ -349,7 +349,6 @@ protected void loadOrgStructure(int level, String parentOid, String oidPrefix,
String uoid = repositoryService.addObject(user, null, result);
user.setOid(uoid);
allUsersCreated.add(user.asObjectable());
registerObject(user.asObjectable(), false);
usersAtThisLevel.add(uoid);
objectCount++;
}
Expand Down Expand Up @@ -459,10 +458,10 @@ protected void scanChildren(int level, String parentOid, OperationResult opResul
objectCount++;
System.out.println("#" + objectCount + ": parent level = " + level + ", childOid = " + childOid);
ObjectType objectType = repositoryService.getObject(ObjectType.class, childOid, null, opResult).asObjectable();
registerObject(objectType, false); // children will be registered to graph later
if (objectType instanceof OrgType) {
allOrgCreated.add((OrgType) objectType);
registerOrgToLevels(level+1, objectType.getOid());
registerOrgToLevels(level + 1, objectType.getOid());
registerObject(objectType, false); // children will be registered to graph later
scanChildren(level + 1, objectType.getOid(), opResult);
} else if (objectType instanceof UserType) {
allUsersCreated.add((UserType) objectType);
Expand Down Expand Up @@ -516,6 +515,9 @@ private List<String> generateParentsForLevel(String explicitParentOid, int level
}

protected void registerObject(ObjectType objectType, boolean registerChildrenLinks) {
if (!(objectType instanceof OrgType)) {
return;
}
String oid = objectType.getOid();
registerVertexIfNeeded(oid);
for (ObjectReferenceType ort : objectType.getParentOrgRef()) {
Expand All @@ -530,7 +532,7 @@ protected void registerObject(ObjectType objectType, boolean registerChildrenLin

if (registerChildrenLinks) {
// let's check for existing children
List<String> children = getChildren(oid);
List<String> children = getOrgChildren(oid);
for (String child : children) {
registerVertexIfNeeded(child);
orgGraph.addEdge(child, oid);
Expand All @@ -550,6 +552,15 @@ protected List<String> getChildren(String oid) {
return childrenQuery.list();
}

private List<String> getOrgChildren(String oid) {
Query childrenQuery = getSession().createQuery("select distinct parentRef.ownerOid from RParentOrgRef as parentRef" +
" join parentRef.owner as owner where parentRef.targetOid=:oid" +
" and owner.objectTypeClass = :orgType");
childrenQuery.setParameter("orgType", RObjectType.ORG); // TODO eliminate use of parameter here
childrenQuery.setString("oid", oid);
return childrenQuery.list();
}


protected void removeOrgStructure(OperationResult result) throws Exception {
for (String rootOid : rootOids) {
Expand Down Expand Up @@ -915,59 +926,6 @@ protected void _test300AddRemoveOrgs() throws Exception {
}
}

public void _test310AddRemoveUsers() throws Exception {
OperationResult opResult = new OperationResult("===[ test310AddRemoveUsers ]===");

int totalRounds = 0;
OrgClosureStatistics stat = new OrgClosureStatistics();

long totalTimeNodeRemovals = 0, totalTimeNodeAdditions = 0;
for (int level = 0; level < getConfiguration().getUserRoundsForLevel().length; level++) {
for (int round = 0; round < getConfiguration().getUserRoundsForLevel()[level]; round++) {

// removal
List<String> levelOids = usersByLevels.get(level);
if (levelOids.isEmpty()) {
continue;
}
int index = (int) Math.floor(Math.random() * levelOids.size());
String oid = levelOids.get(index);
UserType user = repositoryService.getObject(UserType.class, oid, null, opResult).asObjectable();

System.out.println("Removing user #" + totalRounds + " (" + level + "/" + round + "): " + user.getOid() + " (parents: " + getParentsOids(user.asPrismObject()) + ")");
long start = System.currentTimeMillis();
removeUser(user.getOid(), opResult);
long timeRemoval = System.currentTimeMillis() - start;
System.out.println(" ... done in " + timeRemoval + " ms" + getNetDurationMessage());
stat.recordExtended(repositoryService.getConfiguration().getHibernateDialect(), allOrgCreated.size(), allUsersCreated.size(), closureSize, "AddRemoveUsers", level, false, getNetDuration());
totalTimeNodeRemovals += getNetDuration();

checkClosure(getVertices());

// addition
System.out.println("Re-adding user #" + totalRounds);
start = System.currentTimeMillis();
reAddUser(user, opResult);
long timeAddition = System.currentTimeMillis() - start;
System.out.println(" ... done in " + timeAddition + "ms" + getNetDurationMessage());
stat.recordExtended(repositoryService.getConfiguration().getHibernateDialect(), allOrgCreated.size(), allUsersCreated.size(), closureSize, "AddRemoveUsers", level, true, getNetDuration());

checkClosure(getVertices());

totalTimeNodeAdditions += getNetDuration();
totalRounds++;
}
}

if (totalRounds > 0) {
System.out.println("Avg time for an arbitrary user removal: " + ((double) totalTimeNodeRemovals / totalRounds) + " ms");
System.out.println("Avg time for an arbitrary user re-addition: " + ((double) totalTimeNodeAdditions / totalRounds) + " ms");
LOGGER.info("===================================================");
LOGGER.info("Statistics for user node removal/addition:");
stat.dump(LOGGER, repositoryService.getConfiguration().getHibernateDialect(), allOrgCreated.size(), allUsersCreated.size(), closureSize, "AddRemoveUsers");
}
}

protected void _test390CyclePrevention() throws Exception {
OperationResult opResult = new OperationResult("===[ test390CyclePrevention ]===");
String childOid = orgsByLevels.get(1).get(0); // we hope it exists
Expand Down
Expand Up @@ -69,7 +69,6 @@ public OrgClosureConcurrencyTest() {
configuration.setParentsInLevel(PARENTS_IN_LEVEL);
configuration.setLinkRoundsForLevel(LINK_ROUNDS_FOR_LEVELS);
configuration.setNodeRoundsForLevel(NODE_ROUNDS_FOR_LEVELS);
configuration.setUserRoundsForLevel(USER_ROUNDS_FOR_LEVELS);
}

@Override
Expand Down Expand Up @@ -294,11 +293,6 @@ protected void _test300AddRemoveNodesMT(final boolean random) throws Exception {
List<String> levelOids = orgsByLevels.get(level);
generateNodesAtOneLevel(nodesToRemove, nodesToAdd, OrgType.class, rounds, levelOids, opResult);
}
for (int level = 0; level < getConfiguration().getUserRoundsForLevel().length; level++) {
int rounds = getConfiguration().getUserRoundsForLevel()[level];
List<String> levelOids = usersByLevels.get(level);
generateNodesAtOneLevel(nodesToRemove, nodesToAdd, UserType.class, rounds, levelOids, opResult);
}

int numberOfRunners = 3;
final List<Thread> runners = Collections.synchronizedList(new ArrayList<Thread>());
Expand Down Expand Up @@ -435,14 +429,18 @@ private void generateNodesAtOneLevel(Set<ObjectType> nodesToRemove, Set<ObjectTy
void removeObject(ObjectType objectType) throws Exception {
repositoryService.deleteObject(objectType.getClass(), objectType.getOid(), new OperationResult("dummy"));
synchronized(orgGraph) {
orgGraph.removeVertex(objectType.getOid());
if (objectType instanceof OrgType) {
orgGraph.removeVertex(objectType.getOid());
}
}
}

void addObject(ObjectType objectType) throws Exception {
repositoryService.addObject(objectType.asPrismObject(), null, new OperationResult("dummy"));
synchronized(orgGraph) {
registerObject(objectType, true);
if (objectType instanceof OrgType) {
registerObject(objectType, true);
}
}
}

Expand Down
Expand Up @@ -27,12 +27,11 @@
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class OrgClosureCorrectnessTest extends AbstractOrgClosureTest {

private static final int[] ORG_CHILDREN_IN_LEVEL = { 1, 2, 3, 0 };
private static final int[] USER_CHILDREN_IN_LEVEL = { 0, 1, 2, 3 };
private static final int[] PARENTS_IN_LEVEL = { 0, 2, 2, 3 };
private static final int[] LINK_ROUNDS_FOR_LEVELS = { 0, 5, 10 };
private static final int[] NODE_ROUNDS_FOR_LEVELS = { 1, 5, 10 };
private static final int[] USER_ROUNDS_FOR_LEVELS = { 0, 5 ,5, 10 };
private static final int[] ORG_CHILDREN_IN_LEVEL = { 1, 2, 3 };
private static final int[] USER_CHILDREN_IN_LEVEL = null;
private static final int[] PARENTS_IN_LEVEL = { 0, 2, 2 };
private static final int[] LINK_ROUNDS_FOR_LEVELS = { 0, 5, 10 };
private static final int[] NODE_ROUNDS_FOR_LEVELS = { 1, 5, 10 };

// trivial case for debugging
// private static final int[] ORG_CHILDREN_IN_LEVEL = { 1, 2, 0 };
Expand All @@ -54,14 +53,12 @@ public OrgClosureCorrectnessTest() {
configuration.setParentsInLevel(PARENTS_IN_LEVEL);
configuration.setLinkRoundsForLevel(LINK_ROUNDS_FOR_LEVELS);
configuration.setNodeRoundsForLevel(NODE_ROUNDS_FOR_LEVELS);
configuration.setUserRoundsForLevel(USER_ROUNDS_FOR_LEVELS);
}

@Test(enabled = true) public void test100LoadOrgStructure() throws Exception { _test100LoadOrgStructure(); }
@Test(enabled = true) public void test150CheckClosure() throws Exception { _test150CheckClosure(); }
@Test(enabled = true) public void test200AddRemoveLinks() throws Exception { _test200AddRemoveLinks(); }
@Test(enabled = true) public void test300AddRemoveOrgs() throws Exception { _test300AddRemoveOrgs(); }
@Test(enabled = true) public void test310AddRemoveUsers() throws Exception { _test310AddRemoveUsers(); }
@Test(enabled = true) public void test390CyclePrevention() throws Exception { _test390CyclePrevention(); }
@Test(enabled = true) public void test410RandomUnloadOrgStructure() throws Exception { _test410RandomUnloadOrgStructure(); }

Expand Down
Expand Up @@ -43,14 +43,12 @@ public OrgClosurePerformanceTest1() {
configuration.setParentsInLevel(PARENTS_IN_LEVEL);
configuration.setLinkRoundsForLevel(LINK_ROUNDS_FOR_LEVELS);
configuration.setNodeRoundsForLevel(NODE_ROUNDS_FOR_LEVELS);
configuration.setUserRoundsForLevel(USER_ROUNDS_FOR_LEVELS);
}

@Test(enabled = true) public void test100LoadOrgStructure() throws Exception { _test100LoadOrgStructure(); }
@Test(enabled = true) public void test150CheckClosure() throws Exception { _test150CheckClosure(); }
@Test(enabled = true) public void test200AddRemoveLinks() throws Exception { _test200AddRemoveLinks(); }
@Test(enabled = true) public void test300AddRemoveOrgs() throws Exception { _test300AddRemoveOrgs(); }
@Test(enabled = true) public void test310AddRemoveUsers() throws Exception { _test310AddRemoveUsers(); }
@Test(enabled = true) public void test410RandomUnloadOrgStructure() throws Exception { _test410RandomUnloadOrgStructure(); }

@Override
Expand Down
Expand Up @@ -43,14 +43,12 @@ public OrgClosurePerformanceTest2() {
configuration.setParentsInLevel(PARENTS_IN_LEVEL);
configuration.setLinkRoundsForLevel(LINK_ROUNDS_FOR_LEVELS);
configuration.setNodeRoundsForLevel(NODE_ROUNDS_FOR_LEVELS);
configuration.setUserRoundsForLevel(USER_ROUNDS_FOR_LEVELS);
}

@Test(enabled = true) public void test100LoadOrgStructure() throws Exception { _test100LoadOrgStructure(); }
@Test(enabled = true) public void test150CheckClosure() throws Exception { _test150CheckClosure(); }
@Test(enabled = true) public void test200AddRemoveLinks() throws Exception { _test200AddRemoveLinks(); }
@Test(enabled = true) public void test300AddRemoveOrgs() throws Exception { _test300AddRemoveOrgs(); }
@Test(enabled = true) public void test310AddRemoveUsers() throws Exception { _test310AddRemoveUsers(); }
@Test(enabled = true) public void test410RandomUnloadOrgStructure() throws Exception { _test410RandomUnloadOrgStructure(); }

@Override
Expand Down
Expand Up @@ -47,9 +47,6 @@ public class OrgClosureTestConfiguration {
// how many times should be add/remove node test be carried out for a given level
private int[] nodeRoundsForLevel;

// how many times should be add/remove user test be carried out for a given level
private int[] userRoundsForLevel;

// each (what number) of deletions in test410 should be the closure tested
private int deletionsToClosureTest;

Expand Down Expand Up @@ -109,14 +106,6 @@ public void setNodeRoundsForLevel(int[] nodeRoundsForLevel) {
this.nodeRoundsForLevel = nodeRoundsForLevel;
}

public int[] getUserRoundsForLevel() {
return userRoundsForLevel;
}

public void setUserRoundsForLevel(int[] userRoundsForLevel) {
this.userRoundsForLevel = userRoundsForLevel;
}

public int getDeletionsToClosureTest() {
return deletionsToClosureTest;
}
Expand Down

0 comments on commit b648b10

Please sign in to comment.