You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2014/12/07 12:37:35 UTC

svn commit: r1643662 [6/6] - in /lucene/dev/branches/lucene6005: ./ lucene/ lucene/codecs/ lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/ lucene/core/ lucene/core/src/java/org/apache/lucene/codecs/ lucene/core/src/java/org/apache/lucene/co...

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java Sun Dec  7 11:37:32 2014
@@ -18,21 +18,12 @@ package org.apache.solr.rest;
 
 import org.apache.solr.request.SolrRequestInfo;
 import org.apache.solr.rest.schema.CopyFieldCollectionResource;
-import org.apache.solr.rest.schema.SchemaResource;
-import org.apache.solr.rest.schema.DefaultSearchFieldResource;
 import org.apache.solr.rest.schema.DynamicFieldCollectionResource;
 import org.apache.solr.rest.schema.DynamicFieldResource;
 import org.apache.solr.rest.schema.FieldCollectionResource;
 import org.apache.solr.rest.schema.FieldResource;
 import org.apache.solr.rest.schema.FieldTypeCollectionResource;
 import org.apache.solr.rest.schema.FieldTypeResource;
-import org.apache.solr.rest.schema.SchemaNameResource;
-import org.apache.solr.rest.schema.SchemaSimilarityResource;
-import org.apache.solr.rest.schema.SchemaVersionResource;
-import org.apache.solr.rest.schema.SchemaZkVersionResource;
-import org.apache.solr.rest.schema.SolrQueryParserDefaultOperatorResource;
-import org.apache.solr.rest.schema.SolrQueryParserResource;
-import org.apache.solr.rest.schema.UniqueKeyFieldResource;
 import org.apache.solr.schema.IndexSchema;
 import org.restlet.Application;
 import org.restlet.Restlet;
@@ -58,30 +49,11 @@ public class SolrSchemaRestApi extends A
   public static final String FIELDTYPES = IndexSchema.FIELD_TYPES.toLowerCase(Locale.ROOT);
   public static final String FIELDTYPES_PATH = "/" + FIELDTYPES;
 
-  public static final String NAME_PATH = "/" + IndexSchema.NAME.toLowerCase(Locale.ROOT);
   public static final String NAME_SEGMENT = "/{" + IndexSchema.NAME.toLowerCase(Locale.ROOT) + "}";
   
   public static final String COPY_FIELDS = IndexSchema.COPY_FIELDS.toLowerCase(Locale.ROOT);
   public static final String COPY_FIELDS_PATH = "/" + COPY_FIELDS;
   
-  public static final String VERSION_PATH = "/" + IndexSchema.VERSION.toLowerCase(Locale.ROOT);
-  
-  public static final String DEFAULT_SEARCH_FIELD = IndexSchema.DEFAULT_SEARCH_FIELD.toLowerCase(Locale.ROOT);
-  public static final String DEFAULT_SEARCH_FIELD_PATH = "/" + DEFAULT_SEARCH_FIELD;
-  
-  public static final String SIMILARITY_PATH = "/" + IndexSchema.SIMILARITY.toLowerCase(Locale.ROOT);
-  
-  public static final String SOLR_QUERY_PARSER = IndexSchema.SOLR_QUERY_PARSER.toLowerCase(Locale.ROOT);
-  public static final String SOLR_QUERY_PARSER_PATH = "/" + SOLR_QUERY_PARSER;
-  
-  public static final String DEFAULT_OPERATOR = IndexSchema.DEFAULT_OPERATOR.toLowerCase(Locale.ROOT);
-  public static final String DEFAULT_OPERATOR_PATH = SOLR_QUERY_PARSER_PATH + "/" + DEFAULT_OPERATOR;
-  
-  public static final String UNIQUE_KEY_FIELD = IndexSchema.UNIQUE_KEY.toLowerCase(Locale.ROOT);
-  public static final String UNIQUE_KEY_FIELD_PATH = "/" + UNIQUE_KEY_FIELD;
-  
-  public static final String ZK_VERSION_PATH = "/zkversion";  
-
   /**
    * Returns reserved endpoints under /schema
    */
@@ -90,15 +62,7 @@ public class SolrSchemaRestApi extends A
     reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + FIELDS_PATH);
     reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + DYNAMIC_FIELDS_PATH);
     reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + FIELDTYPES_PATH);
-    reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + NAME_PATH);
     reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + COPY_FIELDS_PATH);
-    reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + VERSION_PATH);
-    reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + DEFAULT_SEARCH_FIELD_PATH);
-    reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + SIMILARITY_PATH);
-    reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + SOLR_QUERY_PARSER_PATH);
-    reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + DEFAULT_OPERATOR_PATH);
-    reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + UNIQUE_KEY_FIELD_PATH);
-    reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + ZK_VERSION_PATH);
     return Collections.unmodifiableSet(reservedEndpoints);
   }
 
@@ -123,10 +87,7 @@ public class SolrSchemaRestApi extends A
 
     log.info("createInboundRoot started for /schema");
 
-    router.attach("", SchemaResource.class);
-    // Allow a trailing slash on full-schema requests
-    router.attach("/", SchemaResource.class);
-    
+
     router.attach(FIELDS_PATH, FieldCollectionResource.class);
     // Allow a trailing slash on collection requests
     router.attach(FIELDS_PATH + "/", FieldCollectionResource.class);
@@ -145,23 +106,7 @@ public class SolrSchemaRestApi extends A
     router.attach(COPY_FIELDS_PATH, CopyFieldCollectionResource.class);
     // Allow a trailing slash on collection requests
     router.attach(COPY_FIELDS_PATH + "/", CopyFieldCollectionResource.class);
-    
-    router.attach(NAME_PATH, SchemaNameResource.class);
-    
-    router.attach(VERSION_PATH, SchemaVersionResource.class);
-    
-    router.attach(UNIQUE_KEY_FIELD_PATH, UniqueKeyFieldResource.class);
 
-    router.attach(DEFAULT_SEARCH_FIELD_PATH, DefaultSearchFieldResource.class);
-    
-    router.attach(SIMILARITY_PATH, SchemaSimilarityResource.class);
-
-    // At present solrQueryParser only contains defaultOperator, but there may be more children in the future
-    router.attach(SOLR_QUERY_PARSER_PATH, SolrQueryParserResource.class);
-    router.attach(DEFAULT_OPERATOR_PATH, SolrQueryParserDefaultOperatorResource.class);
-
-    router.attach(ZK_VERSION_PATH, SchemaZkVersionResource.class);
-    
     router.attachDefault(RestManager.ManagedEndpoint.class);
     
     // attach all the dynamically registered schema resources

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/schema/SchemaManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/schema/SchemaManager.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/schema/SchemaManager.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/schema/SchemaManager.java Sun Dec  7 11:37:32 2014
@@ -18,17 +18,26 @@ package org.apache.solr.schema;
  */
 
 
+import org.apache.solr.cloud.ZkController;
 import org.apache.solr.cloud.ZkSolrResourceLoader;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.core.ConfigOverlay;
 import org.apache.solr.core.CoreDescriptor;
 import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.rest.BaseSolrResource;
 import org.apache.solr.util.CommandOperation;
