Author: tommaso
Date: Thu Feb 25 08:04:39 2016
New Revision: 1732256

URL: http://svn.apache.org/viewvc?rev=1732256&view=rev
Log:
OAK-4055 - fixed subtree index use case, minor adjustments to tests

Added:
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookup.java
   (with props)
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorIT.java
      - copied, changed from r1731805, 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexIT.java
      - copied, changed from r1731805, 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTestIT.java
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookupTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SubtreeSolrIndexIT.java
   (with props)
Removed:
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTestIT.java
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryEngineIT.java
Modified:
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/configuration/nodestate/NodeStateSolrServersObserver.java
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/osgi/SolrQueryIndexProviderService.java
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParser.java
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/OakSolrServer.java
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/RemoteSolrServerProvider.java
    
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/SolrServerRegistry.java
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParserTest.java
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/LMSEstimatorTest.java
    
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexTest.java

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/configuration/nodestate/NodeStateSolrServersObserver.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/configuration/nodestate/NodeStateSolrServersObserver.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/configuration/nodestate/NodeStateSolrServersObserver.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/configuration/nodestate/NodeStateSolrServersObserver.java
 Thu Feb 25 08:04:39 2016
@@ -21,6 +21,7 @@ import javax.annotation.Nullable;
 
 import org.apache.jackrabbit.oak.api.PropertyState;
 import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.SolrServerConfiguration;
+import org.apache.jackrabbit.oak.plugins.index.solr.server.OakSolrServer;
 import org.apache.jackrabbit.oak.plugins.index.solr.server.SolrServerProvider;
 import org.apache.jackrabbit.oak.plugins.index.solr.server.SolrServerRegistry;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
@@ -46,22 +47,11 @@ public class NodeStateSolrServersObserve
     }
 
     private void shutdownRegisteredSolrServers(NodeState nodeState) {
-        log.info("shutting down servers at {}", nodeState);
+        log.debug("shutting down persisted Solr server");
         NodeStateSolrServerConfigurationProvider 
nodeStateSolrServerConfigurationProvider = new 
NodeStateSolrServerConfigurationProvider(nodeState);
-        SolrServerConfiguration<SolrServerProvider> solrServerConfiguration = 
nodeStateSolrServerConfigurationProvider.getSolrServerConfiguration();
-        SolrServer searchingSolrServer = 
SolrServerRegistry.get(solrServerConfiguration, 
SolrServerRegistry.Strategy.SEARCHING);
-        if (searchingSolrServer != null) {
-            searchingSolrServer.shutdown();
-            log.info("searching SolrServer shut down");
-            SolrServerRegistry.unregister(solrServerConfiguration, 
SolrServerRegistry.Strategy.SEARCHING);
-        }
-
-        SolrServer indexingSolrServer = 
SolrServerRegistry.get(solrServerConfiguration, 
SolrServerRegistry.Strategy.INDEXING);
-        if (indexingSolrServer != null) {
-            indexingSolrServer.shutdown();
-            log.info("indexing SolrServer shut down");
-            SolrServerRegistry.unregister(solrServerConfiguration, 
SolrServerRegistry.Strategy.INDEXING);
-        }
+        OakSolrServer oakSolrServer = new 
OakSolrServer(nodeStateSolrServerConfigurationProvider);
+        oakSolrServer.shutdown();
+        log.info("persisted Solr server has been shutdown");
     }
 
     private class ChangingSolrServersNodeStateDiff implements NodeStateDiff {
@@ -132,6 +122,7 @@ public class NodeStateSolrServersObserve
         }
 
         private boolean isSolrServerNode(String name, NodeState nodeState) {
+            log.info("checking {} in {}", name, nodeState);
             return "server".equals(name) && 
nodeState.hasProperty("solrServerType");
         }
 

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/osgi/SolrQueryIndexProviderService.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/osgi/SolrQueryIndexProviderService.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/osgi/SolrQueryIndexProviderService.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/osgi/SolrQueryIndexProviderService.java
 Thu Feb 25 08:04:39 2016
@@ -54,7 +54,7 @@ public class SolrQueryIndexProviderServi
 
     private final List<ServiceRegistration> regs = Lists.newArrayList();
 
-    @Reference(target = "(|(server.type=embedded)(server.type=remote))")
+    @Reference
     private SolrServerProvider solrServerProvider;
 
     @Reference

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParser.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParser.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParser.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParser.java
 Thu Feb 25 08:04:39 2016
@@ -40,14 +40,14 @@ import static org.apache.jackrabbit.oak.
 import static 
