From 8c714348aeea51df19e7603905f85995bcf0371c Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Mon, 25 Jun 2018 19:09:57 +0530 Subject: [PATCH] SOLR-12506: Add SolrJ support for the modify collection API --- solr/CHANGES.txt | 2 + .../solr/cloud/CollectionsAPISolrJTest.java | 48 ++++++++++ .../solrj/request/CollectionAdminRequest.java | 87 +++++++++++++++++++ .../common/params/CollectionAdminParams.java | 18 ++-- 4 files changed, 146 insertions(+), 9 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 2d4e364c480..8a08dda9b9a 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -86,6 +86,8 @@ New Features * SOLR-12507: Modify collection API should support un-setting properties. (shalin) +* SOLR-12506: Add SolrJ support for the modify collection API. (shalin) + Bug Fixes ---------------------- diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java index d9e153ed055..0a1b1edaef7 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTest.java @@ -493,4 +493,52 @@ public class CollectionsAPISolrJTest extends SolrCloudTestCase { }); } + + @Test + public void testModifyCollectionAttribute() throws IOException, SolrServerException { + final String collection = "testAddAndDeleteCollectionAttribute"; + CollectionAdminRequest.createCollection(collection, "conf", 1, 1) + .process(cluster.getSolrClient()); + + CollectionAdminRequest.modifyCollection(collection, null) + .setAttribute("replicationFactor", 25) + .process(cluster.getSolrClient()); + + waitForState("Expecting attribute 'replicationFactor' to be 25", collection, + (n, c) -> 25 == c.getReplicationFactor()); + + CollectionAdminRequest.modifyCollection(collection, null) + .unsetAttribute("maxShardsPerNode") + .process(cluster.getSolrClient()); + + waitForState("Expecting attribute 'maxShardsPerNode' to be deleted", collection, + (n, c) -> null == c.get("maxShardsPerNode")); + + try { + CollectionAdminRequest.modifyCollection(collection, null) + .setAttribute("non_existent_attr", 25) + .process(cluster.getSolrClient()); + fail("An attempt to set unknown collection attribute should have failed"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + CollectionAdminRequest.modifyCollection(collection, null) + .setAttribute("non_existent_attr", null) + .process(cluster.getSolrClient()); + fail("An attempt to set null value should have failed"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + CollectionAdminRequest.modifyCollection(collection, null) + .unsetAttribute("non_existent_attr") + .process(cluster.getSolrClient()); + fail("An attempt to unset unknown collection attribute should have failed"); + } catch (IllegalArgumentException e) { + // expected + } + } } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java index e8f9022751c..1f5fdd22062 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java @@ -393,6 +393,15 @@ public abstract class CollectionAdminRequest return new Create(collection, config, ImplicitDocRouter.NAME, null, checkNotNull("shards",shards), numNrtReplicas, numTlogReplicas, numPullReplicas); } + /** + * Returns a SolrRequest for modifying a collection with the given properties + * @param collection the collection name + * @param properties a map of key and values with which the collection is to be modified + */ + public static Modify modifyCollection(String collection, Map properties) { + return new Modify(collection, properties); + } + // CREATE request public static class Create extends AsyncCollectionSpecificAdminRequest { @@ -2322,4 +2331,82 @@ public abstract class CollectionAdminRequest } + /** + * A Modify Collection request + */ + public static class Modify extends AsyncCollectionSpecificAdminRequest { + protected Map attributes; + + private Modify(String collection, Map attributes) { + super(CollectionAction.MODIFYCOLLECTION, collection); + this.attributes = attributes; + } + + /** + * Sets the attributes to be modified using the Modify Collection API. + * Note: this method will overwrite any previously set attributes + * + * @param attributes a map of attribute key vs value + */ + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + /** + * Sets the collection attribute to the given value + * + * @param key a string attribute key, must be one of the entries documented + * in the Modify Collection API documentation + * @param value the attribute value for the given key + */ + public Modify setAttribute(String key, Object value) { + if (key == null) { + throw new IllegalArgumentException("Attribute key cannot be null for the modify collection API"); + } + if (!MODIFIABLE_COLLECTION_PROPERTIES.contains(key)) { + throw new IllegalArgumentException("Unknown attribute key: " + + key + ". Must be one of: " + MODIFIABLE_COLLECTION_PROPERTIES); + } + if (value == null) { + throw new IllegalArgumentException("Value cannot be null for key: " + key); + } + if (attributes == null) { + attributes = new HashMap<>(); + } + attributes.put(key, value); + return this; + } + + /** + * Removes the given key from the collection + * + * @param key the string attribute key, must be one of the entries documented + * in the Modify Collection API documentation + */ + public Modify unsetAttribute(String key) { + if (key == null) { + throw new IllegalArgumentException("Attribute key cannot be null for the modify collection API"); + } + if (!MODIFIABLE_COLLECTION_PROPERTIES.contains(key)) { + throw new IllegalArgumentException("Unknown attribute key: " + + key + ". Must be one of: " + MODIFIABLE_COLLECTION_PROPERTIES); + } + if (attributes == null) { + attributes = new HashMap<>(); + } + attributes.put(key, ""); + return this; + } + + @Override + public SolrParams getParams() { + ModifiableSolrParams params = new ModifiableSolrParams(super.getParams()); + params.set(CoreAdminParams.COLLECTION, collection); + for (Map.Entry entry : attributes.entrySet()) { + params.set(entry.getKey(), String.valueOf(entry.getValue())); + } + return params; + } + } + } diff --git a/solr/solrj/src/java/org/apache/solr/common/params/CollectionAdminParams.java b/solr/solrj/src/java/org/apache/solr/common/params/CollectionAdminParams.java index 100b0a31c66..6153eb13617 100644 --- a/solr/solrj/src/java/org/apache/solr/common/params/CollectionAdminParams.java +++ b/solr/solrj/src/java/org/apache/solr/common/params/CollectionAdminParams.java @@ -36,47 +36,47 @@ public interface CollectionAdminParams { /** * A parameter to specify list of Solr nodes to be used (e.g. for collection creation or restore operation). */ - public static final String CREATE_NODE_SET_PARAM = "createNodeSet"; + String CREATE_NODE_SET_PARAM = "createNodeSet"; /** * A parameter which specifies if the provided list of Solr nodes (via {@linkplain #CREATE_NODE_SET_PARAM}) * should be shuffled before being used. */ - public static final String CREATE_NODE_SET_SHUFFLE_PARAM = "createNodeSet.shuffle"; + String CREATE_NODE_SET_SHUFFLE_PARAM = "createNodeSet.shuffle"; /** * A parameter to specify the name of the index backup strategy to be used. */ - public static final String INDEX_BACKUP_STRATEGY = "indexBackup"; + String INDEX_BACKUP_STRATEGY = "indexBackup"; /** * This constant defines the index backup strategy based on copying index files to desired location. */ - public static final String COPY_FILES_STRATEGY = "copy-files"; + String COPY_FILES_STRATEGY = "copy-files"; /** * This constant defines the strategy to not copy index files (useful for meta-data only backup). */ - public static final String NO_INDEX_BACKUP_STRATEGY = "none"; + String NO_INDEX_BACKUP_STRATEGY = "none"; /** * This constant defines a list of valid index backup strategies. */ - public static final Collection INDEX_BACKUP_STRATEGIES = + Collection INDEX_BACKUP_STRATEGIES = Arrays.asList(COPY_FILES_STRATEGY, NO_INDEX_BACKUP_STRATEGY); /** * Name of collection property to set */ - public static final String PROPERTY_NAME = "propertyName"; + String PROPERTY_NAME = "propertyName"; /** * Value of collection property to set */ - public static final String PROPERTY_VALUE = "propertyValue"; + String PROPERTY_VALUE = "propertyValue"; /** * The name of the config set to be used for a collection */ - public static final String COLL_CONF = "collection.configName"; + String COLL_CONF = "collection.configName"; }