Versioning, workspaces and clone/merge functionality
vasilievip Jun 3, 2013 7:18 AMHello,
I have some issue with merging versioned nodes between workspaces. I have use-case when there is 3 types of data "PRODUCTION", "QA" and "USER".
- Production version of data available for access via API for external usage
- QA version of data created by software for users/admins to review and merge (approve) into production
- And last type - when user wants to change QA version of data and then merge into production
The issue I have is that node properties/nodes is not merged via VersionManager.merge/Version.update/VersionManager.doneMerge.
Few doubt I have on this:
- Am I doing something wrong?
- I cant find code which merges properties. Is this not supported?
- What needs to be done to merge properties/nodes properly?
Please advise,
Thank you in advance
P.S.:
1. Same question to jackrabbit users: http://jackrabbit.510166.n4.nabble.com/Versioning-workspaces-and-clone-merge-functionality-td4658803.html
2. Code I have:
{code:java}
@Test
public void testProdQaUserVersions() throws Exception {
//Session to production version of data
Session session_prod = repository.login("PROD");
Node records_prod = session_prod.getRootNode().addNode("records");
records_prod.addMixin("mix:versionable");
records_prod.addNode("record").addMixin("mix:versionable");
records_prod.addNode("record").addMixin("mix:versionable");
records_prod.getSession().save();
printHistory("prod initially", session_prod, "/records/record");
//Create QA version of data
//prod_session.getWorkspace().createWorkspace("QA", "PROD");
Session session_qa = repository.login("QA");
session_qa.getWorkspace().clone("PROD", "/records", "/records", false);
VersionManager versionManagerProd = session_prod.getWorkspace().getVersionManager();
VersionManager versionManagerQa = session_qa.getWorkspace().getVersionManager();
//Change QA nodes first time
versionManagerQa.checkout("/records/record");
session_qa.getNode("/records/record").setProperty("111", "111");
session_qa.save();
versionManagerQa.checkin("/records/record");
//Change cloned node second time
versionManagerQa.checkout("/records/record");
session_qa.getNode("/records/record").setProperty("222", "222");
session_qa.save();
versionManagerQa.checkin("/records/record");
session_qa.getNode("/records").addNode("record").addMixin("mix:versionable");
session_qa.getNode("/records").addNode("record").addMixin("mix:versionable");
session_qa.save();
//Check source node
assertFalse(session_prod.getNode("/records/record").hasProperty("222"));
assertFalse(session_prod.getNode("/records/record").hasProperty("111"));
//Check QA node
assertTrue(session_qa.getNode("/records/record").hasProperty("111"));
assertTrue(session_qa.getNode("/records/record").hasProperty("222"));
assertEquals("111", session_qa.getNode("/records/record").getProperty("111").getString());
assertEquals("222", session_qa.getNode("/records/record").getProperty("222").getString());
assertTrue(session_qa.nodeExists("/records/record[4]"));
printHistory("qa changes", session_qa, "/records/record");
printHistory("prod before merge", session_prod, "/records/record");
//Merge clone into source
//versionManagerProd.checkout("/records");
NodeIterator iter = versionManagerProd.merge("/records", session_qa.getWorkspace().getName(), true);
while (iter.hasNext()) {
Node node = iter.nextNode();
Version v = (Version) session_prod.getNodeByIdentifier(node.getProperty("jcr:mergeFailed").getValues()[0].getString());
//what needs to be done here??
//v.update(prod_session.getWorkspace().getName());
versionManagerProd.doneMerge("/records", v);
}
//versionManagerProd.checkin("/records");
printHistory("prod after merge", session_prod, "/records/record");
assertTrue(session_prod.nodeExists("/records/record[4]"));
assertTrue(session_prod.getNode("/records/record").hasProperty("111"));
assertTrue(session_prod.getNode("/records/record").hasProperty("222"));
assertEquals("111", session_prod.getNode("/records/record").getProperty("111").getString());
assertEquals("222", session_prod.getNode("/records/record").getProperty("222").getString());
}
private void printHistory(String comment, Session session, String path) {
System.out.println(comment);
VersionHistory history = null;
try {
history = session.getWorkspace().getVersionManager().getVersionHistory(path);
VersionIterator versions = history.getAllVersions();
while (versions.hasNext()) {
Version version = versions.nextVersion();
System.out.println(version);
}
} catch (RepositoryException e) {
e.printStackTrace();
}
}
{code}
And the output I see
{code}
prod initially
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/jcr:rootVersion {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.486+03:00, jcr:uuid=56127295-7e09-4ad0-b591-b68184969b33}
qa changes
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/jcr:rootVersion {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.486+03:00, jcr:uuid=56127295-7e09-4ad0-b591-b68184969b33, jcr:successors=[7e8b541317f1e7056bcc65-fee4-4245-8ca7-ada6f95c5d42]}
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/1.0 {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.663+03:00, jcr:predecessors=[7e8b541317f1e756127295-7e09-4ad0-b591-b68184969b33], jcr:uuid=056bcc65-fee4-4245-8ca7-ada6f95c5d42, jcr:successors=[7e8b541317f1e765cb3758-826a-4639-bf33-6cc8f3d97ace]}
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/1.1 {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.742+03:00, jcr:predecessors=[7e8b541317f1e7056bcc65-fee4-4245-8ca7-ada6f95c5d42], jcr:uuid=65cb3758-826a-4639-bf33-6cc8f3d97ace}
prod before merge
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/jcr:rootVersion {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.486+03:00, jcr:uuid=56127295-7e09-4ad0-b591-b68184969b33, jcr:successors=[7e8b541317f1e7056bcc65-fee4-4245-8ca7-ada6f95c5d42]}
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/1.0 {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.663+03:00, jcr:predecessors=[7e8b541317f1e756127295-7e09-4ad0-b591-b68184969b33], jcr:uuid=056bcc65-fee4-4245-8ca7-ada6f95c5d42, jcr:successors=[7e8b541317f1e765cb3758-826a-4639-bf33-6cc8f3d97ace]}
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/1.1 {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.742+03:00, jcr:predecessors=[7e8b541317f1e7056bcc65-fee4-4245-8ca7-ada6f95c5d42], jcr:uuid=65cb3758-826a-4639-bf33-6cc8f3d97ace}
prod after merge
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/jcr:rootVersion {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.486+03:00, jcr:uuid=56127295-7e09-4ad0-b591-b68184969b33, jcr:successors=[7e8b541317f1e7056bcc65-fee4-4245-8ca7-ada6f95c5d42]}
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/1.0 {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.663+03:00, jcr:predecessors=[7e8b541317f1e756127295-7e09-4ad0-b591-b68184969b33], jcr:uuid=056bcc65-fee4-4245-8ca7-ada6f95c5d42, jcr:successors=[7e8b541317f1e765cb3758-826a-4639-bf33-6cc8f3d97ace]}
/jcr:system/jcr:versionStorage/bf/7b/b8/bf7bb857096cddad7236e2635944c412e176a79f/1.1 {jcr:primaryType=nt:version, jcr:created=2013-05-31T22:43:58.742+03:00, jcr:predecessors=[7e8b541317f1e7056bcc65-fee4-4245-8ca7-ada6f95c5d42], jcr:uuid=65cb3758-826a-4639-bf33-6cc8f3d97ace}
{code}
Same code on jackrabbit has same results, however when switched to mix:simpleVersionable - test case passes, but there is missing history for /records/record:
{code}
prod initially
version node /jcr:system/jcr:versionStorage/bb/2d/48/bb2d486a-4dff-4152-bca1-021c2b682dfd/jcr:rootVersion
qa changes
version node /jcr:system/jcr:versionStorage/be/4b/51/be4b51c8-8150-489b-9306-40a4cf1667ec/jcr:rootVersion
version node /jcr:system/jcr:versionStorage/be/4b/51/be4b51c8-8150-489b-9306-40a4cf1667ec/1.0
version node /jcr:system/jcr:versionStorage/be/4b/51/be4b51c8-8150-489b-9306-40a4cf1667ec/1.1
prod before merge
version node /jcr:system/jcr:versionStorage/bb/2d/48/bb2d486a-4dff-4152-bca1-021c2b682dfd/jcr:rootVersion
prod after merge
version node /jcr:system/jcr:versionStorage/bb/2d/48/bb2d486a-4dff-4152-bca1-021c2b682dfd/jcr:rootVersion
{code}