+import org.apache.zookeeper.KeeperException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.Reader;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -79,7 +88,7 @@ public class SchemaManager {
    * @param rdr The input as a Reader
    * @return Lis of errors . If the List is empty then the operation is successful.
    */
-  public List performOperations(Reader rdr)  {
+  public List performOperations(Reader rdr) throws Exception {
     List<CommandOperation> ops = null;
     try {
       ops = CommandOperation.parse(rdr);
@@ -102,13 +111,13 @@ public class SchemaManager {
 
   }
 
-  private List doOperations(List<CommandOperation> operations){
+  private List doOperations(List<CommandOperation> operations) throws InterruptedException, IOException, KeeperException {
     int timeout = req.getParams().getInt(BaseSolrResource.UPDATE_TIMEOUT_SECS, -1);
     long startTime = System.nanoTime();
-    long endTime = timeout >0  ? System.nanoTime()+ (timeout * 1000*1000) : Long.MAX_VALUE;
+    long endTime = timeout > 0 ? System.nanoTime() + (timeout * 1000 * 1000) : Long.MAX_VALUE;
     SolrCore core = req.getCore();
-    for(;System.nanoTime() < endTime ;) {
-      managedIndexSchema = (ManagedIndexSchema) core.getLatestSchema();
+    for (; System.nanoTime() < endTime; ) {
+      managedIndexSchema = getFreshManagedSchema();
       for (CommandOperation op : operations) {
         if (ADD_FIELD.equals(op.name) || ADD_DYNAMIC_FIELD.equals(op.name)) {
           applyAddField(op);
@@ -123,20 +132,51 @@ public class SchemaManager {
       }
       List errs = CommandOperation.captureErrors(operations);
       if (!errs.isEmpty()) return errs;
+      SolrResourceLoader loader = req.getCore().getResourceLoader();
+      if (loader instanceof ZkSolrResourceLoader) {
 
-      try {
-        managedIndexSchema.persistManagedSchema(false);
-        core.setLatestSchema(managedIndexSchema);
-        waitForOtherReplicasToUpdate(timeout, startTime);
-        return EMPTY_LIST;
-      } catch (ManagedIndexSchema.SchemaChangedInZkException e) {
-        String s = "Failed to update schema because schema is modified";
-        log.warn(s, e);
-        continue;
-      } catch (Exception e){
-        String s = "Exception persisting schema";
-        log.warn(s, e);
-        return singletonList(s + e.getMessage());
+        StringWriter sw = new StringWriter();
+        try {
+          managedIndexSchema.persist(sw);
+        } catch (IOException e) {
+          log.info("race condition ");
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "unable to serialize schema");
+          //unlikely
+        }
+
+        try {
+          ZkController.persistConfigResourceToZooKeeper(loader,
+              managedIndexSchema.getSchemaZkVersion(),
+              managedIndexSchema.getResourceName(),
+              sw.toString().getBytes(StandardCharsets.UTF_8),
+              true);
+          return EMPTY_LIST;
+        } catch (ZkController.ResourceModifiedInZkException e) {
+          log.info("Race condition schema modified by another node");
+          continue;
+        } catch (Exception e) {
+          String s = "Exception persisting schema";
+          log.warn(s, e);
+          return singletonList(s + e.getMessage());
+        }
+
+      }else {
+
+        try {
+          //only for non cloud stuff
+          managedIndexSchema.persistManagedSchema(false);
+          core.setLatestSchema(managedIndexSchema);
+          waitForOtherReplicasToUpdate(timeout, startTime);
+          return EMPTY_LIST;
+        } catch (ManagedIndexSchema.SchemaChangedInZkException e) {
+          String s = "Failed to update schema because schema is modified";
+          log.warn(s, e);
+          continue;
+        } catch (Exception e) {
+          String s = "Exception persisting schema";
+          log.warn(s, e);
+          return singletonList(s + e.getMessage());
+        }
       }
     }
 
@@ -231,4 +271,28 @@ public class SchemaManager {
     return true;
   }
 
+  public ManagedIndexSchema getFreshManagedSchema() throws IOException, KeeperException, InterruptedException {
+    SolrResourceLoader resourceLoader = req.getCore().getResourceLoader();
+    if (resourceLoader instanceof ZkSolrResourceLoader) {
+      ZkSolrResourceLoader loader = (ZkSolrResourceLoader) resourceLoader;
+      InputStream in = resourceLoader.openResource(req.getSchema().getResourceName());
+      if (in instanceof ZkSolrResourceLoader.ZkByteArrayInputStream) {
+        int version = ((ZkSolrResourceLoader.ZkByteArrayInputStream) in).getStat().getVersion();
+        log.info("managed schema loaded . version : {} ", version);
+        return new ManagedIndexSchema(req.getCore().getSolrConfig(),
+            req.getSchema().getResourceName() ,new InputSource(in),
+            true,
+            req.getSchema().getResourceName(),
+            version,new Object());
+      }else {
+        return (ManagedIndexSchema) req.getCore().getLatestSchema();
+      }
+
+    } else {
+      return (ManagedIndexSchema) req.getCore().getLatestSchema();
+    }
+
+
+
+  }
 }

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java Sun Dec  7 11:37:32 2014
@@ -343,26 +343,31 @@ public class SolrDispatchFilter extends
           // get or create/cache the parser for the core
           SolrRequestParsers parser = config.getRequestParsers();
 
-          // Handle /schema/* and /config/* paths via Restlet
-          if( path.equals("/schema") || path.startsWith("/schema/")
-              /*|| path.equals("/config") || path.startsWith("/config/")*/) {
-            solrReq = parser.parse(core, path, req);
-            SolrRequestInfo.setRequestInfo(new SolrRequestInfo(solrReq, new SolrQueryResponse()));
-            if( path.equals(req.getServletPath()) ) {
-              // avoid endless loop - pass through to Restlet via webapp
-              chain.doFilter(request, response);
-            } else {
-              // forward rewritten URI (without path prefix and core/collection name) to Restlet
-              req.getRequestDispatcher(path).forward(request, response);
-            }
-            return;
-          }
 
           // Determine the handler from the url path if not set
           // (we might already have selected the cores handler)
           if( handler == null && path.length() > 1 ) { // don't match "" or "/" as valid path
             handler = core.getRequestHandler( path );
+
+            if(handler == null){
+              //may be a restlet path
+              // Handle /schema/* paths via Restlet
+              if( path.equals("/schema") || path.startsWith("/schema/")) {
+                solrReq = parser.parse(core, path, req);
+                SolrRequestInfo.setRequestInfo(new SolrRequestInfo(solrReq, new SolrQueryResponse()));
+                if( path.equals(req.getServletPath()) ) {
+                  // avoid endless loop - pass through to Restlet via webapp
+                  chain.doFilter(request, response);
+                } else {
+                  // forward rewritten URI (without path prefix and core/collection name) to Restlet
+                  req.getRequestDispatcher(path).forward(request, response);
+                }
+                return;
+              }
+
+            }
             // no handler yet but allowed to handle select; let's check
+
             if( handler == null && parser.isHandleSelect() ) {
               if( "/select".equals( path ) || "/select/".equals( path ) ) {
                 solrReq = parser.parse( core, path, req );

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java Sun Dec  7 11:37:32 2014
@@ -53,6 +53,7 @@ import org.apache.solr.common.util.Conte
 import org.apache.solr.common.util.ContentStreamBase;
 import org.apache.solr.common.util.FastInputStream;
 import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.RequestHandlers;
 import org.apache.solr.core.SolrConfig;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
@@ -149,7 +150,7 @@ public class SolrRequestParsers
 
     // Handlers and login will want to know the path. If it contains a ':'
     // the handler could use it for RESTful URLs
-    sreq.getContext().put( "path", path );
+    sreq.getContext().put( "path", RequestHandlers.normalize(path) );
     sreq.getContext().put("httpMethod", req.getMethod());
 
     if(addHttpRequestToContext) {

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/BufferStore.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/BufferStore.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/BufferStore.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/BufferStore.java Sun Dec  7 11:37:32 2014
@@ -21,6 +21,7 @@ import java.util.concurrent.ArrayBlockin
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * @lucene.experimental
@@ -45,7 +46,14 @@ public class BufferStore implements Stor
 
   private final int bufferSize;
 
+  private final AtomicLong shardBuffercacheAllocate;
+  private final AtomicLong shardBuffercacheLost;
+
   public synchronized static void initNewBuffer(int bufferSize, long totalAmount) {
+    initNewBuffer(bufferSize, totalAmount, null);
+  }
+
+  public synchronized static void initNewBuffer(int bufferSize, long totalAmount, Metrics metrics) {
     if (totalAmount == 0) {
       return;
     }
@@ -55,13 +63,21 @@ public class BufferStore implements Stor
       if (count > Integer.MAX_VALUE) {
         count = Integer.MAX_VALUE;
       }
-      BufferStore store = new BufferStore(bufferSize, (int) count);
+      AtomicLong shardBuffercacheLost = new AtomicLong(0);
+      AtomicLong shardBuffercacheAllocate = new AtomicLong(0);
+      if (metrics != null) {
+        shardBuffercacheLost = metrics.shardBuffercacheLost;
+        shardBuffercacheAllocate = metrics.shardBuffercacheAllocate;
+      }
+      BufferStore store = new BufferStore(bufferSize, (int) count, shardBuffercacheAllocate, shardBuffercacheLost);
       bufferStores.put(bufferSize, store);
     }
   }
 
-  private BufferStore(int bufferSize, int count) {
+  private BufferStore(int bufferSize, int count, AtomicLong shardBuffercacheAllocate, AtomicLong shardBuffercacheLost) {
     this.bufferSize = bufferSize;
+    this.shardBuffercacheAllocate = shardBuffercacheAllocate;
+    this.shardBuffercacheLost = shardBuffercacheLost;
     buffers = setupBuffers(bufferSize, count);
   }
 
@@ -102,14 +118,17 @@ public class BufferStore implements Stor
     checkReturn(buffers.offer(buffer));
   }
 
-  private void checkReturn(boolean offer) {
-
+  private void checkReturn(boolean accepted) {
+    if (!accepted) {
+      shardBuffercacheLost.incrementAndGet();
+    }
   }
 
   private byte[] newBuffer(byte[] buf) {
     if (buf != null) {
       return buf;
     }
+    shardBuffercacheAllocate.incrementAndGet();
     return new byte[bufferSize];
   }
 }

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/CachedIndexOutput.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/CachedIndexOutput.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/CachedIndexOutput.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/CachedIndexOutput.java Sun Dec  7 11:37:32 2014
@@ -37,7 +37,7 @@ public class CachedIndexOutput extends R
   
   public CachedIndexOutput(BlockDirectory directory, IndexOutput dest,
       int blockSize, String name, Cache cache, int bufferSize) {
-    super(bufferSize);
+    super("dest=" + dest + " name=" + name, bufferSize);
     this.directory = directory;
     this.dest = dest;
     this.blockSize = blockSize;

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java Sun Dec  7 11:37:32 2014
@@ -49,9 +49,7 @@ public class Metrics implements Updater
   public AtomicLong recordWrites = new AtomicLong(0);
   public AtomicLong queriesExternal = new AtomicLong(0);
   public AtomicLong queriesInternal = new AtomicLong(0);
-  public AtomicLong shardBuffercacheAllocate1024 = new AtomicLong(0);
-  public AtomicLong shardBuffercacheAllocate8192 = new AtomicLong(0);
-  public AtomicLong shardBuffercacheAllocateOther = new AtomicLong(0);
+  public AtomicLong shardBuffercacheAllocate = new AtomicLong(0);
   public AtomicLong shardBuffercacheLost = new AtomicLong(0);
   public Map<String,MethodCall> methodCalls = new ConcurrentHashMap<>();
   
@@ -101,6 +99,8 @@ public class Metrics implements Updater
       metricsRecord.setMetric("record.writes", getPerSecond(recordWrites.getAndSet(0), seconds));
       metricsRecord.setMetric("query.external", getPerSecond(queriesExternal.getAndSet(0), seconds));
       metricsRecord.setMetric("query.internal", getPerSecond(queriesInternal.getAndSet(0), seconds));
+      metricsRecord.setMetric("buffercache.allocations", getPerSecond(shardBuffercacheAllocate.getAndSet(0), seconds));
+      metricsRecord.setMetric("buffercache.lost", getPerSecond(shardBuffercacheLost.getAndSet(0), seconds));
       for (Entry<String,MethodCall> entry : methodCalls.entrySet()) {
         String key = entry.getKey();
         MethodCall value = entry.getValue();

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/ReusedBufferedIndexOutput.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/ReusedBufferedIndexOutput.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/ReusedBufferedIndexOutput.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/blockcache/ReusedBufferedIndexOutput.java Sun Dec  7 11:37:32 2014
@@ -43,11 +43,12 @@ public abstract class ReusedBufferedInde
   
   private final Store store;
   
-  public ReusedBufferedIndexOutput() {
-    this(BUFFER_SIZE);
+  public ReusedBufferedIndexOutput(String resourceDescription) {
+    this(resourceDescription, BUFFER_SIZE);
   }
   
-  public ReusedBufferedIndexOutput(int bufferSize) {
+  public ReusedBufferedIndexOutput(String resourceDescription, int bufferSize) {
+    super(resourceDescription);
     checkBufferSize(bufferSize);
     this.bufferSize = bufferSize;
     store = BufferStore.instance(bufferSize);

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/hdfs/HdfsFileWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/hdfs/HdfsFileWriter.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/hdfs/HdfsFileWriter.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/store/hdfs/HdfsFileWriter.java Sun Dec  7 11:37:32 2014
@@ -38,7 +38,7 @@ public class HdfsFileWriter extends Outp
   public static final int BUFFER_SIZE = 16384;
   
   public HdfsFileWriter(FileSystem fileSystem, Path path) throws IOException {
-    super(getOutputStream(fileSystem, path), BUFFER_SIZE);
+    super("fileSystem=" + fileSystem + " path=" + path, getOutputStream(fileSystem, path), BUFFER_SIZE);
   }
   
   private static final OutputStream getOutputStream(FileSystem fileSystem, Path path) throws IOException {

Modified: lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java Sun Dec  7 11:37:32 2014
@@ -94,7 +94,10 @@ class RunUpdateProcessor extends UpdateR
   {
     updateHandler.commit(cmd);
     super.processCommit(cmd);
-    changesSinceCommit = false;
+    if (!cmd.softCommit) {
+      // a hard commit means we don't need to flush the transaction log
+      changesSinceCommit = false;
+    }
   }
 
   /**

Modified: lucene/dev/branches/lucene6005/solr/core/src/test-files/solr/collection1/conf/schema11.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test-files/solr/collection1/conf/schema11.xml?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test-files/solr/collection1/conf/schema11.xml (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test-files/solr/collection1/conf/schema11.xml Sun Dec  7 11:37:32 2014
@@ -330,6 +330,7 @@ valued. -->
         Longer patterns will be matched first.  if equal size patterns
         both match, the first appearing in the schema will be used.  -->
    <dynamicField name="*_s"  	type="string"  indexed="true"  stored="true"/>
+   <dynamicField name="*_s_dv"  type="string"  indexed="true"  stored="true" docValues="true"/>
    <dynamicField name="*_ss"  	type="string"  indexed="true"  stored="true" multiValued="true"/>
    <dynamicField name="*_sS" 	type="string"  indexed="false" stored="true"/>
    <dynamicField name="*_i"  	type="int"    indexed="true"  stored="true"/>

Modified: lucene/dev/branches/lucene6005/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml Sun Dec  7 11:37:32 2014
@@ -482,6 +482,21 @@
     </lst>
   </requestHandler>
 
+  <requestHandler name="/search-facet-def" class="solr.SearchHandler" >
+    <lst name="defaults">
+      <str name="facet.field">foo_s</str>
+    </lst>
+    <lst name="appends">
+      <str name="facet.query">foo_s:bar</str>
+    </lst>
+  </requestHandler>
+  <requestHandler name="/search-facet-invariants" class="solr.SearchHandler" >
+    <lst name="invariants">
+      <str name="facet.field">foo_s</str>
+      <str name="facet.query">foo_s:bar</str>
+    </lst>
+  </requestHandler>
+
   <admin>
     <defaultQuery>solr</defaultQuery>
     <gettableFiles>solrconfig.xml schema.xml admin-extra.html</gettableFiles>

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/MinimalSchemaTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/MinimalSchemaTest.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/MinimalSchemaTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/MinimalSchemaTest.java Sun Dec  7 11:37:32 2014
@@ -106,13 +106,15 @@ public class MinimalSchemaTest extends S
     for (String handler : handlerNames) {
       try {
 
-        if (handler.startsWith("/update")) {
-          continue;
-        }
-        if (handler.startsWith("/mlt")) {
+
+        if (handler.startsWith("/update") ||
+            handler.startsWith("/admin") ||
+            handler.startsWith("/schema") ||
+            handler.startsWith("/config") ||
+            handler.startsWith("/mlt")
+            ) {
           continue;
         }
-        if(handler.equals("/admin/ping")) continue;
 
         assertQ("failure w/handler: '" + handler + "'",
                 req("qt", handler,

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java Sun Dec  7 11:37:32 2014
@@ -18,6 +18,7 @@ package org.apache.solr.cloud;
  */
 
 import java.io.File;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -40,9 +41,12 @@ import org.apache.solr.common.SolrInputD
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.cloud.ZkCoreNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.servlet.SolrDispatchFilter;
 import org.junit.After;
 import org.junit.Before;
 import org.slf4j.Logger;
@@ -104,6 +108,8 @@ public class HttpPartitionTest extends A
   public void doTest() throws Exception {
     waitForThingsToLevelOut(30000);
 
+    testLeaderInitiatedRecoveryCRUD();
+
     // test a 1x2 collection
     testRf2();
 
@@ -122,7 +128,59 @@ public class HttpPartitionTest extends A
 
     log.info("HttpParitionTest succeeded ... shutting down now!");
   }
-  
+
+  /**
+   * Tests handling of lir state znodes.
+   */
+  protected void testLeaderInitiatedRecoveryCRUD() throws Exception {
+    String testCollectionName = "c8n_crud_1x2";
+    String shardId = "shard1";
+    createCollection(testCollectionName, 1, 2, 1);
+    cloudClient.setDefaultCollection(testCollectionName);
+
+    Replica leader =
+        cloudClient.getZkStateReader().getLeaderRetry(testCollectionName, shardId);
+    JettySolrRunner leaderJetty = getJettyOnPort(getReplicaPort(leader));
+
+    CoreContainer cores = ((SolrDispatchFilter)leaderJetty.getDispatchFilter().getFilter()).getCores();
+    ZkController zkController = cores.getZkController();
+    assertNotNull("ZkController is null", zkController);
+
+    Replica notLeader =
+        ensureAllReplicasAreActive(testCollectionName, shardId, 1, 2, maxWaitSecsToSeeAllActive).get(0);
+
+    ZkCoreNodeProps replicaCoreNodeProps = new ZkCoreNodeProps(notLeader);
+    String replicaUrl = replicaCoreNodeProps.getCoreUrl();
+
+    assertTrue(!zkController.isReplicaInRecoveryHandling(replicaUrl));
+    assertTrue(zkController.ensureReplicaInLeaderInitiatedRecovery(testCollectionName, shardId, replicaUrl, replicaCoreNodeProps, false));
+    assertTrue(zkController.isReplicaInRecoveryHandling(replicaUrl));
+    Map<String,Object> lirStateMap = zkController.getLeaderInitiatedRecoveryStateObject(testCollectionName, shardId, notLeader.getName());
+    assertNotNull(lirStateMap);
+    assertEquals(ZkStateReader.DOWN, lirStateMap.get("state"));
+    zkController.removeReplicaFromLeaderInitiatedRecoveryHandling(replicaUrl);
+    assertTrue(!zkController.isReplicaInRecoveryHandling(replicaUrl));
+
+    // test old non-json format handling
+    SolrZkClient zkClient = zkController.getZkClient();
+    String znodePath = zkController.getLeaderInitiatedRecoveryZnodePath(testCollectionName, shardId, notLeader.getName());
+    zkClient.setData(znodePath, "down".getBytes(StandardCharsets.UTF_8), true);
+    lirStateMap = zkController.getLeaderInitiatedRecoveryStateObject(testCollectionName, shardId, notLeader.getName());
+    assertNotNull(lirStateMap);
+    assertEquals(ZkStateReader.DOWN, lirStateMap.get("state"));
+    zkClient.delete(znodePath, -1, false);
+
+    // try to clean up
+    try {
+      CollectionAdminRequest req = new CollectionAdminRequest.Delete();
+      req.setCollectionName(testCollectionName);
+      req.process(cloudClient);
+    } catch (Exception e) {
+      // don't fail the test
+      log.warn("Could not delete collection {} after test completed", testCollectionName);
+    }
+  }
+
   protected void testRf2() throws Exception {
     // create a collection that has 1 shard but 2 replicas
     String testCollectionName = "c8n_1x2";

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java Sun Dec  7 11:37:32 2014
@@ -909,11 +909,13 @@ public class OverseerTest extends SolrTe
 
       mockController = new MockZKController(server.getZkAddress(), "node1");
 
-      for (int i=0; i<100; i++)  {
+      final int MAX_COLLECTIONS = 10, MAX_CORES = 10, MAX_STATE_CHANGES = 20000, STATE_FORMAT = 2;
+
+      for (int i=0; i<MAX_COLLECTIONS; i++)  {
         ZkNodeProps m = new ZkNodeProps(Overseer.QUEUE_OPERATION, CollectionParams.CollectionAction.CREATE.toLower(),
             "name", "perf" + i,
             ZkStateReader.NUM_SHARDS_PROP, "1",
-            "stateFormat", "2",
+            "stateFormat", String.valueOf(STATE_FORMAT),
             ZkStateReader.REPLICATION_FACTOR, "1",
             ZkStateReader.MAX_SHARDS_PER_NODE, "1"
             );
@@ -922,7 +924,7 @@ public class OverseerTest extends SolrTe
         controllerClient.makePath("/collections/perf" + i, true);
       }
 
-      for (int i = 0, j = 0, k = 0; i < 20000; i++, j++, k++) {
+      for (int i = 0, j = 0, k = 0; i < MAX_STATE_CHANGES; i++, j++, k++) {
         ZkNodeProps m = new ZkNodeProps(Overseer.QUEUE_OPERATION, OverseerAction.STATE.toLower(),
             ZkStateReader.STATE_PROP, ZkStateReader.RECOVERING,
             ZkStateReader.NODE_NAME_PROP,  "node1",
@@ -934,8 +936,8 @@ public class OverseerTest extends SolrTe
             + "/solr/");
         DistributedQueue q = Overseer.getInQueue(controllerClient);
         q.offer(ZkStateReader.toJSON(m));
-        if (j == 99) j = 0;
-        if (k == 9) k = 0;
+        if (j >= MAX_COLLECTIONS - 1) j = 0;
+        if (k >= MAX_CORES - 1) k = 0;
         if (i > 0 && i % 100 == 0) log.info("Published {} items", i);
       }
 

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentOptimizationTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentOptimizationTest.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentOptimizationTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentOptimizationTest.java Sun Dec  7 11:37:32 2014
@@ -20,7 +20,9 @@ package org.apache.solr.handler.componen
 import org.apache.solr.BaseDistributedSearchTestCase;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.ShardParams;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.junit.BeforeClass;
 
@@ -115,6 +117,17 @@ public class DistributedQueryComponentOp
 
     verifySinglePass("q", "id:19", "fl", "id,*a_sS", "sort", "payload asc", "distrib.singlePass", "true");
     verifySinglePass("q", "id:19", "fl", "id,dynamic,cat*", "sort", "payload asc", "distrib.singlePass", "true");
+
+    // see SOLR-6795, distrib.singlePass=true would return score even when not asked for
+    handle.clear();
+    handle.put("timestamp", SKIPVAL);
+    handle.put("_version_", SKIPVAL);
+    // we don't to compare maxScore because most distributed requests return it anyway (just because they have score already)
+    handle.put("maxScore", SKIPVAL);
+    query("q", "{!func}id", ShardParams.DISTRIB_SINGLE_PASS, "true");
+
+    // fix for a bug where not all fields are returned if using multiple fl parameters, see SOLR-6796
+    query("q","*:*", "fl", "id", "fl","dynamic","sort","payload desc", ShardParams.DISTRIB_SINGLE_PASS, "true");
   }
 
   private void verifySinglePass(String... q) throws SolrServerException {

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java Sun Dec  7 11:37:32 2014
@@ -126,6 +126,59 @@ public class SimpleFacetsTest extends So
     add_doc("id", "2004", "hotel_s1", "b", "airport_s1", "ams", "duration_i1", "5");
   }
 
+
+  public void testDefaultsAndAppends() throws Exception {
+    // all defaults
+    assertQ( req("indent","true", "q","*:*", "rows","0", "facet","true", "qt","/search-facet-def")
+             // only one default facet.field
+             ,"//lst[@name='facet_fields']/lst[@name='foo_s']"
+             ,"count(//lst[@name='facet_fields']/lst[@name='foo_s'])=1"
+             ,"count(//lst[@name='facet_fields']/lst)=1"
+             // only one default facet.query
+             ,"//lst[@name='facet_queries']/int[@name='foo_s:bar']"
+             ,"count(//lst[@name='facet_queries']/int[@name='foo_s:bar'])=1"
+             ,"count(//lst[@name='facet_queries']/int)=1"
+             );
+
+    // override default & pre-pend to appends
+    assertQ( req("indent","true", "q","*:*", "rows","0", "facet","true", "qt","/search-facet-def",
+                 "facet.field", "bar_s",
+                 "facet.query", "bar_s:yak"
+                 )
+             // override single default facet.field
+             ,"//lst[@name='facet_fields']/lst[@name='bar_s']"
+             ,"count(//lst[@name='facet_fields']/lst[@name='bar_s'])=1"
+             ,"count(//lst[@name='facet_fields']/lst)=1"
+             // add an additional facet.query
+             ,"//lst[@name='facet_queries']/int[@name='foo_s:bar']"
+             ,"//lst[@name='facet_queries']/int[@name='bar_s:yak']"
+             ,"count(//lst[@name='facet_queries']/int[@name='foo_s:bar'])=1"
+             ,"count(//lst[@name='facet_queries']/int[@name='bar_s:yak'])=1"
+             ,"count(//lst[@name='facet_queries']/int)=2"
+             );
+  }
+
+  public void testInvariants() throws Exception {
+    // no matter if we try to use facet.field or facet.query, results shouldn't change
+    for (String ff : new String[] { "facet.field", "bogus" }) {
+      for (String fq : new String[] { "facet.query", "bogus" }) {
+        assertQ( req("indent","true", "q", "*:*", "rows","0", "facet","true", 
+                     "qt","/search-facet-invariants",
+                     ff, "bar_s",
+                     fq, "bar_s:yak")
+                 // only one invariant facet.field
+                 ,"//lst[@name='facet_fields']/lst[@name='foo_s']"
+                 ,"count(//lst[@name='facet_fields']/lst[@name='foo_s'])=1"
+                 ,"count(//lst[@name='facet_fields']/lst)=1"
+                 // only one invariant facet.query
+                 ,"//lst[@name='facet_queries']/int[@name='foo_s:bar']"
+                 ,"count(//lst[@name='facet_queries']/int[@name='foo_s:bar'])=1"
+                 ,"count(//lst[@name='facet_queries']/int)=1"
+                 );
+      }
+    }
+  }
+
   @Test
   public void testCachingBigTerms() throws Exception {
     assertQ( req("indent","true", "q", "id:[42 TO 47]",

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/SolrRestletTestBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/SolrRestletTestBase.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/SolrRestletTestBase.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/SolrRestletTestBase.java Sun Dec  7 11:37:32 2014
@@ -47,10 +47,6 @@ abstract public class SolrRestletTestBas
     solrSchemaRestApi.setInitParameter("org.restlet.application", "org.apache.solr.rest.SolrSchemaRestApi");
     extraServlets.put(solrSchemaRestApi, "/schema/*");  // '/schema/*' matches '/schema', '/schema/', and '/schema/whatever...'
 
-    final ServletHolder solrConfigRestApi = new ServletHolder("SolrConfigRestApi", ServerServlet.class);
-    solrConfigRestApi.setInitParameter("org.restlet.application", "org.apache.solr.rest.SolrConfigRestApi");
-    extraServlets.put(solrConfigRestApi, "/config/*");
-
     createJettyAndHarness(TEST_HOME(), "solrconfig.xml", "schema-rest.xml", "/solr", true, extraServlets);
   }
 }

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/TestRestManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/TestRestManager.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/TestRestManager.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/TestRestManager.java Sun Dec  7 11:37:32 2014
@@ -125,7 +125,6 @@ public class TestRestManager extends Sol
     Set<String> reservedEndpoints = registry.getReservedEndpoints();
     assertTrue(reservedEndpoints.size() > 2);
     assertTrue(reservedEndpoints.contains(RestManager.SCHEMA_BASE_PATH + RestManager.MANAGED_ENDPOINT));
-    assertTrue(reservedEndpoints.contains(RestManager.CONFIG_BASE_PATH + RestManager.MANAGED_ENDPOINT));
     for (String endpoint : reservedEndpoints) {
 
       try {

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java Sun Dec  7 11:37:32 2014
@@ -25,6 +25,7 @@ import org.apache.solr.cloud.AbstractFul
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.util.RESTfulServerProvider;
 import org.apache.solr.util.RestTestHarness;
+import org.junit.BeforeClass;
 import org.noggit.JSONParser;
 import org.noggit.ObjectBuilder;
 import org.slf4j.Logger;
@@ -48,6 +49,16 @@ public class TestBulkSchemaConcurrent  e
   static final Logger log =  LoggerFactory.getLogger(TestBulkSchemaConcurrent.class);
   private List<RestTestHarness> restTestHarnesses = new ArrayList<>();
 
+  @BeforeClass
+  public static void initSysProperties() {
+    System.setProperty("managed.schema.mutable", "true");
+    System.setProperty("enable.update.log", "true");
+  }
+
+  protected String getCloudSolrConfig() {
+    return "solrconfig-managed-schema.xml";
+  }
+
   private void setupHarnesses() {
     for (final SolrServer client : clients) {
       RestTestHarness harness = new RestTestHarness(new RESTfulServerProvider() {
@@ -101,7 +112,7 @@ public class TestBulkSchemaConcurrent  e
 
     }
 
-    assertTrue(success);
+    assertTrue(collectErrors.toString(), success);
 
 
   }
@@ -138,7 +149,7 @@ public class TestBulkSchemaConcurrent  e
 
 
     RestTestHarness publisher = restTestHarnesses.get(r.nextInt(restTestHarnesses.size()));
-    payload = payload.replace("replaceFieldA1", aField);
+    payload = payload.replace("replaceFieldA", aField);
 
     payload = payload.replace("replaceDynamicField", dynamicFldName);
     payload = payload.replace("dynamicFieldLol","lol"+seed);

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/TestCollapseQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/TestCollapseQParserPlugin.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/TestCollapseQParserPlugin.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/TestCollapseQParserPlugin.java Sun Dec  7 11:37:32 2014
@@ -17,18 +17,16 @@
 
 package org.apache.solr.search;
 
+import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import com.carrotsearch.hppc.IntOpenHashSet;
-
-import java.io.IOException;
-import java.util.*;
-import java.util.Random;
 
+//We want codecs that support DocValues, and ones supporting blank/empty values.
+@SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42"})
 public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
 
   @BeforeClass
@@ -48,10 +46,12 @@ public class TestCollapseQParserPlugin e
 
   @Test
   public void testCollapseQueries() throws Exception {
-    String[] doc = {"id","1", "term_s", "YYYY", "group_s", "group1", "test_ti", "5", "test_tl", "10", "test_tf", "2000"};
+    final String group = (random().nextBoolean() ? "group_s" : "group_s_dv");
+    
+    String[] doc = {"id","1", "term_s", "YYYY", group, "group1", "test_ti", "5", "test_tl", "10", "test_tf", "2000"};
     assertU(adoc(doc));
     assertU(commit());
-    String[] doc1 = {"id","2", "term_s","YYYY", "group_s", "group1", "test_ti", "50", "test_tl", "100", "test_tf", "200"};
+    String[] doc1 = {"id","2", "term_s","YYYY", group, "group1", "test_ti", "50", "test_tl", "100", "test_tf", "200"};
     assertU(adoc(doc1));
 
 
@@ -63,10 +63,10 @@ public class TestCollapseQParserPlugin e
     assertU(adoc(doc3));
 
 
-    String[] doc4 = {"id","5", "term_s", "YYYY", "group_s", "group2", "test_ti", "4", "test_tl", "10", "test_tf", "2000"};
+    String[] doc4 = {"id","5", "term_s", "YYYY", group, "group2", "test_ti", "4", "test_tl", "10", "test_tf", "2000"};
     assertU(adoc(doc4));
     assertU(commit());
-    String[] doc5 = {"id","6", "term_s","YYYY", "group_s", "group2", "test_ti", "10", "test_tl", "100", "test_tf", "200"};
+    String[] doc5 = {"id","6", "term_s","YYYY", group, "group2", "test_ti", "10", "test_tl", "100", "test_tf", "200"};
     assertU(adoc(doc5));
     assertU(commit());
 
@@ -75,10 +75,10 @@ public class TestCollapseQParserPlugin e
     //Test collapse by score and following sort by score
     ModifiableSolrParams params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s}");
+    params.add("fq", "{!collapse field="+group+"}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
-    assertQ(req(params), "*[count(//doc)=2]",
+    assertQ(req(params, "indent", "on"), "*[count(//doc)=2]",
                        "//result/doc[1]/float[@name='id'][.='2.0']",
                        "//result/doc[2]/float[@name='id'][.='6.0']"
         );
@@ -87,7 +87,7 @@ public class TestCollapseQParserPlugin e
     // SOLR-5544 test ordering with empty sort param
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s nullPolicy=expand min=test_tf}");
+    params.add("fq", "{!collapse field="+group+" nullPolicy=expand min=test_tf}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     params.add("sort","");
@@ -101,7 +101,7 @@ public class TestCollapseQParserPlugin e
     // Test value source collapse criteria
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s nullPolicy=collapse min=field(test_ti)}");
+    params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=field(test_ti)}");
     params.add("sort", "test_ti desc");
     assertQ(req(params), "*[count(//doc)=3]",
         "//result/doc[1]/float[@name='id'][.='4.0']",
@@ -112,7 +112,7 @@ public class TestCollapseQParserPlugin e
     // Test value source collapse criteria with cscore function
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s nullPolicy=collapse min=cscore()}");
+    params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=cscore()}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     assertQ(req(params), "*[count(//doc)=3]",
@@ -124,7 +124,7 @@ public class TestCollapseQParserPlugin e
     // Test value source collapse criteria with compound cscore function
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s nullPolicy=collapse min=sum(cscore(),field(test_ti))}");
+    params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=sum(cscore(),field(test_ti))}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     assertQ(req(params), "*[count(//doc)=3]",
@@ -137,7 +137,7 @@ public class TestCollapseQParserPlugin e
 
     params = new ModifiableSolrParams();
     params.add("q", "YYYY");
-    params.add("fq", "{!collapse field=group_s nullPolicy=collapse}");
+    params.add("fq", "{!collapse field="+group+" nullPolicy=collapse}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     params.add("qf", "term_s");
@@ -151,7 +151,7 @@ public class TestCollapseQParserPlugin e
     //Test SOLR-5773 with score collapse criteria
     params = new ModifiableSolrParams();
     params.add("q", "YYYY");
-    params.add("fq", "{!collapse field=group_s nullPolicy=collapse}");
+    params.add("fq", "{!collapse field="+group+" nullPolicy=collapse}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     params.add("qf", "term_s");
@@ -165,7 +165,7 @@ public class TestCollapseQParserPlugin e
     //Test SOLR-5773 with max field collapse criteria
     params = new ModifiableSolrParams();
     params.add("q", "YYYY");
-    params.add("fq", "{!collapse field=group_s min=test_ti nullPolicy=collapse}");
+    params.add("fq", "{!collapse field="+group+" min=test_ti nullPolicy=collapse}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     params.add("qf", "term_s");
@@ -180,7 +180,7 @@ public class TestCollapseQParserPlugin e
     //Test SOLR-5773 elevating documents with null group
     params = new ModifiableSolrParams();
     params.add("q", "YYYY");
-    params.add("fq", "{!collapse field=group_s}");
+    params.add("fq", "{!collapse field="+group+"}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     params.add("qf", "term_s");
@@ -197,7 +197,7 @@ public class TestCollapseQParserPlugin e
     //Test collapse by min int field and sort
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s min=test_ti}");
+    params.add("fq", "{!collapse field="+group+" min=test_ti}");
     params.add("sort", "id desc");
     assertQ(req(params), "*[count(//doc)=2]",
                            "//result/doc[1]/float[@name='id'][.='5.0']",
@@ -205,7 +205,7 @@ public class TestCollapseQParserPlugin e
 
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s min=test_ti}");
+    params.add("fq", "{!collapse field="+group+" min=test_ti}");
     params.add("sort", "id asc");
     assertQ(req(params), "*[count(//doc)=2]",
                          "//result/doc[1]/float[@name='id'][.='1.0']",
@@ -213,7 +213,7 @@ public class TestCollapseQParserPlugin e
 
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s min=test_ti}");
+    params.add("fq", "{!collapse field="+group+" min=test_ti}");
     params.add("sort", "test_tl asc,id desc");
     assertQ(req(params), "*[count(//doc)=2]",
         "//result/doc[1]/float[@name='id'][.='5.0']",
@@ -221,7 +221,7 @@ public class TestCollapseQParserPlugin e
 
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s min=test_ti}");
+    params.add("fq", "{!collapse field="+group+" min=test_ti}");
     params.add("sort", "score desc,id asc");
     params.add("defType", "edismax");
     params.add("bf", "field(id)");
@@ -235,7 +235,7 @@ public class TestCollapseQParserPlugin e
     //Test collapse by max int field
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s max=test_ti}");
+    params.add("fq", "{!collapse field="+group+" max=test_ti}");
     params.add("sort", "test_ti asc");
     assertQ(req(params), "*[count(//doc)=2]",
                          "//result/doc[1]/float[@name='id'][.='6.0']",
@@ -247,7 +247,7 @@ public class TestCollapseQParserPlugin e
     //Test collapse by min long field
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s min=test_tl}");
+    params.add("fq", "{!collapse field="+group+" min=test_tl}");
     params.add("sort", "test_ti desc");
     assertQ(req(params), "*[count(//doc)=2]",
         "//result/doc[1]/float[@name='id'][.='1.0']",
@@ -257,7 +257,7 @@ public class TestCollapseQParserPlugin e
     //Test collapse by max long field
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s max=test_tl}");
+    params.add("fq", "{!collapse field="+group+" max=test_tl}");
     params.add("sort", "test_ti desc");
     assertQ(req(params), "*[count(//doc)=2]",
                          "//result/doc[1]/float[@name='id'][.='2.0']",
@@ -267,7 +267,7 @@ public class TestCollapseQParserPlugin e
     //Test collapse by min float field
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s min=test_tf}");
+    params.add("fq", "{!collapse field="+group+" min=test_tf}");
     params.add("sort", "test_ti desc");
     assertQ(req(params), "*[count(//doc)=2]",
                          "//result/doc[1]/float[@name='id'][.='2.0']",
@@ -279,7 +279,7 @@ public class TestCollapseQParserPlugin e
     //Test collapse by min float field
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s max=test_tf}");
+    params.add("fq", "{!collapse field="+group+" max=test_tf}");
     params.add("sort", "test_ti asc");
     assertQ(req(params), "*[count(//doc)=2]",
                          "//result/doc[1]/float[@name='id'][.='5.0']",
@@ -288,7 +288,7 @@ public class TestCollapseQParserPlugin e
     //Test collapse by min float field sort by score
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s max=test_tf}");
+    params.add("fq", "{!collapse field="+group+" max=test_tf}");
     params.add("defType", "edismax");
     params.add("bf", "field(id)");
     params.add("fl", "score, id");
@@ -304,7 +304,7 @@ public class TestCollapseQParserPlugin e
     //Test nullPolicy expand
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s max=test_tf nullPolicy=expand}");
+    params.add("fq", "{!collapse field="+group+" max=test_tf nullPolicy=expand}");
     params.add("sort", "id desc");
     assertQ(req(params), "*[count(//doc)=4]",
         "//result/doc[1]/float[@name='id'][.='5.0']",
@@ -316,7 +316,7 @@ public class TestCollapseQParserPlugin e
 
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s max=test_tf nullPolicy=collapse}");
+    params.add("fq", "{!collapse field="+group+" max=test_tf nullPolicy=collapse}");
     params.add("sort", "id desc");
     assertQ(req(params), "*[count(//doc)=3]",
         "//result/doc[1]/float[@name='id'][.='5.0']",
@@ -326,7 +326,7 @@ public class TestCollapseQParserPlugin e
 
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s}");
+    params.add("fq", "{!collapse field="+group+"}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     params.add("fq","{!tag=test_ti}id:5");
@@ -338,7 +338,7 @@ public class TestCollapseQParserPlugin e
     // SOLR-5230 - ensure CollapsingFieldValueCollector.finish() is called
     params = new ModifiableSolrParams();
     params.add("q", "*:*");
-    params.add("fq", "{!collapse field=group_s}");
+    params.add("fq", "{!collapse field="+group+"}");
     params.add("group", "true");
     params.add("group.field", "id");
     assertQ(req(params), "*[count(//doc)=2]");
@@ -350,7 +350,7 @@ public class TestCollapseQParserPlugin e
     assertU(commit());
     params = new ModifiableSolrParams();
     params.add("q", "YYYY");
-    params.add("fq", "{!collapse field=group_s nullPolicy=collapse}");
+    params.add("fq", "{!collapse field="+group+" nullPolicy=collapse}");
     params.add("defType", "edismax");
     params.add("bf", "field(test_ti)");
     params.add("qf", "term_s");
@@ -371,4 +371,18 @@ public class TestCollapseQParserPlugin e
         SolrException.ErrorCode.BAD_REQUEST);
   }
 
+  @Test
+  public void testEmptyCollection() throws Exception {
+    // group_s is docValues=false and group_dv_s is docValues=true
+    String group = (random().nextBoolean() ? "group_s" : "group_s_dv");
+
+    // min-or-max is for CollapsingScoreCollector vs. CollapsingFieldValueCollector
+    String optional_min_or_max = (random().nextBoolean() ? "" : (random().nextBoolean() ? "min=field(test_ti)" : "max=field(test_ti)"));
+    
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.add("q", "*:*");
+    params.add("fq", "{!collapse field="+group+" "+optional_min_or_max+"}");
+    assertQ(req(params), "*[count(//doc)=0]");
+  }
+
 }

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java Sun Dec  7 11:37:32 2014
@@ -23,12 +23,17 @@ import org.apache.solr.common.SolrDocume
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 
 public class CloudMLTQParserTest extends AbstractFullDistribZkTestBase {
+
+  static Logger log = LoggerFactory.getLogger(CloudMLTQParserTest.class);
+  
   public CloudMLTQParserTest() {
     fixShardCount = true;
     shardCount = 2;
@@ -125,13 +130,20 @@ public class CloudMLTQParserTest extends
     String expectedQueryString = "lowerfilt:over lowerfilt:fox lowerfilt:lazy lowerfilt:brown "
         + "lowerfilt:jumped lowerfilt:red lowerfilt:dogs. lowerfilt:quote lowerfilt:the";
     
-    ArrayList<String> actualParsedQueries = (ArrayList<String>) queryResponse
-        .getDebugMap().get("parsedquery");
-    
-    for(int counter=0; counter < actualParsedQueries.size(); counter++) {
-      assertTrue("Parsed queries aren't equal",
-          compareParsedQueryStrings(expectedQueryString,
-          actualParsedQueries.get(counter)));
+    try {
+      ArrayList<String> actualParsedQueries = (ArrayList<String>) queryResponse
+          .getDebugMap().get("parsedquery");
+
+      for (int counter = 0; counter < actualParsedQueries.size(); counter++) {
+        assertTrue("Parsed queries aren't equal",
+            compareParsedQueryStrings(expectedQueryString,
+                actualParsedQueries.get(counter)));
+      }
+    } catch (ClassCastException ex) {
+      // TODO: Adding this to just track a rare test failure.
+      // Once SOLR-6755 is resolved, this should be removed.
+      log.info("QueryResponse.debugMap: {}", queryResponse.getDebugMap().toString());
+      log.info("ClusterState: {}", cloudClient.getZkStateReader().getClusterState().toString());
     }
 
     // Assert that {!mlt}id does not throw an exception i.e. implicitly, only fields that are stored + have explicit

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/params/DefaultSolrParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/params/DefaultSolrParams.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/params/DefaultSolrParams.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/params/DefaultSolrParams.java Sun Dec  7 11:37:32 2014
@@ -18,8 +18,7 @@
 package org.apache.solr.common.params;
 
 import java.util.Iterator;
-
-import org.apache.solr.common.util.IteratorChain;
+import java.util.LinkedHashSet;
 
 /**
  *
@@ -52,10 +51,17 @@ public class DefaultSolrParams extends S
 
   @Override
   public Iterator<String> getParameterNamesIterator() {
-    final IteratorChain<String> c = new IteratorChain<>();
-    c.addIterator(defaults.getParameterNamesIterator());
-    c.addIterator(params.getParameterNamesIterator());
-    return c;
+    // We need to compute the set of all param names in advance 
+    // So we don't wind up with an iterator that returns the same
+    // String more then once (SOLR-6780)
+    LinkedHashSet<String> allKeys = new LinkedHashSet<>();
+    for (SolrParams p : new SolrParams [] {params, defaults}) {
+      Iterator<String> localKeys = p.getParameterNamesIterator();
+      while (localKeys.hasNext()) {
+        allKeys.add(localKeys.next());
+      }
+    }
+    return allKeys.iterator();
   }
 
   @Override

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/util/IteratorChain.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/util/IteratorChain.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/util/IteratorChain.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/util/IteratorChain.java Sun Dec  7 11:37:32 2014
@@ -23,8 +23,10 @@ import java.util.List;
 
 /** Chain several Iterators, so that this iterates
  *  over all of them in sequence.
+ *
+ * @deprecated This class is no longer used by Solr, and may be removed in future versions
  */
-
+@Deprecated
 public class IteratorChain<E> implements Iterator<E> {
 
   private final List<Iterator<E>> iterators = new ArrayList<>();

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/common/params/SolrParamTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/common/params/SolrParamTest.java?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/common/params/SolrParamTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/common/params/SolrParamTest.java Sun Dec  7 11:37:32 2014
@@ -19,14 +19,93 @@ package org.apache.solr.common.params;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
 
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.solr.common.SolrException;
 
 /**
  */
-public class SolrParamTest extends LuceneTestCase 
-{  
+public class SolrParamTest extends LuceneTestCase {  
+
+  public void testParamIterators() {
+
+    ModifiableSolrParams aaa = new ModifiableSolrParams();
+    aaa.add("foo", "a1");
+    aaa.add("foo", "a2");
+
+    assertIterSize("aaa: foo", 1, aaa);
+    assertIterSize("required aaa: foo", 1, aaa.required());
+
+    assertEquals(new String[] { "a1", "a2" }, aaa.getParams("foo"));
+
+    aaa.add("yak", "a3");
+
+    assertIterSize("aaa: foo & yak", 2, aaa);
+    assertIterSize("required aaa: foo & yak", 2, aaa.required());
+
+    assertEquals(new String[] { "a1", "a2" }, aaa.getParams("foo"));
+    assertEquals(new String[] { "a3" }, aaa.getParams("yak"));
+
+    ModifiableSolrParams bbb = new ModifiableSolrParams();
+    bbb.add("foo", "b1");
+    bbb.add("foo", "b2");
+    bbb.add("zot", "b3");
+
+    assertIterSize("bbb: foo & zot", 2, bbb);
+    assertIterSize("required bbb: foo & zot", 2, bbb.required());
+
+    assertEquals(new String[] { "b1", "b2" }, bbb.getParams("foo"));
+    assertEquals(new String[] { "b3" }, bbb.getParams("zot"));
+
+    SolrParams def = SolrParams.wrapDefaults(aaa, bbb);
+
+    assertIterSize("def: aaa + bbb", 3, def);
+    assertIterSize("required def: aaa + bbb", 3, def.required());
+
+    assertEquals(new String[] { "a1", "a2" }, def.getParams("foo"));
+    assertEquals(new String[] { "a3" }, def.getParams("yak"));
+    assertEquals(new String[] { "b3" }, def.getParams("zot"));
+
+    SolrParams append = SolrParams.wrapAppended(aaa, bbb);
+
+    assertIterSize("append: aaa + bbb", 3, append);
+    assertIterSize("required appended: aaa + bbb", 3, append.required());
+
+    assertEquals(new String[] { "a1", "a2", "b1", "b2", }, append.getParams("foo"));
+    assertEquals(new String[] { "a3" }, append.getParams("yak"));
+    assertEquals(new String[] { "b3" }, append.getParams("zot"));
+
+  }
+
+  public void testModParamAddParams() {
+
+    ModifiableSolrParams aaa = new ModifiableSolrParams();
+    aaa.add("foo", "a1");
+    aaa.add("foo", "a2");
+    aaa.add("yak", "a3");
+    
+    ModifiableSolrParams bbb = new ModifiableSolrParams();
+    bbb.add("foo", "b1");
+    bbb.add("foo", "b2");
+    bbb.add("zot", "b3");
+    
+    SolrParams def = SolrParams.wrapDefaults(aaa, bbb);
+    assertEquals(new String[] { "a1", "a2" }, def.getParams("foo"));
+    assertEquals(new String[] { "a3" }, def.getParams("yak"));
+    assertEquals(new String[] { "b3" }, def.getParams("zot"));
+
+    ModifiableSolrParams combined = new ModifiableSolrParams();
+    combined.add(def);
+
+    assertEquals(new String[] { "a1", "a2" }, combined.getParams("foo"));
+    assertEquals(new String[] { "a3" }, combined.getParams("yak"));
+    assertEquals(new String[] { "b3" }, combined.getParams("zot"));
+
+  }
+
   public void testGetParams() {
     Map<String,String> pmap = new HashMap<>();
     pmap.put( "str"        , "string"   );
@@ -194,4 +273,18 @@ public class SolrParamTest extends Lucen
     }
     return 200;
   }
+
+  static <T> List<T> iterToList(Iterator<T> iter) {
+    List<T> result = new ArrayList<>();
+    while (iter.hasNext()) {
+      result.add(iter.next());
+    }
+    return result;
+  }
+
+  static void assertIterSize(String msg, int expectedSize, SolrParams p) {
+    List<String> keys = iterToList(p.getParameterNamesIterator());
+    assertEquals(msg + " " + keys.toString(), expectedSize, keys.size());
+  }
+
 }

Modified: lucene/dev/branches/lucene6005/solr/webapp/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/webapp/build.xml?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/webapp/build.xml (original)
+++ lucene/dev/branches/lucene6005/solr/webapp/build.xml Sun Dec  7 11:37:32 2014
@@ -46,7 +46,7 @@
     <build-manifest title="Apache Solr Search Server"
                     implementation.title="org.apache.solr"/>
     <ant dir="${common-solr.dir}" inheritall="false" target="contribs-add-to-war"/>
-    <war destfile="${dist}/solr-${version}${solr.war.suffix}.war"
+    <war destfile="${server.dir}/webapps/solr.war"
          webxml="web/WEB-INF/web.xml"
          manifest="${manifest.file}">
       <lib dir="${common-solr.dir}/core/lib" excludes="${exclude.from.war},${common.classpath.excludes}"/>

Modified: lucene/dev/branches/lucene6005/solr/webapp/web/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/webapp/web/WEB-INF/web.xml?rev=1643662&r1=1643661&r2=1643662&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/webapp/web/WEB-INF/web.xml (original)
+++ lucene/dev/branches/lucene6005/solr/webapp/web/WEB-INF/web.xml Sun Dec  7 11:37:32 2014
@@ -135,15 +135,6 @@
     </init-param>
   </servlet>
 
-  <servlet>
-    <servlet-name>SolrConfigRestApi</servlet-name>
-    <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
-    <init-param>
-      <param-name>org.restlet.application</param-name>
-      <param-value>org.apache.solr.rest.SolrConfigRestApi</param-value>
-    </init-param>
-  </servlet>
-  
   <servlet-mapping>
     <servlet-name>RedirectOldAdminUI</servlet-name>
     <url-pattern>/admin/</url-pattern>
@@ -177,11 +168,6 @@
     <url-pattern>/schema/*</url-pattern>
   </servlet-mapping>
   
-  <servlet-mapping>
-    <servlet-name>SolrConfigRestApi</servlet-name>
-    <url-pattern>/config/*</url-pattern>
-  </servlet-mapping>
-  
   <mime-mapping>
     <extension>.xsl</extension>
     <!-- per http://www.w3.org/TR/2006/PR-xslt20-20061121/ -->