From 15ae014c598c0c02926ca3d7039f6389488e981e Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Tue, 11 Aug 2020 15:05:14 +1000 Subject: [PATCH] SOLR-14680: Provide simple interfaces to our cloud classes (only API) (#1694) --- .../org/apache/solr/cluster/api/ApiType.java | 31 +++++++ .../solr/cluster/api/CollectionConfig.java | 27 +++++++ .../apache/solr/cluster/api/HashRange.java | 42 ++++++++++ .../org/apache/solr/cluster/api/Resource.java | 41 ++++++++++ .../org/apache/solr/cluster/api/Router.java | 25 ++++++ .../org/apache/solr/cluster/api/Shard.java | 39 +++++++++ .../apache/solr/cluster/api/ShardReplica.java | 57 +++++++++++++ .../apache/solr/cluster/api/SimpleMap.java | 80 +++++++++++++++++++ .../apache/solr/cluster/api/SolrCluster.java | 48 +++++++++++ .../solr/cluster/api/SolrCollection.java | 34 ++++++++ .../org/apache/solr/cluster/api/SolrNode.java | 36 +++++++++ 11 files changed, 460 insertions(+) create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/ApiType.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/CollectionConfig.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/HashRange.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/Resource.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/Router.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/Shard.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/ShardReplica.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/SimpleMap.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/SolrCluster.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/SolrCollection.java create mode 100644 solr/solrj/src/java/org/apache/solr/cluster/api/SolrNode.java diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/ApiType.java b/solr/solrj/src/java/org/apache/solr/cluster/api/ApiType.java new file mode 100644 index 000000000000..b469b5f8c01e --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/ApiType.java @@ -0,0 +1,31 @@ +/* + * 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.cluster.api; + +/** + * Types of API calls + */ +public enum ApiType { + V1("solr"), + V2("api"); + final String prefix; + + ApiType(String prefix) { + this.prefix = prefix; + } +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/CollectionConfig.java b/solr/solrj/src/java/org/apache/solr/cluster/api/CollectionConfig.java new file mode 100644 index 000000000000..4f6b82c8cc37 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/CollectionConfig.java @@ -0,0 +1,27 @@ +/* + * 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.cluster.api; + + +public interface CollectionConfig { + + String name(); + + SimpleMap resources(); + +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/HashRange.java b/solr/solrj/src/java/org/apache/solr/cluster/api/HashRange.java new file mode 100644 index 000000000000..e02bf9bbe651 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/HashRange.java @@ -0,0 +1,42 @@ +/* + * 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.cluster.api; + +/** + * A range of hash that is stored in a shard + */ +public interface HashRange { + + /** minimum value (inclusive) */ + int min(); + + /** maximum value (inclusive) */ + int max(); + + /** Check if a given hash falls in this range */ + default boolean includes(int hash) { + return hash >= min() && hash <= max(); + } + + /** Check if another range is a subset of this range */ + default boolean isSubset(HashRange subset) { + return min() <= subset.min() && max() >= subset.max(); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/Resource.java b/solr/solrj/src/java/org/apache/solr/cluster/api/Resource.java new file mode 100644 index 000000000000..470590e83e2e --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/Resource.java @@ -0,0 +1,41 @@ +/* + * 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.cluster.api; + +import org.apache.solr.common.SolrException; + +import java.io.IOException; +import java.io.InputStream; + +/**A binary resource. The impl is agnostic of the content type */ +public interface Resource { + /** + * This is a full path. e.g schema.xml , solrconfig.xml , lang/stopwords.txt etc + */ + String name(); + /** read a file/resource. + * The caller should consume the stream completely and should not hold a reference to this stream. + * This method closes the stream soon after the method returns + * @param resourceConsumer This should be a full path. e.g schema.xml , solrconfig.xml , lang/stopwords.txt etc + */ + void get(Consumer resourceConsumer) throws SolrException; + + interface Consumer { + void read(InputStream is) throws IOException; + } +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/Router.java b/solr/solrj/src/java/org/apache/solr/cluster/api/Router.java new file mode 100644 index 000000000000..e2a147e84024 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/Router.java @@ -0,0 +1,25 @@ +/* + * 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.cluster.api; + +/**identify shards for a given routing key or document id */ +public interface Router { + + /**shard name for a given routing key */ + String shard(String routingKey); +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/Shard.java b/solr/solrj/src/java/org/apache/solr/cluster/api/Shard.java new file mode 100644 index 000000000000..d618fcd20dfc --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/Shard.java @@ -0,0 +1,39 @@ +/* + * 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.cluster.api; + +/**A shard of a collection */ +public interface Shard { + + /**name of the shard */ + String name(); + + /**collection this shard belongs to */ + String collection(); + + /**hash range of this shard. null if this is not using hash based router */ + HashRange range(); + + /** replicas of the shard */ + SimpleMap replicas(); + + /** + * Name of the replica that is acting as the leader at the moment + */ + String leader(); +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/ShardReplica.java b/solr/solrj/src/java/org/apache/solr/cluster/api/ShardReplica.java new file mode 100644 index 000000000000..1a9d83429d4d --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/ShardReplica.java @@ -0,0 +1,57 @@ +/* + * 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.cluster.api; + +import org.apache.solr.common.cloud.Replica; + +/** replica of a shard */ +public interface ShardReplica { + /** Name of this replica */ + String name(); + + /** The shard which it belongs to */ + String shard(); + + /** collection which it belongs to */ + String collection(); + + /** Name of the node where this replica is present */ + String node(); + + /** Name of the core where this is hosted */ + String core(); + + /** type of the replica */ + Replica.Type type(); + + /** Is the replica alive now */ + boolean alive(); + + /**Size of the index in bytes. Keep in mind that this may result in a network call. + * Also keep in mind that the value that you get is at best an approximation. + * The exact size may vary from replica to replica + */ + long indexSize(); + + /**Is this replica the leader */ + boolean isLeader(); + + /**Baseurl for this replica + */ + String url(ApiType type); +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/SimpleMap.java b/solr/solrj/src/java/org/apache/solr/cluster/api/SimpleMap.java new file mode 100644 index 000000000000..473da05d8124 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/SimpleMap.java @@ -0,0 +1,80 @@ +/* + * 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.cluster.api; + +import org.apache.solr.common.MapWriter; + +import java.io.IOException; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * A simplified read-only key-value structure. It is designed to support large datasets without consuming lot of memory + * The objective is to provide implementations that are cheap and memory efficient to implement and consume. + * The keys are always {@link CharSequence} objects, The values can be of any type + */ +public interface SimpleMap extends MapWriter { + + /**get a value by key. If not present , null is returned */ + T get(String key); + + /**Navigate through all keys and values */ + void forEachEntry(BiConsumer fun); + + /** iterate through all keys + * The default impl is suboptimal. Proper implementations must do it more efficiently + * */ + default void forEachKey(Consumer fun) { + forEachEntry((k, t) -> fun.accept(k)); + } + + int size(); + /** + * iterate through all keys but abort in between if required + * The default impl is suboptimal. Proper implementations must do it more efficiently + * @param fun Consume each key and return a boolean to signal whether to proceed or not. If true , continue. If false stop + * */ + default void abortableForEachKey(Function fun) { + abortableForEach((key, t) -> fun.apply(key)); + } + + + /** + * Navigate through all key-values but abort in between if required. + * The default impl is suboptimal. Proper implementations must do it more efficiently + * @param fun Consume each entry and return a boolean to signal whether to proceed or not. If true, continue, if false stop + */ + default void abortableForEach(BiFunction fun) { + forEachEntry(new BiConsumer<>() { + boolean end = false; + @Override + public void accept(String k, T v) { + if (end) return; + end = fun.apply(k, v); + } + }); + } + + + @Override + default void writeMap(EntryWriter ew) throws IOException { + forEachEntry(ew::putNoEx); + } +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/SolrCluster.java b/solr/solrj/src/java/org/apache/solr/cluster/api/SolrCluster.java new file mode 100644 index 000000000000..794309a3214c --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/SolrCluster.java @@ -0,0 +1,48 @@ +/* + * 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.cluster.api; + +import org.apache.solr.common.SolrException; + +/** Represents a Solr cluster */ + +public interface SolrCluster { + + /** collections in the cluster */ + SimpleMap collections() throws SolrException; + + /** collections in the cluster and aliases */ + SimpleMap collections(boolean includeAlias) throws SolrException; + + /** nodes in the cluster */ + SimpleMap nodes() throws SolrException; + + + /** Config sets in the cluster*/ + SimpleMap configs() throws SolrException; + + /** Name of the node in which the overseer is running */ + String overseerNode() throws SolrException; + + /** + * The name of the node in which this method is invoked from. returns null, if this is not invoked from a + * Solr node + */ + String thisNode(); + +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/SolrCollection.java b/solr/solrj/src/java/org/apache/solr/cluster/api/SolrCollection.java new file mode 100644 index 000000000000..04eeee7c0500 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/SolrCollection.java @@ -0,0 +1,34 @@ +/* + * 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.cluster.api; + +/** Represents a collection in Solr */ +public interface SolrCollection { + + String name(); + + /** shards of a collection */ + SimpleMap shards(); + + /** Name of the configset used by this collection */ + String config(); + + /**Router used in this collection */ + Router router(); + +} diff --git a/solr/solrj/src/java/org/apache/solr/cluster/api/SolrNode.java b/solr/solrj/src/java/org/apache/solr/cluster/api/SolrNode.java new file mode 100644 index 000000000000..872e3c2181b0 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/cluster/api/SolrNode.java @@ -0,0 +1,36 @@ +/* + * 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.cluster.api; + +/** A read only view of a Solr node */ +public interface SolrNode { + + /** The node name */ + String name(); + + /**Base http url for this node + * + */ + String baseUrl(ApiType type); + + /** + * Get all the cores in a given node. + * This usually involves a network call. So, it's likely to be expensive + */ + SimpleMap cores(); +}