Repository: sentry
Updated Branches:
  refs/heads/master 372ffc9b4 -> 755e94250


SENTRY-2042: Support file based Sentry provider for Solr plugin. (Hrishikesh 
Gadre, reviewed by Kalyan Kumar Kalvagadda)


Project: http://git-wip-us.apache.org/repos/asf/sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/755e9425
Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/755e9425
Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/755e9425

Branch: refs/heads/master
Commit: 755e94250e430e290a0642bcb5a575d29f190b4c
Parents: 372ffc9
Author: Kalyan Kumar Kalvagadda <[email protected]>
Authored: Mon Nov 20 16:10:23 2017 -0600
Committer: Kalyan Kumar Kalvagadda <[email protected]>
Committed: Mon Nov 20 16:10:23 2017 -0600

----------------------------------------------------------------------
 sentry-binding/sentry-binding-solr/pom.xml      |   1 -
 .../solr/authz/SentrySolrPluginImpl.java        |  54 +++-
 sentry-tests/sentry-tests-solr/pom.xml          |   4 +-
 .../e2e/solr/AbstractSolrSentryTestCase.java    | 265 +++++--------------
 .../e2e/solr/SolrSentryServiceTestBase.java     | 211 +++++++++++++++
 .../tests/e2e/solr/TestDocLevelOperations.java  |   2 +-
 .../tests/e2e/solr/TestSolrAdminOperations.java |  19 +-
 .../e2e/solr/TestSolrCollectionOperations.java  |  57 +---
 .../e2e/solr/TestSolrConfigOperations.java      |   2 +-
 .../e2e/solr/TestSolrSchemaOperations.java      |   2 +-
 .../TestSolrWithSimpleFileProviderBackend.java  | 127 +++++++++
 .../solr/sentry/test-authz-provider.ini         | 104 +-------
 12 files changed, 466 insertions(+), 382 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-binding/sentry-binding-solr/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/pom.xml 
b/sentry-binding/sentry-binding-solr/pom.xml
index 2452e2f..c64769b 100644
--- a/sentry-binding/sentry-binding-solr/pom.xml
+++ b/sentry-binding/sentry-binding-solr/pom.xml
@@ -76,7 +76,6 @@ limitations under the License.
     <dependency>
       <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-provider-file</artifactId>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SentrySolrPluginImpl.java
----------------------------------------------------------------------
diff --git 
a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SentrySolrPluginImpl.java
 
b/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SentrySolrPluginImpl.java
index c0ead28..91d08f0 100644
--- 
a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SentrySolrPluginImpl.java
+++ 
b/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SentrySolrPluginImpl.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sentry.binding.solr.authz;
 
+import static 
org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION;
 import static org.apache.sentry.binding.solr.authz.SolrAuthzBinding.QUERY;
 import static org.apache.sentry.binding.solr.authz.SolrAuthzBinding.UPDATE;
 
@@ -43,6 +44,7 @@ import org.apache.sentry.core.model.solr.Collection;
 import org.apache.sentry.core.model.solr.SolrConstants;
 import org.apache.sentry.core.model.solr.SolrModelAction;
 import org.apache.sentry.core.model.solr.SolrModelAuthorizable;
