You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by th...@apache.org on 2014/12/31 21:32:42 UTC

svn commit: r1648775 - in /lucene/dev/trunk/solr: ./ core/src/java/org/apache/solr/update/processor/ core/src/test-files/solr/collection1/conf/ core/src/test/org/apache/solr/update/processor/

Author: thelabdude
Date: Wed Dec 31 20:32:42 2014
New Revision: 1648775

URL: http://svn.apache.org/r1648775
Log:
SOLR-6761: Ability to ignore commit and optimize requests from clients when running in SolrCloud mode.

Added:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactory.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactoryTest.java   (with props)
Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1648775&r1=1648774&r2=1648775&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Wed Dec 31 20:32:42 2014
@@ -268,6 +268,9 @@ New Features
 
 * SOLR-6435: Add bin/post script to simplify posting content to Solr (ehatcher)
 
+* SOLR-6761: Ability to ignore commit and/or optimize requests from clients when running in
+  SolrCloud mode using the IgnoreCommitOptimizeUpdateProcessorFactory. (Timothy Potter)
+
   
 Bug Fixes
 ----------------------

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactory.java?rev=1648775&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactory.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactory.java Wed Dec 31 20:32:42 2014
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.update.processor;
+
+import static org.apache.solr.common.SolrException.ErrorCode;
+
+import java.io.IOException;
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.update.CommitUpdateCommand;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * Gives system administrators a way to ignore explicit commit or optimize requests from clients.
+ * The factory can be configured to return a specific HTTP response code, default is 403, and
+ * optional response message, such as to warn the client application that its request was ignored.
+ * </p>
+ */
+public class IgnoreCommitOptimizeUpdateProcessorFactory extends UpdateRequestProcessorFactory {
+
+  public final static Logger log = LoggerFactory.getLogger(IgnoreCommitOptimizeUpdateProcessorFactory.class);
+
+  private static final String DEFAULT_RESPONSE_MSG = "Explicit commit/optimize requests are forbidden!";
+  
+  protected ErrorCode errorCode;
+  protected String responseMsg;
+  protected boolean ignoreOptimizeOnly = false; // default behavior is to ignore commits and optimize
+
+  @Override
+  public void init(final NamedList args) {
+    SolrParams params = (args != null) ? SolrParams.toSolrParams(args) : null;
+    if (params == null) {
+      errorCode = ErrorCode.FORBIDDEN; // default is 403 error
+      responseMsg = DEFAULT_RESPONSE_MSG;
+      ignoreOptimizeOnly = false;
+      return;
+    }
+
+    ignoreOptimizeOnly = params.getBool("ignoreOptimizeOnly", false);
+
+    int statusCode = params.getInt("statusCode", ErrorCode.FORBIDDEN.code);
+    if (statusCode == 200) {
+      errorCode = null; // not needed but makes the logic clearer
+      responseMsg = params.get("responseMessage"); // OK to be null for 200's
+    } else {
+      errorCode = ErrorCode.getErrorCode(statusCode);
+      if (errorCode == ErrorCode.UNKNOWN) {
+        // only allow the error codes supported by the SolrException.ErrorCode class
+        StringBuilder validCodes = new StringBuilder();
+        int appended = 0;
+        for (ErrorCode code : ErrorCode.values()) {
+          if (code != ErrorCode.UNKNOWN) {
+            if (appended++ > 0) validCodes.append(", ");
+            validCodes.append(code.code);
+          }
+        }
+        throw new IllegalArgumentException("Configured status code " + statusCode +
+            " not supported! Please choose one of: " + validCodes.toString());
+      }
+
+      // must always have a response message if sending an error code
+      responseMsg = params.get("responseMessage", DEFAULT_RESPONSE_MSG);
+    }
+  }
+
+  @Override
+  public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next) {
+    return new IgnoreCommitOptimizeUpdateProcessor(rsp, this, next);
+  }
+}
+
+class IgnoreCommitOptimizeUpdateProcessor extends UpdateRequestProcessor {
+
+  private final SolrQueryResponse rsp;
+  private final ErrorCode errorCode;
+  private final String responseMsg;
+  private final boolean ignoreOptimizeOnly;
+
+  IgnoreCommitOptimizeUpdateProcessor(SolrQueryResponse rsp,
+                                      IgnoreCommitOptimizeUpdateProcessorFactory factory,
+                                      UpdateRequestProcessor next)
+  {
+    super(next);
+    this.rsp = rsp;
+    this.errorCode = factory.errorCode;
+    this.responseMsg = factory.responseMsg;
+    this.ignoreOptimizeOnly = factory.ignoreOptimizeOnly;
+  }
+
+  @Override
+  public void processCommit(CommitUpdateCommand cmd) throws IOException {
+
+    if (ignoreOptimizeOnly && !cmd.optimize) {
+      // we're setup to only ignore optimize requests so it's OK to pass this commit on down the line
+      if (next != null) next.processCommit(cmd);
+      return;
+    }
+
+    final String cmdType = cmd.optimize ? "optimize" : "commit";
+    if (errorCode != null) {
+      IgnoreCommitOptimizeUpdateProcessorFactory.log.info(
+          "{} from client application ignored with error code: {}", cmdType, errorCode.code);
+      rsp.setException(new SolrException(errorCode, responseMsg));
+    } else {
+      // errorcode is null, treat as a success with an optional message warning the commit request was ignored
+      IgnoreCommitOptimizeUpdateProcessorFactory.log.info(
+          "{} from client application ignored with status code: 200", cmdType);
+      if (responseMsg != null) {
+        NamedList<Object> responseHeader = rsp.getResponseHeader();
+        if (responseHeader != null) {
+          responseHeader.add("msg", responseMsg);
+        } else {
+          responseHeader = new SimpleOrderedMap<Object>();
+          responseHeader.add("msg", responseMsg);
+          rsp.add("responseHeader", responseHeader);
+        }
+      }
+    }
+  }
+}

