Author: tomekr
Date: Mon Sep 18 07:49:39 2017
New Revision: 1808672

URL: http://svn.apache.org/viewvc?rev=1808672&view=rev
Log:
OAK-6638: Add a composite-prepare command in oak-run

Added:
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompositePrepareCommand.java
Modified:
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java
    jackrabbit/oak/trunk/oak-run/src/main/resources/logback.xml

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java?rev=1808672&r1=1808671&r2=1808672&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java
 Mon Sep 18 07:49:39 2017
@@ -34,6 +34,7 @@ public final class AvailableModes {
             .put("check", new CheckCommand())
             .put("datastorecacheupgrade", new DataStoreCacheUpgradeCommand())
             .put("compact", new CompactCommand())
+            .put("composite-prepare", new CompositePrepareCommand())
             .put("console", new ConsoleCommand())
             .put("datastorecheck", new DataStoreCheckCommand())
             .put("debug", new DebugCommand())

Added: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompositePrepareCommand.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompositePrepareCommand.java?rev=1808672&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompositePrepareCommand.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/CompositePrepareCommand.java
 Mon Sep 18 07:49:39 2017
@@ -0,0 +1,149 @@
+/*
+ * 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.run;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.run.commons.Command;
+import org.apache.jackrabbit.oak.segment.SegmentNodeBuilder;
+import org.apache.jackrabbit.oak.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.apache.jackrabbit.JcrConstants.JCR_UUID;
+
+public class CompositePrepareCommand implements Command {
+
+    @Override
+    public void execute(String... args) throws Exception {
+        OptionParser parser = new OptionParser();
+
+        OptionSpec<?> help = parser
+                .acceptsAll(asList("h", "?", "help"), "show help")
+                .forHelp();
+        OptionSpec<String> paths = parser.accepts("paths", "a list of paths to 
transform from nt:resource to oak:Resource")
+                .withRequiredArg()
+                .ofType(String.class)
+                .withValuesSeparatedBy(',')
+                .defaultsTo("/apps", "/libs");
+        OptionSpec<File> storeO = parser.nonOptions("path to segment store 
(required)")
+                .ofType(File.class);
+        OptionSet options = parser.parse(args);
+
+        if (options.has(help)) {
+            parser.printHelpOn(System.out);
+            System.exit(0);
+        }
+
+        File store = storeO.value(options);
+
+        if (store == null) {
+            parser.printHelpOn(System.out);
+            System.exit(1);
+        }
+
+        FileStoreBuilder builder = FileStoreBuilder.fileStoreBuilder(store);
+        FileStore fs = builder.build();
+        try {
+            new OakResourceTransformer(fs, paths.values(options)).transform();
+        } finally {
+            fs.close();
+        }
+    }
+
+    public static class OakResourceTransformer {
+
+        private static final Logger LOG = 
LoggerFactory.getLogger(CompositePrepareCommand.class);
+
+        private final FileStore fileStore;
+
+        private final List<String> paths;
+
+        private int totalNodes;
+
+        private int modifiedNodes;
+
+        public OakResourceTransformer(FileStore fileStore, List<String> paths) 
{
+            this.paths = paths;
+            this.fileStore = fileStore;
+        }
+
+        public void transform() throws InterruptedException, IOException {
+            SegmentNodeState headNodeState = fileStore.getHead();
+            SegmentNodeBuilder superRootBuilder = headNodeState.builder();
+            for (String cp : 
superRootBuilder.getChildNode("checkpoints").getChildNodeNames()) {
+                LOG.info("Transforming checkpoint {}", cp);
+                NodeBuilder cpRoot = 
superRootBuilder.getChildNode("checkpoints").getChildNode(cp).getChildNode("root");
+                transformRootBuilder(cpRoot);
+            }
+            LOG.info("Transforming root");
+            transformRootBuilder(superRootBuilder.getChildNode("root"));
+            fileStore.getRevisions().setHead(headNodeState.getRecordId(), 
superRootBuilder.getNodeState().getRecordId());
+            fileStore.flush();
+        }
+
+        private void transformRootBuilder(NodeBuilder rootBuilder) {
+            for (String p : paths) {
+                NodeBuilder builder = rootBuilder;
+                for (String e : PathUtils.elements(p)) {
+                    builder = builder.getChildNode(e);
+                }
+                if (builder.exists()) {
+                    totalNodes = modifiedNodes = 0;
+                    LOG.info("  path: {}", p);
+                    NodeBuilder indexData = rootBuilder
+                            .child(IndexConstants.INDEX_DEFINITIONS_NAME)
+                            .child("uuid")
+                            .child(IndexConstants.INDEX_CONTENT_NODE_NAME);
+                    transformBuilder(builder, indexData);
+                    LOG.info("    all nodes: {}, updated nodes: {}", 
totalNodes, modifiedNodes);
+                }
+            }
+        }
+
+        private void transformBuilder(NodeBuilder builder, NodeBuilder 
uuidIndexData) {
+            String type = builder.getName(NodeTypeConstants.JCR_PRIMARYTYPE);
+            if (NodeTypeConstants.NT_RESOURCE.equals(type)) {
+                String index = builder.getString(JCR_UUID);
+                uuidIndexData.getChildNode(index).remove();
+
+                builder.setProperty(NodeTypeConstants.JCR_PRIMARYTYPE, 
NodeTypeConstants.NT_OAK_RESOURCE, Type.NAME);
+                builder.removeProperty(JCR_UUID);
+
+                modifiedNodes++;
+            }
+            for (String child : builder.getChildNodeNames()) {
+                transformBuilder(builder.getChildNode(child), uuidIndexData);
+            }
+            totalNodes++;
+        }
+    }
+
+}

Modified: jackrabbit/oak/trunk/oak-run/src/main/resources/logback.xml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/resources/logback.xml?rev=1808672&r1=1808671&r2=1808672&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/resources/logback.xml (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/resources/logback.xml Mon Sep 18 
07:49:39 2017
@@ -54,6 +54,9 @@
   <!-- Display information messages from oak-run check (oak-segment-tar) -->
   <logger 
name="org.apache.jackrabbit.oak.segment.file.tooling.ConsistencyChecker" 
level="DEBUG"/>
 
+  <!-- Display information messages from oak-run composite-prepare -->
+  <logger name="org.apache.jackrabbit.oak.run.CompositePrepareCommand" 
level="INFO"/>
+
   <root level="warn">
     <appender-ref ref="STDERR" />
   </root>


Reply via email to