+import org.apache.sentry.provider.file.SimpleFileProviderBackend;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.params.CoreAdminParams;
@@ -110,6 +112,20 @@ public class SentrySolrPluginImpl implements 
AuthorizationPlugin {
    */
   public static final String SENTRY_HADOOP_CONF_DIR_PROPERTY = 
"authorization.sentry.hadoop.conf";
 
+  /**
+   * A configuration property to specify the kerberos principal to be used for 
communicating with
+   * HDFS. This is required only in case of {@linkplain 
SimpleFileProviderBackend} when the policy
+   * file is stored on HDFS.
+   */
+  public static final String SENTRY_HDFS_KERBEROS_PRINCIPAL = 
"authorization.hdfs.kerberos.principal";
+
+  /**
+   * A configuration property to specify the kerberos keytab file to be used 
for communicating with
+   * HDFS. This is required only in case of {@linkplain 
SimpleFileProviderBackend} when the policy
+   * file is stored on HDFS.
+   */
+  public static final String SENTRY_HDFS_KERBEROS_KEYTAB = 
"authorization.hdfs.kerberos.keytabfile";
+
   private String solrSuperUser;
   private SolrAuthzBinding binding;
   private Optional<AuditLogger> auditLog = Optional.empty();
@@ -267,7 +283,16 @@ public class SentrySolrPluginImpl implements 
AuthorizationPlugin {
       List<URL> configFiles = getHadoopConfigFiles(sentryHadoopConfLoc);
       configFiles.add((new File(sentrySiteLoc)).toURI().toURL());
 
-      binding = new SolrAuthzBinding(new SolrAuthzConf(configFiles));
+      SolrAuthzConf conf = new SolrAuthzConf(configFiles);
+      if (shouldInitializeKereberos(conf)) {
+        String princ = 
Preconditions.checkNotNull(config.get(SENTRY_HDFS_KERBEROS_PRINCIPAL),
+            "The authorization plugin is missing the " + 
SENTRY_HDFS_KERBEROS_PRINCIPAL + " property.");
+        String keytab = 
Preconditions.checkNotNull(config.get(SENTRY_HDFS_KERBEROS_KEYTAB),
+            "The authorization plugin is missing the " + 
SENTRY_HDFS_KERBEROS_KEYTAB + " property.");
+        initKerberos(conf, keytab, princ);
+      }
+
+      binding = new SolrAuthzBinding(conf);
       LOG.info("SolrAuthzBinding created successfully");
     } catch (Exception e) {
       throw new SolrException(ErrorCode.SERVER_ERROR, "Unable to create 
SolrAuthzBinding", e);
@@ -405,4 +430,31 @@ public class SentrySolrPluginImpl implements 
AuthorizationPlugin {
 
     return result;
   }
+
+  /**
+   * Initialize kerberos via UserGroupInformation.  Will only attempt to login
+   * during the first request, subsequent calls will have no effect.
+   */
+  private void initKerberos(SolrAuthzConf authzConf, String keytabFile, String 
principal) {
+    synchronized (SentrySolrPluginImpl.class) {
+      UserGroupInformation.setConfiguration(authzConf);
+      LOG.info(
+          "Attempting to acquire kerberos ticket with keytab: {}, principal: 
{} ",
+          keytabFile, principal);
+      try {
+        UserGroupInformation.loginUserFromKeytab(principal, keytabFile);
+      } catch (IOException ioe) {
+        throw new SolrException(ErrorCode.SERVER_ERROR, ioe);
+      }
+      LOG.info("Got Kerberos ticket");
+    }
+  }
+
+  private boolean shouldInitializeKereberos(SolrAuthzConf conf) {
+    String providerBackend = 
conf.get(SolrAuthzConf.AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar());
+    String authVal = conf.get(HADOOP_SECURITY_AUTHENTICATION);
+    return SimpleFileProviderBackend.class.getName().equals(providerBackend)
+           && "kerberos".equalsIgnoreCase(authVal);
+  }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-solr/pom.xml 
b/sentry-tests/sentry-tests-solr/pom.xml
index 9d400b2..c171b6f 100644
--- a/sentry-tests/sentry-tests-solr/pom.xml
+++ b/sentry-tests/sentry-tests-solr/pom.xml
@@ -274,7 +274,9 @@ limitations under the License.
           <systemPropertyVariables>
             
<test.solr.allowed.securerandom>NativePRNG</test.solr.allowed.securerandom>
             <!-- Solr test framework randomizes the locale configuration which 
sometimes
-                 result in test failures due to derby initialization errors -->
+                 result in test failures due to derby initialization errors 
(Ref: LUCENE-8009).
+                 To reduce the flakiness of the unit tests, setting the locale 
explicitly.
+             -->
             <tests.locale>en-US</tests.locale>
           </systemPropertyVariables>
         </configuration>

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestCase.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestCase.java
 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestCase.java
index e6e7a70..3d4d555 100644
--- 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestCase.java
+++ 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestCase.java
@@ -19,18 +19,11 @@ package org.apache.sentry.tests.e2e.solr;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.Thread.UncaughtExceptionHandler;
 import java.net.MalformedURLException;
 import java.net.URI;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-import java.util.Locale;
 
 import javax.servlet.http.HttpServletResponse;
 
@@ -43,19 +36,11 @@ import org.apache.http.client.methods.HttpRequestBase;
 import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.util.EntityUtils;
 import org.apache.commons.io.IOUtils;
-import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 
 import org.apache.sentry.binding.solr.authz.SentrySolrPluginImpl;
-import org.apache.sentry.core.common.exception.SentryUserException;
-import org.apache.sentry.core.model.solr.SolrConstants;
-import org.apache.sentry.core.model.solr.SolrModelAuthorizable;
-import 
org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
-import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
-import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
-import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
@@ -66,208 +51,23 @@ import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.SolrInputField;
 import org.apache.solr.common.util.Utils;
 import org.apache.solr.SolrTestCaseJ4;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
 import org.restlet.representation.Representation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope;
 
 @ThreadLeakScope(ThreadLeakScope.Scope.NONE)
 @SolrTestCaseJ4.SuppressSSL
 public abstract class AbstractSolrSentryTestCase extends SolrCloudTestCase {
-  private static final Logger log = 
LoggerFactory.getLogger(AbstractSolrSentryTestCase.class);
   protected static final int NUM_SERVERS = 3;
   protected static final String COMPONENT_SOLR = "solr";
   protected static final String SERVICE_NAME = "service1";
   protected static final String ADMIN_ROLE  = "admin_role";
-  private static final String SENTRY_SITE_LOC_SYSPROP = 
"solr."+SentrySolrPluginImpl.SNTRY_SITE_LOCATION_PROPERTY;
+  protected static final String SENTRY_SITE_LOC_SYSPROP = 
"solr."+SentrySolrPluginImpl.SNTRY_SITE_LOCATION_PROPERTY;
   protected static final String ALL_DOCS = "*:*";
 
-  protected static TestSentryServer sentrySvc;
-  protected static SentryGenericServiceClient sentryClient;
-  protected static UncaughtExceptionHandler orgExceptionHandler;
-
-  @BeforeClass
-  public static void setupClass() throws Exception {
-    skipBrokenLocales();
-
-    Path testDataPath = createTempDir("solr-integration-db-");
-
-    try {
-      sentrySvc = new TestSentryServer(testDataPath, getUserGroupMappings());
-      sentrySvc.startSentryService();
-      sentryClient = sentrySvc.connectToSentryService();
-      log.info("Successfully started Sentry service");
-    } catch (Exception ex) {
-      log.error ("Unexpected exception while starting Sentry service", ex);
-      throw ex;
-    }
-
-    for (int i = 0; i < 4; i++) {
-      sentryClient.createRole(TestSentryServer.ADMIN_USER, "role"+i, 
COMPONENT_SOLR);
-      sentryClient.grantRoleToGroups(TestSentryServer.ADMIN_USER, "role"+i, 
COMPONENT_SOLR, Collections.singleton("group"+i));
-    }
-
-    log.info("Successfully created roles in Sentry service");
-
-    sentryClient.createRole(TestSentryServer.ADMIN_USER, ADMIN_ROLE, 
COMPONENT_SOLR);
-    sentryClient.grantRoleToGroups(TestSentryServer.ADMIN_USER, ADMIN_ROLE, 
COMPONENT_SOLR,
-        Collections.singleton(TestSentryServer.ADMIN_GROUP));
-    grantAdminPrivileges(TestSentryServer.ADMIN_USER, ADMIN_ROLE, 
SolrConstants.ALL, SolrConstants.ALL);
-
-    log.info("Successfully granted admin privileges to " + ADMIN_ROLE);
-
-
-    System.setProperty(SENTRY_SITE_LOC_SYSPROP, 
sentrySvc.getSentrySitePath().toString());
-
-    // set the solr for the loginUser and belongs to solr group
-    // Note - Solr/Sentry unit tests don't use Hadoop authentication 
framework. Hence the
-    // UserGroupInformation is not available when the request is being 
processed by the Solr server.
-    // The document level security search component requires this 
UserGroupInformation while querying
-    // the roles associated with the user. Please refer to implementation of
-    // SentryGenericProviderBackend#getRoles(...) method. Hence this is a 
workaround to satisfy this requirement.
-    
UserGroupInformation.setLoginUser(UserGroupInformation.createUserForTesting("solr",
 new String[]{"solr"}));
-
-    try {
-      configureCluster(NUM_SERVERS)
-        
.withSecurityJson(TEST_PATH().resolve("security").resolve("security.json"))
-        .addConfig("cloud-minimal", 
TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf"))
-        .addConfig("cloud-managed", 
TEST_PATH().resolve("configsets").resolve("cloud-managed").resolve("conf"))
-        .addConfig("cloud-minimal_doc_level_security", 
TEST_PATH().resolve("configsets")
-                      
.resolve("cloud-minimal_doc_level_security").resolve("conf"))
-        .configure();
-      log.info("Successfully started Solr service");
-
-    } catch (Exception ex) {
-      log.error ("Unexpected exception while starting SolrCloud", ex);
-      throw ex;
-    }
-
-    log.info("Successfully setup Solr with Sentry service");
-  }
-
-  /**
-   * A sample failed run was with following parameters
-   * -Dtests.seed=C92C593AE70E7466 -Dtests.locale=und 
-Dtests.timezone=Europe/Sarajevo -Dtests.asserts=true 
-Dtests.file.encoding=UTF-8
-   */
-  private static void skipBrokenLocales() {
-    assumeFalse("This test fails on UNIX whenever Locale has a language, 
country, or variant that does not satisfy" +
-                " the IETF BCP 47 language tag syntax requirements",
-                "und".equals(Locale.getDefault().toLanguageTag()));
-    assumeFalse("This test fails on UNIX with error - Supplied locale 
description 'sr__#Latn' is invalid, expecting ln[_CO[_variant]]" +
-                "ln=lower-case two-letter ISO-639 language code, CO=upper-case 
two-letter ISO-3166 country code",
-                "sr-Latn".equals(Locale.getDefault().toLanguageTag()));
-  }
-
-  @AfterClass
-  public static void cleanUpResources() throws Exception {
-    if (sentryClient != null) {
-      sentryClient.close();
-      sentryClient = null;
-    }
-    if (sentrySvc != null) {
-      sentrySvc.close();
-      sentrySvc = null;
-    }
-    System.clearProperty(SENTRY_SITE_LOC_SYSPROP);
-  }
-
-  public static void grantAdminPrivileges(String requestor, String roleName, 
String entityName, String action)
-      throws SentryUserException {
-    List<TAuthorizable> auths = new ArrayList<>(1);
-    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Admin.name(), entityName));
-
-    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
-    privilege.setGrantOption(TSentryGrantOption.TRUE);
-    sentryClient.grantPrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
-  }
-
-  public static void revokeAdminPrivileges(String requestor, String roleName, 
String entityName, String action)
-      throws SentryUserException {
-    List<TAuthorizable> auths = new ArrayList<>(1);
-    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Admin.name(), entityName));
-
-    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
-    privilege.setGrantOption(TSentryGrantOption.TRUE);
-    sentryClient.revokePrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
-  }
-
-  public static void grantCollectionPrivileges(String requestor, String 
roleName,
-      String collectionName, String action) throws SentryUserException {
-    List<TAuthorizable> auths = new ArrayList<>(1);
-    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Collection.name(), 
collectionName));
-
-    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
-    privilege.setGrantOption(TSentryGrantOption.TRUE);
-    sentryClient.grantPrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
-  }
-
-  public static void revokeCollectionPrivileges(String requestor, String 
roleName,
-      String collectionName, String action) throws SentryUserException {
-    List<TAuthorizable> auths = new ArrayList<>(1);
-    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Collection.name(), 
collectionName));
-
-    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
-    privilege.setGrantOption(TSentryGrantOption.TRUE);
-    sentryClient.revokePrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
-  }
-
-  public static void grantConfigPrivileges(String requestor, String roleName, 
String configName,
-      String action) throws SentryUserException {
-    List<TAuthorizable> auths = new ArrayList<>(1);
-    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Config.name(), 
configName));
-
-    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
-    privilege.setGrantOption(TSentryGrantOption.TRUE);
-    sentryClient.grantPrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
-  }
-
-  public static void revokeConfigPrivileges(String requestor, String roleName, 
String configName,
-      String action) throws SentryUserException {
-    List<TAuthorizable> auths = new ArrayList<>(1);
-    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Config.name(), 
configName));
-
-    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
-    privilege.setGrantOption(TSentryGrantOption.TRUE);
-    sentryClient.revokePrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
-  }
-
-  public static void grantSchemaPrivileges(String requestor, String roleName, 
String schemaName,
-      String action) throws SentryUserException {
-    List<TAuthorizable> auths = new ArrayList<>(1);
-    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Schema.name(), 
schemaName));
-
-    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
-    privilege.setGrantOption(TSentryGrantOption.TRUE);
-    sentryClient.grantPrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
-  }
-
-  public static void revokeSchemaPrivileges(String requestor, String roleName, 
String schemaName,
-      String action) throws SentryUserException {
-    List<TAuthorizable> auths = new ArrayList<>(1);
-    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Schema.name(), 
schemaName));
-
-    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
-    privilege.setGrantOption(TSentryGrantOption.TRUE);
-    sentryClient.revokePrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
-  }
-
-  protected static Map<String, Set<String>> getUserGroupMappings() {
-    Map<String, Set<String>> result = new HashMap<>();
-    result.put("user0", Collections.singleton("group0"));
-    result.put("user1", Collections.singleton("group1"));
-    result.put("user2", Collections.singleton("group2"));
-    result.put("user3", Collections.singleton("group3"));
-    result.put(TestSentryServer.ADMIN_USER, 
Collections.singleton(TestSentryServer.ADMIN_GROUP));
-    result.put("solr", Collections.singleton("solr"));
-    result.put("junit", Collections.singleton("junit"));
-    result.put("doclevel", Collections.singleton("doclevel"));
-    return Collections.unmodifiableMap(result);
-  }
 
   /**
    * Get the user defined in the Solr authentication plugin
@@ -596,5 +396,66 @@ public abstract class AbstractSolrSentryTestCase extends 
SolrCloudTestCase {
     return makeHttpRequest(client, firstServer, httpMethod, path, content, 
contentType, expectedStatusCode);
   }
 
+  protected SolrDocumentList expectedDocs(SolrInputDocument... docs) {
+    SolrDocumentList result = new SolrDocumentList();
+
+    for (SolrInputDocument doc : docs) {
+      SolrDocument r = new SolrDocument();
+      for (SolrInputField field : doc) {
+        r.setField(field.getName(), field.getValue());
+      }
+      result.add(r);
+    }
+    return result;
+  }
+
+  protected void adminUpdateActionFailure(String userName, String 
collectionName)
+      throws SolrServerException, IOException {
+    String tmp = getAuthenticatedUser();
+    try {
+      setAuthenticationUser(userName); // This user doesn't have admin 
permissions
+      // Create collection.
+      CollectionAdminRequest.Create createCmd =
+          CollectionAdminRequest.createCollection(collectionName, 
"cloud-minimal", 1, NUM_SERVERS);
+      createCmd.process(cluster.getSolrClient());
+      fail("This admin request should have failed with authorization error.");
+
+    } catch (RemoteSolrException ex) {
+      assertEquals(HttpServletResponse.SC_FORBIDDEN , ex.code());
+    } finally {
+      setAuthenticationUser(tmp);
+    }
+  }
+
+  protected void verifyCollectionUpdateFailure(String userName, String 
collectionName,
+      SolrInputDocument doc) throws SolrServerException, IOException {
+    String tmp = getAuthenticatedUser();
+    try {
+      setAuthenticationUser(userName);
+      cluster.getSolrClient().add(collectionName, doc);
+      cluster.getSolrClient().commit(collectionName);
+      fail("This collection query request should have failed with 
authorization error.");
 
+    } catch (RemoteSolrException ex) {
+      assertEquals(HttpServletResponse.SC_FORBIDDEN, ex.code());
+    } finally {
+      setAuthenticationUser(tmp);
+    }
+  }
+
+  protected void verifyCollectionQueryFailure(String userName, String 
collectionName,
+      String queryStr) throws SolrServerException, IOException {
+    String tmp = getAuthenticatedUser();
+    try {
+      setAuthenticationUser(userName);
+      cluster.getSolrClient().query(collectionName, new SolrQuery(queryStr));
+      fail("This collection query request should have failed with 
authorization error.");
+
+    } catch (SolrServerException ex) {
+      assertTrue(ex.getRootCause() instanceof RemoteSolrException);
+      assertEquals(HttpServletResponse.SC_FORBIDDEN, 
((RemoteSolrException)ex.getRootCause()).code());
+    } finally {
+      setAuthenticationUser(tmp);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/SolrSentryServiceTestBase.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/SolrSentryServiceTestBase.java
 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/SolrSentryServiceTestBase.java
new file mode 100644
index 0000000..c4a46fa
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/SolrSentryServiceTestBase.java
@@ -0,0 +1,211 @@
+/*
+ * 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.sentry.tests.e2e.solr;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.sentry.core.common.exception.SentryUserException;
+import org.apache.sentry.core.model.solr.SolrConstants;
+import org.apache.sentry.core.model.solr.SolrModelAuthorizable;
+import 
org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SolrSentryServiceTestBase extends AbstractSolrSentryTestCase {
+  private static final Logger log = 
LoggerFactory.getLogger(SolrSentryServiceTestBase.class);
+  protected static TestSentryServer sentrySvc;
+  protected static SentryGenericServiceClient sentryClient;
+  protected static UncaughtExceptionHandler orgExceptionHandler;
+
+  @BeforeClass
+  public static void setupClass() throws Exception {
+    Path testDataPath = createTempDir("solr-integration-db-");
+
+    try {
+      sentrySvc = new TestSentryServer(testDataPath, getUserGroupMappings());
+      sentrySvc.startSentryService();
+      sentryClient = sentrySvc.connectToSentryService();
+      log.info("Successfully started Sentry service");
+    } catch (Exception ex) {
+      log.error ("Unexpected exception while starting Sentry service", ex);
+      throw ex;
+    }
+
+    for (int i = 0; i < 4; i++) {
+      sentryClient.createRole(TestSentryServer.ADMIN_USER, "role"+i, 
COMPONENT_SOLR);
+      sentryClient.grantRoleToGroups(TestSentryServer.ADMIN_USER, "role"+i, 
COMPONENT_SOLR, Collections.singleton("group"+i));
+    }
+
+    log.info("Successfully created roles in Sentry service");
+
+    sentryClient.createRole(TestSentryServer.ADMIN_USER, ADMIN_ROLE, 
COMPONENT_SOLR);
+    sentryClient.grantRoleToGroups(TestSentryServer.ADMIN_USER, ADMIN_ROLE, 
COMPONENT_SOLR,
+        Collections.singleton(TestSentryServer.ADMIN_GROUP));
+    grantAdminPrivileges(TestSentryServer.ADMIN_USER, ADMIN_ROLE, 
SolrConstants.ALL, SolrConstants.ALL);
+
+    log.info("Successfully granted admin privileges to " + ADMIN_ROLE);
+
+
+    System.setProperty(SENTRY_SITE_LOC_SYSPROP, 
sentrySvc.getSentrySitePath().toString());
+
+    // set the solr for the loginUser and belongs to solr group
+    // Note - Solr/Sentry unit tests don't use Hadoop authentication 
framework. Hence the
+    // UserGroupInformation is not available when the request is being 
processed by the Solr server.
+    // The document level security search component requires this 
UserGroupInformation while querying
+    // the roles associated with the user. Please refer to implementation of
+    // SentryGenericProviderBackend#getRoles(...) method. Hence this is a 
workaround to satisfy this requirement.
+    
UserGroupInformation.setLoginUser(UserGroupInformation.createUserForTesting("solr",
 new String[]{"solr"}));
+
+    try {
+      configureCluster(NUM_SERVERS)
+        
.withSecurityJson(TEST_PATH().resolve("security").resolve("security.json"))
+        .addConfig("cloud-minimal", 
TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf"))
+        .addConfig("cloud-managed", 
TEST_PATH().resolve("configsets").resolve("cloud-managed").resolve("conf"))
+        .addConfig("cloud-minimal_doc_level_security", 
TEST_PATH().resolve("configsets")
+                      
.resolve("cloud-minimal_doc_level_security").resolve("conf"))
+        .configure();
+      log.info("Successfully started Solr service");
+
+    } catch (Exception ex) {
+      log.error ("Unexpected exception while starting SolrCloud", ex);
+      throw ex;
+    }
+
+    log.info("Successfully setup Solr with Sentry service");
+  }
+
+  @AfterClass
+  public static void cleanUpResources() throws Exception {
+    if (sentryClient != null) {
+      sentryClient.close();
+      sentryClient = null;
+    }
+    if (sentrySvc != null) {
+      sentrySvc.close();
+      sentrySvc = null;
+    }
+    System.clearProperty(SENTRY_SITE_LOC_SYSPROP);
+  }
+
+  public static void grantAdminPrivileges(String requestor, String roleName, 
String entityName, String action)
+      throws SentryUserException {
+    List<TAuthorizable> auths = new ArrayList<>(1);
+    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Admin.name(), entityName));
+
+    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
+    privilege.setGrantOption(TSentryGrantOption.TRUE);
+    sentryClient.grantPrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
+  }
+
+  public static void revokeAdminPrivileges(String requestor, String roleName, 
String entityName, String action)
+      throws SentryUserException {
+    List<TAuthorizable> auths = new ArrayList<>(1);
+    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Admin.name(), entityName));
+
+    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
+    privilege.setGrantOption(TSentryGrantOption.TRUE);
+    sentryClient.revokePrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
+  }
+
+  public static void grantCollectionPrivileges(String requestor, String 
roleName,
+      String collectionName, String action) throws SentryUserException {
+    List<TAuthorizable> auths = new ArrayList<>(1);
+    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Collection.name(), 
collectionName));
+
+    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
+    privilege.setGrantOption(TSentryGrantOption.TRUE);
+    sentryClient.grantPrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
+  }
+
+  public static void revokeCollectionPrivileges(String requestor, String 
roleName,
+      String collectionName, String action) throws SentryUserException {
+    List<TAuthorizable> auths = new ArrayList<>(1);
+    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Collection.name(), 
collectionName));
+
+    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
+    privilege.setGrantOption(TSentryGrantOption.TRUE);
+    sentryClient.revokePrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
+  }
+
+  public static void grantConfigPrivileges(String requestor, String roleName, 
String configName,
+      String action) throws SentryUserException {
+    List<TAuthorizable> auths = new ArrayList<>(1);
+    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Config.name(), 
configName));
+
+    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
+    privilege.setGrantOption(TSentryGrantOption.TRUE);
+    sentryClient.grantPrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
+  }
+
+  public static void revokeConfigPrivileges(String requestor, String roleName, 
String configName,
+      String action) throws SentryUserException {
+    List<TAuthorizable> auths = new ArrayList<>(1);
+    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Config.name(), 
configName));
+
+    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
+    privilege.setGrantOption(TSentryGrantOption.TRUE);
+    sentryClient.revokePrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
+  }
+
+  public static void grantSchemaPrivileges(String requestor, String roleName, 
String schemaName,
+      String action) throws SentryUserException {
+    List<TAuthorizable> auths = new ArrayList<>(1);
+    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Schema.name(), 
schemaName));
+
+    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
+    privilege.setGrantOption(TSentryGrantOption.TRUE);
+    sentryClient.grantPrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
+  }
+
+  public static void revokeSchemaPrivileges(String requestor, String roleName, 
String schemaName,
+      String action) throws SentryUserException {
+    List<TAuthorizable> auths = new ArrayList<>(1);
+    auths.add(new 
TAuthorizable(SolrModelAuthorizable.AuthorizableType.Schema.name(), 
schemaName));
+
+    TSentryPrivilege privilege = new TSentryPrivilege(COMPONENT_SOLR, 
SERVICE_NAME, auths, action);
+    privilege.setGrantOption(TSentryGrantOption.TRUE);
+    sentryClient.revokePrivilege(requestor, roleName, COMPONENT_SOLR, 
privilege);
+  }
+
+  protected static Map<String, Set<String>> getUserGroupMappings() {
+    Map<String, Set<String>> result = new HashMap<>();
+    result.put("user0", Collections.singleton("group0"));
+    result.put("user1", Collections.singleton("group1"));
+    result.put("user2", Collections.singleton("group2"));
+    result.put("user3", Collections.singleton("group3"));
+    result.put(TestSentryServer.ADMIN_USER, 
Collections.singleton(TestSentryServer.ADMIN_GROUP));
+    result.put("solr", Collections.singleton("solr"));
+    result.put("junit", Collections.singleton("junit"));
+    result.put("doclevel", Collections.singleton("doclevel"));
+    return Collections.unmodifiableMap(result);
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
index a24ceee..7834f33 100644
--- 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
+++ 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
@@ -43,7 +43,7 @@ import org.junit.Test;
 /**
  * Test the document-level security features
  */
