You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2013/01/18 19:31:23 UTC

svn commit: r1435287 [34/41] - in /lucene/dev/branches/LUCENE-2878: ./ dev-tools/ dev-tools/eclipse/ dev-tools/idea/.idea/libraries/ dev-tools/idea/lucene/analysis/icu/ dev-tools/maven/ dev-tools/maven/lucene/benchmark/ dev-tools/maven/solr/ dev-tools/...

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/ConcatFieldUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/ConcatFieldUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/ConcatFieldUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/ConcatFieldUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -51,18 +51,15 @@ import org.apache.commons.lang.StringUti
  * </p>
  *
  * <pre class="prettyprint">
- *  &lt;updateRequestProcessorChain&gt;
- *    &lt;processor class="solr.ConcatFieldUpdateProcessorFactory"&gt;
- *      &lt;str name="delimiter"&gt;; &lt;/str&gt;
- *      &lt;lst name="exclude"&gt;
- *        &lt;str name="fieldName"&gt;primary_author&lt;/str&gt;
- *      &lt;/lst&gt;
- *    &lt;/processor&gt;
- *    &lt;processor class="solr.FirstFieldValueUpdateProcessorFactory"&gt;
- *      &lt;str name="fieldName"&gt;primary_author&lt;/str&gt;
- *    &lt;/processor&gt;
- *  &lt;/updateRequestProcessorChain&gt;
- * </pre>
+ * &lt;processor class="solr.ConcatFieldUpdateProcessorFactory"&gt;
+ *   &lt;str name="delimiter"&gt;; &lt;/str&gt;
+ *   &lt;lst name="exclude"&gt;
+ *     &lt;str name="fieldName"&gt;primary_author&lt;/str&gt;
+ *   &lt;/lst&gt;
+ * &lt;/processor&gt;
+ * &lt;processor class="solr.FirstFieldValueUpdateProcessorFactory"&gt;
+ *   &lt;str name="fieldName"&gt;primary_author&lt;/str&gt;
+ * &lt;/processor&gt;</pre>
  */
 public final class ConcatFieldUpdateProcessorFactory extends FieldMutatingUpdateProcessorFactory {
 
@@ -82,6 +79,7 @@ public final class ConcatFieldUpdateProc
                                             SolrQueryResponse rsp,
                                             UpdateRequestProcessor next) {
     return new FieldMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected SolrInputField mutate(final SolrInputField src) {
         if (src.getValueCount() <= 1) return src;
 
@@ -99,6 +97,7 @@ public final class ConcatFieldUpdateProc
 
     final IndexSchema schema = core.getSchema();
     return new FieldMutatingUpdateProcessor.FieldNameSelector() {
+      @Override
       public boolean shouldMutate(final String fieldName) {
 
         // first check type since it should be fastest

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/CountFieldValuesUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/CountFieldValuesUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/CountFieldValuesUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/CountFieldValuesUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -50,20 +50,17 @@ import org.apache.commons.lang.StringUti
  * </p>
  *
  * <pre class="prettyprint">
- * &lt;updateRequestProcessorChain&gt;
- *   &lt;processor class="solr.CloneFieldUpdateProcessorFactory"&gt;
- *     &lt;str name="source"&gt;category&lt;/str&gt;
- *     &lt;str name="dest"&gt;category_count&lt;/str&gt;
- *   &lt;/processor&gt;
- *   &lt;processor class="solr.CountFieldValuesUpdateProcessorFactory"&gt;
- *     &lt;str name="fieldName"&gt;category_count&lt;/str&gt;
- *   &lt;/processor&gt;
- *   &lt;processor class="solr.DefaultValueUpdateProcessorFactory"&gt;
- *     &lt;str name="fieldName"&gt;category_count&lt;/str&gt;
- *     &lt;int name="value"&gt;0&lt;/int&gt;
- *   &lt;/processor&gt;
- * &lt;/updateRequestProcessorChain&gt;
- * </pre>
+ * &lt;processor class="solr.CloneFieldUpdateProcessorFactory"&gt;
+ *   &lt;str name="source"&gt;category&lt;/str&gt;
+ *   &lt;str name="dest"&gt;category_count&lt;/str&gt;
+ * &lt;/processor&gt;
+ * &lt;processor class="solr.CountFieldValuesUpdateProcessorFactory"&gt;
+ *   &lt;str name="fieldName"&gt;category_count&lt;/str&gt;
+ * &lt;/processor&gt;
+ * &lt;processor class="solr.DefaultValueUpdateProcessorFactory"&gt;
+ *   &lt;str name="fieldName"&gt;category_count&lt;/str&gt;
+ *   &lt;int name="value"&gt;0&lt;/int&gt;
+ * &lt;/processor&gt;</pre>
  *
  * <p>
  * <b>NOTE:</b> The use of {@link DefaultValueUpdateProcessorFactory} is 
@@ -83,6 +80,7 @@ public final class CountFieldValuesUpdat
                                             SolrQueryResponse rsp,
                                             UpdateRequestProcessor next) {
     return new FieldMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected SolrInputField mutate(final SolrInputField src) {
         SolrInputField result = new SolrInputField(src.getName());
         result.setValue(src.getValueCount(),

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/DefaultValueUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/DefaultValueUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/DefaultValueUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/DefaultValueUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -71,10 +71,12 @@ public class DefaultValueUpdateProcessor
     super.init(args);
   }
 
+  @Override
   public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
                                             SolrQueryResponse rsp, 
                                             UpdateRequestProcessor next ) {
     return new DefaultValueUpdateProcessor(fieldName, next) {
+      @Override
       public Object getDefaultValue() { return defaultValue; }
     };
   }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java Fri Jan 18 18:30:54 2013
@@ -20,6 +20,7 @@ package org.apache.solr.update.processor
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -37,14 +38,15 @@ import org.apache.solr.common.SolrExcept
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.SolrInputField;
 import org.apache.solr.common.cloud.ClusterState;
+import org.apache.solr.common.cloud.DocCollection;
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
 import org.apache.solr.common.cloud.ZkCoreNodeProps;
-import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.cloud.ZooKeeperException;
 import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.ShardParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.params.UpdateParams;
 import org.apache.solr.common.util.Hash;
@@ -138,6 +140,8 @@ public class DistributedUpdateProcessor 
 
   private int numNodes;
 
+  private UpdateCommand updateCommand;  // the current command this processor is working on.
+
   
   public DistributedUpdateProcessor(SolrQueryRequest req,
       SolrQueryResponse rsp, UpdateRequestProcessor next) {
@@ -164,7 +168,7 @@ public class DistributedUpdateProcessor 
     zkController = req.getCore().getCoreDescriptor().getCoreContainer().getZkController();
     if (zkEnabled) {
       numNodes =  zkController.getZkStateReader().getClusterState().getLiveNodes().size();
-      cmdDistrib = new SolrCmdDistributor(numNodes, coreDesc.getCoreContainer().getZkController().getCmdDistribExecutor());
+      cmdDistrib = new SolrCmdDistributor(numNodes, coreDesc.getCoreContainer().getZkController().getUpdateShardHandler());
     }
     //this.rsp = reqInfo != null ? reqInfo.getRsp() : null;
 
@@ -175,30 +179,56 @@ public class DistributedUpdateProcessor 
     }
   }
 
-  private List<Node> setupRequest(int hash) {
+
+  private List<Node> setupRequest(String id, SolrInputDocument doc) {
     List<Node> nodes = null;
 
     // if we are in zk mode...
     if (zkEnabled) {
-      // set num nodes
-      numNodes = zkController.getClusterState().getLiveNodes().size();
-      
-      String shardId = getShard(hash, collection, zkController.getClusterState()); // get the right shard based on the hash...
+
+      if ((updateCommand.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.PEER_SYNC)) != 0) {
+        isLeader = false;     // we actually might be the leader, but we don't want leader-logic for these types of updates anyway.
+        forwardToLeader = false;
+        return nodes;
+      }
+
+      String coreName = req.getCore().getName();
+      String coreNodeName = zkController.getNodeName() + "_" + coreName;
+
+      ClusterState cstate = zkController.getClusterState();
+      numNodes = cstate.getLiveNodes().size();
+      DocCollection coll = cstate.getCollection(collection);
+      Slice slice = coll.getRouter().getTargetSlice(id, doc, req.getParams(), coll);
+
+      if (slice == null) {
+        // No slice found.  Most strict routers will have already thrown an exception, so a null return is
+        // a signal to use the slice of this core.
+        // TODO: what if this core is not in the targeted collection?
+        String shardId = req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId();
+        slice = coll.getSlice(shardId);
+        if (slice == null) {
+          throw new SolrException(ErrorCode.BAD_REQUEST, "No shard " + shardId + " in " + coll);
+        }
+      }
+
+
+      String shardId = slice.getName();
 
       try {
-        ZkCoreNodeProps leaderProps = new ZkCoreNodeProps(zkController.getZkStateReader().getLeaderProps(
+        // Not equivalent to getLeaderProps, which does retries to find a leader.
+        // Replica leader = slice.getLeader();
+
+        ZkCoreNodeProps leaderProps = new ZkCoreNodeProps(zkController.getZkStateReader().getLeaderRetry(
             collection, shardId));
-        
+
         String leaderNodeName = leaderProps.getCoreNodeName();
-        String coreName = req.getCore().getName();
-        String coreNodeName = zkController.getNodeName() + "_" + coreName;
         isLeader = coreNodeName.equals(leaderNodeName);
-        
-        DistribPhase phase = 
+
+        DistribPhase phase =
             DistribPhase.parseParam(req.getParams().get(DISTRIB_UPDATE_PARAM));
-       
-        doDefensiveChecks(shardId, phase);
-     
+
+        doDefensiveChecks(phase);
+
 
         if (DistribPhase.FROMLEADER == phase) {
           // we are coming from the leader, just go local - add no urls
@@ -219,7 +249,7 @@ public class DistributedUpdateProcessor 
               skipListSet = new HashSet<String>(skipList.length);
               skipListSet.addAll(Arrays.asList(skipList));
             }
-            
+
             for (ZkCoreNodeProps props : replicaProps) {
               if (skipList != null) {
                 if (!skipListSet.contains(props.getCoreUrl())) {
@@ -230,14 +260,14 @@ public class DistributedUpdateProcessor 
               }
             }
           }
-          
+
         } else {
           // I need to forward onto the leader...
           nodes = new ArrayList<Node>(1);
           nodes.add(new RetryNode(leaderProps, zkController.getZkStateReader(), collection, shardId));
           forwardToLeader = true;
         }
-        
+
       } catch (InterruptedException e) {
         Thread.currentThread().interrupt();
         throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "",
@@ -248,11 +278,14 @@ public class DistributedUpdateProcessor 
     return nodes;
   }
 
-  private void doDefensiveChecks(String shardId, DistribPhase phase) {
+
+  private void doDefensiveChecks(DistribPhase phase) {
+    boolean isReplayOrPeersync = (updateCommand.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.REPLAY)) != 0;
+    if (isReplayOrPeersync) return;
+
     String from = req.getParams().get("distrib.from");
-    boolean logReplay = req.getParams().getBool(LOG_REPLAY, false);
     boolean localIsLeader = req.getCore().getCoreDescriptor().getCloudDescriptor().isLeader();
-    if (!logReplay && DistribPhase.FROMLEADER == phase && localIsLeader && from != null) { // from will be null on log replay
+    if (DistribPhase.FROMLEADER == phase && localIsLeader && from != null) { // from will be null on log replay
       log.error("Request says it is coming from leader, but we are the leader: " + req.getParamString());
       throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Request says it is coming from leader, but we are the leader");
     }
@@ -264,13 +297,6 @@ public class DistributedUpdateProcessor 
   }
 
 
-  private String getShard(int hash, String collection, ClusterState clusterState) {
-    // ranges should be part of the cloud state and eventually gotten from zk
-
-    // get the shard names
-    return clusterState.getShard(hash, collection);
-  }
-
   // used for deleteByQuery to get the list of nodes this leader should forward to
   private List<Node> setupRequest() {
     List<Node> nodes = null;
@@ -278,7 +304,7 @@ public class DistributedUpdateProcessor 
 
     try {
 
-      ZkCoreNodeProps leaderProps = new ZkCoreNodeProps(zkController.getZkStateReader().getLeaderProps(
+      ZkCoreNodeProps leaderProps = new ZkCoreNodeProps(zkController.getZkStateReader().getLeaderRetry(
           collection, shardId));
 
       String leaderNodeName = leaderProps.getCoreNodeName();
@@ -310,12 +336,11 @@ public class DistributedUpdateProcessor 
 
   @Override
   public void processAdd(AddUpdateCommand cmd) throws IOException {
-    // TODO: check for id field?
-    int hash = 0;
+    updateCommand = cmd;
+
     if (zkEnabled) {
       zkCheck();
-      hash = hash(cmd);
-      nodes = setupRequest(hash);
+      nodes = setupRequest(cmd.getHashableId(), cmd.getSolrInputDocument());
     } else {
       isLeader = getNonZkLeaderAssumption(req);
     }
@@ -394,11 +419,9 @@ public class DistributedUpdateProcessor 
 
     // TODO: we should do this in the background it would seem
     for (SolrCmdDistributor.Error error : response.errors) {
-      if (error.node instanceof RetryNode || error.e instanceof SolrException) {
+      if (error.node instanceof RetryNode) {
         // we don't try to force a leader to recover
         // when we cannot forward to it
-        // and we assume SolrException means
-        // the node went down
         continue;
       }
       // TODO: we should force their state to recovering ??
@@ -411,8 +434,8 @@ public class DistributedUpdateProcessor 
       log.info("try and ask " + recoveryUrl + " to recover");
       try {
         server = new HttpSolrServer(recoveryUrl);
-        server.setSoTimeout(5000);
-        server.setConnectionTimeout(5000);
+        server.setSoTimeout(15000);
+        server.setConnectionTimeout(15000);
         
         RequestRecovery recoverRequestCmd = new RequestRecovery();
         recoverRequestCmd.setAction(CoreAdminAction.REQUESTRECOVERY);
@@ -444,11 +467,22 @@ public class DistributedUpdateProcessor 
   private boolean versionAdd(AddUpdateCommand cmd) throws IOException {
     BytesRef idBytes = cmd.getIndexedId();
 
-    if (vinfo == null || idBytes == null) {
+    if (idBytes == null) {
       super.processAdd(cmd);
       return false;
     }
 
+    if (vinfo == null) {
+      if (isAtomicUpdate(cmd)) {
+        throw new SolrException
+          (SolrException.ErrorCode.BAD_REQUEST,
+           "Atomic document updates are not supported unless <updateLog/> is configured");
+      } else {
+        super.processAdd(cmd);
+        return false;
+      }
+    }
+
     // This is only the hash for the bucket, and must be based only on the uniqueKey (i.e. do not use a pluggable hash here)
     int bucketHash = Hash.murmurhash3_x86_32(idBytes.bytes, idBytes.offset, idBytes.length, 0);
 
@@ -471,8 +505,8 @@ public class DistributedUpdateProcessor 
       }
     }
 
-    boolean isReplay = (cmd.getFlags() & UpdateCommand.REPLAY) != 0;
-    boolean leaderLogic = isLeader && !isReplay;
+    boolean isReplayOrPeersync = (cmd.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.REPLAY)) != 0;
+    boolean leaderLogic = isLeader && !isReplayOrPeersync;
 
 
     VersionBucket bucket = vinfo.bucket(bucketHash);
@@ -567,21 +601,26 @@ public class DistributedUpdateProcessor 
     return false;
   }
 
-
-  // TODO: may want to switch to using optimistic locking in the future for better concurrency
-  // that's why this code is here... need to retry in a loop closely around/in versionAdd
-  boolean getUpdatedDocument(AddUpdateCommand cmd, long versionOnUpdate) throws IOException {
+  /**
+   * Utility method that examines the SolrInputDocument in an AddUpdateCommand
+   * and returns true if the documents contains atomic update instructions.
+   */
+  public static boolean isAtomicUpdate(final AddUpdateCommand cmd) {
     SolrInputDocument sdoc = cmd.getSolrInputDocument();
-    boolean update = false;
     for (SolrInputField sif : sdoc.values()) {
       if (sif.getValue() instanceof Map) {
-        update = true;
-        break;
+        return true;
       }
     }
+    return false;
+  }
 
-    if (!update) return false;
+  // TODO: may want to switch to using optimistic locking in the future for better concurrency
+  // that's why this code is here... need to retry in a loop closely around/in versionAdd
+  boolean getUpdatedDocument(AddUpdateCommand cmd, long versionOnUpdate) throws IOException {
+    if (!isAtomicUpdate(cmd)) return false;
 
+    SolrInputDocument sdoc = cmd.getSolrInputDocument();
     BytesRef id = cmd.getIndexedId();
     SolrInputDocument oldDoc = RealTimeGetComponent.getInputDocument(cmd.getReq().getCore(), id);
 
@@ -663,16 +702,16 @@ public class DistributedUpdateProcessor 
   
   @Override
   public void processDelete(DeleteUpdateCommand cmd) throws IOException {
+    updateCommand = cmd;
+
     if (!cmd.isDeleteById()) {
       doDeleteByQuery(cmd);
       return;
     }
 
-    int hash = 0;
     if (zkEnabled) {
       zkCheck();
-      hash = hash(cmd);
-      nodes = setupRequest(hash);
+      nodes = setupRequest(cmd.getId(), null);
     } else {
       isLeader = getNonZkLeaderAssumption(req);
     }
@@ -751,22 +790,19 @@ public class DistributedUpdateProcessor 
     if (zkEnabled && DistribPhase.NONE == phase) {
       boolean leaderForAnyShard = false;  // start off by assuming we are not a leader for any shard
 
-      Map<String,Slice> slices = zkController.getClusterState().getSlices(collection);
-      if (slices == null) {
-        throw new SolrException(ErrorCode.BAD_REQUEST,
-            "Cannot find collection:" + collection + " in "
-                + zkController.getClusterState().getCollections());
-      }
+      ModifiableSolrParams outParams = new ModifiableSolrParams(filterParams(req.getParams()));
+      outParams.set(DISTRIB_UPDATE_PARAM, DistribPhase.TOLEADER.toString());
 
-      ModifiableSolrParams params = new ModifiableSolrParams(filterParams(req.getParams()));
-      params.set(DISTRIB_UPDATE_PARAM, DistribPhase.TOLEADER.toString());
+      DocCollection coll = zkController.getClusterState().getCollection(collection);
+      SolrParams params = req.getParams();
+      Collection<Slice> slices = coll.getRouter().getSearchSlices(params.get(ShardParams.SHARD_KEYS), params, coll);
 
       List<Node> leaders =  new ArrayList<Node>(slices.size());
-      for (Map.Entry<String,Slice> sliceEntry : slices.entrySet()) {
-        String sliceName = sliceEntry.getKey();
-        ZkNodeProps leaderProps;
+      for (Slice slice : slices) {
+        String sliceName = slice.getName();
+        Replica leader;
         try {
-          leaderProps = zkController.getZkStateReader().getLeaderProps(collection, sliceName);
+          leader = zkController.getZkStateReader().getLeaderRetry(collection, sliceName);
         } catch (InterruptedException e) {
           throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Exception finding leader for shard " + sliceName, e);
         }
@@ -775,7 +811,7 @@ public class DistributedUpdateProcessor 
         // should we send out slice-at-a-time and if a node returns "hey, I'm not a leader" (or we get an error because it went down) then look up the new leader?
 
         // Am I the leader for this slice?
-        ZkCoreNodeProps coreLeaderProps = new ZkCoreNodeProps(leaderProps);
+        ZkCoreNodeProps coreLeaderProps = new ZkCoreNodeProps(leader);
         String leaderNodeName = coreLeaderProps.getCoreNodeName();
         String coreName = req.getCore().getName();
         String coreNodeName = zkController.getNodeName() + "_" + coreName;
@@ -789,8 +825,8 @@ public class DistributedUpdateProcessor 
         }
       }
 
-      params.remove("commit"); // this will be distributed from the local commit
-      cmdDistrib.distribDelete(cmd, leaders, params);
+      outParams.remove("commit"); // this will be distributed from the local commit
+      cmdDistrib.distribDelete(cmd, leaders, outParams);
 
       if (!leaderForAnyShard) {
         return;
@@ -826,8 +862,8 @@ public class DistributedUpdateProcessor 
     }
     versionOnUpdate = Math.abs(versionOnUpdate);  // normalize to positive version
 
-    boolean isReplay = (cmd.getFlags() & UpdateCommand.REPLAY) != 0;
-    boolean leaderLogic = isLeader && !isReplay;
+    boolean isReplayOrPeersync = (cmd.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.REPLAY)) != 0;
+    boolean leaderLogic = isLeader && !isReplayOrPeersync;
 
     if (!leaderLogic && versionOnUpdate==0) {
       throw new SolrException(ErrorCode.BAD_REQUEST, "missing _version_ on update from leader");
@@ -890,6 +926,11 @@ public class DistributedUpdateProcessor 
 
 
   private void zkCheck() {
+    if ((updateCommand.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.PEER_SYNC)) != 0) {
+      // for log reply or peer sync, we don't need to be connected to ZK
+      return;
+    }
+
     if (zkController.isConnected()) {
       return;
     }
@@ -933,8 +974,8 @@ public class DistributedUpdateProcessor 
     long signedVersionOnUpdate = versionOnUpdate;
     versionOnUpdate = Math.abs(versionOnUpdate);  // normalize to positive version
 
-    boolean isReplay = (cmd.getFlags() & UpdateCommand.REPLAY) != 0;
-    boolean leaderLogic = isLeader && !isReplay;
+    boolean isReplayOrPeersync = (cmd.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.REPLAY)) != 0;
+    boolean leaderLogic = isLeader && !isReplayOrPeersync;
 
     if (!leaderLogic && versionOnUpdate==0) {
       throw new SolrException(ErrorCode.BAD_REQUEST, "missing _version_ on update from leader");
@@ -1004,6 +1045,8 @@ public class DistributedUpdateProcessor 
 
   @Override
   public void processCommit(CommitUpdateCommand cmd) throws IOException {
+    updateCommand = cmd;
+
     if (zkEnabled) {
       zkCheck();
     }
@@ -1058,7 +1101,7 @@ public class DistributedUpdateProcessor 
     ClusterState clusterState = req.getCore().getCoreDescriptor()
         .getCoreContainer().getZkController().getClusterState();
     List<Node> urls = new ArrayList<Node>();
-    Map<String,Slice> slices = clusterState.getSlices(collection);
+    Map<String,Slice> slices = clusterState.getSlicesMap(collection);
     if (slices == null) {
       throw new ZooKeeperException(ErrorCode.BAD_REQUEST,
           "Could not find collection in zk: " + clusterState);
@@ -1081,19 +1124,6 @@ public class DistributedUpdateProcessor 
     return urls;
   }
   
-  // TODO: move this to AddUpdateCommand/DeleteUpdateCommand and cache it? And
-  // make the hash pluggable of course.
-  // The hash also needs to be pluggable
-  private int hash(AddUpdateCommand cmd) {
-    String hashableId = cmd.getHashableId();
-    
-    return Hash.murmurhash3_x86_32(hashableId, 0, hashableId.length(), 0);
-  }
-  
-  private int hash(DeleteUpdateCommand cmd) {
-    return Hash.murmurhash3_x86_32(cmd.getId(), 0, cmd.getId().length(), 0);
-  }
-  
   // RetryNodes are used in the case of 'forward to leader' where we want
   // to try the latest leader on a fail in the case the leader just went down.
   public static class RetryNode extends StdNode {
@@ -1108,24 +1138,19 @@ public class DistributedUpdateProcessor 
       this.collection = collection;
       this.shardId = shardId;
     }
-    
-    @Override
-    public String toString() {
-      return url;
-    }
 
     @Override
     public boolean checkRetry() {
       ZkCoreNodeProps leaderProps;
       try {
-        leaderProps = new ZkCoreNodeProps(zkStateReader.getLeaderProps(
+        leaderProps = new ZkCoreNodeProps(zkStateReader.getLeaderRetry(
             collection, shardId));
       } catch (InterruptedException e) {
         Thread.currentThread().interrupt();
         return false;
       }
       
-      this.url = leaderProps.getCoreUrl();
+      this.nodeProps = leaderProps;
 
       return true;
     }
@@ -1146,9 +1171,9 @@ public class DistributedUpdateProcessor 
       if (!super.equals(obj)) return false;
       if (getClass() != obj.getClass()) return false;
       RetryNode other = (RetryNode) obj;
-      if (url == null) {
-        if (other.url != null) return false;
-      } else if (!url.equals(other.url)) return false;
+      if (nodeProps.getCoreUrl() == null) {
+        if (other.nodeProps.getCoreUrl() != null) return false;
+      } else if (!nodeProps.getCoreUrl().equals(other.nodeProps.getCoreUrl())) return false;
 
       return true;
     }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldLengthUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldLengthUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldLengthUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldLengthUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -43,8 +43,7 @@ import org.apache.solr.core.SolrCore;
  *     &lt;str&gt;solr.TrieIntField&lt;/str&gt;
  *     &lt;str&gt;solr.TrieLongField&lt;/str&gt;
  *   &lt;/arr&gt;
- * &lt;/processor&gt;
- * </pre>
+ * &lt;/processor&gt;</pre>
  */
 public final class FieldLengthUpdateProcessorFactory extends FieldMutatingUpdateProcessorFactory {
 
@@ -68,6 +67,7 @@ public final class FieldLengthUpdateProc
                                             SolrQueryResponse rsp,
                                             UpdateRequestProcessor next) {
     return new FieldValueMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected Object mutateValue(final Object src) {
         if (src instanceof CharSequence) {
           return new Integer(((CharSequence)src).length());

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldMutatingUpdateProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldMutatingUpdateProcessor.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldMutatingUpdateProcessor.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldMutatingUpdateProcessor.java Fri Jan 18 18:30:54 2013
@@ -133,6 +133,7 @@ public abstract class FieldMutatingUpdat
   /** Singleton indicating all fields should be mutated */
   public static final FieldNameSelector SELECT_ALL_FIELDS 
     = new FieldNameSelector() {
+        @Override
         public boolean shouldMutate(final String fieldName) {
           return true;
         }
@@ -141,6 +142,7 @@ public abstract class FieldMutatingUpdat
   /** Singleton indicating no fields should be mutated */
   public static final FieldNameSelector SELECT_NO_FIELDS 
     = new FieldNameSelector() {
+        @Override
         public boolean shouldMutate(final String fieldName) {
           return false;
         }
@@ -170,6 +172,7 @@ public abstract class FieldMutatingUpdat
     
     if (SELECT_ALL_FIELDS == includes) {
       return new FieldNameSelector() {
+        @Override
         public boolean shouldMutate(final String fieldName) {
           return ! excludes.shouldMutate(fieldName);
         }
@@ -177,6 +180,7 @@ public abstract class FieldMutatingUpdat
     }
 
     return new FieldNameSelector() {
+      @Override
       public boolean shouldMutate(final String fieldName) {
         return (includes.shouldMutate(fieldName)
                 && ! excludes.shouldMutate(fieldName));
@@ -244,6 +248,7 @@ public abstract class FieldMutatingUpdat
       this.regexes = regexes;
     }
 
+    @Override
     public boolean shouldMutate(final String fieldName) {
       
       // order of checks is bsaed on what should be quicker 

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldMutatingUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldMutatingUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldMutatingUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldMutatingUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -91,8 +91,7 @@ import org.apache.solr.util.plugin.SolrC
  *   &lt;lst name="exclude"&gt;
  *     &lt;str name="typeClass"&gt;solr.DateField&lt;/str&gt;
  *   &lt;/lst&gt;
- * &lt;/processor&gt;
- * </pre>
+ * &lt;/processor&gt;</pre>
  * 
  * <p>
  * Subclasses define the default selection behavior to be applied if no 
@@ -197,6 +196,7 @@ public abstract class FieldMutatingUpdat
 
   }
 
+  @Override
   public void inform(final SolrCore core) {
     
     final IndexSchema schema = core.getSchema();
@@ -242,7 +242,7 @@ public abstract class FieldMutatingUpdat
 
   /**
    * Removes all instance of the key from NamedList, returning the Set of 
-   * Strings that key refered to.  Throws an error if the key didn't refer 
+   * Strings that key referred to.  Throws an error if the key didn't refer
    * to one or more strings (or arrays of strings)
    * @exception SolrException invalid arr/str structure.
    */

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldValueMutatingUpdateProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldValueMutatingUpdateProcessor.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldValueMutatingUpdateProcessor.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldValueMutatingUpdateProcessor.java Fri Jan 18 18:30:54 2013
@@ -36,6 +36,7 @@ public abstract class FieldValueMutating
   
   
   public static final Object DELETE_VALUE_SINGLETON = new Object() {
+      @Override
       public String toString() { 
         return "!!Singleton Object Triggering Value Deletion!!";
       }
@@ -58,6 +59,7 @@ public abstract class FieldValueMutating
    */
   protected abstract Object mutateValue(final Object src);
   
+  @Override
   protected final SolrInputField mutate(final SolrInputField src) {
     SolrInputField result = new SolrInputField(src.getName());
     for (final Object srcVal : src.getValues()) {

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldValueSubsetUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldValueSubsetUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldValueSubsetUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/FieldValueSubsetUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -37,6 +37,7 @@ public abstract class FieldValueSubsetUp
                                                   SolrQueryResponse rsp,
                                                   UpdateRequestProcessor next) {
     return new FieldMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected SolrInputField mutate(final SolrInputField src) {
         if (src.getValueCount() <= 1) return src;
 

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/HTMLStripFieldUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/HTMLStripFieldUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/HTMLStripFieldUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/HTMLStripFieldUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -43,8 +43,7 @@ import java.io.StringWriter;
  * <pre class="prettyprint">
  * &lt;processor class="solr.HTMLStripFieldUpdateProcessorFactory"&gt;
  *   &lt;str name="typeClass"&gt;solr.StrField&lt;/str&gt;
- * &lt;/processor&gt;
- * </pre>
+ * &lt;/processor&gt;</pre>
  */
 public final class HTMLStripFieldUpdateProcessorFactory extends FieldMutatingUpdateProcessorFactory {
 
@@ -61,6 +60,7 @@ public final class HTMLStripFieldUpdateP
                                             SolrQueryResponse rsp,
                                             UpdateRequestProcessor next) {
     return new FieldValueMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected Object mutateValue(final Object src) {
         if (src instanceof CharSequence) {
           CharSequence s = (CharSequence)src;

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/IgnoreFieldUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/IgnoreFieldUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/IgnoreFieldUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/IgnoreFieldUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -42,22 +42,16 @@ import org.apache.solr.response.SolrQuer
  * </p>
  *
  * <pre class="prettyprint">
- *  &lt;updateRequestProcessorChain&gt;
- *    &lt;processor class="solr.IgnoreFieldUpdateProcessorFactory" /&gt;
- *  &lt;/updateRequestProcessorChain&gt;
- * </pre>
+ * &lt;processor class="solr.IgnoreFieldUpdateProcessorFactory" /&gt;</pre>
  *
  * <p>
  * In this second example, any field name ending in "_raw" found in a 
  * document being added would be removed...
  * </p>
  * <pre class="prettyprint">
- *  &lt;updateRequestProcessorChain&gt;
- *    &lt;processor class="solr.IgnoreFieldUpdateProcessorFactory"&gt;
- *      &lt;str name="fieldRegex"&gt;.*_raw&lt;/str&gt;
- *    &lt;/processor&gt;
- *  &lt;/updateRequestProcessorChain&gt;
- * </pre>
+ * &lt;processor class="solr.IgnoreFieldUpdateProcessorFactory"&gt;
+ *   &lt;str name="fieldRegex"&gt;.*_raw&lt;/str&gt;
+ * &lt;/processor&gt;</pre>
  */
 public final class IgnoreFieldUpdateProcessorFactory extends FieldMutatingUpdateProcessorFactory {
 
@@ -66,6 +60,7 @@ public final class IgnoreFieldUpdateProc
                                             SolrQueryResponse rsp,
                                             UpdateRequestProcessor next) {
     return new FieldMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected SolrInputField mutate(final SolrInputField src) {
         return null;
       }
@@ -78,6 +73,7 @@ public final class IgnoreFieldUpdateProc
 
     final IndexSchema schema = core.getSchema();
     return new FieldMutatingUpdateProcessor.FieldNameSelector() {
+      @Override
       public boolean shouldMutate(final String fieldName) {
 
         FieldType type = schema.getFieldTypeNoEx(fieldName);

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -94,7 +94,7 @@ class LogUpdateProcessor extends UpdateR
   
   @Override
   public void processAdd(AddUpdateCommand cmd) throws IOException {
-    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString()); }
+    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString() + " " + req); }
 
     // call delegate first so we can log things like the version that get set later
     if (next != null) next.processAdd(cmd);
@@ -117,7 +117,7 @@ class LogUpdateProcessor extends UpdateR
 
   @Override
   public void processDelete( DeleteUpdateCommand cmd ) throws IOException {
-    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString()); }
+    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString() + " " + req); }
     if (next != null) next.processDelete(cmd);
 
     if (cmd.isDeleteById()) {
@@ -145,7 +145,7 @@ class LogUpdateProcessor extends UpdateR
 
   @Override
   public void processMergeIndexes(MergeIndexesCommand cmd) throws IOException {
-    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString()); }
+    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString() + " " + req); }
     if (next != null) next.processMergeIndexes(cmd);
 
     toLog.add("mergeIndexes", cmd.toString());
@@ -153,7 +153,7 @@ class LogUpdateProcessor extends UpdateR
 
   @Override
   public void processCommit( CommitUpdateCommand cmd ) throws IOException {
-    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString()); }
+    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString() + " " + req); }
     if (next != null) next.processCommit(cmd);
 
 
@@ -166,7 +166,7 @@ class LogUpdateProcessor extends UpdateR
    */
   @Override
   public void processRollback( RollbackUpdateCommand cmd ) throws IOException {
-    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString()); }
+    if (logDebug) { log.debug("PRE_UPDATE " + cmd.toString() + " " + req); }
     if (next != null) next.processRollback(cmd);
 
     toLog.add("rollback", "");
@@ -175,7 +175,7 @@ class LogUpdateProcessor extends UpdateR
 
   @Override
   public void finish() throws IOException {
-    if (logDebug) { log.debug("PRE_UPDATE finish()"); }
+    if (logDebug) { log.debug("PRE_UPDATE FINISH " + req); }
     if (next != null) next.finish();
 
     // LOG A SUMMARY WHEN ALL DONE (INFO LEVEL)

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/NoOpDistributingUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/NoOpDistributingUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/NoOpDistributingUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/NoOpDistributingUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -38,6 +38,7 @@ public class NoOpDistributingUpdateProce
 
   /** Returns null 
    */
+  @Override
   public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
                                             SolrQueryResponse rsp, 
                                             UpdateRequestProcessor next ) {

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RegexReplaceProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RegexReplaceProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RegexReplaceProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RegexReplaceProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -52,8 +52,7 @@ import org.slf4j.LoggerFactory;
  *   &lt;str name="fieldName"&gt;title&lt;/str&gt;
  *   &lt;str name="pattern"&gt;\s+&lt;/str&gt;
  *   &lt;str name="replacement"&gt; &lt;/str&gt;
- * &lt;/processor&gt;
- * </pre>
+ * &lt;/processor&gt;</pre>
  * 
  * @see java.util.regex.Pattern
  */
@@ -98,6 +97,7 @@ public final class RegexReplaceProcessor
   /** 
    * @see FieldMutatingUpdateProcessor#SELECT_NO_FIELDS
    */
+  @Override
   protected FieldMutatingUpdateProcessor.FieldNameSelector 
     getDefaultSelector(final SolrCore core) {
 
@@ -110,6 +110,7 @@ public final class RegexReplaceProcessor
                                             SolrQueryResponse response,
                                             UpdateRequestProcessor next) {
     return new FieldValueMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected Object mutateValue(final Object src) {
         if (src instanceof CharSequence) {
           CharSequence txt = (CharSequence)src;

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RemoveBlankFieldUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RemoveBlankFieldUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RemoveBlankFieldUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RemoveBlankFieldUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -39,8 +39,7 @@ import org.apache.solr.response.SolrQuer
  *   &lt;lst name="exclude"&gt;
  *     &lt;str name="fieldRegex"&gt;.*_literal&lt;/str&gt;
  *   &lt;/lst&gt;
- * &lt;/processor&gt;
- * </pre>
+ * &lt;/processor&gt;</pre>
  *
  */
 public final class RemoveBlankFieldUpdateProcessorFactory extends FieldMutatingUpdateProcessorFactory {
@@ -57,6 +56,7 @@ public final class RemoveBlankFieldUpdat
                                             SolrQueryResponse rsp,
                                             UpdateRequestProcessor next) {
     return new FieldValueMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected Object mutateValue(final Object src) {
         if (src instanceof CharSequence 
             && 0 == ((CharSequence)src).length()) {

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -18,7 +18,8 @@
 package org.apache.solr.update.processor;
 
 import java.io.IOException;
-
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.update.*;
@@ -58,6 +59,13 @@ class RunUpdateProcessor extends UpdateR
 
   @Override
   public void processAdd(AddUpdateCommand cmd) throws IOException {
+    
+    if (DistributedUpdateProcessor.isAtomicUpdate(cmd)) {
+      throw new SolrException
+        (SolrException.ErrorCode.BAD_REQUEST,
+         "RunUpdateProcessor has recieved an AddUpdateCommand containing a document that appears to still contain Atomic document update operations, most likely because DistributedUpdateProcessorFactory was explicitly disabled from this updateRequestProcessorChain");
+    }
+
     updateHandler.addDoc(cmd);
     super.processAdd(cmd);
     changesSinceCommit = true;

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/SignatureUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/SignatureUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/SignatureUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/SignatureUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -73,6 +73,7 @@ public class SignatureUpdateProcessorFac
     }
   }
 
+  @Override
   public void inform(SolrCore core) {
     final SchemaField field = core.getSchema().getFieldOrNull(getSignatureField());
     if (null == field) {
@@ -133,7 +134,13 @@ public class SignatureUpdateProcessorFac
       if (enabled) {
         SolrInputDocument doc = cmd.getSolrInputDocument();
         List<String> currDocSigFields = null;
+        boolean isPartialUpdate = DistributedUpdateProcessor.isAtomicUpdate(cmd);
         if (sigFields == null || sigFields.size() == 0) {
+          if (isPartialUpdate)  {
+            throw new SolrException
+                (ErrorCode.SERVER_ERROR,
+                    "Can't use SignatureUpdateProcessor with partial updates on signature fields");
+          }
           Collection<String> docFields = doc.getFieldNames();
           currDocSigFields = new ArrayList<String>(docFields.size());
           currDocSigFields.addAll(docFields);
@@ -148,6 +155,12 @@ public class SignatureUpdateProcessorFac
         for (String field : currDocSigFields) {
           SolrInputField f = doc.getField(field);
           if (f != null) {
+            if (isPartialUpdate)  {
+              throw new SolrException
+                  (ErrorCode.SERVER_ERROR,
+                      "Can't use SignatureUpdateProcessor with partial update request " +
+                          "containing signature field: " + field);
+            }
             sig.add(field);
             Object o = f.getValue();
             if (o instanceof Collection) {

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TextProfileSignature.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TextProfileSignature.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TextProfileSignature.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TextProfileSignature.java Fri Jan 18 18:30:54 2013
@@ -153,6 +153,7 @@ public class TextProfileSignature extend
   }
 
   private static class TokenComparator implements Comparator<Token> {
+    @Override
     public int compare(Token t1, Token t2) {
       return t2.cnt - t1.cnt;
     }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TimestampUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TimestampUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TimestampUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TimestampUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -56,10 +56,12 @@ import org.apache.solr.common.params.Com
 public class TimestampUpdateProcessorFactory
   extends AbstractDefaultValueUpdateProcessorFactory {
 
+  @Override
   public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
                                             SolrQueryResponse rsp, 
                                             UpdateRequestProcessor next ) {
     return new DefaultValueUpdateProcessor(fieldName, next) {
+      @Override
       public Object getDefaultValue() { 
         return SolrRequestInfo.getRequestInfo().getNOW();
       }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TrimFieldUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TrimFieldUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TrimFieldUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TrimFieldUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -39,8 +39,7 @@ import org.apache.solr.response.SolrQuer
  *   &lt;lst name="exclude"&gt;
  *     &lt;str name="fieldRegex"&gt;.*_literal&lt;/str&gt;
  *   &lt;/lst&gt;
- * &lt;/processor&gt;
- * </pre>
+ * &lt;/processor&gt;</pre>
  */
 public final class TrimFieldUpdateProcessorFactory extends FieldMutatingUpdateProcessorFactory {
 
@@ -56,6 +55,7 @@ public final class TrimFieldUpdateProces
                                             SolrQueryResponse rsp,
                                             UpdateRequestProcessor next) {
     return new FieldValueMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected Object mutateValue(final Object src) {
         if (src instanceof CharSequence) {
           return ((CharSequence)src).toString().trim();

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TruncateFieldUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TruncateFieldUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TruncateFieldUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/TruncateFieldUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -40,8 +40,7 @@ import org.apache.solr.response.SolrQuer
  * &lt;processor class="solr.TruncateFieldUpdateProcessorFactory"&gt;
  *   &lt;str name="typeClass"&gt;solr.StrField&lt;/str&gt;
  *   &lt;int name="maxLength"&gt;100&lt;/int&gt;
- * &lt;/processor&gt;
- * </pre>
+ * &lt;/processor&gt;</pre>
  */
 public final class TruncateFieldUpdateProcessorFactory 
   extends FieldMutatingUpdateProcessorFactory {
@@ -88,6 +87,7 @@ public final class TruncateFieldUpdatePr
                                             SolrQueryResponse rsp,
                                             UpdateRequestProcessor next) {
     return new FieldValueMutatingUpdateProcessor(getSelector(), next) {
+      @Override
       protected Object mutateValue(final Object src) {
         if (src instanceof CharSequence) {
           CharSequence s = (CharSequence)src;

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -54,10 +54,12 @@ import org.apache.solr.update.AddUpdateC
 public class UUIDUpdateProcessorFactory
   extends AbstractDefaultValueUpdateProcessorFactory {
 
+  @Override
   public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
                                             SolrQueryResponse rsp, 
                                             UpdateRequestProcessor next ) {
     return new DefaultValueUpdateProcessor(fieldName, next) {
+      @Override
       public Object getDefaultValue() { 
         return UUID.randomUUID().toString().toLowerCase(Locale.ROOT);
       }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java Fri Jan 18 18:30:54 2013
@@ -81,6 +81,7 @@ public final class UpdateRequestProcesso
    * @see RunUpdateProcessorFactory
    * @see DistributedUpdateProcessorFactory
    */
+  @Override
   public void init(PluginInfo info) {
     final String infomsg = "updateRequestProcessorChain \"" + 
       (null != info.name ? info.name : "") + "\"" + 
@@ -144,8 +145,7 @@ public final class UpdateRequestProcesso
    * If the <code>DISTRIB_UPDATE_PARAM</code> is present in the request and is 
    * non-blank, then any factory in this chain prior to the instance of 
    * <code>{@link DistributingUpdateProcessorFactory}</code> will be skipped, 
-   * and the <code>UpdateRequestProcessor</code> returned will be from that 
-   * <code>DistributingUpdateProcessorFactory</code>
+   * except for the log update processor factory.
    *
    * @see UpdateRequestProcessorFactory#getInstance
    * @see DistributingUpdateProcessorFactory#DISTRIB_UPDATE_PARAM
@@ -156,18 +156,28 @@ public final class UpdateRequestProcesso
     UpdateRequestProcessor processor = null;
     UpdateRequestProcessor last = null;
     
-    final String distribPhase = req.getParams().get
-      (DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM, "");
-    final boolean skipToDistrib = ! distribPhase.trim().isEmpty();
+    final String distribPhase = req.getParams().get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM);
+    final boolean skipToDistrib = distribPhase != null;
+    boolean afterDistrib = true;  // we iterate backwards, so true to start
 
     for (int i = chain.length-1; i>=0; i--) {
-      processor = chain[i].getInstance(req, rsp, last);
-      last = processor == null ? last : processor;
-      if (skipToDistrib 
-          && chain[i] instanceof DistributingUpdateProcessorFactory) {
-        break;
+      UpdateRequestProcessorFactory factory = chain[i];
+
+      if (skipToDistrib) {
+        if (afterDistrib) {
+          if (factory instanceof DistributingUpdateProcessorFactory) {
+            afterDistrib = false;
+          }
+        } else if (!(factory instanceof LogUpdateProcessorFactory)) {    // TODO: use a marker interface for this?
+          // skip anything that is not the log factory
+          continue;
+        }
       }
+
+      processor = factory.getInstance(req, rsp, last);
+      last = processor == null ? last : processor;
     }
+
     return last;
   }
 

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java Fri Jan 18 18:30:54 2013
@@ -34,6 +34,7 @@ import org.apache.solr.util.plugin.SolrC
  */
 public abstract class UpdateRequestProcessorFactory implements NamedListInitializedPlugin
 {    
+  @Override
   public void init( NamedList args )
   {
     // could process the Node

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/ConcurrentLFUCache.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/ConcurrentLFUCache.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/ConcurrentLFUCache.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/ConcurrentLFUCache.java Fri Jan 18 18:30:54 2013
@@ -327,6 +327,7 @@ public class ConcurrentLFUCache<K, V> {
       this.lastAccessed = lastAccessed;
     }
 
+    @Override
     public int compareTo(CacheEntry<K, V> that) {
       if (this.hitsCopy == that.hitsCopy) {
         if (this.lastAccessedCopy == that.lastAccessedCopy) {

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java Fri Jan 18 18:30:54 2013
@@ -493,6 +493,7 @@ public class ConcurrentLRUCache<K,V> {
       this.lastAccessed = lastAccessed;
     }
 
+    @Override
     public int compareTo(CacheEntry<K,V> that) {
       if (this.lastAccessedCopy == that.lastAccessedCopy) return 0;
       return this.lastAccessedCopy < that.lastAccessedCopy ? 1 : -1;

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/DefaultSolrThreadFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/DefaultSolrThreadFactory.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/DefaultSolrThreadFactory.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/DefaultSolrThreadFactory.java Fri Jan 18 18:30:54 2013
@@ -35,6 +35,7 @@ public class DefaultSolrThreadFactory im
                      "-thread-";
     }
 
+    @Override
     public Thread newThread(Runnable r) {
         Thread t = new Thread(group, r,
                               prefix + threadNumber.getAndIncrement(),

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/RegexFileFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/RegexFileFilter.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/RegexFileFilter.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/RegexFileFilter.java Fri Jan 18 18:30:54 2013
@@ -34,6 +34,7 @@ public final class RegexFileFilter imple
   public RegexFileFilter(Pattern regex) {
     pattern = regex;
   }
+  @Override
   public boolean accept(File f) {
     return pattern.matcher(f.getName()).matches();
   }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SimplePostTool.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SimplePostTool.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SimplePostTool.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SimplePostTool.java Fri Jan 18 18:30:54 2013
@@ -196,7 +196,8 @@ public class SimplePostTool {
         fatal("System Property 'data' is not valid for this tool: " + mode);
       }
       String params = System.getProperty("params", "");
-      urlStr = System.getProperty("url", SimplePostTool.appendParam(DEFAULT_POST_URL, params));
+      urlStr = System.getProperty("url", DEFAULT_POST_URL);
+      urlStr = SimplePostTool.appendParam(urlStr, params);
       URL url = new URL(urlStr);
       boolean auto = isOn(System.getProperty("auto", DEFAULT_AUTO));
       String type = System.getProperty("type");
@@ -800,7 +801,7 @@ public class SimplePostTool {
             " " + urlc.getResponseMessage() + " for url "+url);
       }
     } catch (IOException e) {
-      warn("An error occured posting data to "+url+". Please check that Solr is running.");
+      warn("An error occurred posting data to "+url+". Please check that Solr is running.");
     }
   }
 
@@ -984,6 +985,7 @@ public class SimplePostTool {
       }
     }
     
+    @Override
     public boolean accept(File file)
     {
       return p.matcher(file.getName()).find();

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java Fri Jan 18 18:30:54 2013
@@ -17,12 +17,8 @@
 
 package org.apache.solr.util;
 
-import org.apache.lucene.document.Document;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.StorableField;
 import org.apache.lucene.index.StoredDocument;
-import org.apache.lucene.queryparser.classic.ParseException;
-import org.apache.lucene.queryparser.classic.QueryParser;
 import org.apache.lucene.search.*;
 import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.solr.common.SolrDocument;
@@ -30,7 +26,6 @@ import org.apache.solr.common.SolrDocume
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.SolrParams;
-import org.apache.solr.common.params.UpdateParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.common.util.StrUtils;
@@ -38,13 +33,12 @@ import org.apache.solr.core.SolrCore;
 import org.apache.solr.handler.component.HighlightComponent;
 import org.apache.solr.handler.component.ResponseBuilder;
 import org.apache.solr.highlight.SolrHighlighter;
+import org.apache.solr.parser.QueryParser;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.search.*;
-import org.apache.solr.update.DocumentBuilder;
-import org.slf4j.Logger;
 
 import java.io.IOException;
 import java.util.*;
@@ -386,7 +380,7 @@ public class SolrPluginUtils {
 
     DocList results = req.getSearcher().getDocList(query,(DocSet)null, sort, start, limit);
     return results;
-    } catch (ParseException e) {
+    } catch (SyntaxError e) {
       throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error parsing query: " + qs);
     }
 
@@ -604,8 +598,6 @@ public class SolrPluginUtils {
 
   /**
    * Escapes all special characters except '"', '-', and '+'
-   *
-   * @see QueryParser#escape
    */
   public static CharSequence partialEscape(CharSequence s) {
     StringBuilder sb = new StringBuilder();
@@ -630,7 +622,7 @@ public class SolrPluginUtils {
   private final static Pattern CONSECUTIVE_OP_PATTERN = Pattern.compile( "\\s+[+-](?:\\s*[+-]+)+" );
 
   /**
-   * Strips operators that are used illegally, otherwise reuturns it's
+   * Strips operators that are used illegally, otherwise returns its
    * input.  Some examples of illegal user queries are: "chocolate +-
    * chip", "chocolate - - chip", and "chocolate chip -".
    */
@@ -726,7 +718,7 @@ public class SolrPluginUtils {
      */
     @Override
     protected Query getFieldQuery(String field, String queryText, boolean quoted)
-      throws ParseException {
+      throws SyntaxError {
 
       if (aliases.containsKey(field)) {
 
@@ -798,7 +790,7 @@ public class SolrPluginUtils {
    * @return null if no queries are generated
    */
   public static List<Query> parseQueryStrings(SolrQueryRequest req,
-                                              String[] queries) throws ParseException {
+                                              String[] queries) throws SyntaxError {
     if (null == queries || 0 == queries.length) return null;
     List<Query> out = new ArrayList<Query>(queries.length);
     for (String q : queries) {
@@ -818,6 +810,7 @@ public class SolrPluginUtils {
    * </p>
    */
   public static class IdentityRegenerator implements CacheRegenerator {
+    @Override
     public boolean regenerateItem(SolrIndexSearcher newSearcher,
                                   SolrCache newCache,
                                   SolrCache oldCache,

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SystemIdResolver.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SystemIdResolver.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SystemIdResolver.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/SystemIdResolver.java Fri Jan 18 18:30:54 2013
@@ -72,6 +72,7 @@ public final class SystemIdResolver impl
   
   public URIResolver asURIResolver() {
     return new URIResolver() {
+      @Override
       public Source resolve(String href, String base) throws TransformerException {
         try {
           final InputSource src = SystemIdResolver.this.resolveEntity(null, null, base, href);
@@ -85,6 +86,7 @@ public final class SystemIdResolver impl
   
   public XMLResolver asXMLResolver() {
     return new XMLResolver() {
+      @Override
       public Object resolveEntity(String publicId, String systemId, String baseURI, String namespace) throws XMLStreamException {
         try {
           final InputSource src = SystemIdResolver.this.resolveEntity(null, publicId, baseURI, systemId);
@@ -117,10 +119,12 @@ public final class SystemIdResolver impl
   
   // *** EntityResolver(2) methods:
   
+  @Override
   public InputSource getExternalSubset(String name, String baseURI) {
     return null;
   }
   
+  @Override
   public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws IOException {
     if (systemId == null)
       return null;
@@ -152,6 +156,7 @@ public final class SystemIdResolver impl
     }
   }
 
+  @Override
   public InputSource resolveEntity(String publicId, String systemId) throws IOException {
     return resolveEntity(null, publicId, null, systemId);
   }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/VersionedFile.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/VersionedFile.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/VersionedFile.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/java/org/apache/solr/util/VersionedFile.java Fri Jan 18 18:30:54 2013
@@ -56,6 +56,7 @@ public class VersionedFile 
         if (!f.exists()) {
           File dir = new File(dirName);
           String[] names = dir.list(new FilenameFilter() {
+            @Override
             public boolean accept(File dir, String name) {
               return name.startsWith(prefix);
             }

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/schema12.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/schema12.xml?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/schema12.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/schema12.xml Fri Jan 18 18:30:54 2013
@@ -597,6 +597,7 @@
    <!-- unused, for testing luke copyFields -->
    <dynamicField name="foo_copysource_*" type="ignored" multiValued="true"/>
    <dynamicField name="bar_copydest_*" type="ignored" multiValued="true"/>
+   <dynamicField name="*_es"  type="text"    indexed="true"  stored="true"/>
 
  </fields>
 

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml Fri Jan 18 18:30:54 2013
@@ -22,6 +22,14 @@
   <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}"/>
   <dataDir>${solr.data.dir:}</dataDir>
 
+  <!-- an update processor the explicitly excludes distrib to test
+       clean errors when people attempt atomic updates w/o it
+  -->
+  <updateRequestProcessorChain name="nodistrib" >
+   <processor class="solr.NoOpDistributingUpdateProcessorFactory" />
+   <processor class="solr.RunUpdateProcessorFactory" />
+ </updateRequestProcessorChain>
+
   <requestHandler name="standard" class="solr.StandardRequestHandler">
   </requestHandler>
 
@@ -39,6 +47,29 @@
     </updateLog>
   </updateHandler>
 
+  <updateRequestProcessorChain name="dedupe">
+    <processor class="org.apache.solr.update.processor.SignatureUpdateProcessorFactory">
+      <bool name="enabled">true</bool>
+      <bool name="overwriteDupes">true</bool>
+      <str name="fields">v_t,t_field</str>
+      <str name="signatureClass">org.apache.solr.update.processor.TextProfileSignature</str>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+  <updateRequestProcessorChain name="stored_sig">
+    <!-- this chain is valid even though the signature field is not
+         indexed, because we are not asking for dups to be overwritten
+      -->
+    <processor class="org.apache.solr.update.processor.SignatureUpdateProcessorFactory">
+      <bool name="enabled">true</bool>
+      <str name="signatureField">non_indexed_signature_sS</str>
+      <bool name="overwriteDupes">false</bool>
+      <str name="fields">v_t,t_field</str>
+      <str name="signatureClass">org.apache.solr.update.processor.TextProfileSignature</str>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+
   <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
 
 </config>

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml Fri Jan 18 18:30:54 2013
@@ -40,7 +40,12 @@
   <!--  The DirectoryFactory to use for indexes.
         solr.StandardDirectoryFactory, the default, is filesystem based.
         solr.RAMDirectoryFactory is memory based and not persistent. -->
-  <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}"/>
+  <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}">
+    <double name="maxWriteMBPerSecDefault">1000000</double>
+    <double name="maxWriteMBPerSecFlush">2000000</double>
+    <double name="maxWriteMBPerSecMerge">3000000</double>
+    <double name="maxWriteMBPerSecRead">4000000</double>
+  </directoryFactory>
 
   <luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
 
@@ -90,7 +95,7 @@
     -->
     
     <updateLog enable="${enable.update.log:false}">
-  	  <str name="dir">${solr.data.dir:}</str>
+  	  <str name="dir">${solr.ulog.dir:}</str>
     </updateLog> 
 
   </updateHandler>
@@ -396,6 +401,10 @@
 				<str>spellcheck</str>
 			</arr>
  </requestHandler>
+ 
+  <requestHandler name="mltrh" class="org.apache.solr.handler.component.SearchHandler">
+
+  </requestHandler>
 
   <searchComponent name="tvComponent" class="org.apache.solr.handler.component.TermVectorComponent"/>
 

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/solr.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/solr.xml?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/solr.xml (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test-files/solr/solr.xml Fri Jan 18 18:30:54 2013
@@ -29,7 +29,15 @@
     If 'null' (or absent), cores will not be manageable via request handler
   -->
   <cores adminPath="/admin/cores" defaultCoreName="collection1" host="127.0.0.1" hostPort="${hostPort:8983}" 
-         hostContext="solr" zkClientTimeout="8000" numShards="${numShards:3}" shareSchema="${shareSchema:false}">
+         hostContext="${hostContext:solr}" zkClientTimeout="${solr.zkclienttimeout:30000}" numShards="${numShards:3}" shareSchema="${shareSchema:false}" 
+         distribUpdateConnTimeout="${distribUpdateConnTimeout:15000}" distribUpdateSoTimeout="${distribUpdateSoTimeout:60000}">
     <core name="collection1" instanceDir="collection1" shard="${shard:}" collection="${collection:collection1}" config="${solrconfig:solrconfig.xml}" schema="${schema:schema.xml}"/>
+    <shardHandlerFactory name="shardHandlerFactory" class="HttpShardHandlerFactory">
+      <int name="socketTimeout">${socketTimeout:60000}</int>
+      <int name="connTimeout">${connTimeout:15000}</int>
+    </shardHandlerFactory>
   </cores>
+  
+    
+
 </solr>

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java Fri Jan 18 18:30:54 2013
@@ -30,9 +30,11 @@ import org.apache.solr.client.solrj.requ
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.core.SolrCore;
 import org.junit.BeforeClass;
+import org.junit.AfterClass;
 
 public class AnalysisAfterCoreReloadTest extends SolrTestCaseJ4 {
   
+  private static String tmpSolrHome;
   int port = 0;
   static final String context = "/solr";
 
@@ -40,9 +42,17 @@ public class AnalysisAfterCoreReloadTest
   
   @BeforeClass
   public static void beforeClass() throws Exception {
-    initCore("solrconfig.xml", "schema.xml");
+    createTempDir();
+    tmpSolrHome = TEMP_DIR + File.separator + AnalysisAfterCoreReloadTest.class.getSimpleName() + System.currentTimeMillis();
+    FileUtils.copyDirectory(new File(TEST_HOME()), new File(tmpSolrHome).getAbsoluteFile());
+    initCore("solrconfig.xml", "schema.xml", new File(tmpSolrHome).getAbsolutePath());
   }
 
+  @AfterClass
+  public static void AfterClass() throws Exception {
+    FileUtils.deleteDirectory(new File(tmpSolrHome).getAbsoluteFile());
+  }
+  
   public void testStopwordsAfterCoreReload() throws Exception {
     SolrInputDocument doc = new SolrInputDocument();
     doc.setField( "id", "42" );

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java Fri Jan 18 18:30:54 2013
@@ -21,20 +21,22 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.HashMap;
-import java.util.Map;
-import java.util.List;
 import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
-import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.LogMergePolicy;
 import org.apache.lucene.index.StorableField;
 import org.apache.lucene.index.StoredDocument;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.IOContext.Context;
+import org.apache.lucene.store.MockDirectoryWrapper;
+import org.apache.lucene.store.RateLimitedDirectoryWrapper;
 import org.apache.lucene.util.English;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.CommonParams;
@@ -55,8 +57,6 @@ import org.apache.solr.search.DocIterato
 import org.apache.solr.search.DocList;
 import org.apache.solr.update.DirectUpdateHandler2;
 import org.apache.solr.util.RefCounted;
-
-
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -126,15 +126,28 @@ public class BasicFunctionalityTest exte
     clearIndex();
 
     // test merge factor picked up
+    // and for rate limited settings
     SolrCore core = h.getCore();
 
-    RefCounted<IndexWriter> iw = ((DirectUpdateHandler2) core
+    RefCounted<IndexWriter> iwr = ((DirectUpdateHandler2) core
         .getUpdateHandler()).getSolrCoreState().getIndexWriter(core);
     try {
-      assertEquals("Mergefactor was not picked up", 8, ((LogMergePolicy) iw
-          .get().getConfig().getMergePolicy()).getMergeFactor());
+      IndexWriter iw = iwr.get();
+      assertEquals("Mergefactor was not picked up", 8, ((LogMergePolicy) iw.getConfig().getMergePolicy()).getMergeFactor());
+      
+      Directory dir = iw.getDirectory();
+      
+      if (dir instanceof MockDirectoryWrapper) {
+        dir = ((MockDirectoryWrapper)dir).getDelegate();
+      }
+      
+      assertTrue(dir.getClass().getName(), dir instanceof RateLimitedDirectoryWrapper);
+      assertEquals(Double.valueOf(1000000), ((RateLimitedDirectoryWrapper)dir).getMaxWriteMBPerSec(Context.DEFAULT));
+      assertEquals(Double.valueOf(2000000), ((RateLimitedDirectoryWrapper)dir).getMaxWriteMBPerSec(Context.FLUSH));
+      assertEquals(Double.valueOf(3000000), ((RateLimitedDirectoryWrapper)dir).getMaxWriteMBPerSec(Context.MERGE));
+      assertEquals(Double.valueOf(4000000), ((RateLimitedDirectoryWrapper)dir).getMaxWriteMBPerSec(Context.READ));
     } finally {
-      iw.decref();
+      iwr.decref();
     }
     // test stats call
     NamedList stats = core.getStatistics();

Modified: lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/OutputWriterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/OutputWriterTest.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/OutputWriterTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/solr/core/src/test/org/apache/solr/OutputWriterTest.java Fri Jan 18 18:30:54 2013
@@ -109,13 +109,16 @@ public class OutputWriterTest extends So
         
         public UselessOutputWriter() {}
 
+        @Override
         public void init(NamedList n) {}
         
+        @Override
         public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response)
         throws IOException {
             writer.write(USELESS_OUTPUT);
         }
 
+      @Override
       public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
         return CONTENT_TYPE_TEXT_UTF8;
       }