Modified: lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml?rev=1648775&r1=1648774&r2=1648775&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml (original)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml Wed Dec 31 20:32:42 2014
@@ -512,4 +512,25 @@
     <processor class="solr.RunUpdateProcessorFactory" />
   </updateRequestProcessorChain>
 
+  <updateRequestProcessorChain name="ignore-commit-from-client-403">
+    <processor class="solr.IgnoreCommitOptimizeUpdateProcessorFactory"/>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+
+  <updateRequestProcessorChain name="ignore-commit-from-client-200">
+    <processor class="solr.IgnoreCommitOptimizeUpdateProcessorFactory">
+      <int name="statusCode">200</int>
+      <str name="responseMessage">Thou shall not issue a commit!</str>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+
+  <updateRequestProcessorChain name="ignore-optimize-only-from-client-403">
+    <processor class="solr.IgnoreCommitOptimizeUpdateProcessorFactory">
+      <str name="responseMessage">Thou shall not issue an optimize, but commits are OK!</str>
+      <bool name="ignoreOptimizeOnly">true</bool>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+
 </config>

Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactoryTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactoryTest.java?rev=1648775&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactoryTest.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/IgnoreCommitOptimizeUpdateProcessorFactoryTest.java Wed Dec 31 20:32:42 2014
@@ -0,0 +1,76 @@
+package org.apache.solr.update.processor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.SolrInputField;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrRequestInfo;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.update.AddUpdateCommand;
+import org.apache.solr.update.CommitUpdateCommand;
+import org.junit.BeforeClass;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.UUID;
+
+public class IgnoreCommitOptimizeUpdateProcessorFactoryTest extends SolrTestCaseJ4 {
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    initCore("solrconfig-update-processor-chains.xml", "schema.xml");
+  }
+
+  public void testIgnoreCommit() throws Exception {
+    // verify that the processor returns an error if it receives a commit
+    SolrQueryResponse rsp = processCommit("ignore-commit-from-client-403", false);
+    assertNotNull("Sending a commit should have resulted in an exception in the response", rsp.getException());
+
+    rsp = processCommit("ignore-commit-from-client-200", false);
+    Exception shouldBeNull = rsp.getException();
+    assertNull("Sending a commit should NOT have resulted in an exception in the response: "+shouldBeNull, shouldBeNull);
+
+    rsp = processCommit("ignore-optimize-only-from-client-403", true);
+    assertNotNull("Sending an optimize should have resulted in an exception in the response", rsp.getException());
+  }
+
+  SolrQueryResponse processCommit(final String chain, boolean optimize) throws IOException {
+    SolrCore core = h.getCore();
+    UpdateRequestProcessorChain pc = core.getUpdateProcessingChain(chain);
+    assertNotNull("No Chain named: " + chain, pc);
+
+    SolrQueryResponse rsp = new SolrQueryResponse();
+    SolrQueryRequest req = new LocalSolrQueryRequest(core, new ModifiableSolrParams());
+    try {
+      SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req,rsp));
+      CommitUpdateCommand cmd = new CommitUpdateCommand(req, false);
+      cmd.optimize = optimize;
+      UpdateRequestProcessor processor = pc.createProcessor(req, rsp);
+      processor.processCommit(cmd);
+    } finally {
+      SolrRequestInfo.clearRequestInfo();
+      req.close();
+    }
+    return rsp;
+  }
+}