-public class TestDocLevelOperations extends AbstractSolrSentryTestCase {
+public class TestDocLevelOperations extends SolrSentryServiceTestBase {
   private static final String AUTH_FIELD = "sentry_auth";
   private static final int NUM_DOCS = 100;
   private static final int EXTRA_AUTH_FIELDS = 2;

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrAdminOperations.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrAdminOperations.java
 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrAdminOperations.java
index 190b9d4..b004ba0 100644
--- 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrAdminOperations.java
+++ 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrAdminOperations.java
@@ -37,7 +37,7 @@ import org.restlet.resource.ClientResource;
 import org.restlet.resource.ResourceException;
 
 @SuppressSSL
-public class TestSolrAdminOperations extends AbstractSolrSentryTestCase {
+public class TestSolrAdminOperations extends SolrSentryServiceTestBase {
 
   @Test
   public void testQueryAdminOperation() throws Exception {
@@ -168,21 +168,4 @@ public class TestSolrAdminOperations extends 
AbstractSolrSentryTestCase {
     }
   }
 
-  protected void adminUpdateActionFailure(String userName, String 
collectionName)
-      throws SolrServerException, IOException {
-    String tmp = getAuthenticatedUser();
-    try {
-      setAuthenticationUser(userName); // This user doesn't have admin 
permissions
-      // Create collection.
-      CollectionAdminRequest.Create createCmd =
-          CollectionAdminRequest.createCollection(collectionName, 
"cloud-minimal", 1, NUM_SERVERS);
-      createCmd.process(cluster.getSolrClient());
-      fail("This admin request should have failed with authorization error.");
-
-    } catch (RemoteSolrException ex) {
-      assertEquals(HttpServletResponse.SC_FORBIDDEN , ex.code());
-    } finally {
-      setAuthenticationUser(tmp);
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrCollectionOperations.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrCollectionOperations.java
 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrCollectionOperations.java
index 3d9faa0..2ca6010 100644
--- 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrCollectionOperations.java
+++ 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrCollectionOperations.java
@@ -18,22 +18,13 @@ package org.apache.sentry.tests.e2e.solr;
 
 import static org.apache.sentry.tests.e2e.solr.TestSentryServer.ADMIN_USER;
 
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletResponse;
-
 import org.apache.sentry.core.model.solr.SolrConstants;
-import org.apache.solr.client.solrj.SolrQuery;
-import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.HttpSolrClient.RemoteSolrException;
-import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.SolrInputDocument;
-import org.apache.solr.common.SolrInputField;
 import org.junit.Test;
 
 
-public class TestSolrCollectionOperations extends AbstractSolrSentryTestCase {
+public class TestSolrCollectionOperations extends SolrSentryServiceTestBase {
 
   @Test
   public void testQueryOperations() throws Exception {
@@ -92,50 +83,4 @@ public class TestSolrCollectionOperations extends 
AbstractSolrSentryTestCase {
     verifyCollectionUpdateFailure("user0", collectionName, solrInputDoc);
     verifyCollectionUpdateFailure("user1", collectionName, solrInputDoc);
   }
-
-
-  protected void verifyCollectionUpdateFailure(String userName, String 
collectionName,
-      SolrInputDocument doc) throws SolrServerException, IOException {
-    String tmp = getAuthenticatedUser();
-    try {
-      setAuthenticationUser(userName);
-      cluster.getSolrClient().add(collectionName, doc);
-      cluster.getSolrClient().commit(collectionName);
-      fail("This collection query request should have failed with 
authorization error.");
-
-    } catch (RemoteSolrException ex) {
-      assertEquals(HttpServletResponse.SC_FORBIDDEN, ex.code());
-    } finally {
-      setAuthenticationUser(tmp);
-    }
-  }
-
-  protected void verifyCollectionQueryFailure(String userName, String 
collectionName,
-      String queryStr) throws SolrServerException, IOException {
-    String tmp = getAuthenticatedUser();
-    try {
-      setAuthenticationUser(userName);
-      cluster.getSolrClient().query(collectionName, new SolrQuery(queryStr));
-      fail("This collection query request should have failed with 
authorization error.");
-
-    } catch (SolrServerException ex) {
-      assertTrue(ex.getRootCause() instanceof RemoteSolrException);
-      assertEquals(HttpServletResponse.SC_FORBIDDEN, 
((RemoteSolrException)ex.getRootCause()).code());
-    } finally {
-      setAuthenticationUser(tmp);
-    }
-  }
-
-  protected SolrDocumentList expectedDocs(SolrInputDocument... docs) {
-    SolrDocumentList result = new SolrDocumentList();
-
-    for (SolrInputDocument doc : docs) {
-      SolrDocument r = new SolrDocument();
-      for (SolrInputField field : doc) {
-        r.setField(field.getName(), field.getValue());
-      }
-      result.add(r);
-    }
-    return result;
-  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrConfigOperations.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrConfigOperations.java
 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrConfigOperations.java
index 620825f..454fd02 100644
--- 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrConfigOperations.java
+++ 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrConfigOperations.java
@@ -35,7 +35,7 @@ import org.restlet.resource.ClientResource;
 import org.restlet.resource.ResourceException;
 
 @SuppressSSL
-public class TestSolrConfigOperations extends AbstractSolrSentryTestCase {
+public class TestSolrConfigOperations extends SolrSentryServiceTestBase {
   @Test
   public void testConfigSetOperations() throws Exception {
     grantConfigPrivileges(ADMIN_USER, "role0", "test", SolrConstants.UPDATE);

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrSchemaOperations.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrSchemaOperations.java
 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrSchemaOperations.java
index 1169b54..2443780 100644
--- 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrSchemaOperations.java
+++ 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrSchemaOperations.java
@@ -31,7 +31,7 @@ import org.restlet.resource.ClientResource;
 import org.restlet.resource.ResourceException;
 
 @SuppressSSL
-public class TestSolrSchemaOperations extends AbstractSolrSentryTestCase {
+public class TestSolrSchemaOperations extends SolrSentryServiceTestBase {
   private static final String fieldToBeAdded = "{ " +
       "\"add-field\":{" +
       "\"name\":\"test\"," +

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrWithSimpleFileProviderBackend.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrWithSimpleFileProviderBackend.java
 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrWithSimpleFileProviderBackend.java
new file mode 100644
index 0000000..f6e7442
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestSolrWithSimpleFileProviderBackend.java
@@ -0,0 +1,127 @@
+/*
+ * 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.sentry.tests.e2e.solr;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrInputDocument;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestSolrWithSimpleFileProviderBackend extends 
AbstractSolrSentryTestCase {
+  private static final Logger log = 
LoggerFactory.getLogger(TestSolrWithSimpleFileProviderBackend.class);
+  protected static final String RESOURCES_DIR = "target" + File.separator + 
"test-classes" + File.separator + "solr";
+
+  @BeforeClass
+  public static void setupClass() throws Exception {
+    // Configure file-based Sentry provider
+    File sentrySiteXml = setupSentry();
+    System.setProperty(SENTRY_SITE_LOC_SYSPROP, 
sentrySiteXml.getAbsolutePath());
+
+    try {
+      configureCluster(NUM_SERVERS)
+        
.withSecurityJson(TEST_PATH().resolve("security").resolve("security.json"))
+        .addConfig("cloud-minimal", 
TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf"))
+        .addConfig("cloud-managed", 
TEST_PATH().resolve("configsets").resolve("cloud-managed").resolve("conf"))
+        .addConfig("cloud-minimal_doc_level_security", 
TEST_PATH().resolve("configsets")
+                      
.resolve("cloud-minimal_doc_level_security").resolve("conf"))
+        .configure();
+      log.info("Successfully started Solr service");
+
+    } catch (Exception ex) {
+      log.error ("Unexpected exception while starting SolrCloud", ex);
+      throw ex;
+    }
+
+    log.info("Successfully setup Solr with Sentry service");
+  }
+
+  private static void addPropertyToSentry(StringBuilder builder, String name, 
String value) {
+    builder.append("<property>\n");
+    builder.append("<name>").append(name).append("</name>\n");
+    builder.append("<value>").append(value).append("</value>\n");
+    builder.append("</property>\n");
+  }
+
+  private static File setupSentry() throws Exception {
+    File sentrySite = File.createTempFile("sentry-site", "xml");
+    sentrySite.deleteOnExit();
+    File authProviderDir = new File(RESOURCES_DIR, "sentry");
+    File authProviderName = new File (authProviderDir, 
"test-authz-provider.ini");
+
+    // need to write sentry-site at execution time because we don't know
+    // the location of sentry.solr.provider.resource beforehand
+    StringBuilder sentrySiteData = new StringBuilder();
+    sentrySiteData.append("<configuration>\n");
+    addPropertyToSentry(sentrySiteData, "sentry.provider",
+      
"org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider");
+    addPropertyToSentry(sentrySiteData, "sentry.solr.provider.resource",
+       authProviderName.getAbsolutePath());
+    sentrySiteData.append("</configuration>\n");
+    FileUtils.writeStringToFile(sentrySite,sentrySiteData.toString(), 
StandardCharsets.UTF_8);
+    return sentrySite;
+  }
+
+  @Test
+  public void testCollectionOperationsSuccess() throws Exception {
+    String collectionName = "testCollectionOperations_s";
+    createCollection("admin", collectionName, "cloud-minimal", NUM_SERVERS, 1);
+
+    cleanSolrCollection("junit", collectionName);
+
+    SolrInputDocument solrInputDoc = createSolrTestDoc();
+    uploadSolrDoc("junit", collectionName, solrInputDoc);
+
+    SolrDocumentList expectedDocs = expectedDocs(solrInputDoc);
+
+    validateSolrDocCountAndContent(expectedDocs,
+        getSolrDocs("junit", collectionName, ALL_DOCS));
+  }
+
+  @Test
+  public void testCollectionOperationFailures() throws Exception {
+    String collectionName = "testCollectionOperations_f";
+
+    // junit user can not create a collection.
+    adminUpdateActionFailure ("junit", collectionName);
+
+    // admin user can create collection
+    createCollection("admin", collectionName, "cloud-minimal", NUM_SERVERS, 1);
+
+    SolrInputDocument solrInputDoc = createSolrTestDoc();
+
+    // foo user can not update collection
+    verifyCollectionUpdateFailure("foo", collectionName, solrInputDoc);
+
+    // junit user can update collection
+    uploadSolrDoc("junit", collectionName, solrInputDoc);
+
+    SolrDocumentList expectedDocs = expectedDocs(solrInputDoc);
+
+    // junit user can query collection
+    validateSolrDocCountAndContent(expectedDocs,
+        getSolrDocs("junit", collectionName, ALL_DOCS));
+
+    // foo user can not query collection
+    verifyCollectionQueryFailure("foo", collectionName, ALL_DOCS);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/755e9425/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
 
b/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
index a376cb8..0751dbe 100644
--- 
a/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
+++ 
b/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
@@ -18,109 +18,13 @@
 [groups]
 junit = junit_role
 admin = admin_role
-docLevel = docLevel_role
-sentryCollection_query_group = sentryCollection_query_role
-sentryCollection_update_group = sentryCollection_update_role
-sentryCollection_query_update_group = sentryCollection_query_update_role
-sentryCollection_all_group = sentryCollection_all_role
-admin_query_group = admin_query_role
-admin_update_group = admin_update_role
-admin_query_update_group = admin_query_update_role
-admin_all_group = admin_all_role
+foo = foo_role
 
 [roles]
-junit_role = collection=admin, collection=collection1, 
collection=docLevelCollection, collection=allRolesCollection, 
collection=testUpdateDeleteOperations
-docLevel_role = collection=docLevelCollection, 
collection=testUpdateDeleteOperations
-admin_role = collection=admin, collection=collection1, 
collection=sentryCollection, collection=sentryCollection_underlying1, 
collection=sentryCollection_underlying2, collection=docLevelCollection, 
collection=allRolesCollection, collection=testInvariantCollection, 
collection=testUpdateDeleteOperations, 
collection=testIndexlevelDoclevelOperations, collection=testUpdateDistribPhase, 
collection=testIdvsIds, collection=testIdvsIdsControl, collection=testFl, 
collection=testNonCommitted, collection=testConcurrentChanges, 
collection=testSuperUser
-sentryCollection_query_role = collection=sentryCollection->action=query
-sentryCollection_update_role = collection=sentryCollection->action=update
-sentryCollection_query_update_role = 
collection=sentryCollection->action=query, 
collection=sentryCollection->action=update
-sentryCollection_all_role = collection=sentryCollection->action=*
-admin_query_role = collection=admin->action=query
-admin_update_role = collection=admin->action=update
-admin_query_update_role = collection=admin->action=query, 
collection=admin->action=update
-admin_all_role = collection=admin->action=*
+junit_role = collection=testCollectionOperations_s, 
collection=testCollectionOperations_f
+admin_role = admin=collections, admin=cores, 
collection=testCollectionOperations_s, collection=testCollectionOperations_f
 
 [users]
 junit = junit
-docLevel = docLevel
 admin = admin
-admin_qua = admin_query_group, admin_update_group, admin_all_group,
-admin_qu = admin_query_group, admin_update_group,
-admin_qa = admin_query_group, admin_all_group,
-admin_q = admin_query_group,
-admin_ua = admin_update_group, admin_all_group,
-admin_u = admin_update_group,
-admin_a = admin_all_group,
-admin_qua__sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group, admin_query_group, 
admin_update_group, admin_all_group,
-admin_qu__sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group, admin_query_group, 
admin_update_group,
-admin_qa__sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group, admin_query_group, 
admin_all_group,
-admin_q__sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group, admin_query_group,
-admin_ua__sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group, admin_update_group, 
admin_all_group,
-admin_u__sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group, admin_update_group,
-admin_a__sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group, admin_all_group,
-admin___sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group,
-admin_qua__sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group, admin_query_group, admin_update_group, 
admin_all_group,
-admin_qu__sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group, admin_query_group, admin_update_group,
-admin_qa__sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group, admin_query_group, admin_all_group,
-admin_q__sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group, admin_query_group,
-admin_ua__sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group, admin_update_group, admin_all_group,
-admin_u__sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group, admin_update_group,
-admin_a__sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group, admin_all_group,
-admin___sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group,
-admin_qua__sentryCollection_qa = sentryCollection_query_group, 
sentryCollection_all_group, admin_query_group, admin_update_group, 
admin_all_group,
-admin_qu__sentryCollection_qa = sentryCollection_query_group, 
sentryCollection_all_group, admin_query_group, admin_update_group,
-admin_qa__sentryCollection_qa = sentryCollection_query_group, 
sentryCollection_all_group, admin_query_group, admin_all_group,
-admin_q__sentryCollection_qa = sentryCollection_query_group, 
sentryCollection_all_group, admin_query_group,
-admin_ua__sentryCollection_qa = sentryCollection_query_group, 
sentryCollection_all_group, admin_update_group, admin_all_group,
-admin_u__sentryCollection_qa = sentryCollection_query_group, 
sentryCollection_all_group, admin_update_group,
-admin_a__sentryCollection_qa = sentryCollection_query_group, 
sentryCollection_all_group, admin_all_group,
-admin___sentryCollection_qa = sentryCollection_query_group, 
sentryCollection_all_group,
-admin_qua__sentryCollection_q = sentryCollection_query_group, 
admin_query_group, admin_update_group, admin_all_group,
-admin_qu__sentryCollection_q = sentryCollection_query_group, 
admin_query_group, admin_update_group,
-admin_qa__sentryCollection_q = sentryCollection_query_group, 
admin_query_group, admin_all_group,
-admin_q__sentryCollection_q = sentryCollection_query_group, admin_query_group,
-admin_ua__sentryCollection_q = sentryCollection_query_group, 
admin_update_group, admin_all_group,
-admin_u__sentryCollection_q = sentryCollection_query_group, admin_update_group,
-admin_a__sentryCollection_q = sentryCollection_query_group, admin_all_group,
-admin___sentryCollection_q = sentryCollection_query_group,
-admin_qua__sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group, admin_query_group, admin_update_group, 
admin_all_group,
-admin_qu__sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group, admin_query_group, admin_update_group,
-admin_qa__sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group, admin_query_group, admin_all_group,
-admin_q__sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group, admin_query_group,
-admin_ua__sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group, admin_update_group, admin_all_group,
-admin_u__sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group, admin_update_group,
-admin_a__sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group, admin_all_group,
-admin___sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group,
-admin_qua__sentryCollection_u = sentryCollection_update_group, 
admin_query_group, admin_update_group, admin_all_group,
-admin_qu__sentryCollection_u = sentryCollection_update_group, 
admin_query_group, admin_update_group,
-admin_qa__sentryCollection_u = sentryCollection_update_group, 
admin_query_group, admin_all_group,
-admin_q__sentryCollection_u = sentryCollection_update_group, admin_query_group,
-admin_ua__sentryCollection_u = sentryCollection_update_group, 
admin_update_group, admin_all_group,
-admin_u__sentryCollection_u = sentryCollection_update_group, 
admin_update_group,
-admin_a__sentryCollection_u = sentryCollection_update_group, admin_all_group,
-admin___sentryCollection_u = sentryCollection_update_group,
-admin_qua__sentryCollection_a = sentryCollection_all_group, admin_query_group, 
admin_update_group, admin_all_group,
-admin_qu__sentryCollection_a = sentryCollection_all_group, admin_query_group, 
admin_update_group,
-admin_qa__sentryCollection_a = sentryCollection_all_group, admin_query_group, 
admin_all_group,
-admin_q__sentryCollection_a = sentryCollection_all_group, admin_query_group,
-admin_ua__sentryCollection_a = sentryCollection_all_group, admin_update_group, 
admin_all_group,
-admin_u__sentryCollection_a = sentryCollection_all_group, admin_update_group,
-admin_a__sentryCollection_a = sentryCollection_all_group, admin_all_group,
-admin___sentryCollection_a = sentryCollection_all_group,
-admin_qua__sentryCollection_ = admin_query_group, admin_update_group, 
admin_all_group,
-admin_qu__sentryCollection_ = admin_query_group, admin_update_group,
-admin_qa__sentryCollection_ = admin_query_group, admin_all_group,
-admin_q__sentryCollection_ = admin_query_group,
-admin_ua__sentryCollection_ = admin_update_group, admin_all_group,
-admin_u__sentryCollection_ = admin_update_group,
-admin_a__sentryCollection_ = admin_all_group,
-admin___sentryCollection_ = sentryCollection_temp_group,
-sentryCollection_qua = sentryCollection_query_group, 
sentryCollection_update_group, sentryCollection_all_group,
-sentryCollection_qu = sentryCollection_query_group, 
sentryCollection_update_group,
-sentryCollection_qa = sentryCollection_query_group, sentryCollection_all_group,
-sentryCollection_q = sentryCollection_query_group,
-sentryCollection_ua = sentryCollection_update_group, 
sentryCollection_all_group,
-sentryCollection_u = sentryCollection_update_group,
-sentryCollection_a = sentryCollection_all_group,
-sentryCollection_ = sentryCollection_temp_group
\ No newline at end of file
+foo = foo

Reply via email to