You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by an...@apache.org on 2015/05/14 08:23:48 UTC
svn commit: r1679317 - in /lucene/dev/branches/branch_5x: ./ solr/
solr/core/ solr/core/src/java/org/apache/solr/core/
solr/core/src/java/org/apache/solr/security/
solr/core/src/java/org/apache/solr/servlet/
solr/core/src/test/org/apache/solr/security/...
Author: anshum
Date: Thu May 14 06:23:47 2015
New Revision: 1679317
URL: http://svn.apache.org/r1679317
Log:
SOLR-7275: Authorization framework for Solr. It defines an interface and a mechanism to create, load and use an Authorization plugin.(merge from trunk)
Added:
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/security/
- copied from r1679316, lucene/dev/trunk/solr/core/src/java/org/apache/solr/security/
lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/security/
- copied from r1679316, lucene/dev/trunk/solr/core/src/test/org/apache/solr/security/
Modified:
lucene/dev/branches/branch_5x/ (props changed)
lucene/dev/branches/branch_5x/solr/ (props changed)
lucene/dev/branches/branch_5x/solr/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_5x/solr/core/ (props changed)
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
lucene/dev/branches/branch_5x/solr/solrj/ (props changed)
lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
Modified: lucene/dev/branches/branch_5x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/CHANGES.txt?rev=1679317&r1=1679316&r2=1679317&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_5x/solr/CHANGES.txt Thu May 14 06:23:47 2015
@@ -123,6 +123,8 @@ New Features
* SOLR-7522: Facet Module - Implement field/terms faceting over single-valued
numeric fields. (yonik)
+* SOLR-7275: Authorization framework for Solr. It defines an interface and a mechanism to create,
+ load, and use an Authorization plugin. (Noble Paul, Ishan Chattopadhyaya, Anshum Gupta)
Bug Fixes
----------------------
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java?rev=1679317&r1=1679316&r2=1679317&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java Thu May 14 06:23:47 2015
@@ -17,9 +17,8 @@
package org.apache.solr.core;
-import static com.google.common.base.Preconditions.*;
-
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -30,8 +29,9 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
import org.apache.solr.cloud.ZkController;
-import org.apache.solr.cloud.ZkSolrResourceLoader;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.util.ExecutorUtil;
@@ -43,6 +43,7 @@ import org.apache.solr.handler.admin.Inf
import org.apache.solr.handler.component.ShardHandlerFactory;
import org.apache.solr.logging.LogWatcher;
import org.apache.solr.request.SolrRequestHandler;
+import org.apache.solr.security.AuthorizationPlugin;
import org.apache.solr.update.UpdateShardHandler;
import org.apache.solr.util.DefaultSolrThreadFactory;
import org.apache.solr.util.FileUtils;
@@ -50,8 +51,7 @@ import org.apache.zookeeper.KeeperExcept
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
+import static com.google.common.base.Preconditions.checkNotNull;
/**
@@ -64,6 +64,8 @@ public class CoreContainer {
final SolrCores solrCores = new SolrCores(this);
+ protected AuthorizationPlugin authorizationPlugin;
+
public static class CoreLoadFailure {
public final CoreDescriptor cd;
@@ -176,6 +178,27 @@ public class CoreContainer {
this.containerProperties = new Properties(properties);
}
+ private void intializeAuthorizationPlugin() {
+ //Initialize the Authorization module
+ Map securityProps = getZkController().getZkStateReader().getSecurityProps();
+ if(securityProps != null) {
+ Map authorizationConf = (Map) securityProps.get("authorization");
+ if(authorizationConf == null) return;
+ String klas = (String) authorizationConf.get("class");
+ if(klas == null){
+ throw new SolrException(ErrorCode.SERVER_ERROR, "class is required for authorization plugin");
+ }
+ log.info("Initializing authorization plugin: " + klas);
+ authorizationPlugin = getResourceLoader().newInstance((String) klas,
+ AuthorizationPlugin.class);
+
+ // Read and pass the authorization context to the plugin
+ authorizationPlugin.init(authorizationConf);
+ } else {
+ log.info("Security conf doesn't exist. Skipping setup for authorization module.");
+ }
+ }
+
/**
* This method allows subclasses to construct a CoreContainer
* without any default init behavior.
@@ -246,6 +269,9 @@ public class CoreContainer {
log.info("Node Name: " + hostName);
zkSys.initZooKeeper(this, solrHome, cfg.getCloudConfig());
+ if (isZooKeeperAware()) {
+ intializeAuthorizationPlugin();
+ }
collectionsHandler = createHandler(cfg.getCollectionsHandlerClass(), CollectionsHandler.class);
containerHandlers.put(COLLECTIONS_HANDLER_PATH, collectionsHandler);
@@ -396,6 +422,16 @@ public class CoreContainer {
}
}
}
+
+ // It should be safe to close the authorization plugin at this point.
+ try {
+ if(authorizationPlugin != null) {
+ authorizationPlugin.close();
+ }
+ } catch (IOException e) {
+ log.warn("Exception while closing authorization plugin.", e);
+ }
+
org.apache.lucene.util.IOUtils.closeWhileHandlingException(loader); // best effort
}
@@ -448,7 +484,7 @@ public class CoreContainer {
solrCores.putDynamicDescriptor(name, cd);
}
- SolrCore old = null;
+ SolrCore old;
if (isShutDown) {
core.close();
@@ -640,7 +676,7 @@ public class CoreContainer {
coresLocator.swap(this, solrCores.getCoreDescriptor(n0), solrCores.getCoreDescriptor(n1));
- log.info("swapped: "+n0 + " with " + n1);
+ log.info("swapped: " + n0 + " with " + n1);
}
/**
@@ -689,8 +725,7 @@ public class CoreContainer {
// cancel recovery in cloud mode
core.getSolrCoreState().cancelRecovery();
}
- String configSetZkPath = core.getResourceLoader() instanceof ZkSolrResourceLoader ? ((ZkSolrResourceLoader)core.getResourceLoader()).getConfigSetZkPath() : null;
-
+
core.unloadOnClose(deleteIndexDir, deleteDataDir, deleteInstanceDir);
if (close)
core.close();
@@ -705,7 +740,6 @@ public class CoreContainer {
throw new SolrException(ErrorCode.SERVER_ERROR, "Error unregistering core [" + name + "] from cloud state", e);
}
}
-
}
public void rename(String name, String toName) {
@@ -885,6 +919,11 @@ public class CoreContainer {
public SolrResourceLoader getResourceLoader() {
return loader;
}
+
+ public AuthorizationPlugin getAuthorizationPlugin() {
+ return authorizationPlugin;
+ }
+
}
class CloserThread extends Thread {
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java?rev=1679317&r1=1679316&r2=1679317&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java Thu May 14 06:23:47 2015
@@ -17,33 +17,6 @@
package org.apache.solr.core;
-import org.apache.lucene.analysis.util.CharFilterFactory;
-import org.apache.lucene.analysis.util.ResourceLoader;
-import org.apache.lucene.analysis.util.ResourceLoaderAware;
-import org.apache.lucene.analysis.util.TokenFilterFactory;
-import org.apache.lucene.analysis.util.TokenizerFactory;
-import org.apache.lucene.analysis.util.WordlistLoader;
-import org.apache.lucene.codecs.Codec;
-import org.apache.lucene.codecs.DocValuesFormat;
-import org.apache.lucene.codecs.PostingsFormat;
-import org.apache.lucene.util.IOUtils;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.handler.admin.CoreAdminHandler;
-import org.apache.solr.handler.component.SearchComponent;
-import org.apache.solr.handler.component.ShardHandlerFactory;
-import org.apache.solr.request.SolrRequestHandler;
-import org.apache.solr.response.QueryResponseWriter;
-import org.apache.solr.rest.RestManager;
-import org.apache.solr.schema.FieldType;
-import org.apache.solr.schema.ManagedIndexSchemaFactory;
-import org.apache.solr.schema.SimilarityFactory;
-import org.apache.solr.search.QParserPlugin;
-import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
-import org.apache.solr.util.FileUtils;
-import org.apache.solr.util.plugin.SolrCoreAware;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@@ -56,7 +29,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.OutputStreamWriter;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URI;
@@ -76,6 +48,33 @@ import java.util.concurrent.ConcurrentHa
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.lucene.analysis.util.CharFilterFactory;
+import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.ResourceLoaderAware;
+import org.apache.lucene.analysis.util.TokenFilterFactory;
+import org.apache.lucene.analysis.util.TokenizerFactory;
+import org.apache.lucene.analysis.util.WordlistLoader;
+import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.DocValuesFormat;
+import org.apache.lucene.codecs.PostingsFormat;
+import org.apache.lucene.util.IOUtils;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.handler.component.SearchComponent;
+import org.apache.solr.handler.component.ShardHandlerFactory;
+import org.apache.solr.request.SolrRequestHandler;
+import org.apache.solr.response.QueryResponseWriter;
+import org.apache.solr.rest.RestManager;
+import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.ManagedIndexSchemaFactory;
+import org.apache.solr.schema.SimilarityFactory;
+import org.apache.solr.search.QParserPlugin;
+import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
+import org.apache.solr.util.FileUtils;
+import org.apache.solr.util.plugin.SolrCoreAware;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* @since solr 1.3
*/
@@ -88,7 +87,7 @@ public class SolrResourceLoader implemen
static final String[] packages = {
"", "analysis.", "schema.", "handler.", "search.", "update.", "core.", "response.", "request.",
"update.processor.", "util.", "spelling.", "handler.component.", "handler.dataimport.",
- "spelling.suggest.", "spelling.suggest.fst.", "rest.schema.analysis."
+ "spelling.suggest.", "spelling.suggest.fst.", "rest.schema.analysis.", "security."
};
protected URLClassLoader classLoader;
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java?rev=1679317&r1=1679316&r2=1679317&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java Thu May 14 06:23:47 2015
@@ -24,6 +24,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
+import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -42,6 +43,7 @@ import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
@@ -79,16 +81,26 @@ import org.apache.solr.request.SolrReque
import org.apache.solr.response.QueryResponseWriter;
import org.apache.solr.response.QueryResponseWriterUtil;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.security.AuthorizationContext;
+import org.apache.solr.security.AuthorizationContext.CollectionRequest;
+import org.apache.solr.security.AuthorizationContext.RequestType;
+import org.apache.solr.security.AuthorizationResponse;
import org.apache.solr.servlet.cache.HttpCacheHeaderUtil;
import org.apache.solr.servlet.cache.Method;
import org.apache.solr.update.processor.DistributingUpdateProcessorFactory;
import org.apache.solr.util.RTimer;
import org.apache.zookeeper.KeeperException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import static org.apache.solr.common.cloud.ZkStateReader.BASE_URL_PROP;
+import static org.apache.solr.common.cloud.ZkStateReader.COLLECTION_PROP;
import static org.apache.solr.common.cloud.ZkStateReader.CORE_NAME_PROP;
import static org.apache.solr.common.cloud.ZkStateReader.NODE_NAME_PROP;
+import static org.apache.solr.common.params.CollectionParams.CollectionAction.CREATE;
+import static org.apache.solr.common.params.CollectionParams.CollectionAction.DELETE;
+import static org.apache.solr.common.params.CollectionParams.CollectionAction.RELOAD;
import static org.apache.solr.servlet.SolrDispatchFilter.Action;
import static org.apache.solr.servlet.SolrDispatchFilter.Action.ADMIN;
import static org.apache.solr.servlet.SolrDispatchFilter.Action.FORWARD;
@@ -101,7 +113,9 @@ import static org.apache.solr.servlet.So
/**
* This class represents a call made to Solr
**/
-class HttpSolrCall {
+public class HttpSolrCall {
+ private static Logger log = LoggerFactory.getLogger(HttpSolrCall.class);
+
private final SolrDispatchFilter solrDispatchFilter;
private final CoreContainer cores;
private final HttpServletRequest req;
@@ -117,6 +131,19 @@ class HttpSolrCall {
private SolrConfig config;
private Map<String, Integer> invalidStates;
+ public RequestType getRequestType() {
+ return requestType;
+ }
+
+ private RequestType requestType;
+
+
+ public List<String> getCollectionsList() {
+ return collectionsList;
+ }
+
+ private List<String> collectionsList;
+
HttpSolrCall(SolrDispatchFilter solrDispatchFilter, CoreContainer cores,
HttpServletRequest request, HttpServletResponse response, boolean retry) {
this.solrDispatchFilter = solrDispatchFilter;
@@ -124,6 +151,7 @@ class HttpSolrCall {
this.req = request;
this.response = response;
this.retry = retry;
+ this.requestType = RequestType.UNKNOWN;
queryParams = SolrRequestParsers.parseQueryString(req.getQueryString());
}
@@ -131,7 +159,20 @@ class HttpSolrCall {
return path;
}
- private void setContext() throws Exception {
+
+ public HttpServletRequest getReq() {
+ return req;
+ }
+
+ public SolrCore getCore() {
+ return core;
+ }
+
+ public SolrParams getQueryParams() {
+ return queryParams;
+ }
+
+ private void init() throws Exception {
//The states of client that is invalid in this request
Aliases aliases = null;
String corename = "";
@@ -158,13 +199,13 @@ class HttpSolrCall {
}
boolean usingAliases = false;
- List<String> collectionsList = null;
// Check for container handlers
handler = cores.getRequestHandler(path);
if (handler != null) {
solrReq = SolrRequestParsers.DEFAULT.parse(null, path, req);
solrReq.getContext().put(CoreContainer.class.getName(), cores);
+ requestType = RequestType.ADMIN;
action = ADMIN;
return;
} else {
@@ -210,6 +251,9 @@ class HttpSolrCall {
// we found a core, update the path
path = path.substring(idx);
addMDCValues();
+ if (collectionsList == null)
+ collectionsList = new ArrayList<>();
+ collectionsList.add(corename);
}
// if we couldn't find it locally, look on other nodes
@@ -351,8 +395,28 @@ class HttpSolrCall {
}
try {
- setContext();
-
+ init();
+ /* Authorize the request if
+ 1. Authorization is enabled, and
+ 2. The requested resource is not a known static file
+ */
+ // TODO: There should be a better way to ignore the static files.
+ if (cores.getAuthorizationPlugin() != null &&
+ !(req.getRequestURI().endsWith(".html")
+ || req.getRequestURI().endsWith(".png")
+ || req.getRequestURI().endsWith(".ico")
+ || req.getRequestURI().endsWith(".css")
+ )) {
+ AuthorizationContext context = getAuthCtx();
+ log.info(context.toString());
+ AuthorizationResponse authResponse = cores.getAuthorizationPlugin().authorize(context);
+ if (!(authResponse.statusCode == HttpStatus.SC_ACCEPTED) && !(authResponse.statusCode == HttpStatus.SC_OK)) {
+ sendError(authResponse.statusCode,
+ "Unauthorized request, Response code: " + authResponse.statusCode);
+ return RETURN;
+ }
+ }
+
HttpServletResponse resp = response;
switch (action) {
case ADMIN:
@@ -593,7 +657,7 @@ class HttpSolrCall {
private void processAliases(Aliases aliases,
List<String> collectionsList) {
- String collection = solrReq.getParams().get("collection");
+ String collection = solrReq.getParams().get(COLLECTION_PROP);
if (collection != null) {
collectionsList = StrUtils.splitSmart(collection, ",", true);
}
@@ -621,7 +685,7 @@ class HttpSolrCall {
}
ModifiableSolrParams params = new ModifiableSolrParams(
solrReq.getParams());
- params.set("collection", collectionString.toString());
+ params.set(COLLECTION_PROP, collectionString.toString());
solrReq.setParams(params);
}
}
@@ -760,6 +824,10 @@ class HttpSolrCall {
return null;
}
+ if (collectionsList == null)
+ collectionsList = new ArrayList<>();
+
+ collectionsList.add(collectionName);
String coreUrl = getCoreUrl(collectionName, origCorename, clusterState,
slices, byCoreName, true);
@@ -807,6 +875,105 @@ class HttpSolrCall {
return null;
}
+ private AuthorizationContext getAuthCtx() {
+
+ String resource = getPath();
+
+ SolrParams params = getQueryParams();
+ final ArrayList<CollectionRequest> collectionRequests = new ArrayList<>();
+ if (getCollectionsList() != null) {
+ for (String collection : getCollectionsList()) {
+ collectionRequests.add(new CollectionRequest(collection));
+ }
+ }
+
+ // Extract collection name from the params in case of a Collection Admin request
+ if (getPath().equals("/admin/collections")) {
+ if (CREATE.isEqual(params.get("action"))||
+ RELOAD.isEqual(params.get("action"))||
+ DELETE.isEqual(params.get("action")))
+ collectionRequests.add(new CollectionRequest(params.get("name")));
+ else if (params.get(COLLECTION_PROP) != null)
+ collectionRequests.add(new CollectionRequest(params.get(COLLECTION_PROP)));
+ }
+
+ // Handle the case when it's a /select request and collections are specified as a param
+ if(resource.equals("/select") && params.get("collection") != null) {
+ collectionRequests.clear();
+ for(String collection:params.get("collection").split(",")) {
+ collectionRequests.add(new CollectionRequest(collection));
+ }
+ }
+
+ // Populate the request type if the request is select or update
+ if(requestType == RequestType.UNKNOWN) {
+ if(resource.startsWith("/select"))
+ requestType = RequestType.READ;
+ if(resource.startsWith("/update"))
+ requestType = RequestType.WRITE;
+ }
+
+ // There's no collection explicitly mentioned, let's try and extract it from the core if one exists for
+ // the purpose of processing this request.
+ if (getCore() != null && (getCollectionsList() == null || getCollectionsList().size() == 0)) {
+ collectionRequests.add(new CollectionRequest(getCore().getCoreDescriptor().getCollectionName()));
+ }
+
+ if (getQueryParams().get(COLLECTION_PROP) != null)
+ collectionRequests.add(new CollectionRequest(getQueryParams().get(COLLECTION_PROP)));
+
+ return new AuthorizationContext() {
+ @Override
+ public SolrParams getParams() {
+ return getQueryParams();
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return getReq().getUserPrincipal();
+ }
+
+ @Override
+ public String getHttpHeader(String s) {
+ return getReq().getHeader(s);
+ }
+
+ @Override
+ public Enumeration getHeaderNames() {
+ return getReq().getHeaderNames();
+ }
+
+ @Override
+ public List<CollectionRequest> getCollectionRequests() {
+ return collectionRequests;
+ }
+
+ @Override
+ public RequestType getRequestType() {
+ return requestType;
+ }
+
+ public String getResource() {
+ return path;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder response = new StringBuilder("userPrincipal: [").append(getUserPrincipal()).append("]")
+ .append(" type: [").append(requestType.toString()).append("], collections: [");
+ for (CollectionRequest collectionRequest : collectionRequests) {
+ response.append(collectionRequest.collectionName).append(", ");
+ }
+ if(collectionRequests.size() > 0)
+ response.delete(response.length() - 1, response.length());
+
+ response.append("], Path: [").append(resource).append("]");
+ return response.toString();
+ }
+ };
+
+ }
+
static final String CONNECTION_HEADER = "Connection";
static final String TRANSFER_ENCODING_HEADER = "Transfer-Encoding";
static final String CONTENT_LENGTH_HEADER = "Content-Length";
Modified: lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java?rev=1679317&r1=1679316&r2=1679317&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java (original)
+++ lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java Thu May 14 06:23:47 2015
@@ -84,6 +84,7 @@ public class ZkStateReader implements Cl
public static final String CLUSTER_STATE = "/clusterstate.json";
public static final String CLUSTER_PROPS = "/clusterprops.json";
public static final String REJOIN_AT_HEAD_PROP = "rejoinAtHead";
+ public static final String SOLR_SECURITY_CONF_PATH = "/security.json";
public static final String REPLICATION_FACTOR = "replicationFactor";
public static final String MAX_SHARDS_PER_NODE = "maxShardsPerNode";
@@ -830,6 +831,23 @@ public class ZkStateReader implements Cl
}
}
+
+
+ /**
+ * Returns the content of /security.json from ZooKeeper as a Map
+ * If the files doesn't exist, it returns null.
+ */
+ public Map getSecurityProps() {
+ try {
+ if(getZkClient().exists(SOLR_SECURITY_CONF_PATH, true)) {
+ return (Map) ZkStateReader.fromJSON(getZkClient()
+ .getData(ZkStateReader.SOLR_SECURITY_CONF_PATH, null, new Stat(), true)) ;
+ }
+ } catch (KeeperException | InterruptedException e) {
+ throw new SolrException(ErrorCode.SERVER_ERROR,"Error reading security properties",e) ;
+ }
+ return null;
+ }
/**
* Returns the baseURL corresponding to a given node's nodeName --
* NOTE: does not (currently) imply that the nodeName (or resulting