org.apache.jackrabbit.oak.plugins.index.solr.util.SolrUtils.partialEscape;
 
 /**
- * the {@link 
org.apache.jackrabbit.oak.plugins.index.solr.query.FilterQueryParser} can parse 
{@link org.apache.jackrabbit.oak.spi.query.Filter}s
+ * the {@link FilterQueryParser} can parse {@link 
org.apache.jackrabbit.oak.spi.query.Filter}s
  * and transform them into {@link org.apache.solr.client.solrj.SolrQuery}s and 
/ or Solr query {@code String}s.
  */
 class FilterQueryParser {
 
     private static final Logger log = 
LoggerFactory.getLogger(FilterQueryParser.class);
 
-    static SolrQuery getQuery(Filter filter, List<QueryIndex.OrderEntry> 
sortOrder, OakSolrConfiguration configuration) {
+    static SolrQuery getQuery(Filter filter, QueryIndex.IndexPlan plan, 
OakSolrConfiguration configuration) {
 
         SolrQuery solrQuery = new SolrQuery();
         setDefaults(solrQuery, configuration);
@@ -65,6 +65,7 @@ class FilterQueryParser {
             }
         }
 
+        List<QueryIndex.OrderEntry> sortOrder = plan.getSortOrder();
         if (sortOrder != null) {
             for (QueryIndex.OrderEntry orderEntry : sortOrder) {
                 SolrQuery.ORDER order;
@@ -248,7 +249,7 @@ class FilterQueryParser {
         if (configuration.useForPathRestrictions()) {
             Filter.PathRestriction pathRestriction = 
filter.getPathRestriction();
             if (pathRestriction != null) {
-                String path = purgePath(filter);
+                String path = purgePath(filter, plan.getPathPrefix());
                 String fieldName = 
configuration.getFieldForPathRestriction(pathRestriction);
                 if (fieldName != null) {
                     if 
(pathRestriction.equals(Filter.PathRestriction.ALL_CHILDREN)) {
@@ -377,8 +378,15 @@ class FilterQueryParser {
         return "[" + (first != null ? first : "*") + " TO " + (last != null ? 
last : "*") + "]";
     }
 
-    private static String purgePath(Filter filter) {
-        return partialEscape(filter.getPath()).toString();
+    private static String purgePath(Filter filter, String pathPrefix) {
+        String path = filter.getPath();
+        if (pathPrefix != null && pathPrefix.length() > 1 && 
path.startsWith(pathPrefix)) {
+            path = path.substring(pathPrefix.length());
+            if (path.length() == 0) {
+                path = "/";
+            }
+        }
+        return partialEscape(path).toString();
     }
 
 }

Added: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookup.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookup.java?rev=1732256&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookup.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookup.java
 Thu Feb 25 08:04:39 2016
@@ -0,0 +1,79 @@
+/*
+ * 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.solr.query;
+
+import java.util.Collection;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.solr.util.SolrIndexInitializer.isSolrIndexNode;
+
+/**
+ * Lookup for Solr indexes to be used for a given {@link Filter}.
+ */
+class SolrIndexLookup {
+    private final NodeState root;
+
+    public SolrIndexLookup(NodeState root) {
+        this.root = root;
+    }
+
+    public Collection<String> collectIndexNodePaths(Filter filter) {
+        return collectIndexNodePaths(filter, true);
+    }
+
+    private Collection<String> collectIndexNodePaths(Filter filter, boolean 
recurse) {
+        Set<String> paths = Sets.newHashSet();
+
+        collectIndexNodePaths(root, "/", paths);
+
+        if (recurse) {
+            StringBuilder sb = new StringBuilder();
+            NodeState nodeState = root;
+            for (String element : PathUtils.elements(filter.getPath())) {
+                nodeState = nodeState.getChildNode(element);
+                collectIndexNodePaths(nodeState,
+                        sb.append("/").append(element).toString(),
+                        paths);
+            }
+        }
+
+        return paths;
+    }
+
+    private static void collectIndexNodePaths(NodeState nodeState, String 
parentPath, Collection<String> paths) {
+        NodeState state = nodeState.getChildNode(INDEX_DEFINITIONS_NAME);
+        for (ChildNodeEntry entry : state.getChildNodeEntries()) {
+            if (isSolrIndexNode(entry.getNodeState())) {
+                paths.add(createIndexNodePath(parentPath, entry.getName()));
+            }
+        }
+    }
+
+    private static String createIndexNodePath(String parentPath, String name) {
+        return PathUtils.concat(parentPath, INDEX_DEFINITIONS_NAME, name);
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
 Thu Feb 25 08:04:39 2016
@@ -27,17 +27,26 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.WeakHashMap;
 
 import com.google.common.collect.AbstractIterator;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Queues;
 import com.google.common.collect.Sets;
 import org.apache.jackrabbit.oak.api.PropertyValue;
 import org.apache.jackrabbit.oak.api.Result.SizePrecision;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
 import org.apache.jackrabbit.oak.commons.json.JsopWriter;
 import org.apache.jackrabbit.oak.plugins.index.aggregate.NodeAggregator;
 import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.OakSolrConfiguration;
+import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.OakSolrConfigurationProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.SolrServerConfigurationProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.nodestate.NodeStateSolrServerConfigurationProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.nodestate.OakSolrNodeStateConfiguration;
+import org.apache.jackrabbit.oak.plugins.index.solr.server.OakSolrServer;
+import org.apache.jackrabbit.oak.plugins.index.solr.server.SolrServerProvider;
 import org.apache.jackrabbit.oak.query.QueryEngineSettings;
 import org.apache.jackrabbit.oak.query.QueryImpl;
 import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression;
@@ -55,7 +64,6 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
 import org.apache.solr.client.solrj.response.FacetField;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.client.solrj.response.SpellCheckResponse;
@@ -67,6 +75,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static org.apache.jackrabbit.oak.commons.PathUtils.*;
+import static 
org.apache.jackrabbit.oak.plugins.index.solr.util.SolrIndexInitializer.isSolrIndexNode;
 
 /**
  * A Solr based {@link QueryIndex}
@@ -85,28 +94,16 @@ public class SolrQueryIndex implements F
 
     private final Logger log = LoggerFactory.getLogger(SolrQueryIndex.class);
 
-    private final String name;
-    private final SolrServer solrServer;
-    private final OakSolrConfiguration configuration;
-
     private final NodeAggregator aggregator;
-    private final LMSEstimator estimator;
+    private final OakSolrConfigurationProvider 
fallbackOakSolrConfigurationProvider;
+    private final SolrServerProvider fallbackSolrServerProvider;
 
+    private static final Map<String, LMSEstimator> estimators = new 
WeakHashMap<String, LMSEstimator>();
 
-    public SolrQueryIndex(String name, SolrServer solrServer, 
OakSolrConfiguration configuration, NodeAggregator aggregator, LMSEstimator 
estimator) {
-        this.name = name;
-        this.solrServer = solrServer;
-        this.configuration = configuration;
+    public SolrQueryIndex(NodeAggregator aggregator, 
OakSolrConfigurationProvider oakSolrConfigurationProvider, SolrServerProvider 
solrServerProvider) {
         this.aggregator = aggregator;
-        this.estimator = estimator;
-    }
-
-    public SolrQueryIndex(String name, SolrServer solrServer, 
OakSolrConfiguration configuration, NodeAggregator aggregator) {
-        this(name, solrServer, configuration, aggregator, new LMSEstimator());
-    }
-
-    public SolrQueryIndex(String name, SolrServer solrServer, 
OakSolrConfiguration configuration) {
-        this(name, solrServer, configuration, null, new LMSEstimator());
+        this.fallbackOakSolrConfigurationProvider = 
oakSolrConfigurationProvider;
+        this.fallbackSolrServerProvider = solrServerProvider;
     }
 
     @Override
@@ -116,20 +113,15 @@ public class SolrQueryIndex implements F
 
     @Override
     public String getIndexName() {
-        return name;
+        return "solr";
     }
 
     @Override
     public double getCost(Filter filter, NodeState root) {
-        // cost is inverse proportional to the number of matching 
restrictions, infinite if no restriction matches
-        double cost = COST_FOR_SINGLE_RESTRICTION / 
getMatchingFilterRestrictions(filter);
-        if (log.isDebugEnabled()) {
-            log.debug("Solr: cost for {} is {}", name, cost);
-        }
-        return cost;
+        throw new UnsupportedOperationException("Not supported as implementing 
AdvancedQueryIndex");
     }
 
-    int getMatchingFilterRestrictions(Filter filter) {
+    int getMatchingFilterRestrictions(Filter filter, OakSolrConfiguration 
configuration) {
         int match = 0;
 
         // full text expressions OR full text conditions defined
@@ -179,7 +171,7 @@ public class SolrQueryIndex implements F
 
     @Override
     public String getPlan(Filter filter, NodeState nodeState) {
-        return FilterQueryParser.getQuery(filter, null, 
configuration).toString();
+        throw new UnsupportedOperationException("Not supported as implementing 
AdvancedQueryIndex");
     }
 
     /**
@@ -217,29 +209,68 @@ public class SolrQueryIndex implements F
 
     @Override
     public Cursor query(final IndexPlan plan, final NodeState root) {
-        return query(plan, plan.getSortOrder(), root);
-    }
-
-    private Cursor query(IndexPlan plan, List<OrderEntry> sortOrder, NodeState 
root) {
         Cursor cursor;
         try {
+
             Filter filter = plan.getFilter();
             final Set<String> relPaths = filter.getFullTextConstraint() != 
null ? getRelativePaths(filter.getFullTextConstraint())
                     : Collections.<String>emptySet();
             final String parent = relPaths.size() == 0 ? "" : 
relPaths.iterator().next();
 
             final int parentDepth = getDepth(parent);
+            String path = plan.getPlanName();
 
-            AbstractIterator<SolrResultRow> iterator = getIterator(filter, 
sortOrder, parent, parentDepth);
+            OakSolrConfiguration configuration = getConfiguration(path, root);
+            SolrServer solrServer = getServer(path, root);
+            LMSEstimator estimator = getEstimator(path);
 
-            cursor = new SolrRowCursor(iterator, plan, 
filter.getQueryEngineSettings());
+            AbstractIterator<SolrResultRow> iterator = getIterator(filter, 
plan, parent, parentDepth, configuration,
+                    solrServer, estimator);
+
+            cursor = new SolrRowCursor(iterator, plan, 
filter.getQueryEngineSettings(), estimator, solrServer, configuration);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
         return cursor;
     }
 
-    private AbstractIterator<SolrResultRow> getIterator(final Filter filter, 
final List<OrderEntry> sortOrder, final String parent, final int parentDepth) {
+    private synchronized LMSEstimator getEstimator(String path) {
+        if (!estimators.containsKey(path)) {
+            estimators.put(path, new LMSEstimator());
+        }
+        return estimators.get(path);
+    }
+
+    private SolrServer getServer(String path, NodeState root) {
+
+        NodeState node = root;
+        for (String name : PathUtils.elements(path)) {
+            node = node.getChildNode(name);
+        }
+
+        try {
+            if (isSolrIndexNode(node)) {
+                if (node.hasChildNode("server")) {
+                    SolrServerConfigurationProvider 
solrServerConfigurationProvider = new NodeStateSolrServerConfigurationProvider(
+                            node.getChildNode("server"));
+                    return new OakSolrServer(solrServerConfigurationProvider);
+                } else {
+                    return fallbackSolrServerProvider.getSearchingSolrServer();
+                }
+            } else if (node.exists()) {
+                log.warn("Cannot open Solr Index at path {} as the index is 
not of type 'solr'", path);
+            }
+        } catch (Exception e) {
+            log.error("Could not access the Solr index at " + path, e);
+        }
+
+        return null;
+    }
+
+    private AbstractIterator<SolrResultRow> getIterator(final Filter filter, 
final IndexPlan plan,
+                                                        final String parent, 
final int parentDepth,
+                                                        final 
OakSolrConfiguration configuration, final SolrServer solrServer,
+                                                        final LMSEstimator 
estimator) {
         return new AbstractIterator<SolrResultRow>() {
             public Collection<FacetField> facetFields = new 
LinkedList<FacetField>();
             private final Set<String> seenPaths = Sets.newHashSet();
@@ -293,7 +324,7 @@ public class SolrQueryIndex implements F
                     if (log.isDebugEnabled()) {
                         log.debug("converting filter {}", filter);
                     }
-                    SolrQuery query = FilterQueryParser.getQuery(filter, 
sortOrder, configuration);
+                    SolrQuery query = FilterQueryParser.getQuery(filter, plan, 
configuration);
                     if (numFound > 0) {
                         long rows = configuration.getRows();
                         long maxQueries = numFound / 2;
@@ -324,7 +355,7 @@ public class SolrQueryIndex implements F
 
                         numFound = docs.getNumFound();
 
-                        onRetrievedDocs(filter, docs);
+                        estimator.update(filter, docs);
 
                         Map<String, Map<String, List<String>>> highlighting = 
queryResponse.getHighlighting();
                         for (SolrDocument doc : docs) {
@@ -371,7 +402,7 @@ public class SolrQueryIndex implements F
                     SpellCheckResponse spellCheckResponse = 
queryResponse.getSpellCheckResponse();
                     if (spellCheckResponse != null && 
spellCheckResponse.getSuggestions() != null &&
                             spellCheckResponse.getSuggestions().size() > 0) {
-                        putSpellChecks(spellCheckResponse, queue, filter);
+                        putSpellChecks(spellCheckResponse, queue, filter, 
configuration, solrServer);
                         noDocs = true;
                     }
 
@@ -381,7 +412,7 @@ public class SolrQueryIndex implements F
                     if (suggest != null) {
                         Set<Map.Entry<String, Object>> suggestEntries = 
suggest.entrySet();
                         if (!suggestEntries.isEmpty()) {
-                            putSuggestions(suggestEntries, queue, filter);
+                            putSuggestions(suggestEntries, queue, filter, 
configuration, solrServer);
                             noDocs = true;
                         }
                     }
@@ -429,8 +460,8 @@ public class SolrQueryIndex implements F
     }
 
     private void putSpellChecks(SpellCheckResponse spellCheckResponse,
-                                        final Deque<SolrResultRow> queue,
-                                        Filter filter) throws 
SolrServerException {
+                                final Deque<SolrResultRow> queue,
+                                Filter filter, OakSolrConfiguration 
configuration, SolrServer solrServer) throws SolrServerException {
         List<SpellCheckResponse.Suggestion> suggestions = 
spellCheckResponse.getSuggestions();
         Collection<String> alternatives = new 
ArrayList<String>(suggestions.size());
         for (SpellCheckResponse.Suggestion suggestion : suggestions) {
@@ -449,7 +480,7 @@ public class SolrQueryIndex implements F
             if (results != null && results.getNumFound() > 0) {
                 for (SolrDocument doc : results) {
                     if 
(filter.isAccessible(String.valueOf(doc.getFieldValue(configuration.getPathField()))))
 {
-                        queue.add (new SolrResultRow(alternative));
+                        queue.add(new SolrResultRow(alternative));
                         break;
                     }
                 }
@@ -457,9 +488,8 @@ public class SolrQueryIndex implements F
         }
     }
 
-    private void putSuggestions(Set<Map.Entry<String, Object>> suggestEntries,
-                                final Deque<SolrResultRow> queue,
-                                Filter filter) throws SolrServerException {
+    private void putSuggestions(Set<Map.Entry<String, Object>> suggestEntries, 
final Deque<SolrResultRow> queue,
+                                Filter filter, OakSolrConfiguration 
configuration, SolrServer solrServer) throws SolrServerException {
         Collection<SimpleOrderedMap<Object>> retrievedSuggestions = new 
HashSet<SimpleOrderedMap<Object>>();
         for (Map.Entry<String, Object> suggester : suggestEntries) {
             SimpleOrderedMap<Object> suggestionResponses = ((SimpleOrderedMap) 
suggester.getValue());
@@ -490,7 +520,7 @@ public class SolrQueryIndex implements F
             if (results != null && results.getNumFound() > 0) {
                 for (SolrDocument doc : results) {
                     if 
(filter.isAccessible(String.valueOf(doc.getFieldValue(configuration.getPathField()))))
 {
-                        queue.add (new 
SolrResultRow(suggestion.get("term").toString(),
+                        queue.add(new 
SolrResultRow(suggestion.get("term").toString(),
                                 
Double.parseDouble(suggestion.get("weight").toString())));
                         break;
                     }
@@ -501,34 +531,84 @@ public class SolrQueryIndex implements F
 
     static boolean isIgnoredProperty(Filter.PropertyRestriction property, 
OakSolrConfiguration configuration) {
         if (NATIVE_LUCENE_QUERY.equals(property.propertyName) || 
NATIVE_SOLR_QUERY.equals(property.propertyName)) {
-               return false;
+            return false;
         } else return (!configuration.useForPropertyRestrictions() // Solr 
index not used for properties
-                        || (configuration.getUsedProperties().size() > 0 && 
!configuration.getUsedProperties().contains(property.propertyName)) // not 
explicitly contained in the used properties
-                        || property.propertyName.contains("/") // no 
child-level property restrictions
-                        || QueryImpl.REP_EXCERPT.equals(property.propertyName) 
// rep:excerpt is not handled at the property level
-                        || 
QueryImpl.OAK_SCORE_EXPLANATION.equals(property.propertyName) // score explain 
is not handled at the property level
-                        || QueryImpl.REP_FACET.equals(property.propertyName) 
// rep:facet is not handled at the property level
-                        || 
QueryConstants.RESTRICTION_LOCAL_NAME.equals(property.propertyName)
-                        || 
configuration.getIgnoredProperties().contains(property.propertyName));
+                || (configuration.getUsedProperties().size() > 0 && 
!configuration.getUsedProperties().contains(property.propertyName)) // not 
explicitly contained in the used properties
+                || property.propertyName.contains("/") // no child-level 
property restrictions
+                || QueryImpl.REP_EXCERPT.equals(property.propertyName) // 
rep:excerpt is not handled at the property level
+                || 
QueryImpl.OAK_SCORE_EXPLANATION.equals(property.propertyName) // score explain 
is not handled at the property level
+                || QueryImpl.REP_FACET.equals(property.propertyName) // 
rep:facet is not handled at the property level
+                || 
QueryConstants.RESTRICTION_LOCAL_NAME.equals(property.propertyName)
+                || 
configuration.getIgnoredProperties().contains(property.propertyName));
     }
 
     @Override
     public List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder, 
NodeState rootState) {
-        // TODO : eventually provide multiple plans for (eventually) filtering 
by ACLs
-        // TODO : eventually provide multiple plans for normal paging vs deep 
paging
-        if (getMatchingFilterRestrictions(filter) > 0) {
-            return Collections.singletonList(planBuilder(filter)
+
+        Collection<String> indexPaths = new 
SolrIndexLookup(rootState).collectIndexNodePaths(filter);
+        List<IndexPlan> plans = 
Lists.newArrayListWithCapacity(indexPaths.size());
+
+        for (String path : indexPaths) {
+            OakSolrConfiguration configuration = getConfiguration(path, 
rootState);
+            SolrServer solrServer = getServer(path, rootState);
+            // only provide the plan if both valid configuration and server 
exist
+            if (configuration != null && solrServer != null) {
+                LMSEstimator estimator = getEstimator(path);
+                IndexPlan plan = getIndexPlan(filter, configuration, 
estimator, sortOrder, path);
+                if (plan != null) {
+                    plans.add(plan);
+                }
+            }
+        }
+        return plans;
+    }
+
+    private OakSolrConfiguration getConfiguration(String path, NodeState 
rootState) {
+        NodeState node = rootState;
+        for (String name : PathUtils.elements(path)) {
+            node = node.getChildNode(name);
+        }
+
+        try {
+            if (isSolrIndexNode(node)) {
+                if (node.hasChildNode("server")) {
+                    return new OakSolrNodeStateConfiguration(node);
+                } else {
+                    return 
fallbackOakSolrConfigurationProvider.getConfiguration();
+                }
+            } else if (node.exists()) {
+                log.warn("Cannot open Solr Index at path {} as the index is 
not of type 'solr'", path);
+            }
+        } catch (Exception e) {
+            log.error("Could not access the Solr index at " + path, e);
+        }
+
+        return null;
+    }
+
+    private IndexPlan getIndexPlan(Filter filter, OakSolrConfiguration 
configuration, LMSEstimator estimator,
+                                   List<OrderEntry> sortOrder, String path) {
+        if (getMatchingFilterRestrictions(filter, configuration) > 0) {
+            return planBuilder(filter)
                     .setEstimatedEntryCount(estimator.estimate(filter))
                     .setSortOrder(sortOrder)
-                    .build());
+                    .setPlanName(path)
+                    .setPathPrefix(getPathPrefix(path))
+                    .build();
         } else {
-            return Collections.emptyList();
+            return null;
         }
     }
 
+    private String getPathPrefix(String indexPath) {
+        // 2 = /oak:index/<index name>
+        String parentPath = PathUtils.getAncestorPath(indexPath, 2);
+        return PathUtils.denotesRoot(parentPath) ? "" : parentPath;
+    }
+
     private IndexPlan.Builder planBuilder(Filter filter) {
         return new IndexPlan.Builder()
-                .setCostPerExecution(solrServer instanceof EmbeddedSolrServer 
? 1 : 2) // disk I/O + network I/O
+                .setCostPerExecution(1.5) // disk I/O + network I/O
                 .setCostPerEntry(0.3) // with properly configured SolrCaches 
~70% of the doc fetches should hit them
                 .setFilter(filter)
                 .setFulltextIndex(true)
@@ -536,11 +616,6 @@ public class SolrQueryIndex implements F
                 .setDelayed(true); //Solr is most usually async
     }
 
-    void onRetrievedDocs(Filter filter, SolrDocumentList docs) {
-        // estimator update
-        estimator.update(filter, docs);
-    }
-
     @Override
     public String getPlanDescription(IndexPlan plan, NodeState root) {
         return plan.toString();
@@ -548,7 +623,7 @@ public class SolrQueryIndex implements F
 
     @Override
     public Cursor query(Filter filter, NodeState rootState) {
-        return query(planBuilder(filter).build(), null, rootState);
+        throw new UnsupportedOperationException("Not supported as implementing 
AdvancedQueryIndex");
     }
 
     static class SolrResultRow {
@@ -566,16 +641,12 @@ public class SolrQueryIndex implements F
             this.facetFields = facetFields;
         }
 
-        SolrResultRow(String path, double score, SolrDocument doc) {
-            this (path, score, doc, null, null);
-        }
-
         SolrResultRow(String suggestion, double score) {
-            this ("/", score, null, suggestion, null);
+            this("/", score, null, suggestion, null);
         }
 
         SolrResultRow(String suggestion) {
-            this ("/", 1.0, null, suggestion, null);
+            this("/", 1.0, null, suggestion, null);
         }
 
         SolrResultRow(String path, float score, SolrDocument doc, 
Collection<FacetField> facetFields) {
@@ -597,10 +668,17 @@ public class SolrQueryIndex implements F
 
         private final Cursor pathCursor;
         private final IndexPlan plan;
+        private final LMSEstimator estimator;
+        private final SolrServer solrServer;
+        private final OakSolrConfiguration configuration;
 
         SolrResultRow currentRow;
 
-        SolrRowCursor(final Iterator<SolrResultRow> it, IndexPlan plan, 
QueryEngineSettings settings) {
+        SolrRowCursor(final Iterator<SolrResultRow> it, IndexPlan plan, 
QueryEngineSettings settings,
+                      LMSEstimator estimator, SolrServer solrServer, 
OakSolrConfiguration configuration) {
+            this.estimator = estimator;
+            this.solrServer = solrServer;
+            this.configuration = configuration;
             Iterator<String> pathIterator = new Iterator<String>() {
 
                 @Override
@@ -642,12 +720,19 @@ public class SolrQueryIndex implements F
 
                 @Override
                 public boolean isVirtualRow() {
-                    return false;
+                    return currentRow.doc == null;
                 }
 
                 @Override
                 public String getPath() {
-                    return pathRow.getPath();
+                    String sub = pathRow.getPath();
+                    if (isVirtualRow()) {
+                        return sub;
+                    } else if (PathUtils.isAbsolute(sub)) {
+                        return plan.getPathPrefix() + sub;
+                    } else {
+                        return PathUtils.concat(plan.getPathPrefix(), sub);
+                    }
                 }
 
                 @Override
@@ -690,13 +775,12 @@ public class SolrQueryIndex implements F
                             if (fieldValue != null) {
                                 value = fieldValue.toString();
                             } else {
-                                value = null;
+                                return null;
                             }
                         }
                     } else {
                         value = Iterables.toString(Collections.emptyList());
                     }
-
                     return PropertyValues.newString(value);
                 }
 
@@ -710,17 +794,17 @@ public class SolrQueryIndex implements F
             switch (precision) {
                 case EXACT:
                     // query solr
-                    SolrQuery countQuery = 
FilterQueryParser.getQuery(plan.getFilter(), null, 
SolrQueryIndex.this.configuration);
+                    SolrQuery countQuery = 
FilterQueryParser.getQuery(plan.getFilter(), null, this.configuration);
                     countQuery.setRows(0);
                     try {
-                        estimate = 
SolrQueryIndex.this.solrServer.query(countQuery).getResults().getNumFound();
+                        estimate = 
this.solrServer.query(countQuery).getResults().getNumFound();
                     } catch (SolrServerException e) {
                         log.warn("could not perform count query {}", 
countQuery);
                     }
                     break;
                 case APPROXIMATION:
                     // estimate result size
-                    estimate = 
SolrQueryIndex.this.estimator.estimate(plan.getFilter());
+                    estimate = this.estimator.estimate(plan.getFilter());
                     break;
                 case FAST_APPROXIMATION:
                     // use already computed index plan's estimate

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
 Thu Feb 25 08:04:39 2016
@@ -16,61 +16,29 @@
  */
 package org.apache.jackrabbit.oak.plugins.index.solr.query;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.concurrent.TimeUnit;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+import java.util.List;
 
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Type;
+import com.google.common.collect.ImmutableList;
 import org.apache.jackrabbit.oak.plugins.index.aggregate.NodeAggregator;
-import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.OakSolrConfiguration;
 import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.OakSolrConfigurationProvider;
-import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.SolrServerConfigurationProvider;
-import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.nodestate.NodeStateSolrServerConfigurationProvider;
-import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.nodestate.OakSolrNodeStateConfiguration;
-import org.apache.jackrabbit.oak.plugins.index.solr.server.OakSolrServer;
 import org.apache.jackrabbit.oak.plugins.index.solr.server.SolrServerProvider;
 import org.apache.jackrabbit.oak.spi.query.QueryIndex;
 import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.solr.client.solrj.SolrServer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
-import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
 
 /**
  * {@link QueryIndexProvider} for {@link SolrQueryIndex}
  */
 public class SolrQueryIndexProvider implements QueryIndexProvider {
 
-    /**
-     * How often it should check for a new Solr index.
-     */
-    private static final long NO_INDEX_CACHE_TIMEOUT = 
TimeUnit.SECONDS.toMillis(30);
-
-    private final Logger log = LoggerFactory.getLogger(getClass());
-
     private final SolrServerProvider solrServerProvider;
 
     private final OakSolrConfigurationProvider oakSolrConfigurationProvider;
 
     private final NodeAggregator aggregator;
 
-    private final Map<NodeState, LMSEstimator> estimators = new 
WeakHashMap<NodeState, LMSEstimator>();
-
-    /**
-     * The last time when it checked for the existence of a Solr index AND 
could not find any.
-     */
-    private volatile long lastNegativeIndexCheck = 0;
-
     public SolrQueryIndexProvider(@Nonnull SolrServerProvider 
solrServerProvider, @Nonnull OakSolrConfigurationProvider 
oakSolrConfigurationProvider,
                                   @Nullable NodeAggregator nodeAggregator) {
         this.oakSolrConfigurationProvider = oakSolrConfigurationProvider;
@@ -85,75 +53,7 @@ public class SolrQueryIndexProvider impl
     @Nonnull
     @Override
     public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
-        List<? extends QueryIndex> queryIndexes;
-        // Return immediately if there are not any Solr indexes and the cache 
timeout has not been exceeded
-        long currentTime = System.currentTimeMillis();
-        if (currentTime - lastNegativeIndexCheck > NO_INDEX_CACHE_TIMEOUT) {
-            queryIndexes = internalGetQueryIndexes(nodeState);
-            lastNegativeIndexCheck = queryIndexes.isEmpty() ? currentTime : 0;
-        } else {
-            queryIndexes = Collections.emptyList();
-        }
-        return queryIndexes;
-    }
-
-    private List<? extends QueryIndex> internalGetQueryIndexes(NodeState 
nodeState) {
-        List<QueryIndex> tempIndexes = new ArrayList<QueryIndex>();
-        NodeState definitions = nodeState.getChildNode(INDEX_DEFINITIONS_NAME);
-        for (ChildNodeEntry entry : definitions.getChildNodeEntries()) {
-            NodeState definition = entry.getNodeState();
-            String name = entry.getName();
-            PropertyState type = definition.getProperty(TYPE_PROPERTY_NAME);
-            if (type != null && 
SolrQueryIndex.TYPE.equals(type.getValue(Type.STRING))) {
-                try {
-                    if (isPersistedConfiguration(definition)) {
-                        OakSolrConfiguration configuration = new 
OakSolrNodeStateConfiguration(definition);
-                        SolrServerConfigurationProvider 
solrServerConfigurationProvider = new 
NodeStateSolrServerConfigurationProvider(definition.getChildNode("server"));
-                        SolrServer solrServer = new 
OakSolrServer(solrServerConfigurationProvider);
-                        // if it does not already exist I need to register an 
observer that updates / closes this SolrServerProvider when the node is 
updated/removed
-                        addQueryIndex(tempIndexes, name, solrServer, 
configuration, definition);
-                    } else { // otherwise use the default configuration 
providers
-                        OakSolrConfiguration configuration = 
oakSolrConfigurationProvider.getConfiguration();
-                        addQueryIndex(tempIndexes, name, 
solrServerProvider.getSearchingSolrServer(), configuration, definition);
-                    }
-                } catch (Exception e) {
-                    log.warn("could not get Solr query index from node {}", 
name, e);
-                }
-            }
-        }
-        return tempIndexes;
-    }
-
-    private boolean isPersistedConfiguration(NodeState definition) {
-        return definition.hasChildNode("server");
-    }
-
-    private void addQueryIndex(List<QueryIndex> tempIndexes, String name, 
SolrServer solrServer, OakSolrConfiguration configuration, NodeState 
definition) {
-        try {
-            if (solrServer != null) {
-                LMSEstimator estimator;
-                synchronized (estimators) {
-                    estimator = estimators.get(definition);
-                    if (estimator == null) {
-                        estimator = new LMSEstimator();
-                        estimators.put(definition, estimator);
-                    }
-                }
-                tempIndexes.add(new SolrQueryIndex(
-                        name,
-                        solrServer,
-                        configuration,
-                        aggregator, estimator));
-            } else {
-                if (log.isWarnEnabled()) {
-                    log.warn("cannot create Solr query index as SolrServer is 
null");
-                }
-            }
-        } catch (Exception e) {
-            if (log.isErrorEnabled()) {
-                log.error("unable to create Solr query index at " + name, e);
-            }
-        }
+        return ImmutableList.of(new SolrQueryIndex(aggregator, 
oakSolrConfigurationProvider, solrServerProvider));
     }
 
 }

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/OakSolrServer.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/OakSolrServer.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/OakSolrServer.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/OakSolrServer.java
 Thu Feb 25 08:04:39 2016
@@ -16,8 +16,8 @@
  */
 package org.apache.jackrabbit.oak.plugins.index.solr.server;
 
-import java.io.IOException;
 import javax.annotation.Nonnull;
+import java.io.IOException;
 
 import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.EmbeddedSolrServerConfiguration;
 import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.SolrServerConfiguration;
@@ -25,6 +25,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.NamedList;
 
 /**

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/RemoteSolrServerProvider.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/RemoteSolrServerProvider.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/RemoteSolrServerProvider.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/RemoteSolrServerProvider.java
 Thu Feb 25 08:04:39 2016
@@ -43,9 +43,6 @@ public class RemoteSolrServerProvider im
 
     private final RemoteSolrServerConfiguration remoteSolrServerConfiguration;
 
-    private SolrServer searchingSolrServer;
-    private SolrServer indexingSolrServer;
-
     public RemoteSolrServerProvider(RemoteSolrServerConfiguration 
remoteSolrServerConfiguration) {
         this.remoteSolrServerConfiguration = remoteSolrServerConfiguration;
     }
@@ -204,15 +201,6 @@ public class RemoteSolrServerProvider im
 
     @Override
     public void close() throws IOException {
-        try {
-            searchingSolrServer.shutdown();
-        } catch (Exception e) {
-            // do nothing
-        }
-        try {
-            indexingSolrServer.shutdown();
-        } catch (Exception e) {
-            // do nothing
-        }
+        // do nothing
     }
 }

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/SolrServerRegistry.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/SolrServerRegistry.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/SolrServerRegistry.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/server/SolrServerRegistry.java
 Thu Feb 25 08:04:39 2016
@@ -67,12 +67,22 @@ public class SolrServerRegistry {
         switch (strategy) {
             case INDEXING:
                 synchronized (indexingServerRegistry) {
-                    indexingServerRegistry.remove(configuration.toString());
+                    SolrServer removed = 
indexingServerRegistry.remove(configuration.toString());
+                    try {
+                        removed.shutdown();
+                    } catch (Exception e) {
+                        // ignore
+                    }
                 }
                 break;
             case SEARCHING:
                 synchronized (searchingServerRegistry) {
-                    searchingServerRegistry.remove(configuration.toString());
+                    SolrServer removed = 
searchingServerRegistry.remove(configuration.toString());
+                    try {
+                        removed.shutdown();
+                    } catch (Exception e) {
+                        // ignore
+                    }
                 }
                 break;
         }

Copied: 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorIT.java
 (from r1731805, 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java)
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorIT.java?p2=jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorIT.java&p1=jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java&r1=1731805&r2=1732256&rev=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorIT.java
 Thu Feb 25 08:04:39 2016
@@ -25,9 +25,9 @@ import org.junit.Test;
 import static org.junit.Assert.assertTrue;
 
 /**
- * Integration test for {@link 
org.apache.jackrabbit.oak.plugins.index.solr.index.SolrCommitHook}
+ * Integration test for {@link SolrIndexEditor}
  */
-public class SolrCommitHookIT extends SolrBaseTest {
+public class SolrIndexEditorIT extends SolrBaseTest {
 
     @Test
     public void testAddSomeNodes() throws Exception {

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParserTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParserTest.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParserTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParserTest.java
 Thu Feb 25 08:04:39 2016
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.plugin
 import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.DefaultSolrConfiguration;
 import 
org.apache.jackrabbit.oak.plugins.index.solr.configuration.OakSolrConfiguration;
 import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.junit.Test;
 
@@ -31,7 +32,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 /**
- * Testcase for {@link 
org.apache.jackrabbit.oak.plugins.index.solr.query.FilterQueryParser}
+ * Testcase for {@link FilterQueryParser}
  */
 public class FilterQueryParserTest {
 
@@ -39,7 +40,8 @@ public class FilterQueryParserTest {
     public void testMatchAllConversionWithNoConstraints() throws Exception {
         Filter filter = mock(Filter.class);
         OakSolrConfiguration configuration = mock(OakSolrConfiguration.class);
-        SolrQuery solrQuery = FilterQueryParser.getQuery(filter, null, 
configuration);
+        QueryIndex.IndexPlan plan = mock(QueryIndex.IndexPlan.class);
+        SolrQuery solrQuery = FilterQueryParser.getQuery(filter, plan, 
configuration);
         assertNotNull(solrQuery);
         assertEquals("*:*", solrQuery.getQuery());
     }
@@ -58,7 +60,8 @@ public class FilterQueryParserTest {
         Filter.PathRestriction pathRestriction = 
Filter.PathRestriction.ALL_CHILDREN;
         when(filter.getPathRestriction()).thenReturn(pathRestriction);
         when(filter.getPath()).thenReturn("/");
-        SolrQuery solrQuery = FilterQueryParser.getQuery(filter, null, 
configuration);
+        QueryIndex.IndexPlan plan = mock(QueryIndex.IndexPlan.class);
+        SolrQuery solrQuery = FilterQueryParser.getQuery(filter, plan, 
configuration);
         assertNotNull(solrQuery);
         String[] filterQueries = solrQuery.getFilterQueries();
         
assertTrue(Arrays.asList(filterQueries).contains(configuration.getFieldForPathRestriction(pathRestriction)
 + ":\\/"));
@@ -76,7 +79,8 @@ public class FilterQueryParserTest {
             }
         };
         when(filter.getQueryStatement()).thenReturn(query);
-        SolrQuery solrQuery = FilterQueryParser.getQuery(filter, null, 
configuration);
+        QueryIndex.IndexPlan plan = mock(QueryIndex.IndexPlan.class);
+        SolrQuery solrQuery = FilterQueryParser.getQuery(filter, plan, 
configuration);
         assertNotNull(solrQuery);
         String[] filterQueries = solrQuery.getFilterQueries();
         assertTrue(Arrays.asList(filterQueries).contains("{!collapse field=" + 
configuration.getCollapsedPathField()

Modified: 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/LMSEstimatorTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/LMSEstimatorTest.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/LMSEstimatorTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/LMSEstimatorTest.java
 Thu Feb 25 08:04:39 2016
@@ -72,6 +72,6 @@ public class LMSEstimatorTest {
         LMSEstimator lmsEstimator = new LMSEstimator();
         Filter filter = mock(Filter.class);
         long estimate = lmsEstimator.estimate(filter);
-        assertEquals(1l, estimate);
+        assertEquals(1L, estimate);
     }
 }
\ No newline at end of file

Copied: 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexIT.java
 (from r1731805, 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTestIT.java)
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexIT.java?p2=jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexIT.java&p1=jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTestIT.java&r1=1731805&r2=1732256&rev=1732256&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTestIT.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexIT.java
 Thu Feb 25 08:04:39 2016
@@ -46,7 +46,7 @@ import static org.junit.Assume.assumeTru
 /**
  * General query extensive testcase for {@link SolrQueryIndex}
  */
-public class SolrIndexQueryTestIT extends AbstractQueryTest {
+public class SolrIndexIT extends AbstractQueryTest {
 
     @Rule
     public TestName name = new TestName();
@@ -245,13 +245,13 @@ public class SolrIndexQueryTestIT extend
         // TODO: OAK-1819
         assumeTrue(!System.getProperty("java.version").startsWith("1.8"));
 
-        String nativeQueryString = "select [jcr:path] from [nt:base] where 
native('solr', 'mlt?q=name:World&mlt.fl=name&mlt.mindf=0&mlt.mintf=0')";
+        String nativeQueryString = "select [jcr:path] from [nt:base] where 
native('solr', 'mlt?q=text:World&mlt.fl=text&mlt.mindf=0&mlt.mintf=0')";
 
         Tree tree = root.getTree("/");
         Tree test = tree.addChild("test");
-        test.addChild("a").setProperty("name", "Hello World, today weather is 
nice");
-        test.addChild("b").setProperty("name", "Cheers World, today weather is 
quite nice");
-        test.addChild("c").setProperty("name", "Halo Welt, today sky is 
cloudy");
+        test.addChild("a").setProperty("text", "Hello World, today weather is 
nice");
+        test.addChild("b").setProperty("text", "Cheers World, today weather is 
quite nice");
+        test.addChild("c").setProperty("text", "Halo Welt, today sky is 
cloudy");
         root.commit();
 
         Iterator<String> strings = executeQuery(nativeQueryString, 
"JCR-SQL2").iterator();
@@ -267,13 +267,13 @@ public class SolrIndexQueryTestIT extend
         // TODO: OAK-1819
         assumeTrue(!System.getProperty("java.version").startsWith("1.8"));
 
-        String nativeQueryString = "select [jcr:path] from [nt:base] where 
native('solr', 'mlt?stream.body=world is nice 
today&mlt.fl=name&mlt.mindf=0&mlt.mintf=0')";
+        String nativeQueryString = "select [jcr:path] from [nt:base] where 
native('solr', 'mlt?stream.body=world is nice 
today&mlt.fl=text&mlt.mindf=0&mlt.mintf=0')";
 
         Tree tree = root.getTree("/");
         Tree test = tree.addChild("test");
-        test.addChild("a").setProperty("name", "Hello World, today weather is 
nice");
-        test.addChild("b").setProperty("name", "Cheers World, today weather is 
quite nice");
-        test.addChild("c").setProperty("name", "Halo Welt, today sky is 
cloudy");
+        test.addChild("a").setProperty("text", "Hello World, today weather is 
nice");
+        test.addChild("b").setProperty("text", "Cheers World, today weather is 
quite nice");
+        test.addChild("c").setProperty("text", "Halo Welt, today sky is 
cloudy");
         root.commit();
 
         Iterator<String> strings = executeQuery(nativeQueryString, 
"JCR-SQL2").iterator();

Added: 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookupTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookupTest.java?rev=1732256&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookupTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookupTest.java
 Thu Feb 25 08:04:39 2016
@@ -0,0 +1,102 @@
+/*
+ * 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.solr.query;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.Set;
+
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.*;
+import static 
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static 
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link SolrIndexLookup}
+ */
+public class SolrIndexLookupTest {
+    private NodeState root = INITIAL_CONTENT;
+
+    private NodeBuilder builder = root.builder();
+
+    @Test
+    public void collectPathOnRootNode() throws Exception {
+        NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+        newSolrIndexDefinition(index, "l1", of("foo"));
+        newSolrIndexDefinition(index, "l2", of("foo"));
+
+        SolrIndexLookup lookup = new SolrIndexLookup(builder.getNodeState());
+        FilterImpl f = new FilterImpl();
+        f.restrictPath("/", Filter.PathRestriction.EXACT);
+        assertEquals(of("/oak:index/l1", "/oak:index/l2"),
+                lookup.collectIndexNodePaths(f));
+    }
+
+    @Test
+    public void collectPathOnSubNode() throws Exception {
+        NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+        newSolrIndexDefinition(index, "l1", of("foo"));
+
+        index = builder.child("a").child(INDEX_DEFINITIONS_NAME);
+        newSolrIndexDefinition(index, "l2", of("foo"));
+
+        index = builder.child("a").child("b").child(INDEX_DEFINITIONS_NAME);
+        newSolrIndexDefinition(index, "l3", of("foo"));
+
+        SolrIndexLookup lookup = new SolrIndexLookup(builder.getNodeState());
+        FilterImpl f = new FilterImpl();
+        f.restrictPath("/a", Filter.PathRestriction.EXACT);
+        assertEquals(of("/oak:index/l1", "/a/oak:index/l2"),
+                lookup.collectIndexNodePaths(f));
+
+        f.restrictPath("/a/b", Filter.PathRestriction.EXACT);
+        assertEquals(of("/oak:index/l1", "/a/oak:index/l2", 
"/a/b/oak:index/l3"),
+                lookup.collectIndexNodePaths(f));
+    }
+
+    private static NodeBuilder newSolrIndexDefinition(
+            @Nonnull NodeBuilder index, @Nonnull String name,
+            @Nullable Set<String> properties) {
+        if (index.hasChildNode(name)) {
+            return index.child(name);
+        }
+        index = index.child(name);
+        index.setProperty(JCR_PRIMARYTYPE, INDEX_DEFINITIONS_NODE_TYPE, NAME)
+                .setProperty(TYPE_PROPERTY_NAME, "solr")
+                .setProperty(ASYNC_PROPERTY_NAME, "async")
+                .setProperty(REINDEX_PROPERTY_NAME, true);
+        index.child("server").setProperty("solrServerType", "embedded");
+        if (properties != null && !properties.isEmpty()) {
+            index.setProperty(createProperty("usedProperties",
+                    properties, STRINGS));
+        }
+        return index;
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexLookupTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to