You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by is...@apache.org on 2017/02/12 13:18:35 UTC
[11/18] lucene-solr:jira/solr-5944: Updating branch by merging latest
changes from master
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
index 98486b8..bcb2faa 100644
--- a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
@@ -29,21 +29,63 @@ import org.apache.solr.client.solrj.io.ModelCache;
import org.apache.solr.client.solrj.io.SolrClientCache;
import org.apache.solr.client.solrj.io.Tuple;
import org.apache.solr.client.solrj.io.comp.StreamComparator;
+import org.apache.solr.client.solrj.io.eval.AbsoluteValueEvaluator;
+import org.apache.solr.client.solrj.io.eval.AddEvaluator;
+import org.apache.solr.client.solrj.io.eval.AndEvaluator;
+import org.apache.solr.client.solrj.io.eval.DivideEvaluator;
+import org.apache.solr.client.solrj.io.eval.EqualsEvaluator;
+import org.apache.solr.client.solrj.io.eval.ExclusiveOrEvaluator;
+import org.apache.solr.client.solrj.io.eval.GreaterThanEqualToEvaluator;
+import org.apache.solr.client.solrj.io.eval.GreaterThanEvaluator;
+import org.apache.solr.client.solrj.io.eval.IfThenElseEvaluator;
+import org.apache.solr.client.solrj.io.eval.LessThanEqualToEvaluator;
+import org.apache.solr.client.solrj.io.eval.LessThanEvaluator;
+import org.apache.solr.client.solrj.io.eval.MultiplyEvaluator;
+import org.apache.solr.client.solrj.io.eval.NotEvaluator;
+import org.apache.solr.client.solrj.io.eval.OrEvaluator;
+import org.apache.solr.client.solrj.io.eval.RawValueEvaluator;
+import org.apache.solr.client.solrj.io.eval.SubtractEvaluator;
import org.apache.solr.client.solrj.io.graph.GatherNodesStream;
import org.apache.solr.client.solrj.io.graph.ShortestPathStream;
-import org.apache.solr.client.solrj.io.ops.AndOperation;
import org.apache.solr.client.solrj.io.ops.ConcatOperation;
import org.apache.solr.client.solrj.io.ops.DistinctOperation;
-import org.apache.solr.client.solrj.io.ops.EqualsOperation;
-import org.apache.solr.client.solrj.io.ops.GreaterThanEqualToOperation;
-import org.apache.solr.client.solrj.io.ops.GreaterThanOperation;
import org.apache.solr.client.solrj.io.ops.GroupOperation;
-import org.apache.solr.client.solrj.io.ops.LessThanEqualToOperation;
-import org.apache.solr.client.solrj.io.ops.LessThanOperation;
-import org.apache.solr.client.solrj.io.ops.NotOperation;
-import org.apache.solr.client.solrj.io.ops.OrOperation;
import org.apache.solr.client.solrj.io.ops.ReplaceOperation;
-import org.apache.solr.client.solrj.io.stream.*;
+import org.apache.solr.client.solrj.io.stream.CloudSolrStream;
+import org.apache.solr.client.solrj.io.stream.CommitStream;
+import org.apache.solr.client.solrj.io.stream.ComplementStream;
+import org.apache.solr.client.solrj.io.stream.DaemonStream;
+import org.apache.solr.client.solrj.io.stream.ExceptionStream;
+import org.apache.solr.client.solrj.io.stream.ExecutorStream;
+import org.apache.solr.client.solrj.io.stream.FacetStream;
+import org.apache.solr.client.solrj.io.stream.FeaturesSelectionStream;
+import org.apache.solr.client.solrj.io.stream.FetchStream;
+import org.apache.solr.client.solrj.io.stream.HashJoinStream;
+import org.apache.solr.client.solrj.io.stream.HavingStream;
+import org.apache.solr.client.solrj.io.stream.InnerJoinStream;
+import org.apache.solr.client.solrj.io.stream.IntersectStream;
+import org.apache.solr.client.solrj.io.stream.JDBCStream;
+import org.apache.solr.client.solrj.io.stream.LeftOuterJoinStream;
+import org.apache.solr.client.solrj.io.stream.MergeStream;
+import org.apache.solr.client.solrj.io.stream.ModelStream;
+import org.apache.solr.client.solrj.io.stream.NullStream;
+import org.apache.solr.client.solrj.io.stream.OuterHashJoinStream;
+import org.apache.solr.client.solrj.io.stream.ParallelStream;
+import org.apache.solr.client.solrj.io.stream.PriorityStream;
+import org.apache.solr.client.solrj.io.stream.RandomStream;
+import org.apache.solr.client.solrj.io.stream.RankStream;
+import org.apache.solr.client.solrj.io.stream.ReducerStream;
+import org.apache.solr.client.solrj.io.stream.RollupStream;
+import org.apache.solr.client.solrj.io.stream.ScoreNodesStream;
+import org.apache.solr.client.solrj.io.stream.SelectStream;
+import org.apache.solr.client.solrj.io.stream.SortStream;
+import org.apache.solr.client.solrj.io.stream.StatsStream;
+import org.apache.solr.client.solrj.io.stream.StreamContext;
+import org.apache.solr.client.solrj.io.stream.TextLogitStream;
+import org.apache.solr.client.solrj.io.stream.TopicStream;
+import org.apache.solr.client.solrj.io.stream.TupleStream;
+import org.apache.solr.client.solrj.io.stream.UniqueStream;
+import org.apache.solr.client.solrj.io.stream.UpdateStream;
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
@@ -151,6 +193,7 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
.withFunctionName("executor", ExecutorStream.class)
.withFunctionName("null", NullStream.class)
.withFunctionName("priority", PriorityStream.class)
+
// metrics
.withFunctionName("min", MinMetric.class)
.withFunctionName("max", MaxMetric.class)
@@ -166,19 +209,36 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
.withFunctionName("group", GroupOperation.class)
.withFunctionName("distinct", DistinctOperation.class)
.withFunctionName("having", HavingStream.class)
- .withFunctionName("and", AndOperation.class)
- .withFunctionName("or", OrOperation.class)
- .withFunctionName("not", NotOperation.class)
- .withFunctionName("gt", GreaterThanOperation.class)
- .withFunctionName("lt", LessThanOperation.class)
- .withFunctionName("eq", EqualsOperation.class)
- .withFunctionName("lteq", LessThanEqualToOperation.class)
- .withFunctionName("gteq", GreaterThanEqualToOperation.class);
+
+ // Stream Evaluators
+ .withFunctionName("val", RawValueEvaluator.class)
+
+ // Boolean Stream Evaluators
+ .withFunctionName("and", AndEvaluator.class)
+ .withFunctionName("eor", ExclusiveOrEvaluator.class)
+ .withFunctionName("eq", EqualsEvaluator.class)
+ .withFunctionName("gt", GreaterThanEvaluator.class)
+ .withFunctionName("gteq", GreaterThanEqualToEvaluator.class)
+ .withFunctionName("lt", LessThanEvaluator.class)
+ .withFunctionName("lteq", LessThanEqualToEvaluator.class)
+ .withFunctionName("not", NotEvaluator.class)
+ .withFunctionName("or", OrEvaluator.class)
+
+ // Number Stream Evaluators
+ .withFunctionName("abs", AbsoluteValueEvaluator.class)
+ .withFunctionName("add", AddEvaluator.class)
+ .withFunctionName("div", DivideEvaluator.class)
+ .withFunctionName("mult", MultiplyEvaluator.class)
+ .withFunctionName("sub", SubtractEvaluator.class)
+
+ // Conditional Stream Evaluators
+ .withFunctionName("if", IfThenElseEvaluator.class)
+ ;
// This pulls all the overrides and additions from the config
List<PluginInfo> pluginInfos = core.getSolrConfig().getPluginInfos(Expressible.class.getName());
for (PluginInfo pluginInfo : pluginInfos) {
- Class<? extends Expressible> clazz = core.getResourceLoader().findClass(pluginInfo.className, Expressible.class);
+ Class<? extends Expressible> clazz = core.getMemClassLoader().findClass(pluginInfo.className, Expressible.class);
streamFactory.withFunctionName(pluginInfo.name, clazz);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java
index 6628368..fd7a754 100644
--- a/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java
@@ -150,6 +150,7 @@ public class UpdateRequestHandler extends ContentStreamHandlerBase implements Pe
pathVsLoaders.put(JSON_PATH,registry.get("application/json"));
pathVsLoaders.put(DOC_PATH,registry.get("application/json"));
pathVsLoaders.put(CSV_PATH,registry.get("application/csv"));
+ pathVsLoaders.put(BIN_PATH,registry.get("application/javabin"));
return registry;
}
@@ -178,6 +179,7 @@ public class UpdateRequestHandler extends ContentStreamHandlerBase implements Pe
public static final String DOC_PATH = "/update/json/docs";
public static final String JSON_PATH = "/update/json";
public static final String CSV_PATH = "/update/csv";
+ public static final String BIN_PATH = "/update/bin";
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandlerApi.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandlerApi.java b/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandlerApi.java
new file mode 100644
index 0000000..6ba3229
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandlerApi.java
@@ -0,0 +1,73 @@
+/*
+ * 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.handler;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.api.Api;
+import org.apache.solr.api.ApiBag;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+
+public class UpdateRequestHandlerApi extends UpdateRequestHandler {
+
+
+ @Override
+ public Collection<Api> getApis() {
+ return Collections.singleton(getApiImpl());
+ }
+
+ private Api getApiImpl() {
+ return new Api(ApiBag.getSpec("core.Update")) {
+ @Override
+ public void call(SolrQueryRequest req, SolrQueryResponse rsp) {
+ String path = req.getPath();
+ String target = mapping.get(path);
+ if(target != null) req.getContext().put("path", target);
+ try {
+ handleRequest(req, rsp);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e){
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,e );
+ }
+ }
+ };
+ }
+
+ @Override
+ public Boolean registerV1() {
+ return Boolean.FALSE;
+ }
+
+ @Override
+ public Boolean registerV2() {
+ return Boolean.TRUE;
+ }
+
+ private static final Map<String, String> mapping = ImmutableMap.<String,String>builder()
+ .put("/update", DOC_PATH)
+ .put(JSON_PATH, DOC_PATH)
+ .put("/update/json/commands", JSON_PATH)
+ .build();
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java b/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java
new file mode 100644
index 0000000..0e58ccc
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java
@@ -0,0 +1,236 @@
+/*
+ * 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.handler.admin;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.Utils;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.util.CommandOperation;
+import org.apache.solr.api.Api;
+import org.apache.solr.api.ApiBag;
+import org.apache.solr.api.ApiSupport;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST;
+import static org.apache.solr.common.util.StrUtils.splitSmart;
+
+/**
+ * This is a utility class to provide an easy mapping of request handlers which support multiple commands
+ * to the V2 API format (core admin api, collections api). This helps in automatically mapping paths
+ * to actions and old parameter names to new parameter names
+ */
+public abstract class BaseHandlerApiSupport implements ApiSupport {
+ protected final Map<SolrRequest.METHOD, Map<V2EndPoint, List<ApiCommand>>> commandsMapping;
+
+ protected BaseHandlerApiSupport() {
+ commandsMapping = new HashMap<>();
+ for (ApiCommand cmd : getCommands()) {
+ Map<V2EndPoint, List<ApiCommand>> m = commandsMapping.get(cmd.getHttpMethod());
+ if (m == null) commandsMapping.put(cmd.getHttpMethod(), m = new HashMap<>());
+ List<ApiCommand> list = m.get(cmd.getEndPoint());
+ if (list == null) m.put(cmd.getEndPoint(), list = new ArrayList<>());
+ list.add(cmd);
+ }
+ }
+
+ @Override
+ public synchronized Collection<Api> getApis() {
+ ImmutableList.Builder<Api> l = ImmutableList.builder();
+ for (V2EndPoint op : getEndPoints()) l.add(getApi(op));
+ return l.build();
+ }
+
+
+ private Api getApi(final V2EndPoint op) {
+ final BaseHandlerApiSupport apiHandler = this;
+ return new Api(ApiBag.getSpec(op.getSpecName())) {
+ @Override
+ public void call(SolrQueryRequest req, SolrQueryResponse rsp) {
+ SolrParams params = req.getParams();
+ SolrRequest.METHOD method = SolrRequest.METHOD.valueOf(req.getHttpMethod());
+ List<ApiCommand> commands = commandsMapping.get(method).get(op);
+ try {
+ if (method == POST) {
+ List<CommandOperation> cmds = req.getCommands(true);
+ if (cmds.size() > 1)
+ throw new SolrException(BAD_REQUEST, "Only one command is allowed");
+ CommandOperation c = cmds.size() == 0 ? null : cmds.get(0);
+ ApiCommand command = null;
+ String commandName = c == null ? null : c.name;
+ for (ApiCommand cmd : commands) {
+ if (Objects.equals(cmd.getName(), commandName)) {
+ command = cmd;
+ break;
+ }
+ }
+
+ if (command == null) {
+ throw new SolrException(BAD_REQUEST, " no such command " + c);
+ }
+ wrapParams(req, c, command, false);
+ command.invoke(req, rsp, apiHandler);
+
+ } else {
+ if (commands == null || commands.isEmpty()) {
+ rsp.add("error", "No support for : " + method + " at :" + req.getPath());
+ return;
+ }
+ if (commands.size() > 1) {
+ for (ApiCommand command : commands) {
+ if (command.getName().equals(req.getPath())) {
+ commands = Collections.singletonList(command);
+ break;
+ }
+ }
+ }
+ wrapParams(req, new CommandOperation("", Collections.EMPTY_MAP), commands.get(0), true);
+ commands.get(0).invoke(req, rsp, apiHandler);
+ }
+
+ } catch (SolrException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new SolrException(BAD_REQUEST, e);
+ } finally {
+ req.setParams(params);
+ }
+
+ }
+ };
+
+ }
+
+ private static void wrapParams(final SolrQueryRequest req, final CommandOperation co, final ApiCommand cmd, final boolean useRequestParams) {
+ final Map<String, String> pathValues = req.getPathTemplateValues();
+ final Map<String, Object> map = co == null || !(co.getCommandData() instanceof Map) ?
+ Collections.singletonMap("", co.getCommandData()) : co.getDataMap();
+ final SolrParams origParams = req.getParams();
+
+ req.setParams(
+ new SolrParams() {
+ @Override
+ public String get(String param) {
+ Object vals = getParams0(param);
+ if (vals == null) return null;
+ if (vals instanceof String) return (String) vals;
+ if (vals instanceof Boolean || vals instanceof Number) return String.valueOf(vals);
+ if (vals instanceof String[] && ((String[]) vals).length > 0) return ((String[]) vals)[0];
+ return null;
+ }
+
+ private Object getParams0(String param) {
+ param = cmd.getParamSubstitute(param);
+ Object o = param.indexOf('.') > 0 ?
+ Utils.getObjectByPath(map, true, splitSmart(param, '.')) :
+ map.get(param);
+ if (o == null) o = pathValues.get(param);
+ if (o == null && useRequestParams) o = origParams.getParams(param);
+ if (o instanceof List) {
+ List l = (List) o;
+ return l.toArray(new String[l.size()]);
+ }
+
+ return o;
+ }
+
+ @Override
+ public String[] getParams(String param) {
+ Object vals = getParams0(param);
+ return vals == null || vals instanceof String[] ?
+ (String[]) vals :
+ new String[]{vals.toString()};
+ }
+
+ @Override
+ public Iterator<String> getParameterNamesIterator() {
+ return cmd.getParamNames(co).iterator();
+
+ }
+
+
+ });
+
+ }
+
+
+ public static Collection<String> getParamNames(CommandOperation op, ApiCommand command) {
+ List<String> result = new ArrayList<>();
+ Object o = op.getCommandData();
+ if (o instanceof Map) {
+ Map map = (Map) o;
+ collectKeyNames(map, result, "");
+ }
+ return result;
+
+ }
+
+ public static void collectKeyNames(Map<String, Object> map, List<String> result, String prefix) {
+ for (Map.Entry<String, Object> e : map.entrySet()) {
+ if (e.getValue() instanceof Map) {
+ collectKeyNames((Map) e.getValue(), result, prefix + e.getKey() + ".");
+ } else {
+ result.add(prefix + e.getKey());
+ }
+ }
+ }
+
+ protected abstract List<ApiCommand> getCommands();
+
+ protected abstract List<V2EndPoint> getEndPoints();
+
+
+ public interface ApiCommand {
+ String getName();
+
+ /**
+ * the http method supported by this command
+ */
+ SolrRequest.METHOD getHttpMethod();
+
+ V2EndPoint getEndPoint();
+
+ default Collection<String> getParamNames(CommandOperation op) {
+ return BaseHandlerApiSupport.getParamNames(op, this);
+ }
+
+
+ default String getParamSubstitute(String name) {
+ return name;
+ }
+
+ void invoke(SolrQueryRequest req, SolrQueryResponse rsp, BaseHandlerApiSupport apiHandler) throws Exception;
+ }
+
+ public interface V2EndPoint {
+
+ String getSpecName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java
new file mode 100644
index 0000000..581fe46
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java
@@ -0,0 +1,319 @@
+/*
+ * 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.handler.admin;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.handler.admin.CollectionsHandler.CollectionOperation;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.util.CommandOperation;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.DELETE;
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET;
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.cloud.OverseerCollectionMessageHandler.COLL_CONF;
+import static org.apache.solr.cloud.OverseerCollectionMessageHandler.CREATE_NODE_SET;
+import static org.apache.solr.common.params.CommonParams.NAME;
+import static org.apache.solr.handler.admin.CollectionsHandler.CollectionOperation.*;
+
+
+public class CollectionHandlerApi extends BaseHandlerApiSupport {
+ final CollectionsHandler handler;
+
+ public CollectionHandlerApi(CollectionsHandler handler) {
+ this.handler = handler;
+ }
+
+ @Override
+ protected List<ApiCommand> getCommands() {
+ return Arrays.asList(Cmd.values());
+ }
+
+ @Override
+ protected List<V2EndPoint> getEndPoints() {
+ return Arrays.asList(EndPoint.values());
+ }
+
+
+ enum Cmd implements ApiCommand {
+ GET_COLLECTIONS(EndPoint.COLLECTIONS, GET, LIST_OP),
+ GET_CLUSTER(EndPoint.CLUSTER, GET, LIST_OP, "/cluster", null),
+ GET_CLUSTER_OVERSEER(EndPoint.CLUSTER, GET, OVERSEERSTATUS_OP, "/cluster/overseer", null),
+ GET_CLUSTER_STATUS_CMD(EndPoint.CLUSTER_CMD_STATUS, GET, REQUESTSTATUS_OP),
+ DELETE_CLUSTER_STATUS(EndPoint.CLUSTER_CMD_STATUS_DELETE, DELETE, DELETESTATUS_OP),
+ GET_A_COLLECTION(EndPoint.COLLECTION_STATE, GET, CLUSTERSTATUS_OP),
+ CREATE_COLLECTION(EndPoint.COLLECTIONS_COMMANDS,
+ POST,
+ CREATE_OP,
+ CREATE_OP.action.toLower(),
+ ImmutableMap.of(
+ COLL_CONF, "config",
+ "createNodeSet.shuffle", "shuffleNodes",
+ "createNodeSet", "nodeSet"
+ ),
+ ImmutableMap.of("properties.", "property.")),
+
+ DELETE_COLL(EndPoint.PER_COLLECTION_DELETE,
+ DELETE,
+ DELETE_OP,
+ DELETE_OP.action.toLower(),
+ ImmutableMap.of(NAME, "collection")),
+
+ RELOAD_COLL(EndPoint.PER_COLLECTION,
+ POST,
+ RELOAD_OP,
+ RELOAD_OP.action.toLower(),
+ ImmutableMap.of(NAME, "collection")),
+ MODIFYCOLLECTION(EndPoint.PER_COLLECTION,
+ POST,
+ MODIFYCOLLECTION_OP,
+ "modify",null),
+ MIGRATE_DOCS(EndPoint.PER_COLLECTION,
+ POST,
+ MIGRATE_OP,
+ "migrate-docs",
+ ImmutableMap.of("split.key", "splitKey",
+ "target.collection", "target",
+ "forward.timeout", "forwardTimeout"
+ )),
+ REBALANCELEADERS(EndPoint.PER_COLLECTION,
+ POST,
+ REBALANCELEADERS_OP,
+ "rebalance-leaders", null),
+ CREATE_ALIAS(EndPoint.COLLECTIONS_COMMANDS,
+ POST,
+ CREATEALIAS_OP,
+ "create-alias",
+ null),
+
+ DELETE_ALIAS(EndPoint.COLLECTIONS_COMMANDS,
+ POST,
+ DELETEALIAS_OP,
+ "delete-alias",
+ null),
+ CREATE_SHARD(EndPoint.PER_COLLECTION_SHARDS_COMMANDS,
+ POST,
+ CREATESHARD_OP,
+ "create",
+ ImmutableMap.of(CREATE_NODE_SET, "nodeSet"),
+ ImmutableMap.of("coreProperties.", "property.")) {
+ @Override
+ public String getParamSubstitute(String param) {
+ return super.getParamSubstitute(param);
+ }
+ },
+
+ SPLIT_SHARD(EndPoint.PER_COLLECTION_SHARDS_COMMANDS,
+ POST,
+ SPLITSHARD_OP,
+ "split",
+ ImmutableMap.of(
+ "split.key", "splitKey"),
+ ImmutableMap.of("coreProperties.", "property.")),
+ DELETE_SHARD(EndPoint.PER_COLLECTION_PER_SHARD_DELETE,
+ DELETE,
+ DELETESHARD_OP),
+
+ CREATE_REPLICA(EndPoint.PER_COLLECTION_SHARDS_COMMANDS,
+ POST,
+ ADDREPLICA_OP,
+ "add-replica",
+ null,
+ ImmutableMap.of("coreProperties.", "property.")),
+
+ DELETE_REPLICA(EndPoint.PER_COLLECTION_PER_SHARD_PER_REPLICA_DELETE,
+ DELETE,
+ DELETEREPLICA_OP),
+
+ SYNC_SHARD(EndPoint.PER_COLLECTION_PER_SHARD_COMMANDS,
+ POST,
+ SYNCSHARD_OP,
+ "synch-shard",
+ null),
+ ADDREPLICAPROP(EndPoint.PER_COLLECTION,
+ POST,
+ ADDREPLICAPROP_OP,
+ "add-replica-property",
+ ImmutableMap.of("property", "name", "property.value", "value")),
+ DELETEREPLICAPROP(EndPoint.PER_COLLECTION,
+ POST,
+ DELETEREPLICAPROP_OP,
+ "delete-replica-property",
+ null),
+ ADDROLE(EndPoint.CLUSTER_CMD,
+ POST,
+ ADDROLE_OP,
+ "add-role",null),
+ REMOVEROLE(EndPoint.CLUSTER_CMD,
+ POST,
+ REMOVEROLE_OP,
+ "remove-role",null),
+
+ CLUSTERPROP(EndPoint.CLUSTER_CMD,
+ POST,
+ CLUSTERPROP_OP,
+ "set-property",null),
+
+ BACKUP(EndPoint.COLLECTIONS_COMMANDS,
+ POST,
+ BACKUP_OP,
+ "backup-collection", null
+ ),
+ RESTORE(EndPoint.COLLECTIONS_COMMANDS,
+ POST,
+ RESTORE_OP,
+ "restore-collection",
+ null
+ ),
+ GET_NODES(EndPoint.CLUSTER_NODES, GET, null) {
+ @Override
+ public void invoke(SolrQueryRequest req, SolrQueryResponse rsp, BaseHandlerApiSupport apiHandler) throws Exception {
+ rsp.add("nodes", ((CollectionHandlerApi) apiHandler).handler.coreContainer.getZkController().getClusterState().getLiveNodes());
+ }
+ },
+ FORCELEADER(EndPoint.PER_COLLECTION_PER_SHARD_COMMANDS,POST, FORCELEADER_OP,"force-leader",null),
+ SYNCSHARD(EndPoint.PER_COLLECTION_PER_SHARD_COMMANDS,POST, SYNCSHARD_OP, "sync-shard",null),
+ BALANCESHARDUNIQUE(EndPoint.PER_COLLECTION, POST, BALANCESHARDUNIQUE_OP, "balance-shard-unique",null)
+
+ ;
+ public final String commandName;
+ public final EndPoint endPoint;
+ public final SolrRequest.METHOD method;
+ public final CollectionOperation target;
+ //mapping of http param name to json attribute
+ public final Map<String, String> paramstoAttr;
+ //mapping of old prefix to new for instance properties.a=val can be substituted with property:{a:val}
+ public final Map<String, String> prefixSubstitutes;
+
+ public SolrRequest.METHOD getMethod() {
+ return method;
+ }
+
+
+ Cmd(EndPoint endPoint, SolrRequest.METHOD method, CollectionOperation target) {
+ this(endPoint, method, target, null, null);
+ }
+
+ Cmd(EndPoint endPoint, SolrRequest.METHOD method, CollectionOperation target,
+ String commandName, Map<String, String> paramstoAttr) {
+ this(endPoint, method, target, commandName, paramstoAttr, Collections.EMPTY_MAP);
+
+ }
+
+ Cmd(EndPoint endPoint, SolrRequest.METHOD method, CollectionOperation target,
+ String commandName, Map<String, String> paramstoAttr, Map<String, String> prefixSubstitutes) {
+ this.commandName = commandName;
+ this.endPoint = endPoint;
+ this.method = method;
+ this.target = target;
+ this.paramstoAttr = paramstoAttr == null ? Collections.EMPTY_MAP : paramstoAttr;
+ this.prefixSubstitutes = prefixSubstitutes;
+
+ }
+
+ @Override
+ public String getName() {
+ return commandName;
+ }
+
+ @Override
+ public SolrRequest.METHOD getHttpMethod() {
+ return method;
+ }
+
+ @Override
+ public V2EndPoint getEndPoint() {
+ return endPoint;
+ }
+
+
+ @Override
+ public Collection<String> getParamNames(CommandOperation op) {
+ Collection<String> paramNames = BaseHandlerApiSupport.getParamNames(op, this);
+ if (!prefixSubstitutes.isEmpty()) {
+ Collection<String> result = new ArrayList<>(paramNames.size());
+ for (Map.Entry<String, String> e : prefixSubstitutes.entrySet()) {
+ for (String paramName : paramNames) {
+ if (paramName.startsWith(e.getKey())) {
+ result.add(paramName.replace(e.getKey(), e.getValue()));
+ } else {
+ result.add(paramName);
+ }
+ }
+ paramNames = result;
+ }
+ }
+
+ return paramNames;
+ }
+
+ @Override
+ public String getParamSubstitute(String param) {
+ String s = paramstoAttr.containsKey(param) ? paramstoAttr.get(param) : param;
+ if (prefixSubstitutes != null) {
+ for (Map.Entry<String, String> e : prefixSubstitutes.entrySet()) {
+ if (s.startsWith(e.getValue())) return s.replace(e.getValue(), e.getKey());
+ }
+ }
+ return s;
+ }
+
+ public void invoke(SolrQueryRequest req, SolrQueryResponse rsp, BaseHandlerApiSupport apiHandler)
+ throws Exception {
+ ((CollectionHandlerApi) apiHandler).handler.invokeAction(req, rsp, ((CollectionHandlerApi) apiHandler).handler.coreContainer, target.action, target);
+ }
+
+ }
+
+ enum EndPoint implements V2EndPoint {
+ CLUSTER("cluster"),
+ CLUSTER_CMD("cluster.Commands"),
+ CLUSTER_NODES("cluster.nodes"),
+ CLUSTER_CMD_STATUS("cluster.commandstatus"),
+ CLUSTER_CMD_STATUS_DELETE("cluster.commandstatus.delete"),
+ COLLECTIONS_COMMANDS("collections.Commands"),
+ COLLECTIONS("collections"),
+ COLLECTION_STATE("collections.collection"),
+ PER_COLLECTION("collections.collection.Commands"),
+ PER_COLLECTION_DELETE("collections.collection.delete"),
+ PER_COLLECTION_SHARDS_COMMANDS("collections.collection.shards.Commands"),
+ PER_COLLECTION_PER_SHARD_COMMANDS("collections.collection.shards.shard.Commands"),
+ PER_COLLECTION_PER_SHARD_DELETE("collections.collection.shards.shard.delete"),
+ PER_COLLECTION_PER_SHARD_PER_REPLICA_DELETE("collections.collection.shards.shard.replica.delete");
+ final String specName;
+
+
+ EndPoint(String specName) {
+ this.specName = specName;
+ }
+
+ @Override
+ public String getSpecName() {
+ return specName;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
index 148d73c..d7759ca 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
@@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
+import org.apache.solr.api.Api;
import org.apache.solr.client.solrj.SolrResponse;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient.Builder;
@@ -106,6 +107,7 @@ import static org.apache.solr.cloud.OverseerCollectionMessageHandler.ONLY_IF_DOW
import static org.apache.solr.cloud.OverseerCollectionMessageHandler.REQUESTID;
import static org.apache.solr.cloud.OverseerCollectionMessageHandler.SHARDS_PROP;
import static org.apache.solr.cloud.OverseerCollectionMessageHandler.SHARD_UNIQUE;
+import static org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST;
import static org.apache.solr.common.cloud.DocCollection.DOC_ROUTER;
import static org.apache.solr.common.cloud.DocCollection.RULE;
import static org.apache.solr.common.cloud.DocCollection.SNITCH;
@@ -135,12 +137,14 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
protected final CoreContainer coreContainer;
+ private final CollectionHandlerApi v2Handler ;
public CollectionsHandler() {
super();
// Unlike most request handlers, CoreContainer initialization
// should happen in the constructor...
this.coreContainer = null;
+ v2Handler = new CollectionHandlerApi(this);
}
@@ -151,6 +155,7 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
*/
public CollectionsHandler(final CoreContainer coreContainer) {
this.coreContainer = coreContainer;
+ v2Handler = new CollectionHandlerApi(this);
}
@Override
@@ -205,33 +210,39 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
CollectionOperation operation = CollectionOperation.get(action);
log.info("Invoked Collection Action :{} with params {} and sendToOCPQueue={}", action.toLower(), req.getParamString(), operation.sendToOCPQueue);
- SolrResponse response = null;
- Map<String, Object> props = operation.execute(req, rsp, this);
- String asyncId = req.getParams().get(ASYNC);
- if (props != null) {
- if (asyncId != null) {
- props.put(ASYNC, asyncId);
- }
- props.put(QUEUE_OPERATION, operation.action.toLower());
- ZkNodeProps zkProps = new ZkNodeProps(props);
- if (operation.sendToOCPQueue) {
- response = handleResponse(operation.action.toLower(), zkProps, rsp, operation.timeOut);
- }
- else Overseer.getStateUpdateQueue(coreContainer.getZkController().getZkClient()).offer(Utils.toJSON(props));
- final String collectionName = zkProps.getStr(NAME);
- if (action.equals(CollectionAction.CREATE) && asyncId == null) {
- if (rsp.getException() == null) {
- waitForActiveCollection(collectionName, zkProps, cores, response);
- }
- }
- }
+ invokeAction(req, rsp, cores, action, operation);
} else {
throw new SolrException(ErrorCode.BAD_REQUEST, "action is a required param");
}
rsp.setHttpCaching(false);
}
-
+ void invokeAction(SolrQueryRequest req, SolrQueryResponse rsp, CoreContainer cores, CollectionAction action, CollectionOperation operation) throws Exception {
+ if (!coreContainer.isZooKeeperAware()) {
+ throw new SolrException(BAD_REQUEST,
+ "Invalid request. collections can be accessed only in SolrCloud mode");
+ }
+ SolrResponse response = null;
+ Map<String, Object> props = operation.execute(req, rsp, this);
+ String asyncId = req.getParams().get(ASYNC);
+ if (props != null) {
+ if (asyncId != null) {
+ props.put(ASYNC, asyncId);
+ }
+ props.put(QUEUE_OPERATION, operation.action.toLower());
+ ZkNodeProps zkProps = new ZkNodeProps(props);
+ if (operation.sendToOCPQueue) {
+ response = handleResponse(operation.action.toLower(), zkProps, rsp, operation.timeOut);
+ }
+ else Overseer.getStateUpdateQueue(coreContainer.getZkController().getZkClient()).offer(Utils.toJSON(props));
+ final String collectionName = zkProps.getStr(NAME);
+ if (action.equals(CollectionAction.CREATE) && asyncId == null) {
+ if (rsp.getException() == null) {
+ waitForActiveCollection(collectionName, zkProps, cores, response);
+ }
+ }
+ }
+ }
static final Set<String> KNOWN_ROLES = ImmutableSet.of("overseer");
@@ -387,7 +398,8 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
COLL_CONF,
NUM_SLICES,
MAX_SHARDS_PER_NODE,
- CREATE_NODE_SET, CREATE_NODE_SET_SHUFFLE,
+ CREATE_NODE_SET,
+ CREATE_NODE_SET_SHUFFLE,
SHARDS_PROP,
STATE_FORMAT,
AUTO_ADD_REPLICAS,
@@ -863,7 +875,6 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
}
-
public static CollectionOperation get(CollectionAction action) {
for (CollectionOperation op : values()) {
if (op.action == action) return op;
@@ -1058,7 +1069,7 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
interface CollectionOp {
Map<String, Object> execute(SolrQueryRequest req, SolrQueryResponse rsp, CollectionsHandler h) throws Exception;
-
+
}
public static final List<String> MODIFIABLE_COLL_PROPS = Arrays.asList(
@@ -1068,4 +1079,14 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
MAX_SHARDS_PER_NODE,
AUTO_ADD_REPLICAS,
COLL_CONF);
+
+ @Override
+ public Collection<Api> getApis() {
+ return v2Handler.getApis();
+ }
+
+ @Override
+ public Boolean registerV2() {
+ return Boolean.TRUE;
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java
index f3a8dd2..5d6f02c 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java
@@ -18,11 +18,13 @@ package org.apache.solr.handler.admin;
import java.lang.invoke.MethodHandles;
+import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import org.apache.solr.api.Api;
import org.apache.solr.client.solrj.SolrResponse;
import org.apache.solr.cloud.OverseerSolrResponse;
import org.apache.solr.cloud.OverseerTaskQueue.QueueEvent;
@@ -61,6 +63,7 @@ public class ConfigSetsHandler extends RequestHandlerBase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
protected final CoreContainer coreContainer;
public static long DEFAULT_ZK_TIMEOUT = 300*1000;
+ private final ConfigSetsHandlerApi configSetsHandlerApi = new ConfigSetsHandlerApi(this);
/**
* Overloaded ctor to inject CoreContainer into the handler.
@@ -71,10 +74,6 @@ public class ConfigSetsHandler extends RequestHandlerBase {
this.coreContainer = coreContainer;
}
- @Override
- final public void init(NamedList args) {
-
- }
@Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
@@ -96,16 +95,7 @@ public class ConfigSetsHandler extends RequestHandlerBase {
ConfigSetAction action = ConfigSetAction.get(a);
if (action == null)
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unknown action: " + a);
- ConfigSetOperation operation = ConfigSetOperation.get(action);
- log.info("Invoked ConfigSet Action :{} with params {} ", action.toLower(), req.getParamString());
- Map<String, Object> result = operation.call(req, rsp, this);
- if (result != null) {
- // We need to differentiate between collection and configsets actions since they currently
- // use the same underlying queue.
- result.put(QUEUE_OPERATION, CONFIGSETS_ACTION_PREFIX + operation.action.toLower());
- ZkNodeProps props = new ZkNodeProps(result);
- handleResponse(operation.action.toLower(), props, rsp, DEFAULT_ZK_TIMEOUT);
- }
+ invokeAction(req, rsp, action);
} else {
throw new SolrException(ErrorCode.BAD_REQUEST, "action is a required param");
}
@@ -113,6 +103,24 @@ public class ConfigSetsHandler extends RequestHandlerBase {
rsp.setHttpCaching(false);
}
+ void invokeAction(SolrQueryRequest req, SolrQueryResponse rsp, ConfigSetAction action) throws Exception {
+ ConfigSetOperation operation = ConfigSetOperation.get(action);
+ log.info("Invoked ConfigSet Action :{} with params {} ", action.toLower(), req.getParamString());
+ Map<String, Object> result = operation.call(req, rsp, this);
+ sendToZk(rsp, operation, result);
+ }
+
+ protected void sendToZk(SolrQueryResponse rsp, ConfigSetOperation operation, Map<String, Object> result)
+ throws KeeperException, InterruptedException {
+ if (result != null) {
+ // We need to differentiate between collection and configsets actions since they currently
+ // use the same underlying queue.
+ result.put(QUEUE_OPERATION, CONFIGSETS_ACTION_PREFIX + operation.action.toLower());
+ ZkNodeProps props = new ZkNodeProps(result);
+ handleResponse(operation.action.toLower(), props, rsp, DEFAULT_ZK_TIMEOUT);
+ }
+ }
+
private void handleResponse(String operation, ZkNodeProps m,
SolrQueryResponse rsp, long timeout) throws KeeperException, InterruptedException {
long time = System.nanoTime();
@@ -160,7 +168,6 @@ public class ConfigSetsHandler extends RequestHandlerBase {
public String getDescription() {
return "Manage SolrCloud ConfigSets";
}
-
@Override
public Category getCategory() {
return Category.ADMIN;
@@ -209,4 +216,14 @@ public class ConfigSetsHandler extends RequestHandlerBase {
throw new SolrException(ErrorCode.SERVER_ERROR, "No such action" + action);
}
}
+
+ @Override
+ public Collection<Api> getApis() {
+ return configSetsHandlerApi.getApis();
+ }
+
+ @Override
+ public Boolean registerV2() {
+ return Boolean.TRUE;
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandlerApi.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandlerApi.java b/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandlerApi.java
new file mode 100644
index 0000000..6037bcd
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandlerApi.java
@@ -0,0 +1,112 @@
+/*
+ * 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.handler.admin;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.handler.admin.ConfigSetsHandler.ConfigSetOperation;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.DELETE;
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET;
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.handler.admin.ConfigSetsHandler.ConfigSetOperation.CREATE_OP;
+import static org.apache.solr.handler.admin.ConfigSetsHandler.ConfigSetOperation.DELETE_OP;
+import static org.apache.solr.handler.admin.ConfigSetsHandler.ConfigSetOperation.LIST_OP;
+
+public class ConfigSetsHandlerApi extends BaseHandlerApiSupport {
+
+ final ConfigSetsHandler configSetHandler;
+
+ public ConfigSetsHandlerApi(ConfigSetsHandler configSetHandler) {
+ this.configSetHandler = configSetHandler;
+ }
+
+
+ @Override
+ protected List<ApiCommand> getCommands() {
+ return Arrays.asList(Cmd.values());
+ }
+
+ @Override
+ protected List<V2EndPoint> getEndPoints() {
+ return Arrays.asList(EndPoint.values());
+ }
+
+ enum Cmd implements ApiCommand {
+ LIST(EndPoint.LIST_CONFIG, LIST_OP, GET),
+ CREATE(EndPoint.CONFIG_COMMANDS, CREATE_OP, POST, "create"),
+ DEL(EndPoint.CONFIG_DEL, DELETE_OP, DELETE)
+ ;
+ private final EndPoint endPoint;
+ private final ConfigSetOperation op;
+ private final SolrRequest.METHOD method;
+ private final String cmdName;
+
+ Cmd(EndPoint endPoint, ConfigSetOperation op, SolrRequest.METHOD method) {
+ this(endPoint, op, method, null);
+ }
+
+ Cmd(EndPoint endPoint, ConfigSetOperation op, SolrRequest.METHOD method, String cmdName) {
+ this.cmdName = cmdName;
+ this.endPoint = endPoint;
+ this.op = op;
+ this.method = method;
+ }
+
+ @Override
+ public String getName() {
+ return cmdName;
+ }
+
+ @Override
+ public SolrRequest.METHOD getHttpMethod() {
+ return method;
+ }
+
+ @Override
+ public V2EndPoint getEndPoint() {
+ return endPoint;
+ }
+
+ @Override
+ public void invoke(SolrQueryRequest req, SolrQueryResponse rsp, BaseHandlerApiSupport apiHandler) throws Exception {
+ ((ConfigSetsHandlerApi) apiHandler).configSetHandler.invokeAction(req, rsp, op.action);
+ }
+
+ }
+ enum EndPoint implements V2EndPoint {
+ LIST_CONFIG("cluster.configs"),
+ CONFIG_COMMANDS("cluster.configs.Commands"),
+ CONFIG_DEL("cluster.configs.delete");
+
+ public final String spec;
+
+ EndPoint(String spec) {
+ this.spec = spec;
+ }
+
+ @Override
+ public String getSpecName() {
+ return spec;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
index a415d8a..275ec18 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
@@ -18,6 +18,7 @@ package org.apache.solr.handler.admin;
import java.io.File;
import java.lang.invoke.MethodHandles;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -28,6 +29,7 @@ import java.util.concurrent.ExecutorService;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang.StringUtils;
+import org.apache.solr.api.Api;
import org.apache.solr.cloud.CloudDescriptor;
import org.apache.solr.cloud.ZkController;
import org.apache.solr.common.SolrException;
@@ -66,6 +68,7 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
protected final CoreContainer coreContainer;
protected final Map<String, Map<String, TaskObject>> requestStatusMap;
+ private final CoreAdminHandlerApi coreAdminHandlerApi;
protected ExecutorService parallelExecutor = ExecutorUtil.newMDCAwareFixedThreadPool(50,
new DefaultSolrThreadFactory("parallelCoreAdminExecutor"));
@@ -88,6 +91,7 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa
map.put(COMPLETED, Collections.synchronizedMap(new LinkedHashMap<String, TaskObject>()));
map.put(FAILED, Collections.synchronizedMap(new LinkedHashMap<String, TaskObject>()));
requestStatusMap = Collections.unmodifiableMap(map);
+ coreAdminHandlerApi = new CoreAdminHandlerApi(this);
}
@@ -103,6 +107,7 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa
map.put(COMPLETED, Collections.synchronizedMap(new LinkedHashMap<String, TaskObject>()));
map.put(FAILED, Collections.synchronizedMap(new LinkedHashMap<String, TaskObject>()));
requestStatusMap = Collections.unmodifiableMap(map);
+ coreAdminHandlerApi = new CoreAdminHandlerApi(this);
}
@@ -119,6 +124,10 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa
parallelExecutor = MetricUtils.instrumentedExecutorService(parallelExecutor, manager.registry(registryName),
SolrMetricManager.mkName("parallelCoreAdminExecutor", getCategory().name(),scope, "threadPool"));
}
+ @Override
+ public Boolean registerV2() {
+ return Boolean.TRUE;
+ }
/**
* The instance of CoreContainer this handler handles. This should be the CoreContainer instance that created this
@@ -381,6 +390,11 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa
}
+ @Override
+ public Collection<Api> getApis() {
+ return coreAdminHandlerApi.getApis();
+ }
+
static {
for (CoreAdminOperation op : CoreAdminOperation.values())
opMap.put(op.action.toString().toLowerCase(Locale.ROOT), op);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandlerApi.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandlerApi.java b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandlerApi.java
new file mode 100644
index 0000000..9d256e6
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandlerApi.java
@@ -0,0 +1,175 @@
+/*
+ * 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.handler.admin;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET;
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.handler.admin.CoreAdminHandlerApi.EndPoint.CORES_COMMANDS;
+import static org.apache.solr.handler.admin.CoreAdminHandlerApi.EndPoint.CORES_STATUS;
+import static org.apache.solr.handler.admin.CoreAdminHandlerApi.EndPoint.NODEAPIS;
+import static org.apache.solr.handler.admin.CoreAdminHandlerApi.EndPoint.NODEINVOKE;
+import static org.apache.solr.handler.admin.CoreAdminHandlerApi.EndPoint.PER_CORE_COMMANDS;
+import static org.apache.solr.handler.admin.CoreAdminOperation.CREATE_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.FORCEPREPAREFORLEADERSHIP_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.INVOKE_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.MERGEINDEXES_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.OVERSEEROP_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.PREPRECOVERY_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.REJOINLEADERELECTION_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.RELOAD_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.RENAME_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.REQUESTAPPLYUPDATES_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.REQUESTBUFFERUPDATES_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.REQUESTRECOVERY_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.REQUESTSTATUS_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.REQUESTSYNCSHARD_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.SPLIT_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.STATUS_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.SWAP_OP;
+import static org.apache.solr.handler.admin.CoreAdminOperation.UNLOAD_OP;
+
+public class CoreAdminHandlerApi extends BaseHandlerApiSupport {
+ private final CoreAdminHandler handler;
+
+ public CoreAdminHandlerApi(CoreAdminHandler handler) {
+ this.handler = handler;
+ }
+
+ enum Cmd implements ApiCommand {
+ CREATE(CORES_COMMANDS, POST, CREATE_OP, null, ImmutableMap.of("config", "configSet")),
+ UNLOAD(PER_CORE_COMMANDS, POST, UNLOAD_OP, null, null),
+ RELOAD(PER_CORE_COMMANDS, POST, RELOAD_OP, null, null),
+ STATUS(CORES_STATUS, GET, STATUS_OP),
+ SWAP(PER_CORE_COMMANDS, POST, SWAP_OP, null, ImmutableMap.of("other", "with")),
+ RENAME(PER_CORE_COMMANDS, POST, RENAME_OP, null, null),
+ MERGEINDEXES(PER_CORE_COMMANDS, POST, MERGEINDEXES_OP, "merge-indexes", null),
+ SPLIT(PER_CORE_COMMANDS, POST, SPLIT_OP, null, ImmutableMap.of("split.key", "splitKey")),
+ PREPRECOVERY(PER_CORE_COMMANDS, POST, PREPRECOVERY_OP, "prep-recovery", null),
+ REQUESTRECOVERY(PER_CORE_COMMANDS, POST, REQUESTRECOVERY_OP, null, null),
+ REQUESTSYNCSHARD(PER_CORE_COMMANDS, POST, REQUESTSYNCSHARD_OP, "request-sync-shard", null),
+ REQUESTBUFFERUPDATES(PER_CORE_COMMANDS, POST, REQUESTBUFFERUPDATES_OP, "request-buffer-updates", null),
+ REQUESTAPPLYUPDATES(PER_CORE_COMMANDS, POST, REQUESTAPPLYUPDATES_OP, "request-apply-updates", null),
+ REQUESTSTATUS(PER_CORE_COMMANDS, POST, REQUESTSTATUS_OP, null, null),
+ OVERSEEROP(NODEAPIS, POST, OVERSEEROP_OP, "overseer-op", null),
+ REJOINLEADERELECTION(NODEAPIS, POST, REJOINLEADERELECTION_OP, "rejoin-leader-election", null),
+ INVOKE(NODEINVOKE, GET, INVOKE_OP, null, null),
+ FORCEPREPAREFORLEADERSHIP(PER_CORE_COMMANDS, POST, FORCEPREPAREFORLEADERSHIP_OP, "force-prepare-for-leadership", null);
+
+ public final String commandName;
+ public final BaseHandlerApiSupport.V2EndPoint endPoint;
+ public final SolrRequest.METHOD method;
+ public final Map<String, String> paramstoAttr;
+ final CoreAdminOperation target;
+
+
+ Cmd(EndPoint endPoint, SolrRequest.METHOD method, CoreAdminOperation target) {
+ this.endPoint = endPoint;
+ this.method = method;
+ this.target = target;
+ commandName = null;
+ paramstoAttr = Collections.EMPTY_MAP;
+
+ }
+
+
+ Cmd(EndPoint endPoint, SolrRequest.METHOD method, CoreAdminOperation target, String commandName,
+ Map<String, String> paramstoAttr) {
+ this.commandName = commandName == null ? target.action.toString().toLowerCase(Locale.ROOT) : commandName;
+ this.endPoint = endPoint;
+ this.method = method;
+ this.target = target;
+ this.paramstoAttr = paramstoAttr == null ? Collections.EMPTY_MAP : paramstoAttr;
+ }
+
+ @Override
+ public String getName() {
+ return commandName;
+ }
+
+ @Override
+ public SolrRequest.METHOD getHttpMethod() {
+ return method;
+ }
+
+ @Override
+ public V2EndPoint getEndPoint() {
+ return endPoint;
+ }
+
+ @Override
+ public String getParamSubstitute(String param) {
+ return paramstoAttr.containsKey(param) ? paramstoAttr.get(param) : param;
+ }
+
+ @Override
+ public void invoke(SolrQueryRequest req, SolrQueryResponse rsp, BaseHandlerApiSupport apiHandler) throws Exception {
+ target.execute(new CoreAdminHandler.CallInfo(((CoreAdminHandlerApi) apiHandler).handler,
+ req,
+ rsp,
+ target));
+
+ }
+
+ }
+
+
+
+ enum EndPoint implements BaseHandlerApiSupport.V2EndPoint {
+ CORES_STATUS("cores.Status"),
+ CORES_COMMANDS("cores.Commands"),
+ PER_CORE_COMMANDS("cores.core.Commands"),
+ NODEINVOKE("node.invoke"),
+ NODEAPIS("node.Commands")
+ ;
+
+ final String specName;
+
+ EndPoint(String specName) {
+ this.specName = specName;
+ }
+
+ @Override
+ public String getSpecName() {
+ return specName;
+ }
+ }
+
+
+ @Override
+ protected List<ApiCommand> getCommands() {
+ return Arrays.asList(Cmd.values());
+ }
+
+ @Override
+ protected List<V2EndPoint> getEndPoints() {
+ return Arrays.asList(EndPoint.values());
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/InfoHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/InfoHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/InfoHandler.java
index 8fdac21..c7cd052 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/InfoHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/InfoHandler.java
@@ -16,24 +16,28 @@
*/
package org.apache.solr.handler.admin;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.solr.api.ApiBag.ReqHandlerToApi;
import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.api.Api;
+import static java.util.Collections.singletonList;
+import static org.apache.solr.api.ApiBag.getSpec;
import static org.apache.solr.common.params.CommonParams.PATH;
-public class InfoHandler extends RequestHandlerBase {
+public class InfoHandler extends RequestHandlerBase {
+
protected final CoreContainer coreContainer;
-
- private ThreadDumpHandler threadDumpHandler = new ThreadDumpHandler();
- private PropertiesRequestHandler propertiesHandler = new PropertiesRequestHandler();
- private LoggingHandler loggingHandler;
- private SystemInfoHandler systemInfoHandler;
/**
* Overloaded ctor to inject CoreContainer into the handler.
@@ -42,9 +46,10 @@ public class InfoHandler extends RequestHandlerBase {
*/
public InfoHandler(final CoreContainer coreContainer) {
this.coreContainer = coreContainer;
- systemInfoHandler = new SystemInfoHandler(coreContainer);
- loggingHandler = new LoggingHandler(coreContainer);
-
+ handlers.put("threads", new ThreadDumpHandler());
+ handlers.put("properties", new PropertiesRequestHandler());
+ handlers.put("logging", new LoggingHandler(coreContainer));
+ handlers.put("system", new SystemInfoHandler(coreContainer));
}
@@ -73,27 +78,19 @@ public class InfoHandler extends RequestHandlerBase {
}
String path = (String) req.getContext().get(PATH);
+ handle(req, rsp, path);
+ }
+
+ private void handle(SolrQueryRequest req, SolrQueryResponse rsp, String path) {
int i = path.lastIndexOf('/');
String name = path.substring(i + 1, path.length());
-
- if (name.equalsIgnoreCase("properties")) {
- propertiesHandler.handleRequest(req, rsp);
- } else if (name.equalsIgnoreCase("threads")) {
- threadDumpHandler.handleRequest(req, rsp);
- } else if (name.equalsIgnoreCase("logging")) {
- loggingHandler.handleRequest(req, rsp);
- } else if (name.equalsIgnoreCase("system")) {
- systemInfoHandler.handleRequest(req, rsp);
- } else {
- if (name.equalsIgnoreCase("info")) name = "";
- throw new SolrException(ErrorCode.NOT_FOUND, "Info Handler not found: " + name);
+ RequestHandlerBase handler = handlers.get(name.toLowerCase(Locale.ROOT));
+ if(handler == null) {
+ throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "No handler by name "+name + " available names are "+ handlers.keySet());
}
-
+ handler.handleRequest(req, rsp);
rsp.setHttpCaching(false);
}
-
-
-
//////////////////////// SolrInfoMBeans methods //////////////////////
@@ -109,39 +106,52 @@ public class InfoHandler extends RequestHandlerBase {
}
protected PropertiesRequestHandler getPropertiesHandler() {
- return propertiesHandler;
+ return (PropertiesRequestHandler) handlers.get("properties");
+
}
protected ThreadDumpHandler getThreadDumpHandler() {
- return threadDumpHandler;
+ return (ThreadDumpHandler) handlers.get("threads");
}
protected LoggingHandler getLoggingHandler() {
- return loggingHandler;
+ return (LoggingHandler) handlers.get("logging");
}
protected SystemInfoHandler getSystemInfoHandler() {
- return systemInfoHandler;
+ return (SystemInfoHandler) handlers.get("system");
}
protected void setPropertiesHandler(PropertiesRequestHandler propertiesHandler) {
- this.propertiesHandler = propertiesHandler;
+ handlers.put("properties", propertiesHandler);
}
protected void setThreadDumpHandler(ThreadDumpHandler threadDumpHandler) {
- this.threadDumpHandler = threadDumpHandler;
+ handlers.put("threads", threadDumpHandler);
}
protected void setLoggingHandler(LoggingHandler loggingHandler) {
- this.loggingHandler = loggingHandler;
+ handlers.put("logging", loggingHandler);
}
protected void setSystemInfoHandler(SystemInfoHandler systemInfoHandler) {
- this.systemInfoHandler = systemInfoHandler;
+ handlers.put("system", systemInfoHandler);
}
@Override
public SolrRequestHandler getSubHandler(String subPath) {
return this;
}
+
+ private Map<String, RequestHandlerBase> handlers = new ConcurrentHashMap<>();
+
+ @Override
+ public Collection<Api> getApis() {
+ return singletonList(new ReqHandlerToApi(this, getSpec("node.Info")));
+ }
+
+ @Override
+ public Boolean registerV2() {
+ return Boolean.TRUE;
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java
index 1b81722..eceb4b7 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java
@@ -20,12 +20,15 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import com.google.common.collect.ImmutableList;
+import org.apache.solr.api.ApiBag;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.Utils;
@@ -34,10 +37,16 @@ import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.SolrConfigHandler;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.security.AuthenticationPlugin;
import org.apache.solr.security.AuthorizationContext;
+import org.apache.solr.security.AuthorizationPlugin;
import org.apache.solr.security.ConfigEditablePlugin;
import org.apache.solr.security.PermissionNameProvider;
import org.apache.solr.util.CommandOperation;
+import org.apache.solr.api.Api;
+import org.apache.solr.api.ApiBag.ReqHandlerToApi;
+import org.apache.solr.api.SpecProvider;
+import org.apache.solr.util.JsonSchemaValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -244,5 +253,66 @@ public abstract class SecurityConfHandler extends RequestHandlerBase implements
return "SecurityConfig: version=" + version + ", data=" + Utils.toJSONString(data);
}
}
+
+ private Collection<Api> apis;
+ private AuthenticationPlugin authcPlugin;
+ private AuthorizationPlugin authzPlugin;
+
+ @Override
+ public Collection<Api> getApis() {
+ if (apis == null) {
+ synchronized (this) {
+ if (apis == null) {
+ Collection<Api> apis = new ArrayList<>();
+ final SpecProvider authcCommands = ApiBag.getSpec("cluster.security.authentication.Commands");
+ final SpecProvider authzCommands = ApiBag.getSpec("cluster.security.authorization.Commands");
+ apis.add(new ReqHandlerToApi(this, ApiBag.getSpec("cluster.security.authentication")));
+ apis.add(new ReqHandlerToApi(this, ApiBag.getSpec("cluster.security.authorization")));
+ SpecProvider authcSpecProvider = () -> {
+ AuthenticationPlugin authcPlugin = cores.getAuthenticationPlugin();
+ return authcPlugin != null && authcPlugin instanceof SpecProvider ?
+ ((SpecProvider) authcPlugin).getSpec() :
+ authcCommands.getSpec();
+ };
+
+ apis.add(new ReqHandlerToApi(this, authcSpecProvider) {
+ @Override
+ public synchronized Map<String, JsonSchemaValidator> getCommandSchema() {
+ //it is possible that the Authentication plugin is modified since the last call. invalidate the
+ // the cached commandSchema
+ if(SecurityConfHandler.this.authcPlugin != cores.getAuthenticationPlugin()) commandSchema = null;
+ SecurityConfHandler.this.authcPlugin = cores.getAuthenticationPlugin();
+ return super.getCommandSchema();
+ }
+ });
+
+ SpecProvider authzSpecProvider = () -> {
+ AuthorizationPlugin authzPlugin = cores.getAuthorizationPlugin();
+ return authzPlugin != null && authzPlugin instanceof SpecProvider ?
+ ((SpecProvider) authzPlugin).getSpec() :
+ authzCommands.getSpec();
+ };
+ apis.add(new ApiBag.ReqHandlerToApi(this, authzSpecProvider) {
+ @Override
+ public synchronized Map<String, JsonSchemaValidator> getCommandSchema() {
+ //it is possible that the Authorization plugin is modified since the last call. invalidate the
+ // the cached commandSchema
+ if(SecurityConfHandler.this.authzPlugin != cores.getAuthorizationPlugin()) commandSchema = null;
+ SecurityConfHandler.this.authzPlugin = cores.getAuthorizationPlugin();
+ return super.getCommandSchema();
+ }
+ });
+
+ this.apis = ImmutableList.copyOf(apis);
+ }
+ }
+ }
+ return this.apis;
+ }
+
+ @Override
+ public Boolean registerV2() {
+ return Boolean.TRUE;
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java b/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java
index bcff0c2..66b9ab8 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java
@@ -50,6 +50,7 @@ import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.PointField;
import org.apache.solr.search.QueryParsing;
+import org.apache.solr.search.DocSet;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.search.facet.FacetDebugInfo;
import org.apache.solr.util.RTimer;
@@ -103,6 +104,11 @@ public class FacetComponent extends SearchComponent {
}
}
+ /* Custom facet components can return a custom SimpleFacets object */
+ protected SimpleFacets newSimpleFacets(SolrQueryRequest req, DocSet docSet, SolrParams params, ResponseBuilder rb) {
+ return new SimpleFacets(req, docSet, params, rb);
+ }
+
/**
* Encapsulates facet ranges and facet queries such that their parameters
* are parsed and cached for efficient re-use.
@@ -253,7 +259,7 @@ public class FacetComponent extends SearchComponent {
if (rb.doFacets) {
SolrParams params = rb.req.getParams();
- SimpleFacets f = new SimpleFacets(rb.req, rb.getResults().docSet, params, rb);
+ SimpleFacets f = newSimpleFacets(rb.req, rb.getResults().docSet, params, rb);
RTimer timer = null;
FacetDebugInfo fdebug = null;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/component/RangeFacetRequest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/RangeFacetRequest.java b/solr/core/src/java/org/apache/solr/handler/component/RangeFacetRequest.java
index f129e73..aa3e3cb 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/RangeFacetRequest.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/RangeFacetRequest.java
@@ -34,7 +34,6 @@ import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.schema.DateRangeField;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.PointField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieDateField;
import org.apache.solr.schema.TrieField;
@@ -144,9 +143,7 @@ public class RangeFacetRequest extends FacetComponent.FacetBase {
FieldType ft = schemaField.getType();
if (ft instanceof TrieField) {
- final TrieField trie = (TrieField) ft;
-
- switch (trie.getType()) {
+ switch (ft.getNumberType()) {
case FLOAT:
calc = new FloatRangeEndpointCalculator(this);
break;
@@ -170,8 +167,7 @@ public class RangeFacetRequest extends FacetComponent.FacetBase {
} else if (ft instanceof DateRangeField) {
calc = new DateRangeEndpointCalculator(this, null);
} else if (ft.isPointField()) {
- final PointField pointField = (PointField) ft;
- switch (pointField.getType()) {
+ switch (ft.getNumberType()) {
case FLOAT:
calc = new FloatRangeEndpointCalculator(this);
break;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java
index a229a85..2f805f4 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java
@@ -199,8 +199,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
boolean isCorrectlySpelled = hits > (maxResultsForSuggest==null ? 0 : maxResultsForSuggest);
NamedList response = new SimpleOrderedMap();
- NamedList suggestions = toNamedList(shardRequest, spellingResult, q, extendedResults);
- response.add("suggestions", suggestions);
+ response.add("suggestions", toNamedList(shardRequest, spellingResult, q, extendedResults));
if (extendedResults) {
response.add("correctlySpelled", isCorrectlySpelled);
@@ -300,7 +299,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
//even in cases when the internal rank is the same.
Collections.sort(collations);
- NamedList collationList = new NamedList();
+ NamedList collationList = new SimpleOrderedMap();
for (SpellCheckCollation collation : collations) {
if (collationExtendedResults) {
NamedList extendedResult = new SimpleOrderedMap();
@@ -424,8 +423,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
NamedList response = new SimpleOrderedMap();
- NamedList suggestions = toNamedList(false, result, origQuery, extendedResults);
- response.add("suggestions", suggestions);
+ response.add("suggestions", toNamedList(false, result, origQuery, extendedResults));
if (extendedResults) {
response.add("correctlySpelled", isCorrectlySpelled);
@@ -436,7 +434,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
.toArray(new SpellCheckCollation[mergeData.collations.size()]);
Arrays.sort(sortedCollations);
- NamedList collations = new NamedList();
+ NamedList collations = new SimpleOrderedMap();
int i = 0;
while (i < maxCollations && i < sortedCollations.length) {
SpellCheckCollation collation = sortedCollations[i];
@@ -636,7 +634,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar
protected NamedList toNamedList(boolean shardRequest,
SpellingResult spellingResult, String origQuery, boolean extendedResults) {
- NamedList result = new NamedList();
+ NamedList result = new SimpleOrderedMap();
Map<Token,LinkedHashMap<String,Integer>> suggestions = spellingResult
.getSuggestions();
boolean hasFreqInfo = spellingResult.hasTokenFrequencyInfo();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/handler/component/StatsField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/StatsField.java b/solr/core/src/java/org/apache/solr/handler/component/StatsField.java
index 5df1b45..03bf814 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/StatsField.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/StatsField.java
@@ -29,7 +29,6 @@ import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
-import org.apache.lucene.legacy.LegacyNumericType;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.queries.function.FunctionQuery;
import org.apache.lucene.queries.function.ValueSource;
@@ -46,6 +45,7 @@ import org.apache.solr.common.util.StrUtils;
import org.apache.solr.request.DocValuesStats;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.schema.NumberType;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocSet;
@@ -57,8 +57,8 @@ import org.apache.solr.search.SyntaxError;
import org.apache.solr.util.hll.HLL;
import org.apache.solr.util.hll.HLLType;
-import com.google.common.hash.Hashing;
import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
/**
* Models all of the information associated with a single {@link StatsParams#STATS_FIELD}
@@ -636,13 +636,13 @@ public class StatsField {
return null;
}
- final LegacyNumericType hashableNumType = getHashableNumericType(field);
+ final NumberType hashableNumType = getHashableNumericType(field);
// some sane defaults
int log2m = 13; // roughly equivilent to "cardinality='0.33'"
int regwidth = 6; // with decent hash, this is plenty for all valid long hashes
- if (LegacyNumericType.FLOAT.equals(hashableNumType) || LegacyNumericType.INT.equals(hashableNumType)) {
+ if (NumberType.FLOAT.equals(hashableNumType) || NumberType.INTEGER.equals(hashableNumType)) {
// for 32bit values, we can adjust our default regwidth down a bit
regwidth--;
@@ -706,7 +706,7 @@ public class StatsField {
if (null == hasher) {
// if this is a function, or a non Long field, pre-hashed is invalid
// NOTE: we ignore hashableNumType - it's LONG for non numerics like Strings
- if (null == field || !LegacyNumericType.LONG.equals(field.getType().getNumericType())) {
+ if (null == field || !(NumberType.LONG.equals(field.getType().getNumberType()) || NumberType.DATE.equals(field.getType().getNumberType()))) {
throw new SolrException(ErrorCode.BAD_REQUEST, "hllPreHashed is only supported with Long based fields");
}
}
@@ -739,16 +739,16 @@ public class StatsField {
}
/**
- * Returns the effective {@link LegacyNumericType} for the field for the purposes of hash values.
- * ie: If the field has an explict LegacyNumericType that is returned; If the field has no explicit
- * LegacyNumericType then {@link LegacyNumericType#LONG} is returned; If field is null, then
- * {@link LegacyNumericType#FLOAT} is assumed for ValueSource.
+ * Returns the effective {@link NumberType} for the field for the purposes of hash values.
+ * ie: If the field has an explict NumberType that is returned; If the field has no explicit
+ * NumberType then {@link NumberType#LONG} is returned; If field is null, then
+ * {@link NumberType#FLOAT} is assumed for ValueSource.
*/
- private static LegacyNumericType getHashableNumericType(SchemaField field) {
+ private static NumberType getHashableNumericType(SchemaField field) {
if (null == field) {
- return LegacyNumericType.FLOAT;
+ return NumberType.FLOAT;
}
- final LegacyNumericType result = field.getType().getNumericType();
- return null == result ? LegacyNumericType.LONG : result;
+ final NumberType result = field.getType().getNumberType();
+ return null == result ? NumberType.LONG : result;
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java b/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java
index e035a75..33ea575 100644
--- a/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java
+++ b/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java
@@ -525,8 +525,7 @@ public class DefaultSolrHighlighter extends SolrHighlighter implements PluginInf
}
int maxCharsToAnalyze = params.getFieldInt(fieldName,
- HighlightParams.MAX_CHARS,
- Highlighter.DEFAULT_MAX_CHARS_TO_ANALYZE);
+ HighlightParams.MAX_CHARS, DEFAULT_MAX_CHARS);
if (maxCharsToAnalyze < 0) {//e.g. -1
maxCharsToAnalyze = Integer.MAX_VALUE;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/highlight/PostingsSolrHighlighter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/PostingsSolrHighlighter.java b/solr/core/src/java/org/apache/solr/highlight/PostingsSolrHighlighter.java
index 513b38a..9fcf9f3 100644
--- a/solr/core/src/java/org/apache/solr/highlight/PostingsSolrHighlighter.java
+++ b/solr/core/src/java/org/apache/solr/highlight/PostingsSolrHighlighter.java
@@ -66,7 +66,7 @@ import org.apache.solr.util.plugin.PluginInfoInitialized;
* <str name="hl.bs.country"></str>
* <str name="hl.bs.variant"></str>
* <str name="hl.bs.type">SENTENCE</str>
- * <int name="hl.maxAnalyzedChars">10000</int>
+ * <int name="hl.maxAnalyzedChars">51200</int>
* <str name="hl.multiValuedSeparatorChar"> </str>
* <bool name="hl.highlightMultiTerm">false</bool>
* </lst>
@@ -204,7 +204,7 @@ public class PostingsSolrHighlighter extends SolrHighlighter implements PluginIn
protected final IndexSchema schema;
public SolrExtendedPostingsHighlighter(SolrQueryRequest req) {
- super(req.getParams().getInt(HighlightParams.MAX_CHARS, PostingsHighlighter.DEFAULT_MAX_LENGTH));
+ super(req.getParams().getInt(HighlightParams.MAX_CHARS, DEFAULT_MAX_CHARS));
this.params = req.getParams();
this.schema = req.getSchema();
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/highlight/SolrHighlighter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/SolrHighlighter.java b/solr/core/src/java/org/apache/solr/highlight/SolrHighlighter.java
index e9ebf0c..a8ee734 100644
--- a/solr/core/src/java/org/apache/solr/highlight/SolrHighlighter.java
+++ b/solr/core/src/java/org/apache/solr/highlight/SolrHighlighter.java
@@ -31,6 +31,7 @@ import java.util.List;
public abstract class SolrHighlighter
{
+ public static int DEFAULT_MAX_CHARS = 51200;
public static int DEFAULT_PHRASE_LIMIT = 5000;
/**
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/highlight/UnifiedSolrHighlighter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/UnifiedSolrHighlighter.java b/solr/core/src/java/org/apache/solr/highlight/UnifiedSolrHighlighter.java
index 2633522..c80e522 100644
--- a/solr/core/src/java/org/apache/solr/highlight/UnifiedSolrHighlighter.java
+++ b/solr/core/src/java/org/apache/solr/highlight/UnifiedSolrHighlighter.java
@@ -62,8 +62,8 @@ import org.apache.solr.util.plugin.PluginInfoInitialized;
* <str name="hl.tag.post">&lt;/em&gt;</str>
* <str name="hl.simple.pre">&lt;em&gt;</str>
* <str name="hl.simple.post">&lt;/em&gt;</str>
- * <str name="hl.tag.ellipsis">... </str>
- * <bool name="hl.defaultSummary">true</bool>
+ * <str name="hl.tag.ellipsis">(internal/unspecified)</str>
+ * <bool name="hl.defaultSummary">false</bool>
* <str name="hl.encoder">simple</str>
* <float name="hl.score.k1">1.2</float>
* <float name="hl.score.b">0.75</float>
@@ -72,7 +72,7 @@ import org.apache.solr.util.plugin.PluginInfoInitialized;
* <str name="hl.bs.country"></str>
* <str name="hl.bs.variant"></str>
* <str name="hl.bs.type">SENTENCE</str>
- * <int name="hl.maxAnalyzedChars">10000</int>
+ * <int name="hl.maxAnalyzedChars">51200</int>
* <bool name="hl.highlightMultiTerm">true</bool>
* <bool name="hl.usePhraseHighlighter">true</bool>
* <int name="hl.cacheFieldValCharsThreshold">524288</int>
@@ -234,7 +234,7 @@ public class UnifiedSolrHighlighter extends SolrHighlighter implements PluginInf
this.params = req.getParams();
this.schema = req.getSchema();
this.setMaxLength(
- params.getInt(HighlightParams.MAX_CHARS, UnifiedHighlighter.DEFAULT_MAX_LENGTH));
+ params.getInt(HighlightParams.MAX_CHARS, DEFAULT_MAX_CHARS));
this.setCacheFieldValCharsThreshold(
params.getInt(HighlightParams.CACHE_FIELD_VAL_CHARS_THRESHOLD, DEFAULT_CACHE_CHARS_THRESHOLD));
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
index 3bebcd3..eb5b687 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
@@ -73,9 +73,6 @@ public class SolrCoreMetricManager implements Closeable {
}
// close old reporters
metricManager.closeReporters(oldRegistryName);
- metricManager.moveMetrics(oldRegistryName, registryName, null);
- // old registry is no longer used - we have moved the metrics
- metricManager.removeRegistry(oldRegistryName);
// load reporters again, using the new core name
loadReporters();
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/solr/core/src/java/org/apache/solr/metrics/SolrMetricInfo.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricInfo.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricInfo.java
index f0bc8a1..4d093eb 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricInfo.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricInfo.java
@@ -30,7 +30,7 @@ public final class SolrMetricInfo {
/**
* Creates a new instance of {@link SolrMetricInfo}.
*
- * @param category the category of the metric (e.g. `QUERYHANDLERS`)
+ * @param category the category of the metric (e.g. `QUERY`)
* @param scope the scope of the metric (e.g. `/admin/ping`)
* @param name the name of the metric (e.g. `Requests`)
*/
@@ -63,8 +63,8 @@ public final class SolrMetricInfo {
/**
* Returns the metric name defined by this object.
* For example, if the name is `Requests`, scope is `/admin/ping`,
- * and category is `QUERYHANDLERS`, then the metric name is
- * `QUERYHANDLERS./admin/ping.Requests`.
+ * and category is `QUERY`, then the metric name is
+ * `QUERY./admin/ping.Requests`.
*
* @return the metric name defined by this object
*/