Author: thomasm
Date: Fri Sep 21 12:47:23 2018
New Revision: 1841577

URL: http://svn.apache.org/viewvc?rev=1841577&view=rev
Log:
OAK-7768: Ability to deprecate an index

Added:
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/LuceneIndexDeprecatedTest.java

Added: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/LuceneIndexDeprecatedTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/LuceneIndexDeprecatedTest.java?rev=1841577&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/LuceneIndexDeprecatedTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/LuceneIndexDeprecatedTest.java
 Fri Sep 21 12:47:23 2018
@@ -0,0 +1,211 @@
+/*
+ * 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.plugins.index.lucene.property;
+
+import static org.apache.jackrabbit.JcrConstants.NT_BASE;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLucenePropertyIndexDefinition;
+import static org.apache.jackrabbit.oak.spi.commit.CommitInfo.EMPTY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.jackrabbit.oak.InitialContentHelper;
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.lucene.IndexTracker;
+import 
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditorProvider;
+import org.apache.jackrabbit.oak.plugins.index.lucene.LucenePropertyIndex;
+import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
+import org.apache.jackrabbit.oak.query.NodeStateNodeTypeInfoProvider;
+import org.apache.jackrabbit.oak.query.QueryEngineSettings;
+import org.apache.jackrabbit.oak.query.ast.NodeTypeInfo;
+import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
+import org.apache.jackrabbit.oak.query.ast.Operator;
+import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.mount.Mounts;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSet;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.spi.FilterReply;
+
+/**
+ * Test the Property2 index mechanism.
+ */
+public class LuceneIndexDeprecatedTest {
+
+    private static final int MANY = 100;
+
+    private NodeState root;
+    private NodeBuilder rootBuilder;
+    private static final EditorHook HOOK = new EditorHook(
+            new IndexUpdateProvider(new LuceneIndexEditorProvider()));
+
+    @Before
+    public void setup() throws Exception {
+        root = EmptyNodeState.EMPTY_NODE;
+        rootBuilder = InitialContentHelper.INITIAL_CONTENT.builder();
+        commit();
+    }
+
+    @Test
+    public void deprecated() throws Exception {
+        NodeBuilder index = newLucenePropertyIndexDefinition(
+                rootBuilder.child(INDEX_DEFINITIONS_NAME),
+                "foo", ImmutableSet.of("foo"), null);
+        index.setProperty(IndexConstants.INDEX_DEPRECATED, false);
+        commit();
+        for (int i = 0; i < MANY; i++) {
+            rootBuilder.child("test").child("n" + i).setProperty("foo", "x" + 
i % 20);
+        }
+        commit();
+
+        FilterImpl f = createFilter(root, NT_BASE);
+        f.restrictProperty("foo", Operator.EQUAL, 
PropertyValues.newString("x10"));
+
+        IndexTracker tracker = new IndexTracker();
+        tracker.update(root);
+        LucenePropertyIndex luceneIndex = new LucenePropertyIndex(tracker);
+        IndexPlan plan = luceneIndex.getPlans(f, null, root).iterator().next();
+        assertTrue(plan.getCostPerExecution() != Double.POSITIVE_INFINITY);
+        ListAppender<ILoggingEvent> appender = createAndRegisterAppender();
+        luceneIndex.query(plan, root);
+
+        assertEquals("[]", appender.list.toString());
+        appender.list.clear();
+
+        // now test with the deprecated flag
+        index = rootBuilder.child(INDEX_DEFINITIONS_NAME).child("foo");
+        index.setProperty(IndexConstants.INDEX_DEPRECATED, true);
+        index.setProperty("refresh", Boolean.TRUE);
+        commit();
+
+        appender.list.clear();
+
+        // need to create a new one - otherwise the cached definition is used
+        tracker = new IndexTracker();
+        tracker.update(root);
+        luceneIndex = new LucenePropertyIndex(tracker);
+        plan = luceneIndex.getPlans(f, null, root).iterator().next();
+        assertTrue(plan.getCostPerExecution() != Double.POSITIVE_INFINITY);
+        luceneIndex.query(plan, root);
+
+        assertEquals("[[WARN] This index is deprecated: /oak:index/foo; " +
+                "it is used for query Filter(query=" +
+                "SELECT * FROM [nt:base], path=*, property=[foo=[x10]]). " +
+                "Please change the query or the index definitions.]", 
appender.list.toString());
+
+        index = rootBuilder.child(INDEX_DEFINITIONS_NAME).child("foo");
+        index.removeProperty(IndexConstants.INDEX_DEPRECATED);
+        index.setProperty("refresh", Boolean.TRUE);
+        commit();
+
+        appender.list.clear();
+
+        // need to create a new one - otherwise the cached definition is used
+        tracker = new IndexTracker();
+        tracker.update(root);
+        luceneIndex = new LucenePropertyIndex(tracker);
+        plan = luceneIndex.getPlans(f, null, root).iterator().next();
+        assertTrue(plan.getCostPerExecution() != Double.POSITIVE_INFINITY);
+        luceneIndex.query(plan, root);
+
+        assertEquals("[]", appender.list.toString());
+
+        deregisterAppender(appender);
+    }
+
+    private void commit() throws Exception {
+        root = HOOK.processCommit(rootBuilder.getBaseState(), 
rootBuilder.getNodeState(), EMPTY);
+        rootBuilder = root.builder();
+    }
+
+    private static FilterImpl createFilter(NodeState root, String 
nodeTypeName) {
+        NodeTypeInfoProvider nodeTypes = new 
NodeStateNodeTypeInfoProvider(root);
+        NodeTypeInfo type = nodeTypes.getNodeTypeInfo(nodeTypeName);
+        SelectorImpl selector = new SelectorImpl(type, nodeTypeName);
+        return new FilterImpl(selector, "SELECT * FROM [" + nodeTypeName + 
"]", new QueryEngineSettings());
+    }
+
+    private ListAppender<ILoggingEvent> createAndRegisterAppender() {
+        WarnFilter filter = new WarnFilter();
+        filter.start();
+        ListAppender<ILoggingEvent> appender = new ListAppender<>();
+        appender.setContext(getContext());
+        appender.setName("TestLogCollector");
+        appender.addFilter(filter);
+        appender.start();
+        rootLogger().addAppender(appender);
+        return appender;
+    }
+
+    private void deregisterAppender(Appender<ILoggingEvent> appender){
+        rootLogger().detachAppender(appender);
+    }
+
+    private static class WarnFilter extends 
ch.qos.logback.core.filter.Filter<ILoggingEvent> {
+
+        @Override
+        public FilterReply decide(ILoggingEvent event) {
+            if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
+                return FilterReply.ACCEPT;
+            } else {
+                return FilterReply.DENY;
+            }
+        }
+    }
+
+    private static LoggerContext getContext(){
+        return (LoggerContext) LoggerFactory.getILoggerFactory();
+    }
+
+    private static ch.qos.logback.classic.Logger rootLogger() {
+        return 
getContext().getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
+    }
+
+    public void startCollecting() {
+        Logger fooLogger = (Logger) 
LoggerFactory.getLogger(LuceneIndexDeprecatedTest.class);
+        ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
+        listAppender.start();
+
+        // add the appender to the logger
+        fooLogger.addAppender(listAppender);
+
+        fooLogger.warn("hello");
+
+        List<ILoggingEvent> logsList = listAppender.list;
+        System.out.println(logsList);
+
+    }
+
+}


Reply via email to