You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2015/05/13 16:29:49 UTC

svn commit: r1679218 - in /jackrabbit/oak/trunk/oak-upgrade/src: main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java

Author: thomasm
Date: Wed May 13 14:29:49 2015
New Revision: 1679218

URL: http://svn.apache.org/r1679218
Log:
OAK-2869 RepositorySidegrade: AsyncIndexUpdate throws a IllegalArgumentException after migrating from segment to document store

Added:
    jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java
Modified:
    jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java

Modified: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java?rev=1679218&r1=1679217&r2=1679218&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java (original)
+++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java Wed May 13 14:29:49 2015
@@ -91,6 +91,10 @@ public class RepositorySidegrade {
 
             copyState(builder, root);
 
+            // removing references to the checkpoints, 
+            // which don't exist in the new repository
+            builder.setChildNode(":async");
+
             target.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
         } catch (Exception e) {
             throw new RepositoryException("Failed to copy content", e);

Added: jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java?rev=1679218&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java (added)
+++ jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java Wed May 13 14:29:49 2015
@@ -0,0 +1,476 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Random;
+import javax.jcr.Binary;
+import javax.jcr.Credentials;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.NodeTypeTemplate;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.nodetype.PropertyDefinitionTemplate;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionManager;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.JackrabbitWorkspace;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.jcr.Jcr;
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static org.apache.jackrabbit.JcrConstants.JCR_FROZENMIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_FROZENPRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.JCR_FROZENUUID;
+import static org.apache.jackrabbit.JcrConstants.JCR_UUID;
+import static org.apache.jackrabbit.JcrConstants.MIX_VERSIONABLE;
+import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
+
+public class RepositorySidegradeTest {
+
+    private static final Calendar DATE = Calendar.getInstance();
+
+    private static final byte[] BINARY = new byte[64 * 1024];
+
+    static {
+        new Random().nextBytes(BINARY);
+    }
+    
+    protected static final Credentials CREDENTIALS = new SimpleCredentials("admin", "admin".toCharArray());
+
+    private NodeStore targetNodeStore;
+    private static Repository targetRepository;
+
+    
+    @BeforeClass
+    public static void init() {
+        // ensure that we create a new repository for the next test
+        targetRepository = null;
+    }
+
+    @Before
+    public synchronized void upgradeRepository() throws Exception {
+        if (targetRepository == null) {
+            targetNodeStore = new SegmentNodeStore();
+            targetRepository = new Jcr(new Oak(targetNodeStore)).createRepository();
+            NodeStore source = createSourceContent();
+            RepositorySidegrade sidegrade = new RepositorySidegrade(source, targetNodeStore);
+            sidegrade.copy();
+        }
+    }
+    
+    public Repository getTargetRepository() {
+        return targetRepository;
+    }
+    
+    public JackrabbitSession createAdminSession() throws RepositoryException {
+        return (JackrabbitSession) getTargetRepository().login(CREDENTIALS);
+    }
+    
+    // OAK-2869
+    private static void setAsync(NodeStore source) throws Exception {
+        NodeBuilder builder = source.getRoot().builder();
+        builder.child(":async").setProperty("test", "123");
+        source.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+    }
+    
+    // OAK-2869
+    @Test    
+    public void verifyAsync() throws Exception {
+        NodeState state = targetNodeStore.getRoot().getChildNode(":async");
+        assertFalse(state.hasProperty("test"));
+    }
+
+    @SuppressWarnings("unchecked")
+    protected NodeStore createSourceContent() throws Exception {
+        NodeStore source = new SegmentNodeStore();
+        setAsync(source);
+        
+        Repository repository = new Jcr(new Oak(source)).createRepository();
+
+        Session session = repository.login(CREDENTIALS);
+        try {
+            JackrabbitWorkspace workspace =
+                    (JackrabbitWorkspace) session.getWorkspace();
+
+            NamespaceRegistry registry = workspace.getNamespaceRegistry();
+            registry.registerNamespace("test", "http://www.example.org/");
+
+            NodeTypeManager nodeTypeManager = workspace.getNodeTypeManager();
+            NodeTypeTemplate template = nodeTypeManager.createNodeTypeTemplate();
+            template.setName("test:unstructured");
+            template.setDeclaredSuperTypeNames(
+                    new String[] {"nt:unstructured"});
+            PropertyDefinitionTemplate pDef1 = nodeTypeManager.createPropertyDefinitionTemplate();
+            pDef1.setName("defaultString");
+            pDef1.setRequiredType(PropertyType.STRING);
+            Value stringValue = session.getValueFactory().createValue("stringValue");
+            pDef1.setDefaultValues(new Value[] {stringValue});
+            template.getPropertyDefinitionTemplates().add(pDef1);
+
+            PropertyDefinitionTemplate pDef2 = nodeTypeManager.createPropertyDefinitionTemplate();
+            pDef2.setName("defaultPath");
+            pDef2.setRequiredType(PropertyType.PATH);
+            Value pathValue = session.getValueFactory().createValue("/jcr:path/nt:value", PropertyType.PATH);
+            pDef2.setDefaultValues(new Value[] {pathValue});
+            template.getPropertyDefinitionTemplates().add(pDef2);
+
+            nodeTypeManager.registerNodeType(template, false);
+
+            template = nodeTypeManager.createNodeTypeTemplate();
+            template.setName("test:referenceable");
+            template.setDeclaredSuperTypeNames(
+                    new String[] {"nt:unstructured", "mix:referenceable"});
+            nodeTypeManager.registerNodeType(template, false);
+
+            Node root = session.getRootNode();
+
+            Node referenceable =
+                root.addNode("referenceable", "test:unstructured");
+            referenceable.addMixin(NodeType.MIX_REFERENCEABLE);
+            Node versionable = root.addNode("versionable", NT_UNSTRUCTURED);
+            versionable.addMixin(MIX_VERSIONABLE);
+            Node child = versionable.addNode("child", "test:referenceable");
+            child.addNode("child2", NT_UNSTRUCTURED);
+            session.save();
+
+            session.getWorkspace().getVersionManager().checkin("/versionable");
+
+            Node properties = root.addNode("properties", "test:unstructured");
+            properties.setProperty("boolean", true);
+            Binary binary = session.getValueFactory().createBinary(
+                    new ByteArrayInputStream(BINARY));
+            try {
+                properties.setProperty("binary", binary);
+            } finally {
+                binary.dispose();
+            }
+            properties.setProperty("date", DATE);
+            properties.setProperty("decimal", new BigDecimal(123));
+            properties.setProperty("double", Math.PI);
+            properties.setProperty("long", 9876543210L);
+            properties.setProperty("reference", referenceable);
+            properties.setProperty("weak_reference", session.getValueFactory().createValue(referenceable, true));
+            properties.setProperty("mv_reference", new Value[]{session.getValueFactory().createValue(versionable, false)});
+            properties.setProperty("mv_weak_reference", new Value[]{session.getValueFactory().createValue(versionable, true)});
+            properties.setProperty("string", "test");
+            properties.setProperty("multiple", "a,b,c".split(","));
+            session.save();
+
+            binary = properties.getProperty("binary").getBinary();
+            try {
+                InputStream stream = binary.getStream();
+                try {
+                    for (byte aBINARY : BINARY) {
+                        assertEquals(aBINARY, (byte) stream.read());
+                    }
+                    assertEquals(-1, stream.read());
+                } finally {
+                    stream.close();
+                }
+            } finally {
+                binary.dispose();
+            }
+            return source;
+        } finally {
+            session.logout();
+        }
+    }
+
+    @Test
+    public void verifyNameSpaces() throws Exception {
+        Session session = createAdminSession();
+        try {
+            assertEquals(
+                    "http://www.example.org/",
+                    session.getNamespaceURI("test"));
+        } finally {
+            session.logout();
+        }
+    }
+
+    @Test
+    public void verifyCustomNodeTypes() throws Exception {
+        Session session = createAdminSession();
+        try {
+            NodeTypeManager manager = session.getWorkspace().getNodeTypeManager();
+            assertTrue(manager.hasNodeType("test:unstructured"));
+
+            NodeType type = manager.getNodeType("test:unstructured");
+            assertFalse(type.isMixin());
+            assertTrue(type.isNodeType("nt:unstructured"));
+            boolean foundDefaultString = false;
+            boolean foundDefaultPath = false;
+            for (PropertyDefinition pDef : type.getPropertyDefinitions()) {
+                if ("defaultString".equals(pDef.getName())) {
+                    assertEquals(PropertyType.STRING, pDef.getRequiredType());
+                    assertNotNull(pDef.getDefaultValues());
+                    assertEquals(1, pDef.getDefaultValues().length);
+                    assertEquals("stringValue", pDef.getDefaultValues()[0].getString());
+                    foundDefaultString = true;
+                } else if ("defaultPath".equals(pDef.getName())) {
+                    assertEquals(PropertyType.PATH, pDef.getRequiredType());
+                    assertNotNull(pDef.getDefaultValues());
+                    assertEquals(1, pDef.getDefaultValues().length);
+                    assertEquals("/jcr:path/nt:value", pDef.getDefaultValues()[0].getString());
+                    foundDefaultPath = true;
+                }
+            }
+            assertTrue("Expected property definition with name \"defaultString\"", foundDefaultString);
+            assertTrue("Expected property definition with name \"defaultPath\"", foundDefaultPath);
+        } finally {
+            session.logout();
+        }
+    }
+
+    @Test
+    public void verifyNewBuiltinNodeTypes() throws Exception {
+        Session session = createAdminSession();
+        try {
+            NodeTypeManager manager = session.getWorkspace().getNodeTypeManager();
+            assertTrue(manager.hasNodeType(UserConstants.NT_REP_MEMBER_REFERENCES));
+            assertTrue(manager.hasNodeType(IndexConstants.INDEX_DEFINITIONS_NODE_TYPE));
+        } finally {
+            session.logout();
+        }
+    }
+
+    @Test
+    public void verifyReplacedBuiltinNodeTypes() throws Exception {
+        Session session = createAdminSession();
+        try {
+            NodeTypeManager manager = session.getWorkspace().getNodeTypeManager();
+            NodeType nt = manager.getNodeType(UserConstants.NT_REP_GROUP);
+            assertTrue("Migrated repository must have new nodetype definitions", nt.isNodeType(UserConstants.NT_REP_MEMBER_REFERENCES));
+        } finally {
+            session.logout();
+        }
+    }
+
+    @Test
+    public void verifyGenericProperties() throws Exception {
+        Session session = createAdminSession();
+        try {
+            assertTrue(session.nodeExists("/properties"));
+            Node properties = session.getNode("/properties");
+            assertEquals(
+                    PropertyType.BOOLEAN,
+                    properties.getProperty("boolean").getType());
+            assertEquals(
+                    true, properties.getProperty("boolean").getBoolean());
+            assertEquals(
+                    PropertyType.BINARY,
+                    properties.getProperty("binary").getType());
+            Binary binary = properties.getProperty("binary").getBinary();
+            try {
+                InputStream stream = binary.getStream();
+                try {
+                    for (byte aBINARY : BINARY) {
+                        assertEquals(aBINARY, (byte) stream.read());
+                    }
+                    assertEquals(-1, stream.read());
+                } finally {
+                    stream.close();
+                }
+            } finally {
+                binary.dispose();
+            }
+            assertEquals(
+                    PropertyType.DATE,
+                    properties.getProperty("date").getType());
+            assertEquals(
+                    DATE.getTimeInMillis(),
+                    properties.getProperty("date").getDate().getTimeInMillis());
+            assertEquals(
+                    PropertyType.DECIMAL,
+                    properties.getProperty("decimal").getType());
+            assertEquals(
+                    new BigDecimal(123),
+                    properties.getProperty("decimal").getDecimal());
+            assertEquals(
+                    PropertyType.DOUBLE,
+                    properties.getProperty("double").getType());
+            assertEquals(
+                    Math.PI, properties.getProperty("double").getDouble());
+            assertEquals(
+                    PropertyType.LONG,
+                    properties.getProperty("long").getType());
+            assertEquals(
+                    9876543210L, properties.getProperty("long").getLong());
+            assertEquals(
+                    PropertyType.STRING,
+                    properties.getProperty("string").getType());
+            assertEquals(
+                    "test", properties.getProperty("string").getString());
+            assertEquals(
+                    PropertyType.STRING,
+                    properties.getProperty("multiple").getType());
+            Value[] values = properties.getProperty("multiple").getValues();
+            assertEquals(3, values.length);
+            assertEquals("a", values[0].getString());
+            assertEquals("b", values[1].getString());
+            assertEquals("c", values[2].getString());
+        } finally {
+            session.logout();
+        }
+    }
+
+    @Test
+    public void verifyReferencePropertiesContent() throws Exception {
+        Session session = createAdminSession();
+        try {
+            assertTrue(session.nodeExists("/referenceable"));
+            String testNodeIdentifier =
+                    session.getNode("/referenceable").getIdentifier();
+
+            assertTrue(session.nodeExists("/properties"));
+            Node properties = session.getNode("/properties");
+
+            assertEquals(
+                    PropertyType.REFERENCE,
+                    properties.getProperty("reference").getType());
+            assertEquals(
+                    testNodeIdentifier,
+                    properties.getProperty("reference").getString());
+            assertEquals(
+                    "/referenceable",
+                    properties.getProperty("reference").getNode().getPath());
+            PropertyIterator refs = session.getNode("/referenceable").getReferences();
+            assertTrue(refs.hasNext());
+            assertEquals(properties.getPath() + "/reference", refs.nextProperty().getPath());
+            assertFalse(refs.hasNext());
+
+            PropertyIterator refs2 = session.getNode("/versionable").getReferences();
+            assertTrue(refs2.hasNext());
+            assertEquals(properties.getPath() + "/mv_reference", refs2.nextProperty().getPath());
+            assertFalse(refs2.hasNext());
+
+            assertEquals(
+                    PropertyType.WEAKREFERENCE,
+                    properties.getProperty("weak_reference").getType());
+            assertEquals(
+                    testNodeIdentifier,
+                    properties.getProperty("weak_reference").getString());
+            assertEquals(
+                    "/referenceable",
+                    properties.getProperty("weak_reference").getNode().getPath());
+            PropertyIterator weakRefs = session.getNode("/referenceable").getWeakReferences();
+            assertTrue(weakRefs.hasNext());
+            assertEquals(properties.getPath() + "/weak_reference", weakRefs.nextProperty().getPath());
+            assertFalse(weakRefs.hasNext());
+            PropertyIterator weakRefs2 = session.getNode("/versionable").getWeakReferences();
+            assertTrue(weakRefs2.hasNext());
+            assertEquals(properties.getPath() + "/mv_weak_reference", weakRefs2.nextProperty().getPath());
+            assertFalse(weakRefs2.hasNext());
+        } finally {
+            session.logout();
+        }
+    }
+
+    @Test
+    public void verifyVersionHistory() throws RepositoryException {
+        Session session = createAdminSession();
+        try {
+            assertTrue(session.nodeExists("/versionable"));
+            Node versionable = session.getNode("/versionable");
+            assertTrue(versionable.hasNode("child"));
+            Node child = versionable.getNode("child");
+            assertTrue(child.hasNode("child2"));
+            Node child2 = child.getNode("child2");
+
+            assertFalse(versionable.isCheckedOut());
+            assertTrue(versionable.hasProperty(JCR_UUID));
+            assertFalse(child.isCheckedOut());
+            assertTrue(child.hasProperty(JCR_UUID));
+            assertFalse(child2.isCheckedOut());
+            assertFalse(child2.hasProperty(JCR_UUID));
+
+            VersionManager manager = session.getWorkspace().getVersionManager();
+            Version version = manager.getBaseVersion("/versionable");
+
+            Node frozen = version.getFrozenNode();
+            assertEquals(
+                    versionable.getPrimaryNodeType().getName(),
+                    frozen.getProperty(JCR_FROZENPRIMARYTYPE).getString());
+            assertEquals(
+                    versionable.getMixinNodeTypes()[0].getName(),
+                    frozen.getProperty(JCR_FROZENMIXINTYPES).getValues()[0].getString());
+            assertEquals(
+                    versionable.getIdentifier(),
+                    frozen.getProperty(JCR_FROZENUUID).getString());
+
+            Node frozenChild = frozen.getNode("child");
+            assertEquals(
+                    child.getPrimaryNodeType().getName(),
+                    frozenChild.getProperty(JCR_FROZENPRIMARYTYPE).getString());
+            assertFalse(frozenChild.hasProperty(JCR_FROZENMIXINTYPES));
+            assertEquals(
+                    "OAK-1789",
+                    child.getIdentifier(),
+                    frozenChild.getProperty(JCR_FROZENUUID).getString());
+
+            Node frozenChild2 = frozenChild.getNode("child2");
+            assertEquals(
+                    child2.getPrimaryNodeType().getName(),
+                    frozenChild2.getProperty(JCR_FROZENPRIMARYTYPE).getString());
+            assertFalse(frozenChild2.hasProperty(JCR_FROZENMIXINTYPES));
+            assertEquals(
+                    "OAK-1789",
+                    child2.getIdentifier(),
+                    frozenChild2.getProperty(JCR_FROZENUUID).getString());
+
+            VersionHistory history = manager.getVersionHistory("/versionable");
+            assertTrue(history.isNodeType("rep:VersionablePaths"));
+            Property versionablePath = history.getProperty("default");
+            assertEquals("/versionable", versionablePath.getString());
+        } finally {
+            session.logout();
+        }
+    }
+
+}