0 Replies Latest reply on Jun 3, 2013 7:18 AM by vasilievip

    Versioning, workspaces and clone/merge functionality

    vasilievip

      Hello,

       

      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}