SOLR-5610 New Collectio API called CLUSTERPROP

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1563876 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Noble Paul 2014-02-03 13:16:12 +00:00
parent dac599c111
commit 732f295c4f
6 changed files with 100 additions and 2 deletions

View File

@ -163,6 +163,8 @@ New Features
* SOLR-5535: Set "partialResults" header for shards that error out if
shards.tolerant is specified. (Steve Davids via shalin)
* SOLR-5610: Support cluster-wide properties with an API called CLUSTERPROP (Noble Paul)
Bug Fixes
----------------------

View File

@ -17,6 +17,7 @@ package org.apache.solr.cloud;
* limitations under the License.
*/
import com.google.common.collect.ImmutableSet;
import org.apache.solr.client.solrj.SolrResponse;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
@ -44,6 +45,7 @@ import org.apache.solr.common.cloud.ZkCoreNodeProps;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.cloud.ZooKeeperException;
import org.apache.solr.common.params.CollectionParams;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction;
import org.apache.solr.common.params.MapSolrParams;
@ -56,8 +58,10 @@ import org.apache.solr.handler.component.ShardRequest;
import org.apache.solr.handler.component.ShardResponse;
import org.apache.solr.update.SolrIndexSplitter;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -69,6 +73,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -121,6 +126,8 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread {
public static final String COLL_PROP_PREFIX = "property.";
public static final Set<String> KNOWN_CLUSTER_PROPS = ImmutableSet.of("legacyCloud");
public static final Map<String,Object> COLL_PROPS = ZkNodeProps.makeMap(
ROUTER, DocRouter.DEFAULT_NAME,
REPLICATION_FACTOR, "1",
@ -396,6 +403,8 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread {
deleteReplica(zkStateReader.getClusterState(), message, results);
} else if (MIGRATE.equals(operation)) {
migrate(zkStateReader.getClusterState(), message, results);
} else if(CollectionParams.CollectionAction.CLUSTERPROP.toString().equalsIgnoreCase(operation)){
handleProp(message,results);
} else if(REMOVEROLE.toString().toLowerCase(Locale.ROOT).equals(operation) || ADDROLE.toString().toLowerCase(Locale.ROOT).equals(operation) ){
processRoleCommand(message, operation);
}
@ -416,6 +425,21 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread {
}
return new OverseerSolrResponse(results);
}
private void handleProp(ZkNodeProps message, NamedList results) throws KeeperException, InterruptedException {
String name = message.getStr("name");
String val = message.getStr("val");
Map m = zkStateReader.getClusterProps();
if(val ==null) m.remove(name);
else m.put(name,val);
if(zkStateReader.getZkClient().exists(ZkStateReader.CLUSTER_PROPS,true))
zkStateReader.getZkClient().setData(ZkStateReader.CLUSTER_PROPS,ZkStateReader.toJSON(m),true);
else
zkStateReader.getZkClient().create(ZkStateReader.CLUSTER_PROPS, ZkStateReader.toJSON(m),CreateMode.PERSISTENT, true);
}
private void processRoleCommand(ZkNodeProps message, String operation) throws KeeperException, InterruptedException {
SolrZkClient zkClient = zkStateReader.getZkClient();

View File

@ -187,6 +187,10 @@ public class CollectionsHandler extends RequestHandlerBase {
handleRole(REMOVEROLE, req, rsp);
break;
}
case CLUSTERPROP: {
this.handleProp(req, rsp);
break;
}
default: {
throw new RuntimeException("Unknown action: " + action);
}
@ -195,6 +199,22 @@ public class CollectionsHandler extends RequestHandlerBase {
rsp.setHttpCaching(false);
}
private void handleProp(SolrQueryRequest req, SolrQueryResponse rsp) throws KeeperException, InterruptedException {
req.getParams().required().check("name");
String name = req.getParams().get("name");
if(!OverseerCollectionProcessor.KNOWN_CLUSTER_PROPS.contains(name)){
throw new SolrException(ErrorCode.BAD_REQUEST, "Not a known cluster property "+ name);
}
Map<String,Object> props = ZkNodeProps.makeMap(
Overseer.QUEUE_OPERATION, CollectionAction.CLUSTERPROP.toString().toLowerCase(Locale.ROOT) );
copyIfNotNull(req.getParams(),props,
"name",
"val");
handleResponse(CollectionAction.CLUSTERPROP.toString().toLowerCase(Locale.ROOT),new ZkNodeProps(props),rsp);
}
static Set<String> KNOWN_ROLES = ImmutableSet.of("overseer");
private void handleRole(CollectionAction action, SolrQueryRequest req, SolrQueryResponse rsp) throws KeeperException, InterruptedException {

View File

@ -18,10 +18,12 @@ package org.apache.solr.cloud;
*/
import static org.apache.solr.cloud.OverseerCollectionProcessor.REPLICATION_FACTOR;
import static org.apache.solr.common.cloud.ZkNodeProps.makeMap;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@ -29,6 +31,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@ -47,6 +50,7 @@ import org.apache.lucene.util.LuceneTestCase.Slow;
import org.apache.lucene.util._TestUtil;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
@ -72,7 +76,9 @@ import org.apache.solr.common.cloud.ZkCoreNodeProps;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CollectionParams.CollectionAction;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.StrUtils;
@ -198,6 +204,7 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa
testErrorHandling();
deletePartiallyCreatedCollection();
deleteCollectionRemovesStaleZkCollectionsNode();
clusterPropTest();
// last
deleteCollectionWithDownNodes();
@ -1186,4 +1193,19 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa
// insurance
DirectUpdateHandler2.commitOnClose = true;
}
private void clusterPropTest() throws Exception {
Map m = makeMap(
"action", CollectionAction.CLUSTERPROP.toString().toLowerCase(Locale.ROOT),
"name", "legacyCloud",
"val", "true");
SolrParams params = new MapSolrParams(m);
SolrRequest request = new QueryRequest(params);
request.setPath("/admin/collections");
CloudSolrServer client = createCloudClient(null);
client.request(request);
assertEquals("cluster property not set", "true", client.getZkStateReader().getClusterProps().get("legacyCloud"));
client.shutdown();
}
}

View File

@ -21,6 +21,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@ -68,6 +69,9 @@ public class ZkStateReader {
public static final String LIVE_NODES_ZKNODE = "/live_nodes";
public static final String ALIASES = "/aliases.json";
public static final String CLUSTER_STATE = "/clusterstate.json";
public static final String CLUSTER_PROPS = "/clusterprops.json";
public static final String ROLES = "/roles.json";
public static final String RECOVERING = "recovering";
@ -595,5 +599,18 @@ public class ZkStateReader {
ZkStateReader.this.aliases = aliases;
}
public Map getClusterProps(){
Map result = null;
try {
if(getZkClient().exists(ZkStateReader.CLUSTER_PROPS,true)){
result = (Map) ZkStateReader.fromJSON(getZkClient().getData(ZkStateReader.CLUSTER_PROPS, null, new Stat(), true)) ;
} else {
result= new LinkedHashMap();
}
return result;
} catch (Exception e) {
throw new SolrException(ErrorCode.SERVER_ERROR,"Error reading cluster properties",e) ;
}
}
}

View File

@ -28,7 +28,20 @@ public interface CollectionParams
public enum CollectionAction {
CREATE, DELETE, RELOAD, SYNCSHARD, CREATEALIAS, DELETEALIAS, SPLITSHARD, DELETESHARD, CREATESHARD, DELETEREPLICA, MIGRATE, ADDROLE,REMOVEROLE ;
CREATE,
DELETE,
RELOAD,
SYNCSHARD,
CREATEALIAS,
DELETEALIAS,
SPLITSHARD,
DELETESHARD,
CREATESHARD,
DELETEREPLICA,
MIGRATE,
ADDROLE,
REMOVEROLE,
CLUSTERPROP;
public static CollectionAction get( String p )
{