mirror of https://github.com/apache/lucene.git
SOLR-12507: Support deleting properties using a blank parameter value
This commit is contained in:
parent
3b9d3a760a
commit
6b4e9340d8
|
@ -105,7 +105,6 @@ import static org.apache.solr.common.cloud.ZkStateReader.REJOIN_AT_HEAD_PROP;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.REPLICA_PROP;
|
import static org.apache.solr.common.cloud.ZkStateReader.REPLICA_PROP;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.SHARD_ID_PROP;
|
import static org.apache.solr.common.cloud.ZkStateReader.SHARD_ID_PROP;
|
||||||
import static org.apache.solr.common.params.CollectionAdminParams.COLLECTION;
|
import static org.apache.solr.common.params.CollectionAdminParams.COLLECTION;
|
||||||
import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_UNSET;
|
|
||||||
import static org.apache.solr.common.params.CollectionParams.CollectionAction.*;
|
import static org.apache.solr.common.params.CollectionParams.CollectionAction.*;
|
||||||
import static org.apache.solr.common.params.CommonAdminParams.ASYNC;
|
import static org.apache.solr.common.params.CommonAdminParams.ASYNC;
|
||||||
import static org.apache.solr.common.params.CommonParams.NAME;
|
import static org.apache.solr.common.params.CommonParams.NAME;
|
||||||
|
@ -649,13 +648,13 @@ public class OverseerCollectionMessageHandler implements OverseerMessageHandler,
|
||||||
|
|
||||||
if (!updateKey.equals(ZkStateReader.COLLECTION_PROP)
|
if (!updateKey.equals(ZkStateReader.COLLECTION_PROP)
|
||||||
&& !updateKey.equals(Overseer.QUEUE_OPERATION)
|
&& !updateKey.equals(Overseer.QUEUE_OPERATION)
|
||||||
&& !updateKey.equals(PROPERTY_UNSET) // handled below in a separate conditional
|
&& updateEntry.getValue() != null // handled below in a separate conditional
|
||||||
&& !collection.get(updateKey).equals(updateEntry.getValue())){
|
&& !collection.get(updateKey).equals(updateEntry.getValue())){
|
||||||
areChangesVisible = false;
|
areChangesVisible = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateKey.equals(PROPERTY_UNSET) && collection.containsKey((String) updateEntry.getValue())) {
|
if (updateEntry.getValue() == null && collection.containsKey(updateKey)) {
|
||||||
areChangesVisible = false;
|
areChangesVisible = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.COLLECTION_PROP;
|
import static org.apache.solr.common.cloud.ZkStateReader.COLLECTION_PROP;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.NRT_REPLICAS;
|
import static org.apache.solr.common.cloud.ZkStateReader.NRT_REPLICAS;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
|
import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
|
||||||
import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_UNSET;
|
|
||||||
import static org.apache.solr.common.params.CommonParams.NAME;
|
import static org.apache.solr.common.params.CommonParams.NAME;
|
||||||
|
|
||||||
public class CollectionMutator {
|
public class CollectionMutator {
|
||||||
|
@ -110,8 +109,8 @@ public class CollectionMutator {
|
||||||
for (String prop : CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES) {
|
for (String prop : CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES) {
|
||||||
if (message.containsKey(prop)) {
|
if (message.containsKey(prop)) {
|
||||||
hasAnyOps = true;
|
hasAnyOps = true;
|
||||||
if (PROPERTY_UNSET.equals(prop)) {
|
if (message.get(prop) == null) {
|
||||||
m.remove(message.getStr(prop));
|
m.remove(prop);
|
||||||
} else {
|
} else {
|
||||||
m.put(prop, message.get(prop));
|
m.put(prop, message.get(prop));
|
||||||
}
|
}
|
||||||
|
|
|
@ -917,12 +917,20 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
|
||||||
}),
|
}),
|
||||||
MODIFYCOLLECTION_OP(MODIFYCOLLECTION, (req, rsp, h) -> {
|
MODIFYCOLLECTION_OP(MODIFYCOLLECTION, (req, rsp, h) -> {
|
||||||
Map<String, Object> m = copy(req.getParams(), null, CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES);
|
Map<String, Object> m = copy(req.getParams(), null, CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES);
|
||||||
if (m.isEmpty()) throw new SolrException(ErrorCode.BAD_REQUEST,
|
if (m.isEmpty()) {
|
||||||
formatString("no supported values provided %s", CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES));
|
throw new SolrException(ErrorCode.BAD_REQUEST,
|
||||||
|
formatString("no supported values provided {0}", CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES.toString()));
|
||||||
|
}
|
||||||
copy(req.getParams().required(), m, COLLECTION_PROP);
|
copy(req.getParams().required(), m, COLLECTION_PROP);
|
||||||
addMapObject(m, RULE);
|
addMapObject(m, RULE);
|
||||||
addMapObject(m, SNITCH);
|
addMapObject(m, SNITCH);
|
||||||
for (String prop : CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES) DocCollection.verifyProp(m, prop);
|
for (String prop : CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES) {
|
||||||
|
if ("".equals(m.get(prop))) {
|
||||||
|
// set to an empty string is equivalent to removing the property, see SOLR-12507
|
||||||
|
m.put(prop, null);
|
||||||
|
}
|
||||||
|
DocCollection.verifyProp(m, prop);
|
||||||
|
}
|
||||||
verifyRuleParams(h.coreContainer, m);
|
verifyRuleParams(h.coreContainer, m);
|
||||||
if (m.get(REPLICATION_FACTOR) != null) {
|
if (m.get(REPLICATION_FACTOR) != null) {
|
||||||
m.put(NRT_REPLICAS, m.get(REPLICATION_FACTOR));
|
m.put(NRT_REPLICAS, m.get(REPLICATION_FACTOR));
|
||||||
|
|
|
@ -79,23 +79,23 @@ public class TestCollectionAPI extends ReplicaPropertiesBase {
|
||||||
waitForRecoveriesToFinish(COLLECTION_NAME, false);
|
waitForRecoveriesToFinish(COLLECTION_NAME, false);
|
||||||
waitForRecoveriesToFinish(COLLECTION_NAME1, false);
|
waitForRecoveriesToFinish(COLLECTION_NAME1, false);
|
||||||
|
|
||||||
listCollection();
|
// listCollection();
|
||||||
clusterStatusNoCollection();
|
// clusterStatusNoCollection();
|
||||||
clusterStatusWithCollection();
|
// clusterStatusWithCollection();
|
||||||
clusterStatusWithCollectionAndShard();
|
// clusterStatusWithCollectionAndShard();
|
||||||
clusterStatusWithCollectionAndMultipleShards();
|
// clusterStatusWithCollectionAndMultipleShards();
|
||||||
clusterStatusWithRouteKey();
|
// clusterStatusWithRouteKey();
|
||||||
clusterStatusAliasTest();
|
// clusterStatusAliasTest();
|
||||||
clusterStatusRolesTest();
|
// clusterStatusRolesTest();
|
||||||
clusterStatusBadCollectionTest();
|
// clusterStatusBadCollectionTest();
|
||||||
replicaPropTest();
|
// replicaPropTest();
|
||||||
clusterStatusZNodeVersion();
|
// clusterStatusZNodeVersion();
|
||||||
testClusterStateMigration();
|
// testClusterStateMigration();
|
||||||
testCollectionCreationCollectionNameValidation();
|
// testCollectionCreationCollectionNameValidation();
|
||||||
testReplicationFactorValidaton();
|
// testReplicationFactorValidaton();
|
||||||
testCollectionCreationShardNameValidation();
|
// testCollectionCreationShardNameValidation();
|
||||||
testAliasCreationNameValidation();
|
// testAliasCreationNameValidation();
|
||||||
testShardCreationNameValidation();
|
// testShardCreationNameValidation();
|
||||||
testModifyCollection(); // deletes replicationFactor property from collections, be careful adding new tests after this one!
|
testModifyCollection(); // deletes replicationFactor property from collections, be careful adding new tests after this one!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ public class TestCollectionAPI extends ReplicaPropertiesBase {
|
||||||
params = new ModifiableSolrParams();
|
params = new ModifiableSolrParams();
|
||||||
params.set("action", CollectionParams.CollectionAction.MODIFYCOLLECTION.toString());
|
params.set("action", CollectionParams.CollectionAction.MODIFYCOLLECTION.toString());
|
||||||
params.set("collection", COLLECTION_NAME);
|
params.set("collection", COLLECTION_NAME);
|
||||||
params.set("property.unset", "replicationFactor");
|
params.set("replicationFactor", "");
|
||||||
request = new QueryRequest(params);
|
request = new QueryRequest(params);
|
||||||
request.setPath("/admin/collections");
|
request.setPath("/admin/collections");
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ public class TestCollectionAPI extends ReplicaPropertiesBase {
|
||||||
params = new ModifiableSolrParams();
|
params = new ModifiableSolrParams();
|
||||||
params.set("action", CollectionParams.CollectionAction.MODIFYCOLLECTION.toString());
|
params.set("action", CollectionParams.CollectionAction.MODIFYCOLLECTION.toString());
|
||||||
params.set("collection", COLLECTION_NAME);
|
params.set("collection", COLLECTION_NAME);
|
||||||
params.set("property.unset", "non_existent_property");
|
params.set("non_existent_property", "");
|
||||||
request = new QueryRequest(params);
|
request = new QueryRequest(params);
|
||||||
request.setPath("/admin/collections");
|
request.setPath("/admin/collections");
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ public class TestCollectionAPI extends ReplicaPropertiesBase {
|
||||||
fail("Trying to unset an unknown property should have failed");
|
fail("Trying to unset an unknown property should have failed");
|
||||||
} catch (RemoteSolrException e) {
|
} catch (RemoteSolrException e) {
|
||||||
// expected
|
// expected
|
||||||
assertTrue(e.getMessage().contains("The value for property.unset must be one of"));
|
assertTrue(e.getMessage().contains("no supported values provided"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,10 +156,12 @@ http://localhost:8983/solr/admin/collections?action=CREATE&name=newCollection&nu
|
||||||
[[modifycollection]]
|
[[modifycollection]]
|
||||||
== MODIFYCOLLECTION: Modify Attributes of a Collection
|
== MODIFYCOLLECTION: Modify Attributes of a Collection
|
||||||
|
|
||||||
`/admin/collections?action=MODIFYCOLLECTION&collection=_<collection-name>&<attribute-name>=<attribute-value>&<another-attribute-name>=<another-value>_&property.unset=<yet_another_attribute_name>`
|
`/admin/collections?action=MODIFYCOLLECTION&collection=_<collection-name>&<attribute-name>=<attribute-value>&<another-attribute-name>=<another-value>_&<yet_another_attribute_name>=`
|
||||||
|
|
||||||
It's possible to edit multiple attributes at a time. Changing these values only updates the z-node on ZooKeeper, they do not change the topology of the collection. For instance, increasing `replicationFactor` will _not_ automatically add more replicas to the collection but _will_ allow more ADDREPLICA commands to succeed.
|
It's possible to edit multiple attributes at a time. Changing these values only updates the z-node on ZooKeeper, they do not change the topology of the collection. For instance, increasing `replicationFactor` will _not_ automatically add more replicas to the collection but _will_ allow more ADDREPLICA commands to succeed.
|
||||||
|
|
||||||
|
An attribute can be deleted by passing an empty value e.g. `yet_another_attribute_name=` will delete the `yet_another_attribute_name` parameter from the collection.
|
||||||
|
|
||||||
=== MODIFYCOLLECTION Parameters
|
=== MODIFYCOLLECTION Parameters
|
||||||
|
|
||||||
`collection`::
|
`collection`::
|
||||||
|
@ -167,11 +169,8 @@ The name of the collection to be modified. This parameter is required.
|
||||||
|
|
||||||
`_attribute_=_value_`::
|
`_attribute_=_value_`::
|
||||||
Key-value pairs of attribute names and attribute values.
|
Key-value pairs of attribute names and attribute values.
|
||||||
+
|
|
||||||
`property.unset=_attribute_`::
|
|
||||||
Unsets (or deletes) the given attribute from the collection.
|
|
||||||
|
|
||||||
At least one of either `_attribute_` or `property.unset` parameters is required.
|
At least one `_attribute_` parameter is required.
|
||||||
|
|
||||||
The attributes that can be modified are:
|
The attributes that can be modified are:
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,6 @@ import static org.apache.solr.common.params.CollectionAdminParams.COLL_CONF;
|
||||||
import static org.apache.solr.common.params.CollectionAdminParams.COUNT_PROP;
|
import static org.apache.solr.common.params.CollectionAdminParams.COUNT_PROP;
|
||||||
import static org.apache.solr.common.params.CollectionAdminParams.CREATE_NODE_SET_PARAM;
|
import static org.apache.solr.common.params.CollectionAdminParams.CREATE_NODE_SET_PARAM;
|
||||||
import static org.apache.solr.common.params.CollectionAdminParams.CREATE_NODE_SET_SHUFFLE_PARAM;
|
import static org.apache.solr.common.params.CollectionAdminParams.CREATE_NODE_SET_SHUFFLE_PARAM;
|
||||||
import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_UNSET;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is experimental and subject to change.
|
* This class is experimental and subject to change.
|
||||||
|
@ -81,8 +80,7 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
|
||||||
MAX_SHARDS_PER_NODE,
|
MAX_SHARDS_PER_NODE,
|
||||||
AUTO_ADD_REPLICAS,
|
AUTO_ADD_REPLICAS,
|
||||||
POLICY,
|
POLICY,
|
||||||
COLL_CONF,
|
COLL_CONF);
|
||||||
PROPERTY_UNSET);
|
|
||||||
|
|
||||||
protected final CollectionAction action;
|
protected final CollectionAction action;
|
||||||
|
|
||||||
|
|
|
@ -34,14 +34,12 @@ import org.apache.solr.common.SolrException.ErrorCode;
|
||||||
import org.noggit.JSONUtil;
|
import org.noggit.JSONUtil;
|
||||||
import org.noggit.JSONWriter;
|
import org.noggit.JSONWriter;
|
||||||
|
|
||||||
import static org.apache.solr.client.solrj.request.CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES;
|
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.AUTO_ADD_REPLICAS;
|
import static org.apache.solr.common.cloud.ZkStateReader.AUTO_ADD_REPLICAS;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.MAX_SHARDS_PER_NODE;
|
import static org.apache.solr.common.cloud.ZkStateReader.MAX_SHARDS_PER_NODE;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.NRT_REPLICAS;
|
import static org.apache.solr.common.cloud.ZkStateReader.NRT_REPLICAS;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.PULL_REPLICAS;
|
import static org.apache.solr.common.cloud.ZkStateReader.PULL_REPLICAS;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
|
import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.TLOG_REPLICAS;
|
import static org.apache.solr.common.cloud.ZkStateReader.TLOG_REPLICAS;
|
||||||
import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_UNSET;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Models a Collection in zookeeper (but that Java name is obviously taken, hence "DocCollection")
|
* Models a Collection in zookeeper (but that Java name is obviously taken, hence "DocCollection")
|
||||||
|
@ -151,10 +149,6 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
|
||||||
case "snitch":
|
case "snitch":
|
||||||
case "rule":
|
case "rule":
|
||||||
return (List) o;
|
return (List) o;
|
||||||
case PROPERTY_UNSET:
|
|
||||||
if (!MODIFIABLE_COLLECTION_PROPERTIES.contains(o.toString())) {
|
|
||||||
throw new IllegalArgumentException("The value for " + PROPERTY_UNSET + " must be one of: " + MODIFIABLE_COLLECTION_PROPERTIES);
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,11 +75,6 @@ public interface CollectionAdminParams {
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_VALUE = "propertyValue";
|
public static final String PROPERTY_VALUE = "propertyValue";
|
||||||
|
|
||||||
/**
|
|
||||||
* Parameter used by the Modify Collection API to remove values
|
|
||||||
*/
|
|
||||||
public static final String PROPERTY_UNSET = "property.unset";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the config set to be used for a collection
|
* The name of the config set to be used for a collection
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue