pre-review
diff --git a/pom.xml b/pom.xml
index fa88493..3de8758 100644
--- a/pom.xml
+++ b/pom.xml
@@ -93,6 +93,7 @@
<easymock.version>3.0</easymock.version>
<objenesis.version>1.2</objenesis.version>
<cglib.version>2.2</cglib.version>
+ <hazelcast.version>3.2</hazelcast.version>
</properties>
<dependencyManagement>
diff --git a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java
index f1e792d..8c52df5 100644
--- a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java
+++ b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java
@@ -27,12 +27,10 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.sentry.hdfs.ServiceConstants.ServerConfig;
import org.apache.sentry.hdfs.UpdateForwarder.ExternalImageRetriever;
-import org.apache.sentry.hdfs.service.thrift.TPathChanges;
import org.apache.sentry.hdfs.service.thrift.TPermissionsUpdate;
import org.apache.sentry.hdfs.service.thrift.TPrivilegeChanges;
import org.apache.sentry.hdfs.service.thrift.TRoleChanges;
import org.apache.sentry.provider.db.SentryPolicyStorePlugin;
-import org.apache.sentry.provider.db.SentryPolicyStorePlugin.SentryPluginException;
import org.apache.sentry.provider.db.service.persistent.SentryStore;
import org.apache.sentry.provider.db.service.thrift.TAlterSentryRoleAddGroupsRequest;
import org.apache.sentry.provider.db.service.thrift.TAlterSentryRoleDeleteGroupsRequest;
@@ -52,6 +50,7 @@
public class SentryPlugin implements SentryPolicyStorePlugin {
private static final Logger LOGGER = LoggerFactory.getLogger(SentryPlugin.class);
+ public static String NULL_COL = "__NULL__";
public static volatile SentryPlugin instance;
@@ -239,10 +238,10 @@
private String getAuthzObj(TSentryPrivilege privilege) {
String authzObj = null;
- if (!SentryStore.isNULL(privilege.getDbName())) {
+ if (!isNULL(privilege.getDbName())) {
String dbName = privilege.getDbName();
String tblName = privilege.getTableName();
- if (SentryStore.isNULL(tblName)) {
+ if (isNULL(tblName)) {
authzObj = dbName;
} else {
authzObj = dbName + "." + tblName;
@@ -253,10 +252,10 @@
private String getAuthzObj(TSentryAuthorizable authzble) {
String authzObj = null;
- if (!SentryStore.isNULL(authzble.getDb())) {
+ if (!isNULL(authzble.getDb())) {
String dbName = authzble.getDb();
String tblName = authzble.getTable();
- if (SentryStore.isNULL(tblName)) {
+ if (isNULL(tblName)) {
authzObj = dbName;
} else {
authzObj = dbName + "." + tblName;
@@ -264,4 +263,16 @@
}
return authzObj;
}
+
+ public static String toNULLCol(String s) {
+ return Strings.isNullOrEmpty(s) ? NULL_COL : s;
+ }
+
+ public static String fromNULLCol(String s) {
+ return isNULL(s) ? "" : s;
+ }
+
+ public static boolean isNULL(String s) {
+ return Strings.isNullOrEmpty(s) || s.equals(NULL_COL);
+ }
}
diff --git a/sentry-provider/sentry-provider-db/pom.xml b/sentry-provider/sentry-provider-db/pom.xml
index b9208ed..b135ac7 100644
--- a/sentry-provider/sentry-provider-db/pom.xml
+++ b/sentry-provider/sentry-provider-db/pom.xml
@@ -28,6 +28,11 @@
<name>Sentry Provider DB</name>
<dependencies>
+ <dependency>
+ <groupId>com.hazelcast</groupId>
+ <artifactId>hazelcast</artifactId>
+ <version>${hazelcast.version}</version>
+ </dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleAddGroupsRequest.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleAddGroupsRequest.java
index 21efbd0..87b5cc0 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleAddGroupsRequest.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleAddGroupsRequest.java
@@ -631,14 +631,14 @@
case 5: // GROUPS
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set0 = iprot.readSetBegin();
- struct.groups = new HashSet<TSentryGroup>(2*_set0.size);
- for (int _i1 = 0; _i1 < _set0.size; ++_i1)
+ org.apache.thrift.protocol.TSet _set72 = iprot.readSetBegin();
+ struct.groups = new HashSet<TSentryGroup>(2*_set72.size);
+ for (int _i73 = 0; _i73 < _set72.size; ++_i73)
{
- TSentryGroup _elem2; // required
- _elem2 = new TSentryGroup();
- _elem2.read(iprot);
- struct.groups.add(_elem2);
+ TSentryGroup _elem74; // required
+ _elem74 = new TSentryGroup();
+ _elem74.read(iprot);
+ struct.groups.add(_elem74);
}
iprot.readSetEnd();
}
@@ -677,9 +677,9 @@
oprot.writeFieldBegin(GROUPS_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.groups.size()));
- for (TSentryGroup _iter3 : struct.groups)
+ for (TSentryGroup _iter75 : struct.groups)
{
- _iter3.write(oprot);
+ _iter75.write(oprot);
}
oprot.writeSetEnd();
}
@@ -707,9 +707,9 @@
oprot.writeString(struct.roleName);
{
oprot.writeI32(struct.groups.size());
- for (TSentryGroup _iter4 : struct.groups)
+ for (TSentryGroup _iter76 : struct.groups)
{
- _iter4.write(oprot);
+ _iter76.write(oprot);
}
}
}
@@ -724,14 +724,14 @@
struct.roleName = iprot.readString();
struct.setRoleNameIsSet(true);
{
- org.apache.thrift.protocol.TSet _set5 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.groups = new HashSet<TSentryGroup>(2*_set5.size);
- for (int _i6 = 0; _i6 < _set5.size; ++_i6)
+ org.apache.thrift.protocol.TSet _set77 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.groups = new HashSet<TSentryGroup>(2*_set77.size);
+ for (int _i78 = 0; _i78 < _set77.size; ++_i78)
{
- TSentryGroup _elem7; // required
- _elem7 = new TSentryGroup();
- _elem7.read(iprot);
- struct.groups.add(_elem7);
+ TSentryGroup _elem79; // required
+ _elem79 = new TSentryGroup();
+ _elem79.read(iprot);
+ struct.groups.add(_elem79);
}
}
struct.setGroupsIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleDeleteGroupsRequest.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleDeleteGroupsRequest.java
index 58e9870..593b7f4 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleDeleteGroupsRequest.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleDeleteGroupsRequest.java
@@ -631,14 +631,14 @@
case 5: // GROUPS
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set8 = iprot.readSetBegin();
- struct.groups = new HashSet<TSentryGroup>(2*_set8.size);
- for (int _i9 = 0; _i9 < _set8.size; ++_i9)
+ org.apache.thrift.protocol.TSet _set80 = iprot.readSetBegin();
+ struct.groups = new HashSet<TSentryGroup>(2*_set80.size);
+ for (int _i81 = 0; _i81 < _set80.size; ++_i81)
{
- TSentryGroup _elem10; // required
- _elem10 = new TSentryGroup();
- _elem10.read(iprot);
- struct.groups.add(_elem10);
+ TSentryGroup _elem82; // required
+ _elem82 = new TSentryGroup();
+ _elem82.read(iprot);
+ struct.groups.add(_elem82);
}
iprot.readSetEnd();
}
@@ -677,9 +677,9 @@
oprot.writeFieldBegin(GROUPS_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.groups.size()));
- for (TSentryGroup _iter11 : struct.groups)
+ for (TSentryGroup _iter83 : struct.groups)
{
- _iter11.write(oprot);
+ _iter83.write(oprot);
}
oprot.writeSetEnd();
}
@@ -707,9 +707,9 @@
oprot.writeString(struct.roleName);
{
oprot.writeI32(struct.groups.size());
- for (TSentryGroup _iter12 : struct.groups)
+ for (TSentryGroup _iter84 : struct.groups)
{
- _iter12.write(oprot);
+ _iter84.write(oprot);
}
}
}
@@ -724,14 +724,14 @@
struct.roleName = iprot.readString();
struct.setRoleNameIsSet(true);
{
- org.apache.thrift.protocol.TSet _set13 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.groups = new HashSet<TSentryGroup>(2*_set13.size);
- for (int _i14 = 0; _i14 < _set13.size; ++_i14)
+ org.apache.thrift.protocol.TSet _set85 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.groups = new HashSet<TSentryGroup>(2*_set85.size);
+ for (int _i86 = 0; _i86 < _set85.size; ++_i86)
{
- TSentryGroup _elem15; // required
- _elem15 = new TSentryGroup();
- _elem15.read(iprot);
- struct.groups.add(_elem15);
+ TSentryGroup _elem87; // required
+ _elem87 = new TSentryGroup();
+ _elem87.read(iprot);
+ struct.groups.add(_elem87);
}
}
struct.setGroupsIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleGrantPrivilegeRequest.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleGrantPrivilegeRequest.java
index 6b051a1..beea1da 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleGrantPrivilegeRequest.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleGrantPrivilegeRequest.java
@@ -721,14 +721,14 @@
case 6: // PRIVILEGES
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set16 = iprot.readSetBegin();
- struct.privileges = new HashSet<TSentryPrivilege>(2*_set16.size);
- for (int _i17 = 0; _i17 < _set16.size; ++_i17)
+ org.apache.thrift.protocol.TSet _set88 = iprot.readSetBegin();
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set88.size);
+ for (int _i89 = 0; _i89 < _set88.size; ++_i89)
{
- TSentryPrivilege _elem18; // required
- _elem18 = new TSentryPrivilege();
- _elem18.read(iprot);
- struct.privileges.add(_elem18);
+ TSentryPrivilege _elem90; // required
+ _elem90 = new TSentryPrivilege();
+ _elem90.read(iprot);
+ struct.privileges.add(_elem90);
}
iprot.readSetEnd();
}
@@ -775,9 +775,9 @@
oprot.writeFieldBegin(PRIVILEGES_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.privileges.size()));
- for (TSentryPrivilege _iter19 : struct.privileges)
+ for (TSentryPrivilege _iter91 : struct.privileges)
{
- _iter19.write(oprot);
+ _iter91.write(oprot);
}
oprot.writeSetEnd();
}
@@ -818,9 +818,9 @@
if (struct.isSetPrivileges()) {
{
oprot.writeI32(struct.privileges.size());
- for (TSentryPrivilege _iter20 : struct.privileges)
+ for (TSentryPrivilege _iter92 : struct.privileges)
{
- _iter20.write(oprot);
+ _iter92.write(oprot);
}
}
}
@@ -843,14 +843,14 @@
}
if (incoming.get(1)) {
{
- org.apache.thrift.protocol.TSet _set21 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.privileges = new HashSet<TSentryPrivilege>(2*_set21.size);
- for (int _i22 = 0; _i22 < _set21.size; ++_i22)
+ org.apache.thrift.protocol.TSet _set93 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set93.size);
+ for (int _i94 = 0; _i94 < _set93.size; ++_i94)
{
- TSentryPrivilege _elem23; // required
- _elem23 = new TSentryPrivilege();
- _elem23.read(iprot);
- struct.privileges.add(_elem23);
+ TSentryPrivilege _elem95; // required
+ _elem95 = new TSentryPrivilege();
+ _elem95.read(iprot);
+ struct.privileges.add(_elem95);
}
}
struct.setPrivilegesIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleGrantPrivilegeResponse.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleGrantPrivilegeResponse.java
index 0cadf16..2bbc208 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleGrantPrivilegeResponse.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleGrantPrivilegeResponse.java
@@ -537,14 +537,14 @@
case 3: // PRIVILEGES
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set24 = iprot.readSetBegin();
- struct.privileges = new HashSet<TSentryPrivilege>(2*_set24.size);
- for (int _i25 = 0; _i25 < _set24.size; ++_i25)
+ org.apache.thrift.protocol.TSet _set96 = iprot.readSetBegin();
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set96.size);
+ for (int _i97 = 0; _i97 < _set96.size; ++_i97)
{
- TSentryPrivilege _elem26; // required
- _elem26 = new TSentryPrivilege();
- _elem26.read(iprot);
- struct.privileges.add(_elem26);
+ TSentryPrivilege _elem98; // required
+ _elem98 = new TSentryPrivilege();
+ _elem98.read(iprot);
+ struct.privileges.add(_elem98);
}
iprot.readSetEnd();
}
@@ -583,9 +583,9 @@
oprot.writeFieldBegin(PRIVILEGES_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.privileges.size()));
- for (TSentryPrivilege _iter27 : struct.privileges)
+ for (TSentryPrivilege _iter99 : struct.privileges)
{
- _iter27.write(oprot);
+ _iter99.write(oprot);
}
oprot.writeSetEnd();
}
@@ -624,9 +624,9 @@
if (struct.isSetPrivileges()) {
{
oprot.writeI32(struct.privileges.size());
- for (TSentryPrivilege _iter28 : struct.privileges)
+ for (TSentryPrivilege _iter100 : struct.privileges)
{
- _iter28.write(oprot);
+ _iter100.write(oprot);
}
}
}
@@ -646,14 +646,14 @@
}
if (incoming.get(1)) {
{
- org.apache.thrift.protocol.TSet _set29 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.privileges = new HashSet<TSentryPrivilege>(2*_set29.size);
- for (int _i30 = 0; _i30 < _set29.size; ++_i30)
+ org.apache.thrift.protocol.TSet _set101 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set101.size);
+ for (int _i102 = 0; _i102 < _set101.size; ++_i102)
{
- TSentryPrivilege _elem31; // required
- _elem31 = new TSentryPrivilege();
- _elem31.read(iprot);
- struct.privileges.add(_elem31);
+ TSentryPrivilege _elem103; // required
+ _elem103 = new TSentryPrivilege();
+ _elem103.read(iprot);
+ struct.privileges.add(_elem103);
}
}
struct.setPrivilegesIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleRevokePrivilegeRequest.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleRevokePrivilegeRequest.java
index 71cc12e..9879888 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleRevokePrivilegeRequest.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TAlterSentryRoleRevokePrivilegeRequest.java
@@ -721,14 +721,14 @@
case 6: // PRIVILEGES
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set32 = iprot.readSetBegin();
- struct.privileges = new HashSet<TSentryPrivilege>(2*_set32.size);
- for (int _i33 = 0; _i33 < _set32.size; ++_i33)
+ org.apache.thrift.protocol.TSet _set104 = iprot.readSetBegin();
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set104.size);
+ for (int _i105 = 0; _i105 < _set104.size; ++_i105)
{
- TSentryPrivilege _elem34; // required
- _elem34 = new TSentryPrivilege();
- _elem34.read(iprot);
- struct.privileges.add(_elem34);
+ TSentryPrivilege _elem106; // required
+ _elem106 = new TSentryPrivilege();
+ _elem106.read(iprot);
+ struct.privileges.add(_elem106);
}
iprot.readSetEnd();
}
@@ -775,9 +775,9 @@
oprot.writeFieldBegin(PRIVILEGES_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.privileges.size()));
- for (TSentryPrivilege _iter35 : struct.privileges)
+ for (TSentryPrivilege _iter107 : struct.privileges)
{
- _iter35.write(oprot);
+ _iter107.write(oprot);
}
oprot.writeSetEnd();
}
@@ -818,9 +818,9 @@
if (struct.isSetPrivileges()) {
{
oprot.writeI32(struct.privileges.size());
- for (TSentryPrivilege _iter36 : struct.privileges)
+ for (TSentryPrivilege _iter108 : struct.privileges)
{
- _iter36.write(oprot);
+ _iter108.write(oprot);
}
}
}
@@ -843,14 +843,14 @@
}
if (incoming.get(1)) {
{
- org.apache.thrift.protocol.TSet _set37 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.privileges = new HashSet<TSentryPrivilege>(2*_set37.size);
- for (int _i38 = 0; _i38 < _set37.size; ++_i38)
+ org.apache.thrift.protocol.TSet _set109 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set109.size);
+ for (int _i110 = 0; _i110 < _set109.size; ++_i110)
{
- TSentryPrivilege _elem39; // required
- _elem39 = new TSentryPrivilege();
- _elem39.read(iprot);
- struct.privileges.add(_elem39);
+ TSentryPrivilege _elem111; // required
+ _elem111 = new TSentryPrivilege();
+ _elem111.read(iprot);
+ struct.privileges.add(_elem111);
}
}
struct.setPrivilegesIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java
index 1a5d3cf..9acef72 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java
@@ -724,14 +724,14 @@
case 3: // AUTHORIZABLE_SET
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set106 = iprot.readSetBegin();
- struct.authorizableSet = new HashSet<TSentryAuthorizable>(2*_set106.size);
- for (int _i107 = 0; _i107 < _set106.size; ++_i107)
+ org.apache.thrift.protocol.TSet _set178 = iprot.readSetBegin();
+ struct.authorizableSet = new HashSet<TSentryAuthorizable>(2*_set178.size);
+ for (int _i179 = 0; _i179 < _set178.size; ++_i179)
{
- TSentryAuthorizable _elem108; // required
- _elem108 = new TSentryAuthorizable();
- _elem108.read(iprot);
- struct.authorizableSet.add(_elem108);
+ TSentryAuthorizable _elem180; // required
+ _elem180 = new TSentryAuthorizable();
+ _elem180.read(iprot);
+ struct.authorizableSet.add(_elem180);
}
iprot.readSetEnd();
}
@@ -743,13 +743,13 @@
case 4: // GROUPS
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set109 = iprot.readSetBegin();
- struct.groups = new HashSet<String>(2*_set109.size);
- for (int _i110 = 0; _i110 < _set109.size; ++_i110)
+ org.apache.thrift.protocol.TSet _set181 = iprot.readSetBegin();
+ struct.groups = new HashSet<String>(2*_set181.size);
+ for (int _i182 = 0; _i182 < _set181.size; ++_i182)
{
- String _elem111; // required
- _elem111 = iprot.readString();
- struct.groups.add(_elem111);
+ String _elem183; // required
+ _elem183 = iprot.readString();
+ struct.groups.add(_elem183);
}
iprot.readSetEnd();
}
@@ -792,9 +792,9 @@
oprot.writeFieldBegin(AUTHORIZABLE_SET_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.authorizableSet.size()));
- for (TSentryAuthorizable _iter112 : struct.authorizableSet)
+ for (TSentryAuthorizable _iter184 : struct.authorizableSet)
{
- _iter112.write(oprot);
+ _iter184.write(oprot);
}
oprot.writeSetEnd();
}
@@ -805,9 +805,9 @@
oprot.writeFieldBegin(GROUPS_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.groups.size()));
- for (String _iter113 : struct.groups)
+ for (String _iter185 : struct.groups)
{
- oprot.writeString(_iter113);
+ oprot.writeString(_iter185);
}
oprot.writeSetEnd();
}
@@ -842,9 +842,9 @@
oprot.writeString(struct.requestorUserName);
{
oprot.writeI32(struct.authorizableSet.size());
- for (TSentryAuthorizable _iter114 : struct.authorizableSet)
+ for (TSentryAuthorizable _iter186 : struct.authorizableSet)
{
- _iter114.write(oprot);
+ _iter186.write(oprot);
}
}
BitSet optionals = new BitSet();
@@ -858,9 +858,9 @@
if (struct.isSetGroups()) {
{
oprot.writeI32(struct.groups.size());
- for (String _iter115 : struct.groups)
+ for (String _iter187 : struct.groups)
{
- oprot.writeString(_iter115);
+ oprot.writeString(_iter187);
}
}
}
@@ -877,27 +877,27 @@
struct.requestorUserName = iprot.readString();
struct.setRequestorUserNameIsSet(true);
{
- org.apache.thrift.protocol.TSet _set116 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.authorizableSet = new HashSet<TSentryAuthorizable>(2*_set116.size);
- for (int _i117 = 0; _i117 < _set116.size; ++_i117)
+ org.apache.thrift.protocol.TSet _set188 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.authorizableSet = new HashSet<TSentryAuthorizable>(2*_set188.size);
+ for (int _i189 = 0; _i189 < _set188.size; ++_i189)
{
- TSentryAuthorizable _elem118; // required
- _elem118 = new TSentryAuthorizable();
- _elem118.read(iprot);
- struct.authorizableSet.add(_elem118);
+ TSentryAuthorizable _elem190; // required
+ _elem190 = new TSentryAuthorizable();
+ _elem190.read(iprot);
+ struct.authorizableSet.add(_elem190);
}
}
struct.setAuthorizableSetIsSet(true);
BitSet incoming = iprot.readBitSet(2);
if (incoming.get(0)) {
{
- org.apache.thrift.protocol.TSet _set119 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
- struct.groups = new HashSet<String>(2*_set119.size);
- for (int _i120 = 0; _i120 < _set119.size; ++_i120)
+ org.apache.thrift.protocol.TSet _set191 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+ struct.groups = new HashSet<String>(2*_set191.size);
+ for (int _i192 = 0; _i192 < _set191.size; ++_i192)
{
- String _elem121; // required
- _elem121 = iprot.readString();
- struct.groups.add(_elem121);
+ String _elem193; // required
+ _elem193 = iprot.readString();
+ struct.groups.add(_elem193);
}
}
struct.setGroupsIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java
index 870f94b..1dda974 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java
@@ -449,17 +449,17 @@
case 2: // PRIVILEGES_MAP_BY_AUTH
if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
{
- org.apache.thrift.protocol.TMap _map122 = iprot.readMapBegin();
- struct.privilegesMapByAuth = new HashMap<TSentryAuthorizable,TSentryPrivilegeMap>(2*_map122.size);
- for (int _i123 = 0; _i123 < _map122.size; ++_i123)
+ org.apache.thrift.protocol.TMap _map194 = iprot.readMapBegin();
+ struct.privilegesMapByAuth = new HashMap<TSentryAuthorizable,TSentryPrivilegeMap>(2*_map194.size);
+ for (int _i195 = 0; _i195 < _map194.size; ++_i195)
{
- TSentryAuthorizable _key124; // required
- TSentryPrivilegeMap _val125; // required
- _key124 = new TSentryAuthorizable();
- _key124.read(iprot);
- _val125 = new TSentryPrivilegeMap();
- _val125.read(iprot);
- struct.privilegesMapByAuth.put(_key124, _val125);
+ TSentryAuthorizable _key196; // required
+ TSentryPrivilegeMap _val197; // required
+ _key196 = new TSentryAuthorizable();
+ _key196.read(iprot);
+ _val197 = new TSentryPrivilegeMap();
+ _val197.read(iprot);
+ struct.privilegesMapByAuth.put(_key196, _val197);
}
iprot.readMapEnd();
}
@@ -491,10 +491,10 @@
oprot.writeFieldBegin(PRIVILEGES_MAP_BY_AUTH_FIELD_DESC);
{
oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, org.apache.thrift.protocol.TType.STRUCT, struct.privilegesMapByAuth.size()));
- for (Map.Entry<TSentryAuthorizable, TSentryPrivilegeMap> _iter126 : struct.privilegesMapByAuth.entrySet())
+ for (Map.Entry<TSentryAuthorizable, TSentryPrivilegeMap> _iter198 : struct.privilegesMapByAuth.entrySet())
{
- _iter126.getKey().write(oprot);
- _iter126.getValue().write(oprot);
+ _iter198.getKey().write(oprot);
+ _iter198.getValue().write(oprot);
}
oprot.writeMapEnd();
}
@@ -527,10 +527,10 @@
if (struct.isSetPrivilegesMapByAuth()) {
{
oprot.writeI32(struct.privilegesMapByAuth.size());
- for (Map.Entry<TSentryAuthorizable, TSentryPrivilegeMap> _iter127 : struct.privilegesMapByAuth.entrySet())
+ for (Map.Entry<TSentryAuthorizable, TSentryPrivilegeMap> _iter199 : struct.privilegesMapByAuth.entrySet())
{
- _iter127.getKey().write(oprot);
- _iter127.getValue().write(oprot);
+ _iter199.getKey().write(oprot);
+ _iter199.getValue().write(oprot);
}
}
}
@@ -545,17 +545,17 @@
BitSet incoming = iprot.readBitSet(1);
if (incoming.get(0)) {
{
- org.apache.thrift.protocol.TMap _map128 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.privilegesMapByAuth = new HashMap<TSentryAuthorizable,TSentryPrivilegeMap>(2*_map128.size);
- for (int _i129 = 0; _i129 < _map128.size; ++_i129)
+ org.apache.thrift.protocol.TMap _map200 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.privilegesMapByAuth = new HashMap<TSentryAuthorizable,TSentryPrivilegeMap>(2*_map200.size);
+ for (int _i201 = 0; _i201 < _map200.size; ++_i201)
{
- TSentryAuthorizable _key130; // required
- TSentryPrivilegeMap _val131; // required
- _key130 = new TSentryAuthorizable();
- _key130.read(iprot);
- _val131 = new TSentryPrivilegeMap();
- _val131.read(iprot);
- struct.privilegesMapByAuth.put(_key130, _val131);
+ TSentryAuthorizable _key202; // required
+ TSentryPrivilegeMap _val203; // required
+ _key202 = new TSentryAuthorizable();
+ _key202.read(iprot);
+ _val203 = new TSentryPrivilegeMap();
+ _val203.read(iprot);
+ struct.privilegesMapByAuth.put(_key202, _val203);
}
}
struct.setPrivilegesMapByAuthIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesForProviderRequest.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesForProviderRequest.java
index 6ff6b48..f5cdcdb 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesForProviderRequest.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesForProviderRequest.java
@@ -618,13 +618,13 @@
case 2: // GROUPS
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set72 = iprot.readSetBegin();
- struct.groups = new HashSet<String>(2*_set72.size);
- for (int _i73 = 0; _i73 < _set72.size; ++_i73)
+ org.apache.thrift.protocol.TSet _set144 = iprot.readSetBegin();
+ struct.groups = new HashSet<String>(2*_set144.size);
+ for (int _i145 = 0; _i145 < _set144.size; ++_i145)
{
- String _elem74; // required
- _elem74 = iprot.readString();
- struct.groups.add(_elem74);
+ String _elem146; // required
+ _elem146 = iprot.readString();
+ struct.groups.add(_elem146);
}
iprot.readSetEnd();
}
@@ -671,9 +671,9 @@
oprot.writeFieldBegin(GROUPS_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.groups.size()));
- for (String _iter75 : struct.groups)
+ for (String _iter147 : struct.groups)
{
- oprot.writeString(_iter75);
+ oprot.writeString(_iter147);
}
oprot.writeSetEnd();
}
@@ -711,9 +711,9 @@
oprot.writeI32(struct.protocol_version);
{
oprot.writeI32(struct.groups.size());
- for (String _iter76 : struct.groups)
+ for (String _iter148 : struct.groups)
{
- oprot.writeString(_iter76);
+ oprot.writeString(_iter148);
}
}
struct.roleSet.write(oprot);
@@ -733,13 +733,13 @@
struct.protocol_version = iprot.readI32();
struct.setProtocol_versionIsSet(true);
{
- org.apache.thrift.protocol.TSet _set77 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
- struct.groups = new HashSet<String>(2*_set77.size);
- for (int _i78 = 0; _i78 < _set77.size; ++_i78)
+ org.apache.thrift.protocol.TSet _set149 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+ struct.groups = new HashSet<String>(2*_set149.size);
+ for (int _i150 = 0; _i150 < _set149.size; ++_i150)
{
- String _elem79; // required
- _elem79 = iprot.readString();
- struct.groups.add(_elem79);
+ String _elem151; // required
+ _elem151 = iprot.readString();
+ struct.groups.add(_elem151);
}
}
struct.setGroupsIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesForProviderResponse.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesForProviderResponse.java
index b900dec..e07a9f4 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesForProviderResponse.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesForProviderResponse.java
@@ -447,13 +447,13 @@
case 2: // PRIVILEGES
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set80 = iprot.readSetBegin();
- struct.privileges = new HashSet<String>(2*_set80.size);
- for (int _i81 = 0; _i81 < _set80.size; ++_i81)
+ org.apache.thrift.protocol.TSet _set152 = iprot.readSetBegin();
+ struct.privileges = new HashSet<String>(2*_set152.size);
+ for (int _i153 = 0; _i153 < _set152.size; ++_i153)
{
- String _elem82; // required
- _elem82 = iprot.readString();
- struct.privileges.add(_elem82);
+ String _elem154; // required
+ _elem154 = iprot.readString();
+ struct.privileges.add(_elem154);
}
iprot.readSetEnd();
}
@@ -484,9 +484,9 @@
oprot.writeFieldBegin(PRIVILEGES_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.privileges.size()));
- for (String _iter83 : struct.privileges)
+ for (String _iter155 : struct.privileges)
{
- oprot.writeString(_iter83);
+ oprot.writeString(_iter155);
}
oprot.writeSetEnd();
}
@@ -512,9 +512,9 @@
struct.status.write(oprot);
{
oprot.writeI32(struct.privileges.size());
- for (String _iter84 : struct.privileges)
+ for (String _iter156 : struct.privileges)
{
- oprot.writeString(_iter84);
+ oprot.writeString(_iter156);
}
}
}
@@ -526,13 +526,13 @@
struct.status.read(iprot);
struct.setStatusIsSet(true);
{
- org.apache.thrift.protocol.TSet _set85 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
- struct.privileges = new HashSet<String>(2*_set85.size);
- for (int _i86 = 0; _i86 < _set85.size; ++_i86)
+ org.apache.thrift.protocol.TSet _set157 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+ struct.privileges = new HashSet<String>(2*_set157.size);
+ for (int _i158 = 0; _i158 < _set157.size; ++_i158)
{
- String _elem87; // required
- _elem87 = iprot.readString();
- struct.privileges.add(_elem87);
+ String _elem159; // required
+ _elem159 = iprot.readString();
+ struct.privileges.add(_elem159);
}
}
struct.setPrivilegesIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesResponse.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesResponse.java
index 7540519..87b1a8b 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesResponse.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesResponse.java
@@ -444,14 +444,14 @@
case 2: // PRIVILEGES
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set56 = iprot.readSetBegin();
- struct.privileges = new HashSet<TSentryPrivilege>(2*_set56.size);
- for (int _i57 = 0; _i57 < _set56.size; ++_i57)
+ org.apache.thrift.protocol.TSet _set128 = iprot.readSetBegin();
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set128.size);
+ for (int _i129 = 0; _i129 < _set128.size; ++_i129)
{
- TSentryPrivilege _elem58; // required
- _elem58 = new TSentryPrivilege();
- _elem58.read(iprot);
- struct.privileges.add(_elem58);
+ TSentryPrivilege _elem130; // required
+ _elem130 = new TSentryPrivilege();
+ _elem130.read(iprot);
+ struct.privileges.add(_elem130);
}
iprot.readSetEnd();
}
@@ -483,9 +483,9 @@
oprot.writeFieldBegin(PRIVILEGES_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.privileges.size()));
- for (TSentryPrivilege _iter59 : struct.privileges)
+ for (TSentryPrivilege _iter131 : struct.privileges)
{
- _iter59.write(oprot);
+ _iter131.write(oprot);
}
oprot.writeSetEnd();
}
@@ -518,9 +518,9 @@
if (struct.isSetPrivileges()) {
{
oprot.writeI32(struct.privileges.size());
- for (TSentryPrivilege _iter60 : struct.privileges)
+ for (TSentryPrivilege _iter132 : struct.privileges)
{
- _iter60.write(oprot);
+ _iter132.write(oprot);
}
}
}
@@ -535,14 +535,14 @@
BitSet incoming = iprot.readBitSet(1);
if (incoming.get(0)) {
{
- org.apache.thrift.protocol.TSet _set61 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.privileges = new HashSet<TSentryPrivilege>(2*_set61.size);
- for (int _i62 = 0; _i62 < _set61.size; ++_i62)
+ org.apache.thrift.protocol.TSet _set133 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set133.size);
+ for (int _i134 = 0; _i134 < _set133.size; ++_i134)
{
- TSentryPrivilege _elem63; // required
- _elem63 = new TSentryPrivilege();
- _elem63.read(iprot);
- struct.privileges.add(_elem63);
+ TSentryPrivilege _elem135; // required
+ _elem135 = new TSentryPrivilege();
+ _elem135.read(iprot);
+ struct.privileges.add(_elem135);
}
}
struct.setPrivilegesIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryRolesResponse.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryRolesResponse.java
index 2439645..c219274 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryRolesResponse.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryRolesResponse.java
@@ -444,14 +444,14 @@
case 2: // ROLES
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set48 = iprot.readSetBegin();
- struct.roles = new HashSet<TSentryRole>(2*_set48.size);
- for (int _i49 = 0; _i49 < _set48.size; ++_i49)
+ org.apache.thrift.protocol.TSet _set120 = iprot.readSetBegin();
+ struct.roles = new HashSet<TSentryRole>(2*_set120.size);
+ for (int _i121 = 0; _i121 < _set120.size; ++_i121)
{
- TSentryRole _elem50; // required
- _elem50 = new TSentryRole();
- _elem50.read(iprot);
- struct.roles.add(_elem50);
+ TSentryRole _elem122; // required
+ _elem122 = new TSentryRole();
+ _elem122.read(iprot);
+ struct.roles.add(_elem122);
}
iprot.readSetEnd();
}
@@ -483,9 +483,9 @@
oprot.writeFieldBegin(ROLES_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.roles.size()));
- for (TSentryRole _iter51 : struct.roles)
+ for (TSentryRole _iter123 : struct.roles)
{
- _iter51.write(oprot);
+ _iter123.write(oprot);
}
oprot.writeSetEnd();
}
@@ -518,9 +518,9 @@
if (struct.isSetRoles()) {
{
oprot.writeI32(struct.roles.size());
- for (TSentryRole _iter52 : struct.roles)
+ for (TSentryRole _iter124 : struct.roles)
{
- _iter52.write(oprot);
+ _iter124.write(oprot);
}
}
}
@@ -535,14 +535,14 @@
BitSet incoming = iprot.readBitSet(1);
if (incoming.get(0)) {
{
- org.apache.thrift.protocol.TSet _set53 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.roles = new HashSet<TSentryRole>(2*_set53.size);
- for (int _i54 = 0; _i54 < _set53.size; ++_i54)
+ org.apache.thrift.protocol.TSet _set125 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.roles = new HashSet<TSentryRole>(2*_set125.size);
+ for (int _i126 = 0; _i126 < _set125.size; ++_i126)
{
- TSentryRole _elem55; // required
- _elem55 = new TSentryRole();
- _elem55.read(iprot);
- struct.roles.add(_elem55);
+ TSentryRole _elem127; // required
+ _elem127 = new TSentryRole();
+ _elem127.read(iprot);
+ struct.roles.add(_elem127);
}
}
struct.setRolesIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryActiveRoleSet.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryActiveRoleSet.java
index 10b421d..1c290ca 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryActiveRoleSet.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryActiveRoleSet.java
@@ -443,13 +443,13 @@
case 2: // ROLES
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set64 = iprot.readSetBegin();
- struct.roles = new HashSet<String>(2*_set64.size);
- for (int _i65 = 0; _i65 < _set64.size; ++_i65)
+ org.apache.thrift.protocol.TSet _set136 = iprot.readSetBegin();
+ struct.roles = new HashSet<String>(2*_set136.size);
+ for (int _i137 = 0; _i137 < _set136.size; ++_i137)
{
- String _elem66; // required
- _elem66 = iprot.readString();
- struct.roles.add(_elem66);
+ String _elem138; // required
+ _elem138 = iprot.readString();
+ struct.roles.add(_elem138);
}
iprot.readSetEnd();
}
@@ -478,9 +478,9 @@
oprot.writeFieldBegin(ROLES_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.roles.size()));
- for (String _iter67 : struct.roles)
+ for (String _iter139 : struct.roles)
{
- oprot.writeString(_iter67);
+ oprot.writeString(_iter139);
}
oprot.writeSetEnd();
}
@@ -506,9 +506,9 @@
oprot.writeBool(struct.all);
{
oprot.writeI32(struct.roles.size());
- for (String _iter68 : struct.roles)
+ for (String _iter140 : struct.roles)
{
- oprot.writeString(_iter68);
+ oprot.writeString(_iter140);
}
}
}
@@ -519,13 +519,13 @@
struct.all = iprot.readBool();
struct.setAllIsSet(true);
{
- org.apache.thrift.protocol.TSet _set69 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
- struct.roles = new HashSet<String>(2*_set69.size);
- for (int _i70 = 0; _i70 < _set69.size; ++_i70)
+ org.apache.thrift.protocol.TSet _set141 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+ struct.roles = new HashSet<String>(2*_set141.size);
+ for (int _i142 = 0; _i142 < _set141.size; ++_i142)
{
- String _elem71; // required
- _elem71 = iprot.readString();
- struct.roles.add(_elem71);
+ String _elem143; // required
+ _elem143 = iprot.readString();
+ struct.roles.add(_elem143);
}
}
struct.setRolesIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryPrivilegeMap.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryPrivilegeMap.java
index e7beee1..2282621 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryPrivilegeMap.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryPrivilegeMap.java
@@ -359,26 +359,26 @@
case 1: // PRIVILEGE_MAP
if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
{
- org.apache.thrift.protocol.TMap _map88 = iprot.readMapBegin();
- struct.privilegeMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map88.size);
- for (int _i89 = 0; _i89 < _map88.size; ++_i89)
+ org.apache.thrift.protocol.TMap _map160 = iprot.readMapBegin();
+ struct.privilegeMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map160.size);
+ for (int _i161 = 0; _i161 < _map160.size; ++_i161)
{
- String _key90; // required
- Set<TSentryPrivilege> _val91; // required
- _key90 = iprot.readString();
+ String _key162; // required
+ Set<TSentryPrivilege> _val163; // required
+ _key162 = iprot.readString();
{
- org.apache.thrift.protocol.TSet _set92 = iprot.readSetBegin();
- _val91 = new HashSet<TSentryPrivilege>(2*_set92.size);
- for (int _i93 = 0; _i93 < _set92.size; ++_i93)
+ org.apache.thrift.protocol.TSet _set164 = iprot.readSetBegin();
+ _val163 = new HashSet<TSentryPrivilege>(2*_set164.size);
+ for (int _i165 = 0; _i165 < _set164.size; ++_i165)
{
- TSentryPrivilege _elem94; // required
- _elem94 = new TSentryPrivilege();
- _elem94.read(iprot);
- _val91.add(_elem94);
+ TSentryPrivilege _elem166; // required
+ _elem166 = new TSentryPrivilege();
+ _elem166.read(iprot);
+ _val163.add(_elem166);
}
iprot.readSetEnd();
}
- struct.privilegeMap.put(_key90, _val91);
+ struct.privilegeMap.put(_key162, _val163);
}
iprot.readMapEnd();
}
@@ -404,14 +404,14 @@
oprot.writeFieldBegin(PRIVILEGE_MAP_FIELD_DESC);
{
oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.privilegeMap.size()));
- for (Map.Entry<String, Set<TSentryPrivilege>> _iter95 : struct.privilegeMap.entrySet())
+ for (Map.Entry<String, Set<TSentryPrivilege>> _iter167 : struct.privilegeMap.entrySet())
{
- oprot.writeString(_iter95.getKey());
+ oprot.writeString(_iter167.getKey());
{
- oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, _iter95.getValue().size()));
- for (TSentryPrivilege _iter96 : _iter95.getValue())
+ oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, _iter167.getValue().size()));
+ for (TSentryPrivilege _iter168 : _iter167.getValue())
{
- _iter96.write(oprot);
+ _iter168.write(oprot);
}
oprot.writeSetEnd();
}
@@ -439,14 +439,14 @@
TTupleProtocol oprot = (TTupleProtocol) prot;
{
oprot.writeI32(struct.privilegeMap.size());
- for (Map.Entry<String, Set<TSentryPrivilege>> _iter97 : struct.privilegeMap.entrySet())
+ for (Map.Entry<String, Set<TSentryPrivilege>> _iter169 : struct.privilegeMap.entrySet())
{
- oprot.writeString(_iter97.getKey());
+ oprot.writeString(_iter169.getKey());
{
- oprot.writeI32(_iter97.getValue().size());
- for (TSentryPrivilege _iter98 : _iter97.getValue())
+ oprot.writeI32(_iter169.getValue().size());
+ for (TSentryPrivilege _iter170 : _iter169.getValue())
{
- _iter98.write(oprot);
+ _iter170.write(oprot);
}
}
}
@@ -457,25 +457,25 @@
public void read(org.apache.thrift.protocol.TProtocol prot, TSentryPrivilegeMap struct) throws org.apache.thrift.TException {
TTupleProtocol iprot = (TTupleProtocol) prot;
{
- org.apache.thrift.protocol.TMap _map99 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32());
- struct.privilegeMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map99.size);
- for (int _i100 = 0; _i100 < _map99.size; ++_i100)
+ org.apache.thrift.protocol.TMap _map171 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32());
+ struct.privilegeMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map171.size);
+ for (int _i172 = 0; _i172 < _map171.size; ++_i172)
{
- String _key101; // required
- Set<TSentryPrivilege> _val102; // required
- _key101 = iprot.readString();
+ String _key173; // required
+ Set<TSentryPrivilege> _val174; // required
+ _key173 = iprot.readString();
{
- org.apache.thrift.protocol.TSet _set103 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- _val102 = new HashSet<TSentryPrivilege>(2*_set103.size);
- for (int _i104 = 0; _i104 < _set103.size; ++_i104)
+ org.apache.thrift.protocol.TSet _set175 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ _val174 = new HashSet<TSentryPrivilege>(2*_set175.size);
+ for (int _i176 = 0; _i176 < _set175.size; ++_i176)
{
- TSentryPrivilege _elem105; // required
- _elem105 = new TSentryPrivilege();
- _elem105.read(iprot);
- _val102.add(_elem105);
+ TSentryPrivilege _elem177; // required
+ _elem177 = new TSentryPrivilege();
+ _elem177.read(iprot);
+ _val174.add(_elem177);
}
}
- struct.privilegeMap.put(_key101, _val102);
+ struct.privilegeMap.put(_key173, _val174);
}
}
struct.setPrivilegeMapIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryRole.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryRole.java
index 7645e25..bf4d4f0 100644
--- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryRole.java
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryRole.java
@@ -528,14 +528,14 @@
case 2: // GROUPS
if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
{
- org.apache.thrift.protocol.TSet _set40 = iprot.readSetBegin();
- struct.groups = new HashSet<TSentryGroup>(2*_set40.size);
- for (int _i41 = 0; _i41 < _set40.size; ++_i41)
+ org.apache.thrift.protocol.TSet _set112 = iprot.readSetBegin();
+ struct.groups = new HashSet<TSentryGroup>(2*_set112.size);
+ for (int _i113 = 0; _i113 < _set112.size; ++_i113)
{
- TSentryGroup _elem42; // required
- _elem42 = new TSentryGroup();
- _elem42.read(iprot);
- struct.groups.add(_elem42);
+ TSentryGroup _elem114; // required
+ _elem114 = new TSentryGroup();
+ _elem114.read(iprot);
+ struct.groups.add(_elem114);
}
iprot.readSetEnd();
}
@@ -574,9 +574,9 @@
oprot.writeFieldBegin(GROUPS_FIELD_DESC);
{
oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.groups.size()));
- for (TSentryGroup _iter43 : struct.groups)
+ for (TSentryGroup _iter115 : struct.groups)
{
- _iter43.write(oprot);
+ _iter115.write(oprot);
}
oprot.writeSetEnd();
}
@@ -607,9 +607,9 @@
oprot.writeString(struct.roleName);
{
oprot.writeI32(struct.groups.size());
- for (TSentryGroup _iter44 : struct.groups)
+ for (TSentryGroup _iter116 : struct.groups)
{
- _iter44.write(oprot);
+ _iter116.write(oprot);
}
}
oprot.writeString(struct.grantorPrincipal);
@@ -621,14 +621,14 @@
struct.roleName = iprot.readString();
struct.setRoleNameIsSet(true);
{
- org.apache.thrift.protocol.TSet _set45 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
- struct.groups = new HashSet<TSentryGroup>(2*_set45.size);
- for (int _i46 = 0; _i46 < _set45.size; ++_i46)
+ org.apache.thrift.protocol.TSet _set117 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.groups = new HashSet<TSentryGroup>(2*_set117.size);
+ for (int _i118 = 0; _i118 < _set117.size; ++_i118)
{
- TSentryGroup _elem47; // required
- _elem47 = new TSentryGroup();
- _elem47.read(iprot);
- struct.groups.add(_elem47);
+ TSentryGroup _elem119; // required
+ _elem119 = new TSentryGroup();
+ _elem119.read(iprot);
+ struct.groups.add(_elem119);
}
}
struct.setGroupsIsSet(true);
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryStoreOp.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryStoreOp.java
new file mode 100644
index 0000000..251f215
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryStoreOp.java
@@ -0,0 +1,72 @@
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package org.apache.sentry.provider.db.service.thrift;
+
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.thrift.TEnum;
+
+public enum TSentryStoreOp implements org.apache.thrift.TEnum {
+ CREATE_ROLE(0),
+ DROP_ROLE(1),
+ GRANT_PRIVILEGES(2),
+ REVOKE_PRVILEGES(3),
+ ADD_GROUPS(4),
+ DEL_GROUPS(5),
+ SET_VERSION(6),
+ DROP_PRIVILEGE(7),
+ RENAME_PRIVILEGE(8),
+ SNAPSHOT(9),
+ NO_OP(100);
+
+ private final int value;
+
+ private TSentryStoreOp(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the integer value of this enum value, as defined in the Thrift IDL.
+ */
+ public int getValue() {
+ return value;
+ }
+
+ /**
+ * Find a the enum type by its integer value, as defined in the Thrift IDL.
+ * @return null if the value is not found.
+ */
+ public static TSentryStoreOp findByValue(int value) {
+ switch (value) {
+ case 0:
+ return CREATE_ROLE;
+ case 1:
+ return DROP_ROLE;
+ case 2:
+ return GRANT_PRIVILEGES;
+ case 3:
+ return REVOKE_PRVILEGES;
+ case 4:
+ return ADD_GROUPS;
+ case 5:
+ return DEL_GROUPS;
+ case 6:
+ return SET_VERSION;
+ case 7:
+ return DROP_PRIVILEGE;
+ case 8:
+ return RENAME_PRIVILEGE;
+ case 9:
+ return SNAPSHOT;
+ case 100:
+ return NO_OP;
+ default:
+ return null;
+ }
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryStoreRecord.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryStoreRecord.java
new file mode 100644
index 0000000..c3b73c5
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TSentryStoreRecord.java
@@ -0,0 +1,1476 @@
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package org.apache.sentry.provider.db.service.thrift;
+
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TSentryStoreRecord implements org.apache.thrift.TBase<TSentryStoreRecord, TSentryStoreRecord._Fields>, java.io.Serializable, Cloneable {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSentryStoreRecord");
+
+ private static final org.apache.thrift.protocol.TField STORE_OP_FIELD_DESC = new org.apache.thrift.protocol.TField("storeOp", org.apache.thrift.protocol.TType.I32, (short)1);
+ private static final org.apache.thrift.protocol.TField ROLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("roleName", org.apache.thrift.protocol.TType.STRING, (short)2);
+ private static final org.apache.thrift.protocol.TField GRANTOR_PRINCIPAL_FIELD_DESC = new org.apache.thrift.protocol.TField("grantorPrincipal", org.apache.thrift.protocol.TType.STRING, (short)3);
+ private static final org.apache.thrift.protocol.TField PRIVILEGES_FIELD_DESC = new org.apache.thrift.protocol.TField("privileges", org.apache.thrift.protocol.TType.SET, (short)4);
+ private static final org.apache.thrift.protocol.TField GROUPS_FIELD_DESC = new org.apache.thrift.protocol.TField("groups", org.apache.thrift.protocol.TType.SET, (short)5);
+ private static final org.apache.thrift.protocol.TField AUTHORIZABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizable", org.apache.thrift.protocol.TType.STRUCT, (short)6);
+ private static final org.apache.thrift.protocol.TField NEW_AUTHORIZABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("newAuthorizable", org.apache.thrift.protocol.TType.STRUCT, (short)7);
+ private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.STRING, (short)8);
+ private static final org.apache.thrift.protocol.TField VERSION_COMMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("versionComment", org.apache.thrift.protocol.TType.STRING, (short)9);
+ private static final org.apache.thrift.protocol.TField SNAPSHOT_FIELD_DESC = new org.apache.thrift.protocol.TField("snapshot", org.apache.thrift.protocol.TType.STRUCT, (short)10);
+
+ private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+ static {
+ schemes.put(StandardScheme.class, new TSentryStoreRecordStandardSchemeFactory());
+ schemes.put(TupleScheme.class, new TSentryStoreRecordTupleSchemeFactory());
+ }
+
+ private TSentryStoreOp storeOp; // required
+ private String roleName; // optional
+ private String grantorPrincipal; // optional
+ private Set<TSentryPrivilege> privileges; // optional
+ private Set<String> groups; // optional
+ private TSentryAuthorizable authorizable; // optional
+ private TSentryAuthorizable newAuthorizable; // optional
+ private String version; // optional
+ private String versionComment; // optional
+ private TStoreSnapshot snapshot; // optional
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ /**
+ *
+ * @see TSentryStoreOp
+ */
+ STORE_OP((short)1, "storeOp"),
+ ROLE_NAME((short)2, "roleName"),
+ GRANTOR_PRINCIPAL((short)3, "grantorPrincipal"),
+ PRIVILEGES((short)4, "privileges"),
+ GROUPS((short)5, "groups"),
+ AUTHORIZABLE((short)6, "authorizable"),
+ NEW_AUTHORIZABLE((short)7, "newAuthorizable"),
+ VERSION((short)8, "version"),
+ VERSION_COMMENT((short)9, "versionComment"),
+ SNAPSHOT((short)10, "snapshot");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // STORE_OP
+ return STORE_OP;
+ case 2: // ROLE_NAME
+ return ROLE_NAME;
+ case 3: // GRANTOR_PRINCIPAL
+ return GRANTOR_PRINCIPAL;
+ case 4: // PRIVILEGES
+ return PRIVILEGES;
+ case 5: // GROUPS
+ return GROUPS;
+ case 6: // AUTHORIZABLE
+ return AUTHORIZABLE;
+ case 7: // NEW_AUTHORIZABLE
+ return NEW_AUTHORIZABLE;
+ case 8: // VERSION
+ return VERSION;
+ case 9: // VERSION_COMMENT
+ return VERSION_COMMENT;
+ case 10: // SNAPSHOT
+ return SNAPSHOT;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ private _Fields optionals[] = {_Fields.ROLE_NAME,_Fields.GRANTOR_PRINCIPAL,_Fields.PRIVILEGES,_Fields.GROUPS,_Fields.AUTHORIZABLE,_Fields.NEW_AUTHORIZABLE,_Fields.VERSION,_Fields.VERSION_COMMENT,_Fields.SNAPSHOT};
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.STORE_OP, new org.apache.thrift.meta_data.FieldMetaData("storeOp", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TSentryStoreOp.class)));
+ tmpMap.put(_Fields.ROLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("roleName", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.GRANTOR_PRINCIPAL, new org.apache.thrift.meta_data.FieldMetaData("grantorPrincipal", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.PRIVILEGES, new org.apache.thrift.meta_data.FieldMetaData("privileges", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET,
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSentryPrivilege.class))));
+ tmpMap.put(_Fields.GROUPS, new org.apache.thrift.meta_data.FieldMetaData("groups", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
+ tmpMap.put(_Fields.AUTHORIZABLE, new org.apache.thrift.meta_data.FieldMetaData("authorizable", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSentryAuthorizable.class)));
+ tmpMap.put(_Fields.NEW_AUTHORIZABLE, new org.apache.thrift.meta_data.FieldMetaData("newAuthorizable", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSentryAuthorizable.class)));
+ tmpMap.put(_Fields.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.VERSION_COMMENT, new org.apache.thrift.meta_data.FieldMetaData("versionComment", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.SNAPSHOT, new org.apache.thrift.meta_data.FieldMetaData("snapshot", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TStoreSnapshot.class)));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSentryStoreRecord.class, metaDataMap);
+ }
+
+ public TSentryStoreRecord() {
+ }
+
+ public TSentryStoreRecord(
+ TSentryStoreOp storeOp)
+ {
+ this();
+ this.storeOp = storeOp;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public TSentryStoreRecord(TSentryStoreRecord other) {
+ if (other.isSetStoreOp()) {
+ this.storeOp = other.storeOp;
+ }
+ if (other.isSetRoleName()) {
+ this.roleName = other.roleName;
+ }
+ if (other.isSetGrantorPrincipal()) {
+ this.grantorPrincipal = other.grantorPrincipal;
+ }
+ if (other.isSetPrivileges()) {
+ Set<TSentryPrivilege> __this__privileges = new HashSet<TSentryPrivilege>();
+ for (TSentryPrivilege other_element : other.privileges) {
+ __this__privileges.add(new TSentryPrivilege(other_element));
+ }
+ this.privileges = __this__privileges;
+ }
+ if (other.isSetGroups()) {
+ Set<String> __this__groups = new HashSet<String>();
+ for (String other_element : other.groups) {
+ __this__groups.add(other_element);
+ }
+ this.groups = __this__groups;
+ }
+ if (other.isSetAuthorizable()) {
+ this.authorizable = new TSentryAuthorizable(other.authorizable);
+ }
+ if (other.isSetNewAuthorizable()) {
+ this.newAuthorizable = new TSentryAuthorizable(other.newAuthorizable);
+ }
+ if (other.isSetVersion()) {
+ this.version = other.version;
+ }
+ if (other.isSetVersionComment()) {
+ this.versionComment = other.versionComment;
+ }
+ if (other.isSetSnapshot()) {
+ this.snapshot = new TStoreSnapshot(other.snapshot);
+ }
+ }
+
+ public TSentryStoreRecord deepCopy() {
+ return new TSentryStoreRecord(this);
+ }
+
+ @Override
+ public void clear() {
+ this.storeOp = null;
+ this.roleName = null;
+ this.grantorPrincipal = null;
+ this.privileges = null;
+ this.groups = null;
+ this.authorizable = null;
+ this.newAuthorizable = null;
+ this.version = null;
+ this.versionComment = null;
+ this.snapshot = null;
+ }
+
+ /**
+ *
+ * @see TSentryStoreOp
+ */
+ public TSentryStoreOp getStoreOp() {
+ return this.storeOp;
+ }
+
+ /**
+ *
+ * @see TSentryStoreOp
+ */
+ public void setStoreOp(TSentryStoreOp storeOp) {
+ this.storeOp = storeOp;
+ }
+
+ public void unsetStoreOp() {
+ this.storeOp = null;
+ }
+
+ /** Returns true if field storeOp is set (has been assigned a value) and false otherwise */
+ public boolean isSetStoreOp() {
+ return this.storeOp != null;
+ }
+
+ public void setStoreOpIsSet(boolean value) {
+ if (!value) {
+ this.storeOp = null;
+ }
+ }
+
+ public String getRoleName() {
+ return this.roleName;
+ }
+
+ public void setRoleName(String roleName) {
+ this.roleName = roleName;
+ }
+
+ public void unsetRoleName() {
+ this.roleName = null;
+ }
+
+ /** Returns true if field roleName is set (has been assigned a value) and false otherwise */
+ public boolean isSetRoleName() {
+ return this.roleName != null;
+ }
+
+ public void setRoleNameIsSet(boolean value) {
+ if (!value) {
+ this.roleName = null;
+ }
+ }
+
+ public String getGrantorPrincipal() {
+ return this.grantorPrincipal;
+ }
+
+ public void setGrantorPrincipal(String grantorPrincipal) {
+ this.grantorPrincipal = grantorPrincipal;
+ }
+
+ public void unsetGrantorPrincipal() {
+ this.grantorPrincipal = null;
+ }
+
+ /** Returns true if field grantorPrincipal is set (has been assigned a value) and false otherwise */
+ public boolean isSetGrantorPrincipal() {
+ return this.grantorPrincipal != null;
+ }
+
+ public void setGrantorPrincipalIsSet(boolean value) {
+ if (!value) {
+ this.grantorPrincipal = null;
+ }
+ }
+
+ public int getPrivilegesSize() {
+ return (this.privileges == null) ? 0 : this.privileges.size();
+ }
+
+ public java.util.Iterator<TSentryPrivilege> getPrivilegesIterator() {
+ return (this.privileges == null) ? null : this.privileges.iterator();
+ }
+
+ public void addToPrivileges(TSentryPrivilege elem) {
+ if (this.privileges == null) {
+ this.privileges = new HashSet<TSentryPrivilege>();
+ }
+ this.privileges.add(elem);
+ }
+
+ public Set<TSentryPrivilege> getPrivileges() {
+ return this.privileges;
+ }
+
+ public void setPrivileges(Set<TSentryPrivilege> privileges) {
+ this.privileges = privileges;
+ }
+
+ public void unsetPrivileges() {
+ this.privileges = null;
+ }
+
+ /** Returns true if field privileges is set (has been assigned a value) and false otherwise */
+ public boolean isSetPrivileges() {
+ return this.privileges != null;
+ }
+
+ public void setPrivilegesIsSet(boolean value) {
+ if (!value) {
+ this.privileges = null;
+ }
+ }
+
+ public int getGroupsSize() {
+ return (this.groups == null) ? 0 : this.groups.size();
+ }
+
+ public java.util.Iterator<String> getGroupsIterator() {
+ return (this.groups == null) ? null : this.groups.iterator();
+ }
+
+ public void addToGroups(String elem) {
+ if (this.groups == null) {
+ this.groups = new HashSet<String>();
+ }
+ this.groups.add(elem);
+ }
+
+ public Set<String> getGroups() {
+ return this.groups;
+ }
+
+ public void setGroups(Set<String> groups) {
+ this.groups = groups;
+ }
+
+ public void unsetGroups() {
+ this.groups = null;
+ }
+
+ /** Returns true if field groups is set (has been assigned a value) and false otherwise */
+ public boolean isSetGroups() {
+ return this.groups != null;
+ }
+
+ public void setGroupsIsSet(boolean value) {
+ if (!value) {
+ this.groups = null;
+ }
+ }
+
+ public TSentryAuthorizable getAuthorizable() {
+ return this.authorizable;
+ }
+
+ public void setAuthorizable(TSentryAuthorizable authorizable) {
+ this.authorizable = authorizable;
+ }
+
+ public void unsetAuthorizable() {
+ this.authorizable = null;
+ }
+
+ /** Returns true if field authorizable is set (has been assigned a value) and false otherwise */
+ public boolean isSetAuthorizable() {
+ return this.authorizable != null;
+ }
+
+ public void setAuthorizableIsSet(boolean value) {
+ if (!value) {
+ this.authorizable = null;
+ }
+ }
+
+ public TSentryAuthorizable getNewAuthorizable() {
+ return this.newAuthorizable;
+ }
+
+ public void setNewAuthorizable(TSentryAuthorizable newAuthorizable) {
+ this.newAuthorizable = newAuthorizable;
+ }
+
+ public void unsetNewAuthorizable() {
+ this.newAuthorizable = null;
+ }
+
+ /** Returns true if field newAuthorizable is set (has been assigned a value) and false otherwise */
+ public boolean isSetNewAuthorizable() {
+ return this.newAuthorizable != null;
+ }
+
+ public void setNewAuthorizableIsSet(boolean value) {
+ if (!value) {
+ this.newAuthorizable = null;
+ }
+ }
+
+ public String getVersion() {
+ return this.version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public void unsetVersion() {
+ this.version = null;
+ }
+
+ /** Returns true if field version is set (has been assigned a value) and false otherwise */
+ public boolean isSetVersion() {
+ return this.version != null;
+ }
+
+ public void setVersionIsSet(boolean value) {
+ if (!value) {
+ this.version = null;
+ }
+ }
+
+ public String getVersionComment() {
+ return this.versionComment;
+ }
+
+ public void setVersionComment(String versionComment) {
+ this.versionComment = versionComment;
+ }
+
+ public void unsetVersionComment() {
+ this.versionComment = null;
+ }
+
+ /** Returns true if field versionComment is set (has been assigned a value) and false otherwise */
+ public boolean isSetVersionComment() {
+ return this.versionComment != null;
+ }
+
+ public void setVersionCommentIsSet(boolean value) {
+ if (!value) {
+ this.versionComment = null;
+ }
+ }
+
+ public TStoreSnapshot getSnapshot() {
+ return this.snapshot;
+ }
+
+ public void setSnapshot(TStoreSnapshot snapshot) {
+ this.snapshot = snapshot;
+ }
+
+ public void unsetSnapshot() {
+ this.snapshot = null;
+ }
+
+ /** Returns true if field snapshot is set (has been assigned a value) and false otherwise */
+ public boolean isSetSnapshot() {
+ return this.snapshot != null;
+ }
+
+ public void setSnapshotIsSet(boolean value) {
+ if (!value) {
+ this.snapshot = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case STORE_OP:
+ if (value == null) {
+ unsetStoreOp();
+ } else {
+ setStoreOp((TSentryStoreOp)value);
+ }
+ break;
+
+ case ROLE_NAME:
+ if (value == null) {
+ unsetRoleName();
+ } else {
+ setRoleName((String)value);
+ }
+ break;
+
+ case GRANTOR_PRINCIPAL:
+ if (value == null) {
+ unsetGrantorPrincipal();
+ } else {
+ setGrantorPrincipal((String)value);
+ }
+ break;
+
+ case PRIVILEGES:
+ if (value == null) {
+ unsetPrivileges();
+ } else {
+ setPrivileges((Set<TSentryPrivilege>)value);
+ }
+ break;
+
+ case GROUPS:
+ if (value == null) {
+ unsetGroups();
+ } else {
+ setGroups((Set<String>)value);
+ }
+ break;
+
+ case AUTHORIZABLE:
+ if (value == null) {
+ unsetAuthorizable();
+ } else {
+ setAuthorizable((TSentryAuthorizable)value);
+ }
+ break;
+
+ case NEW_AUTHORIZABLE:
+ if (value == null) {
+ unsetNewAuthorizable();
+ } else {
+ setNewAuthorizable((TSentryAuthorizable)value);
+ }
+ break;
+
+ case VERSION:
+ if (value == null) {
+ unsetVersion();
+ } else {
+ setVersion((String)value);
+ }
+ break;
+
+ case VERSION_COMMENT:
+ if (value == null) {
+ unsetVersionComment();
+ } else {
+ setVersionComment((String)value);
+ }
+ break;
+
+ case SNAPSHOT:
+ if (value == null) {
+ unsetSnapshot();
+ } else {
+ setSnapshot((TStoreSnapshot)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case STORE_OP:
+ return getStoreOp();
+
+ case ROLE_NAME:
+ return getRoleName();
+
+ case GRANTOR_PRINCIPAL:
+ return getGrantorPrincipal();
+
+ case PRIVILEGES:
+ return getPrivileges();
+
+ case GROUPS:
+ return getGroups();
+
+ case AUTHORIZABLE:
+ return getAuthorizable();
+
+ case NEW_AUTHORIZABLE:
+ return getNewAuthorizable();
+
+ case VERSION:
+ return getVersion();
+
+ case VERSION_COMMENT:
+ return getVersionComment();
+
+ case SNAPSHOT:
+ return getSnapshot();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case STORE_OP:
+ return isSetStoreOp();
+ case ROLE_NAME:
+ return isSetRoleName();
+ case GRANTOR_PRINCIPAL:
+ return isSetGrantorPrincipal();
+ case PRIVILEGES:
+ return isSetPrivileges();
+ case GROUPS:
+ return isSetGroups();
+ case AUTHORIZABLE:
+ return isSetAuthorizable();
+ case NEW_AUTHORIZABLE:
+ return isSetNewAuthorizable();
+ case VERSION:
+ return isSetVersion();
+ case VERSION_COMMENT:
+ return isSetVersionComment();
+ case SNAPSHOT:
+ return isSetSnapshot();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof TSentryStoreRecord)
+ return this.equals((TSentryStoreRecord)that);
+ return false;
+ }
+
+ public boolean equals(TSentryStoreRecord that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_storeOp = true && this.isSetStoreOp();
+ boolean that_present_storeOp = true && that.isSetStoreOp();
+ if (this_present_storeOp || that_present_storeOp) {
+ if (!(this_present_storeOp && that_present_storeOp))
+ return false;
+ if (!this.storeOp.equals(that.storeOp))
+ return false;
+ }
+
+ boolean this_present_roleName = true && this.isSetRoleName();
+ boolean that_present_roleName = true && that.isSetRoleName();
+ if (this_present_roleName || that_present_roleName) {
+ if (!(this_present_roleName && that_present_roleName))
+ return false;
+ if (!this.roleName.equals(that.roleName))
+ return false;
+ }
+
+ boolean this_present_grantorPrincipal = true && this.isSetGrantorPrincipal();
+ boolean that_present_grantorPrincipal = true && that.isSetGrantorPrincipal();
+ if (this_present_grantorPrincipal || that_present_grantorPrincipal) {
+ if (!(this_present_grantorPrincipal && that_present_grantorPrincipal))
+ return false;
+ if (!this.grantorPrincipal.equals(that.grantorPrincipal))
+ return false;
+ }
+
+ boolean this_present_privileges = true && this.isSetPrivileges();
+ boolean that_present_privileges = true && that.isSetPrivileges();
+ if (this_present_privileges || that_present_privileges) {
+ if (!(this_present_privileges && that_present_privileges))
+ return false;
+ if (!this.privileges.equals(that.privileges))
+ return false;
+ }
+
+ boolean this_present_groups = true && this.isSetGroups();
+ boolean that_present_groups = true && that.isSetGroups();
+ if (this_present_groups || that_present_groups) {
+ if (!(this_present_groups && that_present_groups))
+ return false;
+ if (!this.groups.equals(that.groups))
+ return false;
+ }
+
+ boolean this_present_authorizable = true && this.isSetAuthorizable();
+ boolean that_present_authorizable = true && that.isSetAuthorizable();
+ if (this_present_authorizable || that_present_authorizable) {
+ if (!(this_present_authorizable && that_present_authorizable))
+ return false;
+ if (!this.authorizable.equals(that.authorizable))
+ return false;
+ }
+
+ boolean this_present_newAuthorizable = true && this.isSetNewAuthorizable();
+ boolean that_present_newAuthorizable = true && that.isSetNewAuthorizable();
+ if (this_present_newAuthorizable || that_present_newAuthorizable) {
+ if (!(this_present_newAuthorizable && that_present_newAuthorizable))
+ return false;
+ if (!this.newAuthorizable.equals(that.newAuthorizable))
+ return false;
+ }
+
+ boolean this_present_version = true && this.isSetVersion();
+ boolean that_present_version = true && that.isSetVersion();
+ if (this_present_version || that_present_version) {
+ if (!(this_present_version && that_present_version))
+ return false;
+ if (!this.version.equals(that.version))
+ return false;
+ }
+
+ boolean this_present_versionComment = true && this.isSetVersionComment();
+ boolean that_present_versionComment = true && that.isSetVersionComment();
+ if (this_present_versionComment || that_present_versionComment) {
+ if (!(this_present_versionComment && that_present_versionComment))
+ return false;
+ if (!this.versionComment.equals(that.versionComment))
+ return false;
+ }
+
+ boolean this_present_snapshot = true && this.isSetSnapshot();
+ boolean that_present_snapshot = true && that.isSetSnapshot();
+ if (this_present_snapshot || that_present_snapshot) {
+ if (!(this_present_snapshot && that_present_snapshot))
+ return false;
+ if (!this.snapshot.equals(that.snapshot))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder builder = new HashCodeBuilder();
+
+ boolean present_storeOp = true && (isSetStoreOp());
+ builder.append(present_storeOp);
+ if (present_storeOp)
+ builder.append(storeOp.getValue());
+
+ boolean present_roleName = true && (isSetRoleName());
+ builder.append(present_roleName);
+ if (present_roleName)
+ builder.append(roleName);
+
+ boolean present_grantorPrincipal = true && (isSetGrantorPrincipal());
+ builder.append(present_grantorPrincipal);
+ if (present_grantorPrincipal)
+ builder.append(grantorPrincipal);
+
+ boolean present_privileges = true && (isSetPrivileges());
+ builder.append(present_privileges);
+ if (present_privileges)
+ builder.append(privileges);
+
+ boolean present_groups = true && (isSetGroups());
+ builder.append(present_groups);
+ if (present_groups)
+ builder.append(groups);
+
+ boolean present_authorizable = true && (isSetAuthorizable());
+ builder.append(present_authorizable);
+ if (present_authorizable)
+ builder.append(authorizable);
+
+ boolean present_newAuthorizable = true && (isSetNewAuthorizable());
+ builder.append(present_newAuthorizable);
+ if (present_newAuthorizable)
+ builder.append(newAuthorizable);
+
+ boolean present_version = true && (isSetVersion());
+ builder.append(present_version);
+ if (present_version)
+ builder.append(version);
+
+ boolean present_versionComment = true && (isSetVersionComment());
+ builder.append(present_versionComment);
+ if (present_versionComment)
+ builder.append(versionComment);
+
+ boolean present_snapshot = true && (isSetSnapshot());
+ builder.append(present_snapshot);
+ if (present_snapshot)
+ builder.append(snapshot);
+
+ return builder.toHashCode();
+ }
+
+ public int compareTo(TSentryStoreRecord other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+ TSentryStoreRecord typedOther = (TSentryStoreRecord)other;
+
+ lastComparison = Boolean.valueOf(isSetStoreOp()).compareTo(typedOther.isSetStoreOp());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetStoreOp()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeOp, typedOther.storeOp);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetRoleName()).compareTo(typedOther.isSetRoleName());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetRoleName()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.roleName, typedOther.roleName);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetGrantorPrincipal()).compareTo(typedOther.isSetGrantorPrincipal());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetGrantorPrincipal()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.grantorPrincipal, typedOther.grantorPrincipal);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetPrivileges()).compareTo(typedOther.isSetPrivileges());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetPrivileges()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.privileges, typedOther.privileges);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetGroups()).compareTo(typedOther.isSetGroups());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetGroups()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groups, typedOther.groups);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetAuthorizable()).compareTo(typedOther.isSetAuthorizable());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetAuthorizable()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authorizable, typedOther.authorizable);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetNewAuthorizable()).compareTo(typedOther.isSetNewAuthorizable());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetNewAuthorizable()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newAuthorizable, typedOther.newAuthorizable);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetVersion()).compareTo(typedOther.isSetVersion());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetVersion()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, typedOther.version);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetVersionComment()).compareTo(typedOther.isSetVersionComment());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetVersionComment()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.versionComment, typedOther.versionComment);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetSnapshot()).compareTo(typedOther.isSetSnapshot());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetSnapshot()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.snapshot, typedOther.snapshot);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("TSentryStoreRecord(");
+ boolean first = true;
+
+ sb.append("storeOp:");
+ if (this.storeOp == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.storeOp);
+ }
+ first = false;
+ if (isSetRoleName()) {
+ if (!first) sb.append(", ");
+ sb.append("roleName:");
+ if (this.roleName == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.roleName);
+ }
+ first = false;
+ }
+ if (isSetGrantorPrincipal()) {
+ if (!first) sb.append(", ");
+ sb.append("grantorPrincipal:");
+ if (this.grantorPrincipal == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.grantorPrincipal);
+ }
+ first = false;
+ }
+ if (isSetPrivileges()) {
+ if (!first) sb.append(", ");
+ sb.append("privileges:");
+ if (this.privileges == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.privileges);
+ }
+ first = false;
+ }
+ if (isSetGroups()) {
+ if (!first) sb.append(", ");
+ sb.append("groups:");
+ if (this.groups == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.groups);
+ }
+ first = false;
+ }
+ if (isSetAuthorizable()) {
+ if (!first) sb.append(", ");
+ sb.append("authorizable:");
+ if (this.authorizable == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.authorizable);
+ }
+ first = false;
+ }
+ if (isSetNewAuthorizable()) {
+ if (!first) sb.append(", ");
+ sb.append("newAuthorizable:");
+ if (this.newAuthorizable == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.newAuthorizable);
+ }
+ first = false;
+ }
+ if (isSetVersion()) {
+ if (!first) sb.append(", ");
+ sb.append("version:");
+ if (this.version == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.version);
+ }
+ first = false;
+ }
+ if (isSetVersionComment()) {
+ if (!first) sb.append(", ");
+ sb.append("versionComment:");
+ if (this.versionComment == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.versionComment);
+ }
+ first = false;
+ }
+ if (isSetSnapshot()) {
+ if (!first) sb.append(", ");
+ sb.append("snapshot:");
+ if (this.snapshot == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.snapshot);
+ }
+ first = false;
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ if (!isSetStoreOp()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'storeOp' is unset! Struct:" + toString());
+ }
+
+ // check for sub-struct validity
+ if (authorizable != null) {
+ authorizable.validate();
+ }
+ if (newAuthorizable != null) {
+ newAuthorizable.validate();
+ }
+ if (snapshot != null) {
+ snapshot.validate();
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class TSentryStoreRecordStandardSchemeFactory implements SchemeFactory {
+ public TSentryStoreRecordStandardScheme getScheme() {
+ return new TSentryStoreRecordStandardScheme();
+ }
+ }
+
+ private static class TSentryStoreRecordStandardScheme extends StandardScheme<TSentryStoreRecord> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, TSentryStoreRecord struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // STORE_OP
+ if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+ struct.storeOp = TSentryStoreOp.findByValue(iprot.readI32());
+ struct.setStoreOpIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 2: // ROLE_NAME
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.roleName = iprot.readString();
+ struct.setRoleNameIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 3: // GRANTOR_PRINCIPAL
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.grantorPrincipal = iprot.readString();
+ struct.setGrantorPrincipalIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 4: // PRIVILEGES
+ if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
+ {
+ org.apache.thrift.protocol.TSet _set56 = iprot.readSetBegin();
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set56.size);
+ for (int _i57 = 0; _i57 < _set56.size; ++_i57)
+ {
+ TSentryPrivilege _elem58; // required
+ _elem58 = new TSentryPrivilege();
+ _elem58.read(iprot);
+ struct.privileges.add(_elem58);
+ }
+ iprot.readSetEnd();
+ }
+ struct.setPrivilegesIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 5: // GROUPS
+ if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
+ {
+ org.apache.thrift.protocol.TSet _set59 = iprot.readSetBegin();
+ struct.groups = new HashSet<String>(2*_set59.size);
+ for (int _i60 = 0; _i60 < _set59.size; ++_i60)
+ {
+ String _elem61; // required
+ _elem61 = iprot.readString();
+ struct.groups.add(_elem61);
+ }
+ iprot.readSetEnd();
+ }
+ struct.setGroupsIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 6: // AUTHORIZABLE
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.authorizable = new TSentryAuthorizable();
+ struct.authorizable.read(iprot);
+ struct.setAuthorizableIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 7: // NEW_AUTHORIZABLE
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.newAuthorizable = new TSentryAuthorizable();
+ struct.newAuthorizable.read(iprot);
+ struct.setNewAuthorizableIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 8: // VERSION
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.version = iprot.readString();
+ struct.setVersionIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 9: // VERSION_COMMENT
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.versionComment = iprot.readString();
+ struct.setVersionCommentIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 10: // SNAPSHOT
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.snapshot = new TStoreSnapshot();
+ struct.snapshot.read(iprot);
+ struct.setSnapshotIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, TSentryStoreRecord struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.storeOp != null) {
+ oprot.writeFieldBegin(STORE_OP_FIELD_DESC);
+ oprot.writeI32(struct.storeOp.getValue());
+ oprot.writeFieldEnd();
+ }
+ if (struct.roleName != null) {
+ if (struct.isSetRoleName()) {
+ oprot.writeFieldBegin(ROLE_NAME_FIELD_DESC);
+ oprot.writeString(struct.roleName);
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.grantorPrincipal != null) {
+ if (struct.isSetGrantorPrincipal()) {
+ oprot.writeFieldBegin(GRANTOR_PRINCIPAL_FIELD_DESC);
+ oprot.writeString(struct.grantorPrincipal);
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.privileges != null) {
+ if (struct.isSetPrivileges()) {
+ oprot.writeFieldBegin(PRIVILEGES_FIELD_DESC);
+ {
+ oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.privileges.size()));
+ for (TSentryPrivilege _iter62 : struct.privileges)
+ {
+ _iter62.write(oprot);
+ }
+ oprot.writeSetEnd();
+ }
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.groups != null) {
+ if (struct.isSetGroups()) {
+ oprot.writeFieldBegin(GROUPS_FIELD_DESC);
+ {
+ oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.groups.size()));
+ for (String _iter63 : struct.groups)
+ {
+ oprot.writeString(_iter63);
+ }
+ oprot.writeSetEnd();
+ }
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.authorizable != null) {
+ if (struct.isSetAuthorizable()) {
+ oprot.writeFieldBegin(AUTHORIZABLE_FIELD_DESC);
+ struct.authorizable.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.newAuthorizable != null) {
+ if (struct.isSetNewAuthorizable()) {
+ oprot.writeFieldBegin(NEW_AUTHORIZABLE_FIELD_DESC);
+ struct.newAuthorizable.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.version != null) {
+ if (struct.isSetVersion()) {
+ oprot.writeFieldBegin(VERSION_FIELD_DESC);
+ oprot.writeString(struct.version);
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.versionComment != null) {
+ if (struct.isSetVersionComment()) {
+ oprot.writeFieldBegin(VERSION_COMMENT_FIELD_DESC);
+ oprot.writeString(struct.versionComment);
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.snapshot != null) {
+ if (struct.isSetSnapshot()) {
+ oprot.writeFieldBegin(SNAPSHOT_FIELD_DESC);
+ struct.snapshot.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class TSentryStoreRecordTupleSchemeFactory implements SchemeFactory {
+ public TSentryStoreRecordTupleScheme getScheme() {
+ return new TSentryStoreRecordTupleScheme();
+ }
+ }
+
+ private static class TSentryStoreRecordTupleScheme extends TupleScheme<TSentryStoreRecord> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, TSentryStoreRecord struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ oprot.writeI32(struct.storeOp.getValue());
+ BitSet optionals = new BitSet();
+ if (struct.isSetRoleName()) {
+ optionals.set(0);
+ }
+ if (struct.isSetGrantorPrincipal()) {
+ optionals.set(1);
+ }
+ if (struct.isSetPrivileges()) {
+ optionals.set(2);
+ }
+ if (struct.isSetGroups()) {
+ optionals.set(3);
+ }
+ if (struct.isSetAuthorizable()) {
+ optionals.set(4);
+ }
+ if (struct.isSetNewAuthorizable()) {
+ optionals.set(5);
+ }
+ if (struct.isSetVersion()) {
+ optionals.set(6);
+ }
+ if (struct.isSetVersionComment()) {
+ optionals.set(7);
+ }
+ if (struct.isSetSnapshot()) {
+ optionals.set(8);
+ }
+ oprot.writeBitSet(optionals, 9);
+ if (struct.isSetRoleName()) {
+ oprot.writeString(struct.roleName);
+ }
+ if (struct.isSetGrantorPrincipal()) {
+ oprot.writeString(struct.grantorPrincipal);
+ }
+ if (struct.isSetPrivileges()) {
+ {
+ oprot.writeI32(struct.privileges.size());
+ for (TSentryPrivilege _iter64 : struct.privileges)
+ {
+ _iter64.write(oprot);
+ }
+ }
+ }
+ if (struct.isSetGroups()) {
+ {
+ oprot.writeI32(struct.groups.size());
+ for (String _iter65 : struct.groups)
+ {
+ oprot.writeString(_iter65);
+ }
+ }
+ }
+ if (struct.isSetAuthorizable()) {
+ struct.authorizable.write(oprot);
+ }
+ if (struct.isSetNewAuthorizable()) {
+ struct.newAuthorizable.write(oprot);
+ }
+ if (struct.isSetVersion()) {
+ oprot.writeString(struct.version);
+ }
+ if (struct.isSetVersionComment()) {
+ oprot.writeString(struct.versionComment);
+ }
+ if (struct.isSetSnapshot()) {
+ struct.snapshot.write(oprot);
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, TSentryStoreRecord struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ struct.storeOp = TSentryStoreOp.findByValue(iprot.readI32());
+ struct.setStoreOpIsSet(true);
+ BitSet incoming = iprot.readBitSet(9);
+ if (incoming.get(0)) {
+ struct.roleName = iprot.readString();
+ struct.setRoleNameIsSet(true);
+ }
+ if (incoming.get(1)) {
+ struct.grantorPrincipal = iprot.readString();
+ struct.setGrantorPrincipalIsSet(true);
+ }
+ if (incoming.get(2)) {
+ {
+ org.apache.thrift.protocol.TSet _set66 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.privileges = new HashSet<TSentryPrivilege>(2*_set66.size);
+ for (int _i67 = 0; _i67 < _set66.size; ++_i67)
+ {
+ TSentryPrivilege _elem68; // required
+ _elem68 = new TSentryPrivilege();
+ _elem68.read(iprot);
+ struct.privileges.add(_elem68);
+ }
+ }
+ struct.setPrivilegesIsSet(true);
+ }
+ if (incoming.get(3)) {
+ {
+ org.apache.thrift.protocol.TSet _set69 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+ struct.groups = new HashSet<String>(2*_set69.size);
+ for (int _i70 = 0; _i70 < _set69.size; ++_i70)
+ {
+ String _elem71; // required
+ _elem71 = iprot.readString();
+ struct.groups.add(_elem71);
+ }
+ }
+ struct.setGroupsIsSet(true);
+ }
+ if (incoming.get(4)) {
+ struct.authorizable = new TSentryAuthorizable();
+ struct.authorizable.read(iprot);
+ struct.setAuthorizableIsSet(true);
+ }
+ if (incoming.get(5)) {
+ struct.newAuthorizable = new TSentryAuthorizable();
+ struct.newAuthorizable.read(iprot);
+ struct.setNewAuthorizableIsSet(true);
+ }
+ if (incoming.get(6)) {
+ struct.version = iprot.readString();
+ struct.setVersionIsSet(true);
+ }
+ if (incoming.get(7)) {
+ struct.versionComment = iprot.readString();
+ struct.setVersionCommentIsSet(true);
+ }
+ if (incoming.get(8)) {
+ struct.snapshot = new TStoreSnapshot();
+ struct.snapshot.read(iprot);
+ struct.setSnapshotIsSet(true);
+ }
+ }
+ }
+
+}
+
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStoreAuthorizable.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStoreAuthorizable.java
new file mode 100644
index 0000000..99c0dcb
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStoreAuthorizable.java
@@ -0,0 +1,819 @@
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package org.apache.sentry.provider.db.service.thrift;
+
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TStoreAuthorizable implements org.apache.thrift.TBase<TStoreAuthorizable, TStoreAuthorizable._Fields>, java.io.Serializable, Cloneable {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TStoreAuthorizable");
+
+ private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)1);
+ private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.STRING, (short)2);
+ private static final org.apache.thrift.protocol.TField PRIVILEGES_FIELD_DESC = new org.apache.thrift.protocol.TField("privileges", org.apache.thrift.protocol.TType.MAP, (short)3);
+ private static final org.apache.thrift.protocol.TField CHILDREN_FIELD_DESC = new org.apache.thrift.protocol.TField("children", org.apache.thrift.protocol.TType.SET, (short)4);
+
+ private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+ static {
+ schemes.put(StandardScheme.class, new TStoreAuthorizableStandardSchemeFactory());
+ schemes.put(TupleScheme.class, new TStoreAuthorizableTupleSchemeFactory());
+ }
+
+ private String name; // required
+ private String type; // required
+ private Map<String,TStorePrivilege> privileges; // optional
+ private Set<Integer> children; // optional
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ NAME((short)1, "name"),
+ TYPE((short)2, "type"),
+ PRIVILEGES((short)3, "privileges"),
+ CHILDREN((short)4, "children");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // NAME
+ return NAME;
+ case 2: // TYPE
+ return TYPE;
+ case 3: // PRIVILEGES
+ return PRIVILEGES;
+ case 4: // CHILDREN
+ return CHILDREN;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ private _Fields optionals[] = {_Fields.PRIVILEGES,_Fields.CHILDREN};
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.PRIVILEGES, new org.apache.thrift.meta_data.FieldMetaData("privileges", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING),
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TStorePrivilege.class))));
+ tmpMap.put(_Fields.CHILDREN, new org.apache.thrift.meta_data.FieldMetaData("children", org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TStoreAuthorizable.class, metaDataMap);
+ }
+
+ public TStoreAuthorizable() {
+ }
+
+ public TStoreAuthorizable(
+ String name,
+ String type)
+ {
+ this();
+ this.name = name;
+ this.type = type;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public TStoreAuthorizable(TStoreAuthorizable other) {
+ if (other.isSetName()) {
+ this.name = other.name;
+ }
+ if (other.isSetType()) {
+ this.type = other.type;
+ }
+ if (other.isSetPrivileges()) {
+ Map<String,TStorePrivilege> __this__privileges = new HashMap<String,TStorePrivilege>();
+ for (Map.Entry<String, TStorePrivilege> other_element : other.privileges.entrySet()) {
+
+ String other_element_key = other_element.getKey();
+ TStorePrivilege other_element_value = other_element.getValue();
+
+ String __this__privileges_copy_key = other_element_key;
+
+ TStorePrivilege __this__privileges_copy_value = new TStorePrivilege(other_element_value);
+
+ __this__privileges.put(__this__privileges_copy_key, __this__privileges_copy_value);
+ }
+ this.privileges = __this__privileges;
+ }
+ if (other.isSetChildren()) {
+ Set<Integer> __this__children = new HashSet<Integer>();
+ for (Integer other_element : other.children) {
+ __this__children.add(other_element);
+ }
+ this.children = __this__children;
+ }
+ }
+
+ public TStoreAuthorizable deepCopy() {
+ return new TStoreAuthorizable(this);
+ }
+
+ @Override
+ public void clear() {
+ this.name = null;
+ this.type = null;
+ this.privileges = null;
+ this.children = null;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void unsetName() {
+ this.name = null;
+ }
+
+ /** Returns true if field name is set (has been assigned a value) and false otherwise */
+ public boolean isSetName() {
+ return this.name != null;
+ }
+
+ public void setNameIsSet(boolean value) {
+ if (!value) {
+ this.name = null;
+ }
+ }
+
+ public String getType() {
+ return this.type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public void unsetType() {
+ this.type = null;
+ }
+
+ /** Returns true if field type is set (has been assigned a value) and false otherwise */
+ public boolean isSetType() {
+ return this.type != null;
+ }
+
+ public void setTypeIsSet(boolean value) {
+ if (!value) {
+ this.type = null;
+ }
+ }
+
+ public int getPrivilegesSize() {
+ return (this.privileges == null) ? 0 : this.privileges.size();
+ }
+
+ public void putToPrivileges(String key, TStorePrivilege val) {
+ if (this.privileges == null) {
+ this.privileges = new HashMap<String,TStorePrivilege>();
+ }
+ this.privileges.put(key, val);
+ }
+
+ public Map<String,TStorePrivilege> getPrivileges() {
+ return this.privileges;
+ }
+
+ public void setPrivileges(Map<String,TStorePrivilege> privileges) {
+ this.privileges = privileges;
+ }
+
+ public void unsetPrivileges() {
+ this.privileges = null;
+ }
+
+ /** Returns true if field privileges is set (has been assigned a value) and false otherwise */
+ public boolean isSetPrivileges() {
+ return this.privileges != null;
+ }
+
+ public void setPrivilegesIsSet(boolean value) {
+ if (!value) {
+ this.privileges = null;
+ }
+ }
+
+ public int getChildrenSize() {
+ return (this.children == null) ? 0 : this.children.size();
+ }
+
+ public java.util.Iterator<Integer> getChildrenIterator() {
+ return (this.children == null) ? null : this.children.iterator();
+ }
+
+ public void addToChildren(int elem) {
+ if (this.children == null) {
+ this.children = new HashSet<Integer>();
+ }
+ this.children.add(elem);
+ }
+
+ public Set<Integer> getChildren() {
+ return this.children;
+ }
+
+ public void setChildren(Set<Integer> children) {
+ this.children = children;
+ }
+
+ public void unsetChildren() {
+ this.children = null;
+ }
+
+ /** Returns true if field children is set (has been assigned a value) and false otherwise */
+ public boolean isSetChildren() {
+ return this.children != null;
+ }
+
+ public void setChildrenIsSet(boolean value) {
+ if (!value) {
+ this.children = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case NAME:
+ if (value == null) {
+ unsetName();
+ } else {
+ setName((String)value);
+ }
+ break;
+
+ case TYPE:
+ if (value == null) {
+ unsetType();
+ } else {
+ setType((String)value);
+ }
+ break;
+
+ case PRIVILEGES:
+ if (value == null) {
+ unsetPrivileges();
+ } else {
+ setPrivileges((Map<String,TStorePrivilege>)value);
+ }
+ break;
+
+ case CHILDREN:
+ if (value == null) {
+ unsetChildren();
+ } else {
+ setChildren((Set<Integer>)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case NAME:
+ return getName();
+
+ case TYPE:
+ return getType();
+
+ case PRIVILEGES:
+ return getPrivileges();
+
+ case CHILDREN:
+ return getChildren();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case NAME:
+ return isSetName();
+ case TYPE:
+ return isSetType();
+ case PRIVILEGES:
+ return isSetPrivileges();
+ case CHILDREN:
+ return isSetChildren();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof TStoreAuthorizable)
+ return this.equals((TStoreAuthorizable)that);
+ return false;
+ }
+
+ public boolean equals(TStoreAuthorizable that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_name = true && this.isSetName();
+ boolean that_present_name = true && that.isSetName();
+ if (this_present_name || that_present_name) {
+ if (!(this_present_name && that_present_name))
+ return false;
+ if (!this.name.equals(that.name))
+ return false;
+ }
+
+ boolean this_present_type = true && this.isSetType();
+ boolean that_present_type = true && that.isSetType();
+ if (this_present_type || that_present_type) {
+ if (!(this_present_type && that_present_type))
+ return false;
+ if (!this.type.equals(that.type))
+ return false;
+ }
+
+ boolean this_present_privileges = true && this.isSetPrivileges();
+ boolean that_present_privileges = true && that.isSetPrivileges();
+ if (this_present_privileges || that_present_privileges) {
+ if (!(this_present_privileges && that_present_privileges))
+ return false;
+ if (!this.privileges.equals(that.privileges))
+ return false;
+ }
+
+ boolean this_present_children = true && this.isSetChildren();
+ boolean that_present_children = true && that.isSetChildren();
+ if (this_present_children || that_present_children) {
+ if (!(this_present_children && that_present_children))
+ return false;
+ if (!this.children.equals(that.children))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder builder = new HashCodeBuilder();
+
+ boolean present_name = true && (isSetName());
+ builder.append(present_name);
+ if (present_name)
+ builder.append(name);
+
+ boolean present_type = true && (isSetType());
+ builder.append(present_type);
+ if (present_type)
+ builder.append(type);
+
+ boolean present_privileges = true && (isSetPrivileges());
+ builder.append(present_privileges);
+ if (present_privileges)
+ builder.append(privileges);
+
+ boolean present_children = true && (isSetChildren());
+ builder.append(present_children);
+ if (present_children)
+ builder.append(children);
+
+ return builder.toHashCode();
+ }
+
+ public int compareTo(TStoreAuthorizable other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+ TStoreAuthorizable typedOther = (TStoreAuthorizable)other;
+
+ lastComparison = Boolean.valueOf(isSetName()).compareTo(typedOther.isSetName());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetName()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, typedOther.name);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetType()).compareTo(typedOther.isSetType());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetType()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, typedOther.type);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetPrivileges()).compareTo(typedOther.isSetPrivileges());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetPrivileges()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.privileges, typedOther.privileges);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetChildren()).compareTo(typedOther.isSetChildren());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetChildren()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.children, typedOther.children);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("TStoreAuthorizable(");
+ boolean first = true;
+
+ sb.append("name:");
+ if (this.name == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.name);
+ }
+ first = false;
+ if (!first) sb.append(", ");
+ sb.append("type:");
+ if (this.type == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.type);
+ }
+ first = false;
+ if (isSetPrivileges()) {
+ if (!first) sb.append(", ");
+ sb.append("privileges:");
+ if (this.privileges == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.privileges);
+ }
+ first = false;
+ }
+ if (isSetChildren()) {
+ if (!first) sb.append(", ");
+ sb.append("children:");
+ if (this.children == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.children);
+ }
+ first = false;
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ if (!isSetName()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'name' is unset! Struct:" + toString());
+ }
+
+ if (!isSetType()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'type' is unset! Struct:" + toString());
+ }
+
+ // check for sub-struct validity
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class TStoreAuthorizableStandardSchemeFactory implements SchemeFactory {
+ public TStoreAuthorizableStandardScheme getScheme() {
+ return new TStoreAuthorizableStandardScheme();
+ }
+ }
+
+ private static class TStoreAuthorizableStandardScheme extends StandardScheme<TStoreAuthorizable> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, TStoreAuthorizable struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // NAME
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.name = iprot.readString();
+ struct.setNameIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 2: // TYPE
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.type = iprot.readString();
+ struct.setTypeIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 3: // PRIVILEGES
+ if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+ {
+ org.apache.thrift.protocol.TMap _map0 = iprot.readMapBegin();
+ struct.privileges = new HashMap<String,TStorePrivilege>(2*_map0.size);
+ for (int _i1 = 0; _i1 < _map0.size; ++_i1)
+ {
+ String _key2; // required
+ TStorePrivilege _val3; // required
+ _key2 = iprot.readString();
+ _val3 = new TStorePrivilege();
+ _val3.read(iprot);
+ struct.privileges.put(_key2, _val3);
+ }
+ iprot.readMapEnd();
+ }
+ struct.setPrivilegesIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 4: // CHILDREN
+ if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
+ {
+ org.apache.thrift.protocol.TSet _set4 = iprot.readSetBegin();
+ struct.children = new HashSet<Integer>(2*_set4.size);
+ for (int _i5 = 0; _i5 < _set4.size; ++_i5)
+ {
+ int _elem6; // required
+ _elem6 = iprot.readI32();
+ struct.children.add(_elem6);
+ }
+ iprot.readSetEnd();
+ }
+ struct.setChildrenIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, TStoreAuthorizable struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.name != null) {
+ oprot.writeFieldBegin(NAME_FIELD_DESC);
+ oprot.writeString(struct.name);
+ oprot.writeFieldEnd();
+ }
+ if (struct.type != null) {
+ oprot.writeFieldBegin(TYPE_FIELD_DESC);
+ oprot.writeString(struct.type);
+ oprot.writeFieldEnd();
+ }
+ if (struct.privileges != null) {
+ if (struct.isSetPrivileges()) {
+ oprot.writeFieldBegin(PRIVILEGES_FIELD_DESC);
+ {
+ oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, struct.privileges.size()));
+ for (Map.Entry<String, TStorePrivilege> _iter7 : struct.privileges.entrySet())
+ {
+ oprot.writeString(_iter7.getKey());
+ _iter7.getValue().write(oprot);
+ }
+ oprot.writeMapEnd();
+ }
+ oprot.writeFieldEnd();
+ }
+ }
+ if (struct.children != null) {
+ if (struct.isSetChildren()) {
+ oprot.writeFieldBegin(CHILDREN_FIELD_DESC);
+ {
+ oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.children.size()));
+ for (int _iter8 : struct.children)
+ {
+ oprot.writeI32(_iter8);
+ }
+ oprot.writeSetEnd();
+ }
+ oprot.writeFieldEnd();
+ }
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class TStoreAuthorizableTupleSchemeFactory implements SchemeFactory {
+ public TStoreAuthorizableTupleScheme getScheme() {
+ return new TStoreAuthorizableTupleScheme();
+ }
+ }
+
+ private static class TStoreAuthorizableTupleScheme extends TupleScheme<TStoreAuthorizable> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, TStoreAuthorizable struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ oprot.writeString(struct.name);
+ oprot.writeString(struct.type);
+ BitSet optionals = new BitSet();
+ if (struct.isSetPrivileges()) {
+ optionals.set(0);
+ }
+ if (struct.isSetChildren()) {
+ optionals.set(1);
+ }
+ oprot.writeBitSet(optionals, 2);
+ if (struct.isSetPrivileges()) {
+ {
+ oprot.writeI32(struct.privileges.size());
+ for (Map.Entry<String, TStorePrivilege> _iter9 : struct.privileges.entrySet())
+ {
+ oprot.writeString(_iter9.getKey());
+ _iter9.getValue().write(oprot);
+ }
+ }
+ }
+ if (struct.isSetChildren()) {
+ {
+ oprot.writeI32(struct.children.size());
+ for (int _iter10 : struct.children)
+ {
+ oprot.writeI32(_iter10);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, TStoreAuthorizable struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ struct.name = iprot.readString();
+ struct.setNameIsSet(true);
+ struct.type = iprot.readString();
+ struct.setTypeIsSet(true);
+ BitSet incoming = iprot.readBitSet(2);
+ if (incoming.get(0)) {
+ {
+ org.apache.thrift.protocol.TMap _map11 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.privileges = new HashMap<String,TStorePrivilege>(2*_map11.size);
+ for (int _i12 = 0; _i12 < _map11.size; ++_i12)
+ {
+ String _key13; // required
+ TStorePrivilege _val14; // required
+ _key13 = iprot.readString();
+ _val14 = new TStorePrivilege();
+ _val14.read(iprot);
+ struct.privileges.put(_key13, _val14);
+ }
+ }
+ struct.setPrivilegesIsSet(true);
+ }
+ if (incoming.get(1)) {
+ {
+ org.apache.thrift.protocol.TSet _set15 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
+ struct.children = new HashSet<Integer>(2*_set15.size);
+ for (int _i16 = 0; _i16 < _set15.size; ++_i16)
+ {
+ int _elem17; // required
+ _elem17 = iprot.readI32();
+ struct.children.add(_elem17);
+ }
+ }
+ struct.setChildrenIsSet(true);
+ }
+ }
+ }
+
+}
+
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStorePrivilege.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStorePrivilege.java
new file mode 100644
index 0000000..3ce595d
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStorePrivilege.java
@@ -0,0 +1,496 @@
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package org.apache.sentry.provider.db.service.thrift;
+
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TStorePrivilege implements org.apache.thrift.TBase<TStorePrivilege, TStorePrivilege._Fields>, java.io.Serializable, Cloneable {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TStorePrivilege");
+
+ private static final org.apache.thrift.protocol.TField GRANT_OPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("grantOption", org.apache.thrift.protocol.TType.I32, (short)1);
+ private static final org.apache.thrift.protocol.TField PRIVILEGE_FIELD_DESC = new org.apache.thrift.protocol.TField("privilege", org.apache.thrift.protocol.TType.I16, (short)2);
+
+ private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+ static {
+ schemes.put(StandardScheme.class, new TStorePrivilegeStandardSchemeFactory());
+ schemes.put(TupleScheme.class, new TStorePrivilegeTupleSchemeFactory());
+ }
+
+ private TSentryGrantOption grantOption; // required
+ private short privilege; // required
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ /**
+ *
+ * @see TSentryGrantOption
+ */
+ GRANT_OPTION((short)1, "grantOption"),
+ PRIVILEGE((short)2, "privilege");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // GRANT_OPTION
+ return GRANT_OPTION;
+ case 2: // PRIVILEGE
+ return PRIVILEGE;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ private static final int __PRIVILEGE_ISSET_ID = 0;
+ private byte __isset_bitfield = 0;
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.GRANT_OPTION, new org.apache.thrift.meta_data.FieldMetaData("grantOption", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TSentryGrantOption.class)));
+ tmpMap.put(_Fields.PRIVILEGE, new org.apache.thrift.meta_data.FieldMetaData("privilege", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16)));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TStorePrivilege.class, metaDataMap);
+ }
+
+ public TStorePrivilege() {
+ }
+
+ public TStorePrivilege(
+ TSentryGrantOption grantOption,
+ short privilege)
+ {
+ this();
+ this.grantOption = grantOption;
+ this.privilege = privilege;
+ setPrivilegeIsSet(true);
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public TStorePrivilege(TStorePrivilege other) {
+ __isset_bitfield = other.__isset_bitfield;
+ if (other.isSetGrantOption()) {
+ this.grantOption = other.grantOption;
+ }
+ this.privilege = other.privilege;
+ }
+
+ public TStorePrivilege deepCopy() {
+ return new TStorePrivilege(this);
+ }
+
+ @Override
+ public void clear() {
+ this.grantOption = null;
+ setPrivilegeIsSet(false);
+ this.privilege = 0;
+ }
+
+ /**
+ *
+ * @see TSentryGrantOption
+ */
+ public TSentryGrantOption getGrantOption() {
+ return this.grantOption;
+ }
+
+ /**
+ *
+ * @see TSentryGrantOption
+ */
+ public void setGrantOption(TSentryGrantOption grantOption) {
+ this.grantOption = grantOption;
+ }
+
+ public void unsetGrantOption() {
+ this.grantOption = null;
+ }
+
+ /** Returns true if field grantOption is set (has been assigned a value) and false otherwise */
+ public boolean isSetGrantOption() {
+ return this.grantOption != null;
+ }
+
+ public void setGrantOptionIsSet(boolean value) {
+ if (!value) {
+ this.grantOption = null;
+ }
+ }
+
+ public short getPrivilege() {
+ return this.privilege;
+ }
+
+ public void setPrivilege(short privilege) {
+ this.privilege = privilege;
+ setPrivilegeIsSet(true);
+ }
+
+ public void unsetPrivilege() {
+ __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIVILEGE_ISSET_ID);
+ }
+
+ /** Returns true if field privilege is set (has been assigned a value) and false otherwise */
+ public boolean isSetPrivilege() {
+ return EncodingUtils.testBit(__isset_bitfield, __PRIVILEGE_ISSET_ID);
+ }
+
+ public void setPrivilegeIsSet(boolean value) {
+ __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIVILEGE_ISSET_ID, value);
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case GRANT_OPTION:
+ if (value == null) {
+ unsetGrantOption();
+ } else {
+ setGrantOption((TSentryGrantOption)value);
+ }
+ break;
+
+ case PRIVILEGE:
+ if (value == null) {
+ unsetPrivilege();
+ } else {
+ setPrivilege((Short)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case GRANT_OPTION:
+ return getGrantOption();
+
+ case PRIVILEGE:
+ return Short.valueOf(getPrivilege());
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case GRANT_OPTION:
+ return isSetGrantOption();
+ case PRIVILEGE:
+ return isSetPrivilege();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof TStorePrivilege)
+ return this.equals((TStorePrivilege)that);
+ return false;
+ }
+
+ public boolean equals(TStorePrivilege that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_grantOption = true && this.isSetGrantOption();
+ boolean that_present_grantOption = true && that.isSetGrantOption();
+ if (this_present_grantOption || that_present_grantOption) {
+ if (!(this_present_grantOption && that_present_grantOption))
+ return false;
+ if (!this.grantOption.equals(that.grantOption))
+ return false;
+ }
+
+ boolean this_present_privilege = true;
+ boolean that_present_privilege = true;
+ if (this_present_privilege || that_present_privilege) {
+ if (!(this_present_privilege && that_present_privilege))
+ return false;
+ if (this.privilege != that.privilege)
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder builder = new HashCodeBuilder();
+
+ boolean present_grantOption = true && (isSetGrantOption());
+ builder.append(present_grantOption);
+ if (present_grantOption)
+ builder.append(grantOption.getValue());
+
+ boolean present_privilege = true;
+ builder.append(present_privilege);
+ if (present_privilege)
+ builder.append(privilege);
+
+ return builder.toHashCode();
+ }
+
+ public int compareTo(TStorePrivilege other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+ TStorePrivilege typedOther = (TStorePrivilege)other;
+
+ lastComparison = Boolean.valueOf(isSetGrantOption()).compareTo(typedOther.isSetGrantOption());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetGrantOption()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.grantOption, typedOther.grantOption);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetPrivilege()).compareTo(typedOther.isSetPrivilege());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetPrivilege()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.privilege, typedOther.privilege);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("TStorePrivilege(");
+ boolean first = true;
+
+ sb.append("grantOption:");
+ if (this.grantOption == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.grantOption);
+ }
+ first = false;
+ if (!first) sb.append(", ");
+ sb.append("privilege:");
+ sb.append(this.privilege);
+ first = false;
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ if (!isSetGrantOption()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'grantOption' is unset! Struct:" + toString());
+ }
+
+ if (!isSetPrivilege()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'privilege' is unset! Struct:" + toString());
+ }
+
+ // check for sub-struct validity
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+ __isset_bitfield = 0;
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class TStorePrivilegeStandardSchemeFactory implements SchemeFactory {
+ public TStorePrivilegeStandardScheme getScheme() {
+ return new TStorePrivilegeStandardScheme();
+ }
+ }
+
+ private static class TStorePrivilegeStandardScheme extends StandardScheme<TStorePrivilege> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, TStorePrivilege struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // GRANT_OPTION
+ if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+ struct.grantOption = TSentryGrantOption.findByValue(iprot.readI32());
+ struct.setGrantOptionIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 2: // PRIVILEGE
+ if (schemeField.type == org.apache.thrift.protocol.TType.I16) {
+ struct.privilege = iprot.readI16();
+ struct.setPrivilegeIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, TStorePrivilege struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.grantOption != null) {
+ oprot.writeFieldBegin(GRANT_OPTION_FIELD_DESC);
+ oprot.writeI32(struct.grantOption.getValue());
+ oprot.writeFieldEnd();
+ }
+ oprot.writeFieldBegin(PRIVILEGE_FIELD_DESC);
+ oprot.writeI16(struct.privilege);
+ oprot.writeFieldEnd();
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class TStorePrivilegeTupleSchemeFactory implements SchemeFactory {
+ public TStorePrivilegeTupleScheme getScheme() {
+ return new TStorePrivilegeTupleScheme();
+ }
+ }
+
+ private static class TStorePrivilegeTupleScheme extends TupleScheme<TStorePrivilege> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, TStorePrivilege struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ oprot.writeI32(struct.grantOption.getValue());
+ oprot.writeI16(struct.privilege);
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, TStorePrivilege struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ struct.grantOption = TSentryGrantOption.findByValue(iprot.readI32());
+ struct.setGrantOptionIsSet(true);
+ struct.privilege = iprot.readI16();
+ struct.setPrivilegeIsSet(true);
+ }
+ }
+
+}
+
diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStoreSnapshot.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStoreSnapshot.java
new file mode 100644
index 0000000..6c9bbe0
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TStoreSnapshot.java
@@ -0,0 +1,816 @@
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package org.apache.sentry.provider.db.service.thrift;
+
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TStoreSnapshot implements org.apache.thrift.TBase<TStoreSnapshot, TStoreSnapshot._Fields>, java.io.Serializable, Cloneable {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TStoreSnapshot");
+
+ private static final org.apache.thrift.protocol.TField ROOT_AUTHORIZABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("rootAuthorizable", org.apache.thrift.protocol.TType.MAP, (short)1);
+ private static final org.apache.thrift.protocol.TField ROLE_TO_GROUPS_FIELD_DESC = new org.apache.thrift.protocol.TField("roleToGroups", org.apache.thrift.protocol.TType.MAP, (short)2);
+ private static final org.apache.thrift.protocol.TField OBJ_IDS_FIELD_DESC = new org.apache.thrift.protocol.TField("objIds", org.apache.thrift.protocol.TType.MAP, (short)3);
+
+ private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+ static {
+ schemes.put(StandardScheme.class, new TStoreSnapshotStandardSchemeFactory());
+ schemes.put(TupleScheme.class, new TStoreSnapshotTupleSchemeFactory());
+ }
+
+ private Map<String,TStoreAuthorizable> rootAuthorizable; // required
+ private Map<String,Set<String>> roleToGroups; // required
+ private Map<Integer,TStoreAuthorizable> objIds; // required
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ ROOT_AUTHORIZABLE((short)1, "rootAuthorizable"),
+ ROLE_TO_GROUPS((short)2, "roleToGroups"),
+ OBJ_IDS((short)3, "objIds");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // ROOT_AUTHORIZABLE
+ return ROOT_AUTHORIZABLE;
+ case 2: // ROLE_TO_GROUPS
+ return ROLE_TO_GROUPS;
+ case 3: // OBJ_IDS
+ return OBJ_IDS;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.ROOT_AUTHORIZABLE, new org.apache.thrift.meta_data.FieldMetaData("rootAuthorizable", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING),
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TStoreAuthorizable.class))));
+ tmpMap.put(_Fields.ROLE_TO_GROUPS, new org.apache.thrift.meta_data.FieldMetaData("roleToGroups", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING),
+ new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)))));
+ tmpMap.put(_Fields.OBJ_IDS, new org.apache.thrift.meta_data.FieldMetaData("objIds", org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32),
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TStoreAuthorizable.class))));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TStoreSnapshot.class, metaDataMap);
+ }
+
+ public TStoreSnapshot() {
+ }
+
+ public TStoreSnapshot(
+ Map<String,TStoreAuthorizable> rootAuthorizable,
+ Map<String,Set<String>> roleToGroups,
+ Map<Integer,TStoreAuthorizable> objIds)
+ {
+ this();
+ this.rootAuthorizable = rootAuthorizable;
+ this.roleToGroups = roleToGroups;
+ this.objIds = objIds;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public TStoreSnapshot(TStoreSnapshot other) {
+ if (other.isSetRootAuthorizable()) {
+ Map<String,TStoreAuthorizable> __this__rootAuthorizable = new HashMap<String,TStoreAuthorizable>();
+ for (Map.Entry<String, TStoreAuthorizable> other_element : other.rootAuthorizable.entrySet()) {
+
+ String other_element_key = other_element.getKey();
+ TStoreAuthorizable other_element_value = other_element.getValue();
+
+ String __this__rootAuthorizable_copy_key = other_element_key;
+
+ TStoreAuthorizable __this__rootAuthorizable_copy_value = new TStoreAuthorizable(other_element_value);
+
+ __this__rootAuthorizable.put(__this__rootAuthorizable_copy_key, __this__rootAuthorizable_copy_value);
+ }
+ this.rootAuthorizable = __this__rootAuthorizable;
+ }
+ if (other.isSetRoleToGroups()) {
+ Map<String,Set<String>> __this__roleToGroups = new HashMap<String,Set<String>>();
+ for (Map.Entry<String, Set<String>> other_element : other.roleToGroups.entrySet()) {
+
+ String other_element_key = other_element.getKey();
+ Set<String> other_element_value = other_element.getValue();
+
+ String __this__roleToGroups_copy_key = other_element_key;
+
+ Set<String> __this__roleToGroups_copy_value = new HashSet<String>();
+ for (String other_element_value_element : other_element_value) {
+ __this__roleToGroups_copy_value.add(other_element_value_element);
+ }
+
+ __this__roleToGroups.put(__this__roleToGroups_copy_key, __this__roleToGroups_copy_value);
+ }
+ this.roleToGroups = __this__roleToGroups;
+ }
+ if (other.isSetObjIds()) {
+ Map<Integer,TStoreAuthorizable> __this__objIds = new HashMap<Integer,TStoreAuthorizable>();
+ for (Map.Entry<Integer, TStoreAuthorizable> other_element : other.objIds.entrySet()) {
+
+ Integer other_element_key = other_element.getKey();
+ TStoreAuthorizable other_element_value = other_element.getValue();
+
+ Integer __this__objIds_copy_key = other_element_key;
+
+ TStoreAuthorizable __this__objIds_copy_value = new TStoreAuthorizable(other_element_value);
+
+ __this__objIds.put(__this__objIds_copy_key, __this__objIds_copy_value);
+ }
+ this.objIds = __this__objIds;
+ }
+ }
+
+ public TStoreSnapshot deepCopy() {
+ return new TStoreSnapshot(this);
+ }
+
+ @Override
+ public void clear() {
+ this.rootAuthorizable = null;
+ this.roleToGroups = null;
+ this.objIds = null;
+ }
+
+ public int getRootAuthorizableSize() {
+ return (this.rootAuthorizable == null) ? 0 : this.rootAuthorizable.size();
+ }
+
+ public void putToRootAuthorizable(String key, TStoreAuthorizable val) {
+ if (this.rootAuthorizable == null) {
+ this.rootAuthorizable = new HashMap<String,TStoreAuthorizable>();
+ }
+ this.rootAuthorizable.put(key, val);
+ }
+
+ public Map<String,TStoreAuthorizable> getRootAuthorizable() {
+ return this.rootAuthorizable;
+ }
+
+ public void setRootAuthorizable(Map<String,TStoreAuthorizable> rootAuthorizable) {
+ this.rootAuthorizable = rootAuthorizable;
+ }
+
+ public void unsetRootAuthorizable() {
+ this.rootAuthorizable = null;
+ }
+
+ /** Returns true if field rootAuthorizable is set (has been assigned a value) and false otherwise */
+ public boolean isSetRootAuthorizable() {
+ return this.rootAuthorizable != null;
+ }
+
+ public void setRootAuthorizableIsSet(boolean value) {
+ if (!value) {
+ this.rootAuthorizable = null;
+ }
+ }
+
+ public int getRoleToGroupsSize() {
+ return (this.roleToGroups == null) ? 0 : this.roleToGroups.size();
+ }
+
+ public void putToRoleToGroups(String key, Set<String> val) {
+ if (this.roleToGroups == null) {
+ this.roleToGroups = new HashMap<String,Set<String>>();
+ }
+ this.roleToGroups.put(key, val);
+ }
+
+ public Map<String,Set<String>> getRoleToGroups() {
+ return this.roleToGroups;
+ }
+
+ public void setRoleToGroups(Map<String,Set<String>> roleToGroups) {
+ this.roleToGroups = roleToGroups;
+ }
+
+ public void unsetRoleToGroups() {
+ this.roleToGroups = null;
+ }
+
+ /** Returns true if field roleToGroups is set (has been assigned a value) and false otherwise */
+ public boolean isSetRoleToGroups() {
+ return this.roleToGroups != null;
+ }
+
+ public void setRoleToGroupsIsSet(boolean value) {
+ if (!value) {
+ this.roleToGroups = null;
+ }
+ }
+
+ public int getObjIdsSize() {
+ return (this.objIds == null) ? 0 : this.objIds.size();
+ }
+
+ public void putToObjIds(int key, TStoreAuthorizable val) {
+ if (this.objIds == null) {
+ this.objIds = new HashMap<Integer,TStoreAuthorizable>();
+ }
+ this.objIds.put(key, val);
+ }
+
+ public Map<Integer,TStoreAuthorizable> getObjIds() {
+ return this.objIds;
+ }
+
+ public void setObjIds(Map<Integer,TStoreAuthorizable> objIds) {
+ this.objIds = objIds;
+ }
+
+ public void unsetObjIds() {
+ this.objIds = null;
+ }
+
+ /** Returns true if field objIds is set (has been assigned a value) and false otherwise */
+ public boolean isSetObjIds() {
+ return this.objIds != null;
+ }
+
+ public void setObjIdsIsSet(boolean value) {
+ if (!value) {
+ this.objIds = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case ROOT_AUTHORIZABLE:
+ if (value == null) {
+ unsetRootAuthorizable();
+ } else {
+ setRootAuthorizable((Map<String,TStoreAuthorizable>)value);
+ }
+ break;
+
+ case ROLE_TO_GROUPS:
+ if (value == null) {
+ unsetRoleToGroups();
+ } else {
+ setRoleToGroups((Map<String,Set<String>>)value);
+ }
+ break;
+
+ case OBJ_IDS:
+ if (value == null) {
+ unsetObjIds();
+ } else {
+ setObjIds((Map<Integer,TStoreAuthorizable>)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case ROOT_AUTHORIZABLE:
+ return getRootAuthorizable();
+
+ case ROLE_TO_GROUPS:
+ return getRoleToGroups();
+
+ case OBJ_IDS:
+ return getObjIds();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case ROOT_AUTHORIZABLE:
+ return isSetRootAuthorizable();
+ case ROLE_TO_GROUPS:
+ return isSetRoleToGroups();
+ case OBJ_IDS:
+ return isSetObjIds();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof TStoreSnapshot)
+ return this.equals((TStoreSnapshot)that);
+ return false;
+ }
+
+ public boolean equals(TStoreSnapshot that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_rootAuthorizable = true && this.isSetRootAuthorizable();
+ boolean that_present_rootAuthorizable = true && that.isSetRootAuthorizable();
+ if (this_present_rootAuthorizable || that_present_rootAuthorizable) {
+ if (!(this_present_rootAuthorizable && that_present_rootAuthorizable))
+ return false;
+ if (!this.rootAuthorizable.equals(that.rootAuthorizable))
+ return false;
+ }
+
+ boolean this_present_roleToGroups = true && this.isSetRoleToGroups();
+ boolean that_present_roleToGroups = true && that.isSetRoleToGroups();
+ if (this_present_roleToGroups || that_present_roleToGroups) {
+ if (!(this_present_roleToGroups && that_present_roleToGroups))
+ return false;
+ if (!this.roleToGroups.equals(that.roleToGroups))
+ return false;
+ }
+
+ boolean this_present_objIds = true && this.isSetObjIds();
+ boolean that_present_objIds = true && that.isSetObjIds();
+ if (this_present_objIds || that_present_objIds) {
+ if (!(this_present_objIds && that_present_objIds))
+ return false;
+ if (!this.objIds.equals(that.objIds))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder builder = new HashCodeBuilder();
+
+ boolean present_rootAuthorizable = true && (isSetRootAuthorizable());
+ builder.append(present_rootAuthorizable);
+ if (present_rootAuthorizable)
+ builder.append(rootAuthorizable);
+
+ boolean present_roleToGroups = true && (isSetRoleToGroups());
+ builder.append(present_roleToGroups);
+ if (present_roleToGroups)
+ builder.append(roleToGroups);
+
+ boolean present_objIds = true && (isSetObjIds());
+ builder.append(present_objIds);
+ if (present_objIds)
+ builder.append(objIds);
+
+ return builder.toHashCode();
+ }
+
+ public int compareTo(TStoreSnapshot other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+ TStoreSnapshot typedOther = (TStoreSnapshot)other;
+
+ lastComparison = Boolean.valueOf(isSetRootAuthorizable()).compareTo(typedOther.isSetRootAuthorizable());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetRootAuthorizable()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.rootAuthorizable, typedOther.rootAuthorizable);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetRoleToGroups()).compareTo(typedOther.isSetRoleToGroups());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetRoleToGroups()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.roleToGroups, typedOther.roleToGroups);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetObjIds()).compareTo(typedOther.isSetObjIds());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetObjIds()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.objIds, typedOther.objIds);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("TStoreSnapshot(");
+ boolean first = true;
+
+ sb.append("rootAuthorizable:");
+ if (this.rootAuthorizable == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.rootAuthorizable);
+ }
+ first = false;
+ if (!first) sb.append(", ");
+ sb.append("roleToGroups:");
+ if (this.roleToGroups == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.roleToGroups);
+ }
+ first = false;
+ if (!first) sb.append(", ");
+ sb.append("objIds:");
+ if (this.objIds == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.objIds);
+ }
+ first = false;
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ if (!isSetRootAuthorizable()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'rootAuthorizable' is unset! Struct:" + toString());
+ }
+
+ if (!isSetRoleToGroups()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'roleToGroups' is unset! Struct:" + toString());
+ }
+
+ if (!isSetObjIds()) {
+ throw new org.apache.thrift.protocol.TProtocolException("Required field 'objIds' is unset! Struct:" + toString());
+ }
+
+ // check for sub-struct validity
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class TStoreSnapshotStandardSchemeFactory implements SchemeFactory {
+ public TStoreSnapshotStandardScheme getScheme() {
+ return new TStoreSnapshotStandardScheme();
+ }
+ }
+
+ private static class TStoreSnapshotStandardScheme extends StandardScheme<TStoreSnapshot> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, TStoreSnapshot struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // ROOT_AUTHORIZABLE
+ if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+ {
+ org.apache.thrift.protocol.TMap _map18 = iprot.readMapBegin();
+ struct.rootAuthorizable = new HashMap<String,TStoreAuthorizable>(2*_map18.size);
+ for (int _i19 = 0; _i19 < _map18.size; ++_i19)
+ {
+ String _key20; // required
+ TStoreAuthorizable _val21; // required
+ _key20 = iprot.readString();
+ _val21 = new TStoreAuthorizable();
+ _val21.read(iprot);
+ struct.rootAuthorizable.put(_key20, _val21);
+ }
+ iprot.readMapEnd();
+ }
+ struct.setRootAuthorizableIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 2: // ROLE_TO_GROUPS
+ if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+ {
+ org.apache.thrift.protocol.TMap _map22 = iprot.readMapBegin();
+ struct.roleToGroups = new HashMap<String,Set<String>>(2*_map22.size);
+ for (int _i23 = 0; _i23 < _map22.size; ++_i23)
+ {
+ String _key24; // required
+ Set<String> _val25; // required
+ _key24 = iprot.readString();
+ {
+ org.apache.thrift.protocol.TSet _set26 = iprot.readSetBegin();
+ _val25 = new HashSet<String>(2*_set26.size);
+ for (int _i27 = 0; _i27 < _set26.size; ++_i27)
+ {
+ String _elem28; // required
+ _elem28 = iprot.readString();
+ _val25.add(_elem28);
+ }
+ iprot.readSetEnd();
+ }
+ struct.roleToGroups.put(_key24, _val25);
+ }
+ iprot.readMapEnd();
+ }
+ struct.setRoleToGroupsIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 3: // OBJ_IDS
+ if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+ {
+ org.apache.thrift.protocol.TMap _map29 = iprot.readMapBegin();
+ struct.objIds = new HashMap<Integer,TStoreAuthorizable>(2*_map29.size);
+ for (int _i30 = 0; _i30 < _map29.size; ++_i30)
+ {
+ int _key31; // required
+ TStoreAuthorizable _val32; // required
+ _key31 = iprot.readI32();
+ _val32 = new TStoreAuthorizable();
+ _val32.read(iprot);
+ struct.objIds.put(_key31, _val32);
+ }
+ iprot.readMapEnd();
+ }
+ struct.setObjIdsIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, TStoreSnapshot struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.rootAuthorizable != null) {
+ oprot.writeFieldBegin(ROOT_AUTHORIZABLE_FIELD_DESC);
+ {
+ oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, struct.rootAuthorizable.size()));
+ for (Map.Entry<String, TStoreAuthorizable> _iter33 : struct.rootAuthorizable.entrySet())
+ {
+ oprot.writeString(_iter33.getKey());
+ _iter33.getValue().write(oprot);
+ }
+ oprot.writeMapEnd();
+ }
+ oprot.writeFieldEnd();
+ }
+ if (struct.roleToGroups != null) {
+ oprot.writeFieldBegin(ROLE_TO_GROUPS_FIELD_DESC);
+ {
+ oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.roleToGroups.size()));
+ for (Map.Entry<String, Set<String>> _iter34 : struct.roleToGroups.entrySet())
+ {
+ oprot.writeString(_iter34.getKey());
+ {
+ oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, _iter34.getValue().size()));
+ for (String _iter35 : _iter34.getValue())
+ {
+ oprot.writeString(_iter35);
+ }
+ oprot.writeSetEnd();
+ }
+ }
+ oprot.writeMapEnd();
+ }
+ oprot.writeFieldEnd();
+ }
+ if (struct.objIds != null) {
+ oprot.writeFieldBegin(OBJ_IDS_FIELD_DESC);
+ {
+ oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRUCT, struct.objIds.size()));
+ for (Map.Entry<Integer, TStoreAuthorizable> _iter36 : struct.objIds.entrySet())
+ {
+ oprot.writeI32(_iter36.getKey());
+ _iter36.getValue().write(oprot);
+ }
+ oprot.writeMapEnd();
+ }
+ oprot.writeFieldEnd();
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class TStoreSnapshotTupleSchemeFactory implements SchemeFactory {
+ public TStoreSnapshotTupleScheme getScheme() {
+ return new TStoreSnapshotTupleScheme();
+ }
+ }
+
+ private static class TStoreSnapshotTupleScheme extends TupleScheme<TStoreSnapshot> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, TStoreSnapshot struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ {
+ oprot.writeI32(struct.rootAuthorizable.size());
+ for (Map.Entry<String, TStoreAuthorizable> _iter37 : struct.rootAuthorizable.entrySet())
+ {
+ oprot.writeString(_iter37.getKey());
+ _iter37.getValue().write(oprot);
+ }
+ }
+ {
+ oprot.writeI32(struct.roleToGroups.size());
+ for (Map.Entry<String, Set<String>> _iter38 : struct.roleToGroups.entrySet())
+ {
+ oprot.writeString(_iter38.getKey());
+ {
+ oprot.writeI32(_iter38.getValue().size());
+ for (String _iter39 : _iter38.getValue())
+ {
+ oprot.writeString(_iter39);
+ }
+ }
+ }
+ }
+ {
+ oprot.writeI32(struct.objIds.size());
+ for (Map.Entry<Integer, TStoreAuthorizable> _iter40 : struct.objIds.entrySet())
+ {
+ oprot.writeI32(_iter40.getKey());
+ _iter40.getValue().write(oprot);
+ }
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, TStoreSnapshot struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ {
+ org.apache.thrift.protocol.TMap _map41 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.rootAuthorizable = new HashMap<String,TStoreAuthorizable>(2*_map41.size);
+ for (int _i42 = 0; _i42 < _map41.size; ++_i42)
+ {
+ String _key43; // required
+ TStoreAuthorizable _val44; // required
+ _key43 = iprot.readString();
+ _val44 = new TStoreAuthorizable();
+ _val44.read(iprot);
+ struct.rootAuthorizable.put(_key43, _val44);
+ }
+ }
+ struct.setRootAuthorizableIsSet(true);
+ {
+ org.apache.thrift.protocol.TMap _map45 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32());
+ struct.roleToGroups = new HashMap<String,Set<String>>(2*_map45.size);
+ for (int _i46 = 0; _i46 < _map45.size; ++_i46)
+ {
+ String _key47; // required
+ Set<String> _val48; // required
+ _key47 = iprot.readString();
+ {
+ org.apache.thrift.protocol.TSet _set49 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+ _val48 = new HashSet<String>(2*_set49.size);
+ for (int _i50 = 0; _i50 < _set49.size; ++_i50)
+ {
+ String _elem51; // required
+ _elem51 = iprot.readString();
+ _val48.add(_elem51);
+ }
+ }
+ struct.roleToGroups.put(_key47, _val48);
+ }
+ }
+ struct.setRoleToGroupsIsSet(true);
+ {
+ org.apache.thrift.protocol.TMap _map52 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+ struct.objIds = new HashMap<Integer,TStoreAuthorizable>(2*_map52.size);
+ for (int _i53 = 0; _i53 < _map52.size; ++_i53)
+ {
+ int _key54; // required
+ TStoreAuthorizable _val55; // required
+ _key54 = iprot.readI32();
+ _val55 = new TStoreAuthorizable();
+ _val55.read(iprot);
+ struct.objIds.put(_key54, _val55);
+ }
+ }
+ struct.setObjIdsIsSet(true);
+ }
+ }
+
+}
+
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryPrivilege.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryPrivilege.java
index 1c68a0f..1da45a5 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryPrivilege.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryPrivilege.java
@@ -25,7 +25,8 @@
import org.apache.sentry.core.common.utils.PathUtils;
import org.apache.sentry.core.model.db.AccessConstants;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.DbSentryStore;
+import org.apache.sentry.provider.db.service.persistent.StoreUtils;
/**
* Database backed Sentry Privilege. Any changes to this object
@@ -58,11 +59,11 @@
String URI, String action, Boolean grantOption) {
this.privilegeScope = privilegeScope;
this.serverName = serverName;
- this.dbName = SentryStore.toNULLCol(dbName);
- this.tableName = SentryStore.toNULLCol(tableName);
- this.columnName = SentryStore.toNULLCol(columnName);
- this.URI = SentryStore.toNULLCol(URI);
- this.action = SentryStore.toNULLCol(action);
+ this.dbName = StoreUtils.toNULLCol(dbName);
+ this.tableName = StoreUtils.toNULLCol(tableName);
+ this.columnName = StoreUtils.toNULLCol(columnName);
+ this.URI = StoreUtils.toNULLCol(URI);
+ this.action = StoreUtils.toNULLCol(action);
this.grantOption = grantOption;
this.roles = new HashSet<MSentryRole>();
}
@@ -77,11 +78,11 @@
public MSentryPrivilege(MSentryPrivilege other) {
this.privilegeScope = other.privilegeScope;
this.serverName = other.serverName;
- this.dbName = SentryStore.toNULLCol(other.dbName);
- this.tableName = SentryStore.toNULLCol(other.tableName);
- this.columnName = SentryStore.toNULLCol(other.columnName);
- this.URI = SentryStore.toNULLCol(other.URI);
- this.action = SentryStore.toNULLCol(other.action);
+ this.dbName = StoreUtils.toNULLCol(other.dbName);
+ this.tableName = StoreUtils.toNULLCol(other.tableName);
+ this.columnName = StoreUtils.toNULLCol(other.columnName);
+ this.URI = StoreUtils.toNULLCol(other.URI);
+ this.action = StoreUtils.toNULLCol(other.action);
this.grantOption = other.grantOption;
this.roles = new HashSet<MSentryRole>();
for (MSentryRole role : other.roles) {
@@ -304,7 +305,7 @@
}
private boolean isNULL(String s) {
- return SentryStore.isNULL(s);
+ return StoreUtils.isNULL(s);
}
public boolean isActionALL() {
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/DbSentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/DbSentryStore.java
new file mode 100644
index 0000000..136dab6
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/DbSentryStore.java
@@ -0,0 +1,1949 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import static org.apache.sentry.provider.common.ProviderConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.provider.common.ProviderConstants.KV_JOINER;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.jdo.FetchGroup;
+import javax.jdo.JDODataStoreException;
+import javax.jdo.JDOHelper;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Query;
+import javax.jdo.Transaction;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
+import org.apache.sentry.provider.common.ProviderConstants;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.provider.db.SentryAlreadyExistsException;
+import org.apache.sentry.provider.db.SentryGrantDeniedException;
+import org.apache.sentry.provider.db.SentryInvalidInputException;
+import org.apache.sentry.provider.db.SentryNoSuchObjectException;
+import org.apache.sentry.provider.db.service.model.MSentryGroup;
+import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
+import org.apache.sentry.provider.db.service.model.MSentryRole;
+import org.apache.sentry.provider.db.service.model.MSentryVersion;
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessor;
+import org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
+import org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilegeMap;
+import org.apache.sentry.provider.db.service.thrift.TSentryRole;
+import org.apache.sentry.service.thrift.ServiceConstants.PrivilegeScope;
+import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
+import org.datanucleus.store.rdbms.exceptions.MissingTableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.codahale.metrics.Gauge;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+/**
+ * SentryStore is the data access object for Sentry data. Strings
+ * such as role and group names will be normalized to lowercase
+ * in addition to starting and ending whitespace.
+ */
+public class SentryStore {
+ private static final UUID SERVER_UUID = UUID.randomUUID();
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(SentryStore.class);
+
+ public static String NULL_COL = "__NULL__";
+ static final String DEFAULT_DATA_DIR = "sentry_policy_db";
+
+ private static final Set<String> ALL_ACTIONS = Sets.newHashSet(AccessConstants.ALL,
+ AccessConstants.SELECT, AccessConstants.INSERT, AccessConstants.ALTER,
+ AccessConstants.CREATE, AccessConstants.DROP, AccessConstants.INDEX,
+ AccessConstants.LOCK);
+
+ // Now partial revoke just support action with SELECT,INSERT and ALL.
+ // e.g. If we REVOKE SELECT from a privilege with action ALL, it will leads to INSERT
+ // Otherwise, if we revoke other privilege(e.g. ALTER,DROP...), we will remove it from a role directly.
+ private static final Set<String> PARTIAL_REVOKE_ACTIONS = Sets.newHashSet(AccessConstants.ALL,
+ AccessConstants.ACTION_ALL.toLowerCase(), AccessConstants.SELECT, AccessConstants.INSERT);
+
+ /**
+ * Commit order sequence id. This is used by notification handlers
+ * to know the order in which events where committed to the database.
+ * This instance variable is incremented in incrementGetSequenceId
+ * and read in commitUpdateTransaction. Synchronization on this
+ * is required to read commitSequenceId.
+ */
+ private long commitSequenceId;
+ private final PersistenceManagerFactory pmf;
+ private Configuration conf;
+ private PrivCleaner privCleaner = null;
+ private Thread privCleanerThread = null;
+
+ public SentryStore(Configuration conf) throws SentryNoSuchObjectException,
+ SentryAccessDeniedException {
+ commitSequenceId = 0;
+ this.conf = conf;
+ Properties prop = new Properties();
+ prop.putAll(ServerConfig.SENTRY_STORE_DEFAULTS);
+ String jdbcUrl = conf.get(ServerConfig.SENTRY_STORE_JDBC_URL, "").trim();
+ Preconditions.checkArgument(!jdbcUrl.isEmpty(), "Required parameter " +
+ ServerConfig.SENTRY_STORE_JDBC_URL + " missing");
+ String user = conf.get(ServerConfig.SENTRY_STORE_JDBC_USER, ServerConfig.
+ SENTRY_STORE_JDBC_USER_DEFAULT).trim();
+ String pass = conf.get(ServerConfig.SENTRY_STORE_JDBC_PASS, ServerConfig.
+ SENTRY_STORE_JDBC_PASS_DEFAULT).trim();
+ String driverName = conf.get(ServerConfig.SENTRY_STORE_JDBC_DRIVER,
+ ServerConfig.SENTRY_STORE_JDBC_DRIVER_DEFAULT);
+ prop.setProperty(ServerConfig.JAVAX_JDO_URL, jdbcUrl);
+ prop.setProperty(ServerConfig.JAVAX_JDO_USER, user);
+ prop.setProperty(ServerConfig.JAVAX_JDO_PASS, pass);
+ prop.setProperty(ServerConfig.JAVAX_JDO_DRIVER_NAME, driverName);
+ for (Map.Entry<String, String> entry : conf) {
+ String key = entry.getKey();
+ if (key.startsWith(ServerConfig.SENTRY_JAVAX_JDO_PROPERTY_PREFIX) ||
+ key.startsWith(ServerConfig.SENTRY_DATANUCLEUS_PROPERTY_PREFIX)) {
+ key = StringUtils.removeStart(key, ServerConfig.SENTRY_DB_PROPERTY_PREFIX);
+ prop.setProperty(key, entry.getValue());
+ }
+ }
+
+
+ boolean checkSchemaVersion = conf.get(
+ ServerConfig.SENTRY_VERIFY_SCHEM_VERSION,
+ ServerConfig.SENTRY_VERIFY_SCHEM_VERSION_DEFAULT).equalsIgnoreCase(
+ "true");
+ if (!checkSchemaVersion) {
+ prop.setProperty("datanucleus.autoCreateSchema", "true");
+ prop.setProperty("datanucleus.fixedDatastore", "false");
+ }
+
+ // Disallow operations outside of transactions
+ prop.setProperty("datanucleus.NontransactionalRead", "false");
+ prop.setProperty("datanucleus.NontransactionalWrite", "false");
+
+ pmf = JDOHelper.getPersistenceManagerFactory(prop);
+ verifySentryStoreSchema(conf, checkSchemaVersion);
+
+ // Kick off the thread that cleans orphaned privileges (unless told not to)
+ privCleaner = this.new PrivCleaner();
+ if (conf.get(ServerConfig.SENTRY_STORE_ORPHANED_PRIVILEGE_REMOVAL,
+ ServerConfig.SENTRY_STORE_ORPHANED_PRIVILEGE_REMOVAL_DEFAULT)
+ .equalsIgnoreCase("true")) {
+ privCleanerThread = new Thread(privCleaner);
+ privCleanerThread.start();
+ }
+ }
+
+ // ensure that the backend DB schema is set
+ private void verifySentryStoreSchema(Configuration serverConf,
+ boolean checkVersion)
+ throws SentryNoSuchObjectException, SentryAccessDeniedException {
+ if (!checkVersion) {
+ setSentryVersion(SentryStoreSchemaInfo.getSentryVersion(),
+ "Schema version set implicitly");
+ } else {
+ String currentVersion = getSentryVersion();
+ if (!SentryStoreSchemaInfo.getSentryVersion().equals(currentVersion)) {
+ throw new SentryAccessDeniedException(
+ "The Sentry store schema version " + currentVersion
+ + " is different from distribution version "
+ + SentryStoreSchemaInfo.getSentryVersion());
+ }
+ }
+ }
+
+ public synchronized void stop() {
+ if (privCleanerThread != null) {
+ privCleaner.exit();
+ try {
+ privCleanerThread.join();
+ } catch (InterruptedException e) {
+ // Ignore...
+ }
+ }
+ if (pmf != null) {
+ pmf.close();
+ }
+ }
+
+ /**
+ * PersistenceManager object and Transaction object have a one to one
+ * correspondence. Each PersistenceManager object is associated with a
+ * transaction object and vice versa. Hence we create a persistence manager
+ * instance when we create a new transaction. We create a new transaction
+ * for every store API since we want that unit of work to behave as a
+ * transaction.
+ *
+ * Note that there's only one instance of PersistenceManagerFactory object
+ * for the service.
+ *
+ * Synchronized because we obtain persistence manager
+ */
+ public synchronized PersistenceManager openTransaction() {
+ PersistenceManager pm = pmf.getPersistenceManager();
+ Transaction currentTransaction = pm.currentTransaction();
+ currentTransaction.begin();
+ return pm;
+ }
+
+ /**
+ * Synchronized due to sequence id generation
+ */
+ public synchronized CommitContext commitUpdateTransaction(PersistenceManager pm) {
+ commitTransaction(pm);
+ return new CommitContext(SERVER_UUID, incrementGetSequenceId());
+ }
+
+ /**
+ * Increments commitSequenceId which should not be modified outside
+ * this method.
+ *
+ * @return sequence id
+ */
+ private synchronized long incrementGetSequenceId() {
+ return ++commitSequenceId;
+ }
+
+ public void commitTransaction(PersistenceManager pm) {
+ Transaction currentTransaction = pm.currentTransaction();
+ try {
+ Preconditions.checkState(currentTransaction.isActive(), "Transaction is not active");
+ currentTransaction.commit();
+ } finally {
+ pm.close();
+ }
+ }
+
+ public void rollbackTransaction(PersistenceManager pm) {
+ if (pm == null || pm.isClosed()) {
+ return;
+ }
+ Transaction currentTransaction = pm.currentTransaction();
+ if (currentTransaction.isActive()) {
+ try {
+ currentTransaction.rollback();
+ } finally {
+ pm.close();
+ }
+ }
+ }
+ /**
+ Get the MSentry object from roleName
+ Note: Should be called inside a transaction
+ */
+ public MSentryRole getMSentryRole(PersistenceManager pm, String roleName) {
+ Query query = pm.newQuery(MSentryRole.class);
+ query.setFilter("this.roleName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ MSentryRole sentryRole = (MSentryRole) query.execute(roleName);
+ return sentryRole;
+ }
+
+ /**
+ * Normalize the string values
+ */
+ private String trimAndLower(String input) {
+ return input.trim().toLowerCase();
+ }
+ /**
+ * Create a sentry role and persist it.
+ * @param roleName: Name of the role being persisted
+ * @returns commit context used for notification handlers
+ * @throws SentryAlreadyExistsException
+ */
+ public CommitContext createSentryRole(String roleName)
+ throws SentryAlreadyExistsException {
+ roleName = trimAndLower(roleName);
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ pm = openTransaction();
+ MSentryRole mSentryRole = getMSentryRole(pm, roleName);
+ if (mSentryRole == null) {
+ MSentryRole mRole = new MSentryRole(roleName, System.currentTimeMillis());
+ pm.makePersistent(mRole);
+ CommitContext commit = commitUpdateTransaction(pm);
+ rollbackTransaction = false;
+ return commit;
+ } else {
+ throw new SentryAlreadyExistsException("Role: " + roleName);
+ }
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ private <T> Long getCount(Class<T> tClass) {
+ PersistenceManager pm = null;
+ Long size = new Long(-1);
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery();
+ query.setClass(tClass);
+ query.setResult("count(this)");
+ size = (Long)query.execute();
+
+ } finally {
+ commitTransaction(pm);
+ }
+ return size;
+ }
+ public Gauge<Long> getRoleCountGauge() {
+ return new Gauge< Long >() {
+ @Override
+ public Long getValue() {
+ return getCount(MSentryRole.class);
+ }
+ };
+ }
+
+ public Gauge<Long> getPrivilegeCountGauge() {
+ return new Gauge< Long >() {
+ @Override
+ public Long getValue() {
+ return getCount(MSentryPrivilege.class);
+ }
+ };
+ }
+ public Gauge<Long> getGroupCountGauge() {
+ return new Gauge< Long >() {
+ @Override
+ public Long getValue() {
+ return getCount(MSentryGroup.class);
+ }
+ };
+ }
+
+ /**
+ * Lets the test code know how many privs are in the db, so that we know
+ * if they are in fact being cleaned up when not being referenced any more.
+ * @return The number of rows in the db priv table.
+ */
+ @VisibleForTesting
+ long countMSentryPrivileges() {
+ return getCount(MSentryPrivilege.class);
+ }
+
+ public CommitContext alterSentryRoleGrantPrivilege(String grantorPrincipal,
+ String roleName, TSentryPrivilege privilege)
+ throws SentryUserException {
+ return alterSentryRoleGrantPrivileges(grantorPrincipal,
+ roleName, Sets.newHashSet(privilege));
+ }
+
+ public CommitContext alterSentryRoleGrantPrivileges(String grantorPrincipal,
+ String roleName, Set<TSentryPrivilege> privileges)
+ throws SentryUserException {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ roleName = trimAndLower(roleName);
+ try {
+ pm = openTransaction();
+ for (TSentryPrivilege privilege : privileges) {
+ // first do grant check
+ grantOptionCheck(pm, grantorPrincipal, privilege);
+
+ MSentryPrivilege mPrivilege = alterSentryRoleGrantPrivilegeCore(pm, roleName, privilege);
+
+ if (mPrivilege != null) {
+ convertToTSentryPrivilege(mPrivilege, privilege);
+ }
+ }
+ CommitContext commit = commitUpdateTransaction(pm);
+ rollbackTransaction = false;
+ return commit;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ private MSentryPrivilege alterSentryRoleGrantPrivilegeCore(PersistenceManager pm,
+ String roleName, TSentryPrivilege privilege)
+ throws SentryNoSuchObjectException, SentryInvalidInputException {
+ MSentryPrivilege mPrivilege = null;
+ MSentryRole mRole = getMSentryRole(pm, roleName);
+ if (mRole == null) {
+ throw new SentryNoSuchObjectException("Role: " + roleName);
+ } else {
+
+ if ((!isNULL(privilege.getColumnName())) || (!isNULL(privilege.getTableName()))
+ || (!isNULL(privilege.getDbName()))) {
+ // If Grant is for ALL and Either INSERT/SELECT already exists..
+ // need to remove it and GRANT ALL..
+ if (privilege.getAction().equalsIgnoreCase("*")) {
+ TSentryPrivilege tNotAll = new TSentryPrivilege(privilege);
+ tNotAll.setAction(AccessConstants.SELECT);
+ MSentryPrivilege mSelect = getMSentryPrivilege(tNotAll, pm);
+ tNotAll.setAction(AccessConstants.INSERT);
+ MSentryPrivilege mInsert = getMSentryPrivilege(tNotAll, pm);
+ if ((mSelect != null) && (mRole.getPrivileges().contains(mSelect))) {
+ mSelect.removeRole(mRole);
+ privCleaner.incPrivRemoval();
+ pm.makePersistent(mSelect);
+ }
+ if ((mInsert != null) && (mRole.getPrivileges().contains(mInsert))) {
+ mInsert.removeRole(mRole);
+ privCleaner.incPrivRemoval();
+ pm.makePersistent(mInsert);
+ }
+ } else {
+ // If Grant is for Either INSERT/SELECT and ALL already exists..
+ // do nothing..
+ TSentryPrivilege tAll = new TSentryPrivilege(privilege);
+ tAll.setAction(AccessConstants.ALL);
+ MSentryPrivilege mAll = getMSentryPrivilege(tAll, pm);
+ if ((mAll != null) && (mRole.getPrivileges().contains(mAll))) {
+ return null;
+ }
+ }
+ }
+
+ mPrivilege = getMSentryPrivilege(privilege, pm);
+ if (mPrivilege == null) {
+ mPrivilege = convertToMSentryPrivilege(privilege);
+ }
+ mPrivilege.appendRole(mRole);
+ pm.makePersistent(mRole);
+ pm.makePersistent(mPrivilege);
+ }
+ return mPrivilege;
+ }
+
+ public CommitContext alterSentryRoleRevokePrivilege(String grantorPrincipal,
+ String roleName, TSentryPrivilege tPrivilege) throws SentryUserException {
+ return alterSentryRoleRevokePrivileges(grantorPrincipal,
+ roleName, Sets.newHashSet(tPrivilege));
+ }
+
+ public CommitContext alterSentryRoleRevokePrivileges(String grantorPrincipal,
+ String roleName, Set<TSentryPrivilege> tPrivileges) throws SentryUserException {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ roleName = safeTrimLower(roleName);
+ try {
+ pm = openTransaction();
+ for (TSentryPrivilege tPrivilege : tPrivileges) {
+ // first do revoke check
+ grantOptionCheck(pm, grantorPrincipal, tPrivilege);
+
+ alterSentryRoleRevokePrivilegeCore(pm, roleName, tPrivilege);
+ }
+
+ CommitContext commit = commitUpdateTransaction(pm);
+ rollbackTransaction = false;
+ return commit;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ private void alterSentryRoleRevokePrivilegeCore(PersistenceManager pm,
+ String roleName, TSentryPrivilege tPrivilege)
+ throws SentryNoSuchObjectException, SentryInvalidInputException {
+ Query query = pm.newQuery(MSentryRole.class);
+ query.setFilter("this.roleName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ MSentryRole mRole = (MSentryRole) query.execute(roleName);
+ if (mRole == null) {
+ throw new SentryNoSuchObjectException("Role: " + roleName);
+ } else {
+ query = pm.newQuery(MSentryPrivilege.class);
+ MSentryPrivilege mPrivilege = getMSentryPrivilege(tPrivilege, pm);
+ if (mPrivilege == null) {
+ mPrivilege = convertToMSentryPrivilege(tPrivilege);
+ } else {
+ mPrivilege = (MSentryPrivilege) pm.detachCopy(mPrivilege);
+ }
+
+ Set<MSentryPrivilege> privilegeGraph = Sets.newHashSet();
+ if (mPrivilege.getGrantOption() != null) {
+ privilegeGraph.add(mPrivilege);
+ } else {
+ MSentryPrivilege mTure = new MSentryPrivilege(mPrivilege);
+ mTure.setGrantOption(true);
+ privilegeGraph.add(mTure);
+ MSentryPrivilege mFalse = new MSentryPrivilege(mPrivilege);
+ mFalse.setGrantOption(false);
+ privilegeGraph.add(mFalse);
+ }
+ // Get the privilege graph
+ populateChildren(pm, Sets.newHashSet(roleName), mPrivilege, privilegeGraph);
+ for (MSentryPrivilege childPriv : privilegeGraph) {
+ revokePrivilegeFromRole(pm, tPrivilege, mRole, childPriv);
+ }
+ pm.makePersistent(mRole);
+ }
+ }
+
+ /**
+ * Roles can be granted ALL, SELECT, and INSERT on tables. When
+ * a role has ALL and SELECT or INSERT are revoked, we need to remove the ALL
+ * privilege and add SELECT (INSERT was revoked) or INSERT (SELECT was revoked).
+ */
+ private void revokePartial(PersistenceManager pm,
+ TSentryPrivilege requestedPrivToRevoke, MSentryRole mRole,
+ MSentryPrivilege currentPrivilege) throws SentryInvalidInputException {
+ MSentryPrivilege persistedPriv = getMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege), pm);
+ if (persistedPriv == null) {
+ persistedPriv = convertToMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege));
+ }
+
+ if (requestedPrivToRevoke.getAction().equalsIgnoreCase("ALL") || requestedPrivToRevoke.getAction().equalsIgnoreCase("*")) {
+ persistedPriv.removeRole(mRole);
+ privCleaner.incPrivRemoval();
+ pm.makePersistent(persistedPriv);
+ } else if (requestedPrivToRevoke.getAction().equalsIgnoreCase(AccessConstants.SELECT)
+ && (!currentPrivilege.getAction().equalsIgnoreCase(AccessConstants.INSERT))) {
+ revokeRolePartial(pm, mRole, currentPrivilege, persistedPriv, AccessConstants.INSERT);
+ } else if (requestedPrivToRevoke.getAction().equalsIgnoreCase(AccessConstants.INSERT)
+ && (!currentPrivilege.getAction().equalsIgnoreCase(AccessConstants.SELECT))) {
+ revokeRolePartial(pm, mRole, currentPrivilege, persistedPriv, AccessConstants.SELECT);
+ }
+ }
+
+ private void revokeRolePartial(PersistenceManager pm, MSentryRole mRole,
+ MSentryPrivilege currentPrivilege, MSentryPrivilege persistedPriv, String addAction)
+ throws SentryInvalidInputException {
+ // If table / URI, remove ALL
+ persistedPriv.removeRole(mRole);
+ privCleaner.incPrivRemoval();
+ pm.makePersistent(persistedPriv);
+
+ currentPrivilege.setAction(AccessConstants.ALL);
+ persistedPriv = getMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege), pm);
+ if ((persistedPriv != null)&&(mRole.getPrivileges().contains(persistedPriv))) {
+ persistedPriv.removeRole(mRole);
+ privCleaner.incPrivRemoval();
+ pm.makePersistent(persistedPriv);
+
+ currentPrivilege.setAction(addAction);
+ persistedPriv = getMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege), pm);
+ if (persistedPriv == null) {
+ persistedPriv = convertToMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege));
+ mRole.appendPrivilege(persistedPriv);
+ }
+ persistedPriv.appendRole(mRole);
+ pm.makePersistent(persistedPriv);
+ }
+ }
+
+ /**
+ * Revoke privilege from role
+ */
+ private void revokePrivilegeFromRole(PersistenceManager pm, TSentryPrivilege tPrivilege,
+ MSentryRole mRole, MSentryPrivilege mPrivilege) throws SentryInvalidInputException {
+ if (PARTIAL_REVOKE_ACTIONS.contains(mPrivilege.getAction())) {
+ // if this privilege is in {ALL,SELECT,INSERT}
+ // we will do partial revoke
+ revokePartial(pm, tPrivilege, mRole, mPrivilege);
+ } else {
+ // if this privilege is not ALL, SELECT nor INSERT,
+ // we will revoke it from role directly
+ mPrivilege.removeRole(mRole);
+ pm.makePersistent(mPrivilege);
+ }
+ }
+
+ /**
+ * Explore Privilege graph and collect child privileges.
+ * The responsibility to commit/rollback the transaction should be handled by the caller.
+ */
+ private void populateChildren(PersistenceManager pm, Set<String> roleNames, MSentryPrivilege priv,
+ Set<MSentryPrivilege> children) throws SentryInvalidInputException {
+ Preconditions.checkNotNull(pm);
+ if ((!isNULL(priv.getServerName())) || (!isNULL(priv.getDbName()))
+ || (!isNULL(priv.getTableName()))) {
+ // Get all TableLevel Privs
+ Set<MSentryPrivilege> childPrivs = getChildPrivileges(pm, roleNames, priv);
+ for (MSentryPrivilege childPriv : childPrivs) {
+ // Only recurse for table level privs..
+ if ((!isNULL(childPriv.getDbName())) && (!isNULL(childPriv.getTableName()))
+ && (!isNULL(childPriv.getColumnName()))) {
+ populateChildren(pm, roleNames, childPriv, children);
+ }
+ // The method getChildPrivileges() didn't do filter on "action",
+ // if the action is not "All", it should judge the action of children privilege.
+ // For example: a user has a privilege “All on Col1”,
+ // if the operation is “REVOKE INSERT on table”
+ // the privilege should be the child of table level privilege.
+ // but the privilege may still have other meaning, likes "SELECT on Col1".
+ // and the privileges like "SELECT on Col1" should not be revoke.
+ if (!priv.isActionALL()) {
+ if (childPriv.isActionALL()) {
+ // If the child privilege is All, we should convert it to the same
+ // privilege with parent
+ childPriv.setAction(priv.getAction());
+ }
+ // Only include privilege that imply the parent privilege.
+ if (!priv.implies(childPriv)) {
+ continue;
+ }
+ }
+ children.add(childPriv);
+ }
+ }
+ }
+
+ private Set<MSentryPrivilege> getChildPrivileges(PersistenceManager pm, Set<String> roleNames,
+ MSentryPrivilege parent) throws SentryInvalidInputException {
+ // Column and URI do not have children
+ if ((!isNULL(parent.getColumnName())) || (!isNULL(parent.getURI()))) {
+ return new HashSet<MSentryPrivilege>();
+ }
+
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
+ List<String> rolesFiler = new LinkedList<String>();
+ for (String rName : roleNames) {
+ rolesFiler.add("role.roleName == \"" + rName.trim().toLowerCase() + "\"");
+ }
+ StringBuilder filters = new StringBuilder("roles.contains(role) "
+ + "&& (" + Joiner.on(" || ").join(rolesFiler) + ")");
+ filters.append(" && serverName == \"" + parent.getServerName() + "\"");
+ if (!isNULL(parent.getDbName())) {
+ filters.append(" && dbName == \"" + parent.getDbName() + "\"");
+ if (!isNULL(parent.getTableName())) {
+ filters.append(" && tableName == \"" + parent.getTableName() + "\"");
+ filters.append(" && columnName != \"__NULL__\"");
+ } else {
+ filters.append(" && tableName != \"__NULL__\"");
+ }
+ } else {
+ filters.append(" && (dbName != \"__NULL__\" || URI != \"__NULL__\")");
+ }
+
+ query.setFilter(filters.toString());
+ query.setResult("privilegeScope, serverName, dbName, tableName, columnName," +
+ " URI, action, grantOption");
+ Set<MSentryPrivilege> privileges = new HashSet<MSentryPrivilege>();
+ for (Object[] privObj : (List<Object[]>) query.execute()) {
+ MSentryPrivilege priv = new MSentryPrivilege();
+ priv.setPrivilegeScope((String) privObj[0]);
+ priv.setServerName((String) privObj[1]);
+ priv.setDbName((String) privObj[2]);
+ priv.setTableName((String) privObj[3]);
+ priv.setColumnName((String) privObj[4]);
+ priv.setURI((String) privObj[5]);
+ priv.setAction((String) privObj[6]);
+ priv.setGrantOption((Boolean) privObj[7]);
+ privileges.add(priv);
+ }
+ return privileges;
+ }
+
+ private List<MSentryPrivilege> getMSentryPrivileges(TSentryPrivilege tPriv, PersistenceManager pm) {
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ StringBuilder filters = new StringBuilder("this.serverName == \""
+ + toNULLCol(safeTrimLower(tPriv.getServerName())) + "\" ");
+ if (!isNULL(tPriv.getDbName())) {
+ filters.append("&& this.dbName == \"" + toNULLCol(safeTrimLower(tPriv.getDbName())) + "\" ");
+ if (!isNULL(tPriv.getTableName())) {
+ filters.append("&& this.tableName == \"" + toNULLCol(safeTrimLower(tPriv.getTableName())) + "\" ");
+ if (!isNULL(tPriv.getColumnName())) {
+ filters.append("&& this.columnName == \"" + toNULLCol(safeTrimLower(tPriv.getColumnName())) + "\" ");
+ }
+ }
+ }
+ // if db is null, uri is not null
+ else if (!isNULL(tPriv.getURI())){
+ filters.append("&& this.URI == \"" + toNULLCol(safeTrim(tPriv.getURI())) + "\" ");
+ }
+ filters.append("&& this.action == \"" + toNULLCol(safeTrimLower(tPriv.getAction())) + "\"");
+
+ query.setFilter(filters.toString());
+ List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query.execute();
+ return privileges;
+ }
+
+ private MSentryPrivilege getMSentryPrivilege(TSentryPrivilege tPriv, PersistenceManager pm) {
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ query.setFilter("this.serverName == \"" + toNULLCol(safeTrimLower(tPriv.getServerName())) + "\" "
+ + "&& this.dbName == \"" + toNULLCol(safeTrimLower(tPriv.getDbName())) + "\" "
+ + "&& this.tableName == \"" + toNULLCol(safeTrimLower(tPriv.getTableName())) + "\" "
+ + "&& this.columnName == \"" + toNULLCol(safeTrimLower(tPriv.getColumnName())) + "\" "
+ + "&& this.URI == \"" + toNULLCol(safeTrim(tPriv.getURI())) + "\" "
+ + "&& this.grantOption == grantOption "
+ + "&& this.action == \"" + toNULLCol(safeTrimLower(tPriv.getAction())) + "\"");
+ query.declareParameters("Boolean grantOption");
+ query.setUnique(true);
+ Boolean grantOption = null;
+ if (tPriv.getGrantOption().equals(TSentryGrantOption.TRUE)) {
+ grantOption = true;
+ } else if (tPriv.getGrantOption().equals(TSentryGrantOption.FALSE)) {
+ grantOption = false;
+ }
+ Object obj = query.execute(grantOption);
+ if (obj != null)
+ return (MSentryPrivilege) obj;
+ return null;
+ }
+
+ public CommitContext dropSentryRole(String roleName)
+ throws SentryNoSuchObjectException {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ roleName = roleName.trim().toLowerCase();
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryRole.class);
+ query.setFilter("this.roleName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ MSentryRole sentryRole = (MSentryRole) query.execute(roleName);
+ if (sentryRole == null) {
+ throw new SentryNoSuchObjectException("Role " + roleName);
+ } else {
+ pm.retrieve(sentryRole);
+ int numPrivs = sentryRole.getPrivileges().size();
+ sentryRole.removePrivileges();
+ //with SENTRY-398 generic model
+ sentryRole.removeGMPrivileges();
+ privCleaner.incPrivRemoval(numPrivs);
+ pm.deletePersistent(sentryRole);
+ }
+ CommitContext commit = commitUpdateTransaction(pm);
+ rollbackTransaction = false;
+ return commit;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ public CommitContext alterSentryRoleAddGroups( String grantorPrincipal, String roleName,
+ Set<TSentryGroup> groupNames)
+ throws SentryNoSuchObjectException {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ roleName = roleName.trim().toLowerCase();
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryRole.class);
+ query.setFilter("this.roleName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ MSentryRole role = (MSentryRole) query.execute(roleName);
+ if (role == null) {
+ throw new SentryNoSuchObjectException("Role: " + roleName);
+ } else {
+ query = pm.newQuery(MSentryGroup.class);
+ query.setFilter("this.groupName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ List<MSentryGroup> groups = Lists.newArrayList();
+ for (TSentryGroup tGroup : groupNames) {
+ String groupName = tGroup.getGroupName().trim();
+ MSentryGroup group = (MSentryGroup) query.execute(groupName);
+ if (group == null) {
+ group = new MSentryGroup(groupName, System.currentTimeMillis(),
+ Sets.newHashSet(role));
+ }
+ group.appendRole(role);
+ groups.add(group);
+ }
+ pm.makePersistentAll(groups);
+ CommitContext commit = commitUpdateTransaction(pm);
+ rollbackTransaction = false;
+ return commit;
+ }
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ public CommitContext alterSentryRoleDeleteGroups(String roleName,
+ Set<TSentryGroup> groupNames)
+ throws SentryNoSuchObjectException {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ roleName = roleName.trim().toLowerCase();
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryRole.class);
+ query.setFilter("this.roleName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ MSentryRole role = (MSentryRole) query.execute(roleName);
+ if (role == null) {
+ throw new SentryNoSuchObjectException("Role: " + roleName);
+ } else {
+ query = pm.newQuery(MSentryGroup.class);
+ query.setFilter("this.groupName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ List<MSentryGroup> groups = Lists.newArrayList();
+ for (TSentryGroup tGroup : groupNames) {
+ String groupName = tGroup.getGroupName().trim();
+ MSentryGroup group = (MSentryGroup) query.execute(groupName);
+ if (group != null) {
+ group.removeRole(role);
+ groups.add(group);
+ }
+ }
+ pm.makePersistentAll(groups);
+ CommitContext commit = commitUpdateTransaction(pm);
+ rollbackTransaction = false;
+ return commit;
+ }
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ @VisibleForTesting
+ MSentryRole getMSentryRoleByName(String roleName)
+ throws SentryNoSuchObjectException {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ roleName = roleName.trim().toLowerCase();
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryRole.class);
+ query.setFilter("this.roleName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ MSentryRole sentryRole = (MSentryRole) query.execute(roleName);
+ if (sentryRole == null) {
+ throw new SentryNoSuchObjectException("Role " + roleName);
+ } else {
+ pm.retrieve(sentryRole);
+ }
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ return sentryRole;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ private boolean hasAnyServerPrivileges(Set<String> roleNames, String serverName) {
+ if ((roleNames.size() == 0)||(roleNames == null)) return false;
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
+ List<String> rolesFiler = new LinkedList<String>();
+ for (String rName : roleNames) {
+ rolesFiler.add("role.roleName == \"" + rName.trim().toLowerCase() + "\"");
+ }
+ StringBuilder filters = new StringBuilder("roles.contains(role) "
+ + "&& (" + Joiner.on(" || ").join(rolesFiler) + ") ");
+ filters.append("&& serverName == \"" + serverName.trim().toLowerCase() + "\"");
+ query.setFilter(filters.toString());
+ query.setResult("count(this)");
+
+ Long numPrivs = (Long) query.execute();
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ return (numPrivs > 0);
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ List<MSentryPrivilege> getMSentryPrivileges(Set<String> roleNames, TSentryAuthorizable authHierarchy) {
+ if ((roleNames.size() == 0)||(roleNames == null)) return new ArrayList<MSentryPrivilege>();
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
+ List<String> rolesFiler = new LinkedList<String>();
+ for (String rName : roleNames) {
+ rolesFiler.add("role.roleName == \"" + rName.trim().toLowerCase() + "\"");
+ }
+ StringBuilder filters = new StringBuilder("roles.contains(role) "
+ + "&& (" + Joiner.on(" || ").join(rolesFiler) + ") ");
+ if ((authHierarchy != null) && (authHierarchy.getServer() != null)) {
+ filters.append("&& serverName == \"" + authHierarchy.getServer().toLowerCase() + "\"");
+ if (authHierarchy.getDb() != null) {
+ filters.append(" && ((dbName == \"" + authHierarchy.getDb().toLowerCase() + "\") || (dbName == \"__NULL__\")) && (URI == \"__NULL__\")");
+ if ((authHierarchy.getTable() != null)
+ && !AccessConstants.ALL
+ .equalsIgnoreCase(authHierarchy.getTable())) {
+ filters.append(" && ((tableName == \"" + authHierarchy.getTable().toLowerCase() + "\") || (tableName == \"__NULL__\")) && (URI == \"__NULL__\")");
+ if ((authHierarchy.getColumn() != null)
+ && !AccessConstants.ALL
+ .equalsIgnoreCase(authHierarchy.getColumn())) {
+ filters.append(" && ((columnName == \"" + authHierarchy.getColumn().toLowerCase() + "\") || (columnName == \"__NULL__\")) && (URI == \"__NULL__\")");
+ }
+ }
+ }
+ if (authHierarchy.getUri() != null) {
+ filters.append(" && ((URI != \"__NULL__\") && (\"" + authHierarchy.getUri() + "\".startsWith(URI)) || (URI == \"__NULL__\")) && (dbName == \"__NULL__\")");
+ }
+ }
+ query.setFilter(filters.toString());
+ List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query.execute();
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ return privileges;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ List<MSentryPrivilege> getMSentryPrivilegesByAuth(Set<String> roleNames, TSentryAuthorizable authHierarchy) {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ StringBuilder filters = new StringBuilder();
+ if ((roleNames.size() == 0)||(roleNames == null)) {
+ filters.append(" !roles.isEmpty() ");
+ } else {
+ query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
+ List<String> rolesFiler = new LinkedList<String>();
+ for (String rName : roleNames) {
+ rolesFiler.add("role.roleName == \"" + rName.trim().toLowerCase() + "\"");
+ }
+ filters.append("roles.contains(role) "
+ + "&& (" + Joiner.on(" || ").join(rolesFiler) + ") ");
+ }
+ if ((authHierarchy.getServer() != null)) {
+ filters.append("&& serverName == \"" +
+ authHierarchy.getServer().toLowerCase() + "\"");
+ if (authHierarchy.getDb() != null) {
+ filters.append(" && (dbName == \"" +
+ authHierarchy.getDb().toLowerCase() + "\") && (URI == \"__NULL__\")");
+ if (authHierarchy.getTable() != null) {
+ filters.append(" && (tableName == \"" +
+ authHierarchy.getTable().toLowerCase() + "\")");
+ } else {
+ filters.append(" && (tableName == \"__NULL__\")");
+ }
+ } else if (authHierarchy.getUri() != null) {
+ filters.append(" && (URI != \"__NULL__\") && (\"" + authHierarchy.getUri() +
+ "\".startsWith(URI)) && (dbName == \"__NULL__\")");
+ } else {
+ filters.append(" && (dbName == \"__NULL__\") && (URI == \"__NULL__\")");
+ }
+ } else {
+ // if no server, then return empty resultset
+ return new ArrayList<MSentryPrivilege>();
+ }
+ FetchGroup grp = pm.getFetchGroup(
+ org.apache.sentry.provider.db.service.model.MSentryPrivilege.class,
+ "fetchRole");
+ grp.addMember("roles");
+ pm.getFetchPlan().addGroup("fetchRole");
+ query.setFilter(filters.toString());
+ List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query.execute();
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ return privileges;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ public TSentryPrivilegeMap listSentryPrivilegesByAuthorizable(
+ Set<String> groups, TSentryActiveRoleSet activeRoles,
+ TSentryAuthorizable authHierarchy, boolean isAdmin)
+ throws SentryInvalidInputException {
+ Map<String, Set<TSentryPrivilege>> resultPrivilegeMap = Maps.newTreeMap();
+ Set<String> roles = Sets.newHashSet();
+ if (groups != null && !groups.isEmpty()) {
+ roles = getRolesToQuery(groups, new TSentryActiveRoleSet(true, null));
+ }
+ if (activeRoles != null && !activeRoles.isAll()) {
+ // need to check/convert to lowercase here since this is from user input
+ for (String aRole : activeRoles.getRoles()) {
+ roles.add(aRole.toLowerCase());
+ }
+ }
+
+ // An empty 'roles' is a treated as a wildcard (in case of admin role)..
+ // so if not admin, don't return anything if 'roles' is empty..
+ if (isAdmin || !roles.isEmpty()) {
+ List<MSentryPrivilege> mSentryPrivileges = getMSentryPrivilegesByAuth(roles,
+ authHierarchy);
+ for (MSentryPrivilege priv : mSentryPrivileges) {
+ for (MSentryRole role : priv.getRoles()) {
+ TSentryPrivilege tPriv = convertToTSentryPrivilege(priv);
+ if (resultPrivilegeMap.containsKey(role.getRoleName())) {
+ resultPrivilegeMap.get(role.getRoleName()).add(tPriv);
+ } else {
+ Set<TSentryPrivilege> tPrivSet = Sets.newTreeSet();
+ tPrivSet.add(tPriv);
+ resultPrivilegeMap.put(role.getRoleName(), tPrivSet);
+ }
+ }
+ }
+ }
+ return new TSentryPrivilegeMap(resultPrivilegeMap);
+ }
+
+ private Set<MSentryPrivilege> getMSentryPrivilegesByRoleName(String roleName)
+ throws SentryNoSuchObjectException {
+ MSentryRole mSentryRole = getMSentryRoleByName(roleName);
+ return mSentryRole.getPrivileges();
+ }
+
+ /**
+ * Gets sentry privilege objects for a given roleName from the persistence layer
+ * @param roleName : roleName to look up
+ * @return : Set of thrift sentry privilege objects
+ * @throws SentryNoSuchObjectException
+ */
+
+ public Set<TSentryPrivilege> getAllTSentryPrivilegesByRoleName(String roleName)
+ throws SentryNoSuchObjectException {
+ return convertToTSentryPrivileges(getMSentryPrivilegesByRoleName(roleName));
+ }
+
+
+ /**
+ * Gets sentry privilege objects for criteria from the persistence layer
+ * @param roleNames : roleNames to look up (required)
+ * @param authHierarchy : filter push down based on auth hierarchy (optional)
+ * @return : Set of thrift sentry privilege objects
+ * @throws SentryNoSuchObjectException
+ */
+
+ public Set<TSentryPrivilege> getTSentryPrivileges(Set<String> roleNames, TSentryAuthorizable authHierarchy) throws SentryInvalidInputException {
+ if (authHierarchy.getServer() == null) {
+ throw new SentryInvalidInputException("serverName cannot be null !!");
+ }
+ if ((authHierarchy.getTable() != null) && (authHierarchy.getDb() == null)) {
+ throw new SentryInvalidInputException("dbName cannot be null when tableName is present !!");
+ }
+ if ((authHierarchy.getColumn() != null) && (authHierarchy.getTable() == null)) {
+ throw new SentryInvalidInputException("tableName cannot be null when columnName is present !!");
+ }
+ if ((authHierarchy.getUri() == null) && (authHierarchy.getDb() == null)) {
+ throw new SentryInvalidInputException("One of uri or dbName must not be null !!");
+ }
+ return convertToTSentryPrivileges(getMSentryPrivileges(roleNames, authHierarchy));
+ }
+
+
+ private Set<MSentryRole> getMSentryRolesByGroupName(String groupName)
+ throws SentryNoSuchObjectException {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ Set<MSentryRole> roles;
+ pm = openTransaction();
+
+ //If no group name was specified, return all roles
+ if (groupName == null) {
+ Query query = pm.newQuery(MSentryRole.class);
+ roles = new HashSet<MSentryRole>((List<MSentryRole>)query.execute());
+ } else {
+ Query query = pm.newQuery(MSentryGroup.class);
+ MSentryGroup sentryGroup;
+ groupName = groupName.trim();
+ query.setFilter("this.groupName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ sentryGroup = (MSentryGroup) query.execute(groupName);
+ if (sentryGroup == null) {
+ throw new SentryNoSuchObjectException("Group " + groupName);
+ } else {
+ pm.retrieve(sentryGroup);
+ }
+ roles = sentryGroup.getRoles();
+ }
+ for ( MSentryRole role: roles) {
+ pm.retrieve(role);
+ }
+ commitTransaction(pm);
+ rollbackTransaction = false;
+ return roles;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ /**
+ * Gets sentry role objects for a given groupName from the persistence layer
+ * @param groupName : groupName to look up ( if null returns all roles for all groups)
+ * @return : Set of thrift sentry role objects
+ * @throws SentryNoSuchObjectException
+ */
+ public Set<TSentryRole> getTSentryRolesByGroupName(Set<String> groupNames,
+ boolean checkAllGroups) throws SentryNoSuchObjectException {
+ Set<MSentryRole> roleSet = Sets.newHashSet();
+ for (String groupName : groupNames) {
+ try {
+ roleSet.addAll(getMSentryRolesByGroupName(groupName));
+ } catch (SentryNoSuchObjectException e) {
+ // if we are checking for all the given groups, then continue searching
+ if (!checkAllGroups) {
+ throw e;
+ }
+ }
+ }
+ return convertToTSentryRoles(roleSet);
+ }
+
+ public Set<String> getRoleNamesForGroups(Set<String> groups) {
+ Set<String> result = new HashSet<String>();
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryGroup.class);
+ query.setFilter("this.groupName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ for (String group : groups) {
+ MSentryGroup sentryGroup = (MSentryGroup) query.execute(group.trim());
+ if (sentryGroup != null) {
+ for (MSentryRole role : sentryGroup.getRoles()) {
+ result.add(role.getRoleName());
+ }
+ }
+ }
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ return result;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ public Set<MSentryRole> getRolesForGroups(PersistenceManager pm, Set<String> groups) {
+ Set<MSentryRole> result = new HashSet<MSentryRole>();
+ Query query = pm.newQuery(MSentryGroup.class);
+ query.setFilter("this.groupName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ for (String group : groups) {
+ MSentryGroup sentryGroup = (MSentryGroup) query.execute(group.trim());
+ if (sentryGroup != null) {
+ result.addAll(sentryGroup.getRoles());
+ }
+ }
+ return result;
+ }
+
+ public Set<String> listAllSentryPrivilegesForProvider(Set<String> groups, TSentryActiveRoleSet roleSet) throws SentryInvalidInputException {
+ return listSentryPrivilegesForProvider(groups, roleSet, null);
+ }
+
+
+ public Set<String> listSentryPrivilegesForProvider(Set<String> groups,
+ TSentryActiveRoleSet roleSet, TSentryAuthorizable authHierarchy) throws SentryInvalidInputException {
+ Set<String> result = Sets.newHashSet();
+ Set<String> rolesToQuery = getRolesToQuery(groups, roleSet);
+ List<MSentryPrivilege> mSentryPrivileges = getMSentryPrivileges(rolesToQuery, authHierarchy);
+
+ for (MSentryPrivilege priv : mSentryPrivileges) {
+ result.add(toAuthorizable(priv));
+ }
+
+ return result;
+ }
+
+
+ public boolean hasAnyServerPrivileges(Set<String> groups, TSentryActiveRoleSet roleSet, String server) {
+ Set<String> rolesToQuery = getRolesToQuery(groups, roleSet);
+ return hasAnyServerPrivileges(rolesToQuery, server);
+ }
+
+
+
+ private Set<String> getRolesToQuery(Set<String> groups,
+ TSentryActiveRoleSet roleSet) {
+ Set<String> activeRoleNames = toTrimedLower(roleSet.getRoles());
+
+ Set<String> roleNamesForGroups = toTrimedLower(getRoleNamesForGroups(groups));
+ Set<String> rolesToQuery = roleSet.isAll() ? roleNamesForGroups : Sets.intersection(activeRoleNames, roleNamesForGroups);
+ return rolesToQuery;
+ }
+
+ @VisibleForTesting
+ static String toAuthorizable(MSentryPrivilege privilege) {
+ List<String> authorizable = new ArrayList<String>(4);
+ authorizable.add(KV_JOINER.join(AuthorizableType.Server.name().toLowerCase(),
+ privilege.getServerName()));
+ if (isNULL(privilege.getURI())) {
+ if (!isNULL(privilege.getDbName())) {
+ authorizable.add(KV_JOINER.join(AuthorizableType.Db.name().toLowerCase(),
+ privilege.getDbName()));
+ if (!isNULL(privilege.getTableName())) {
+ authorizable.add(KV_JOINER.join(AuthorizableType.Table.name().toLowerCase(),
+ privilege.getTableName()));
+ if (!isNULL(privilege.getColumnName())) {
+ authorizable.add(KV_JOINER.join(AuthorizableType.Column.name().toLowerCase(),
+ privilege.getColumnName()));
+ }
+ }
+ }
+ } else {
+ authorizable.add(KV_JOINER.join(AuthorizableType.URI.name().toLowerCase(),
+ privilege.getURI()));
+ }
+ if (!isNULL(privilege.getAction())
+ && !privilege.getAction().equalsIgnoreCase(AccessConstants.ALL)) {
+ authorizable
+ .add(KV_JOINER.join(ProviderConstants.PRIVILEGE_NAME.toLowerCase(),
+ privilege.getAction()));
+ }
+ return AUTHORIZABLE_JOINER.join(authorizable);
+ }
+
+ @VisibleForTesting
+ static Set<String> toTrimedLower(Set<String> s) {
+ if (null == s) return new HashSet<String>();
+ Set<String> result = Sets.newHashSet();
+ for (String v : s) {
+ result.add(v.trim().toLowerCase());
+ }
+ return result;
+ }
+
+
+ /**
+ * Converts model object(s) to thrift object(s).
+ * Additionally does normalization
+ * such as trimming whitespace and setting appropriate case. Also sets the create
+ * time.
+ */
+
+ private Set<TSentryPrivilege> convertToTSentryPrivileges(Collection<MSentryPrivilege> mSentryPrivileges) {
+ Set<TSentryPrivilege> privileges = new HashSet<TSentryPrivilege>();
+ for(MSentryPrivilege mSentryPrivilege:mSentryPrivileges) {
+ privileges.add(convertToTSentryPrivilege(mSentryPrivilege));
+ }
+ return privileges;
+ }
+
+ private Set<TSentryRole> convertToTSentryRoles(Set<MSentryRole> mSentryRoles) {
+ Set<TSentryRole> roles = new HashSet<TSentryRole>();
+ for(MSentryRole mSentryRole:mSentryRoles) {
+ roles.add(convertToTSentryRole(mSentryRole));
+ }
+ return roles;
+ }
+
+ private TSentryRole convertToTSentryRole(MSentryRole mSentryRole) {
+ TSentryRole role = new TSentryRole();
+ role.setRoleName(mSentryRole.getRoleName());
+ role.setGrantorPrincipal("--");
+ Set<TSentryGroup> sentryGroups = new HashSet<TSentryGroup>();
+ for(MSentryGroup mSentryGroup:mSentryRole.getGroups()) {
+ TSentryGroup group = convertToTSentryGroup(mSentryGroup);
+ sentryGroups.add(group);
+ }
+
+ role.setGroups(sentryGroups);
+ return role;
+ }
+
+ private TSentryGroup convertToTSentryGroup(MSentryGroup mSentryGroup) {
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName(mSentryGroup.getGroupName());
+ return group;
+ }
+
+ private TSentryPrivilege convertToTSentryPrivilege(MSentryPrivilege mSentryPrivilege) {
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ convertToTSentryPrivilege(mSentryPrivilege, privilege);
+ return privilege;
+ }
+
+ private void convertToTSentryPrivilege(MSentryPrivilege mSentryPrivilege,
+ TSentryPrivilege privilege) {
+ privilege.setCreateTime(mSentryPrivilege.getCreateTime());
+ privilege.setAction(fromNULLCol(mSentryPrivilege.getAction()));
+ privilege.setPrivilegeScope(mSentryPrivilege.getPrivilegeScope());
+ privilege.setServerName(fromNULLCol(mSentryPrivilege.getServerName()));
+ privilege.setDbName(fromNULLCol(mSentryPrivilege.getDbName()));
+ privilege.setTableName(fromNULLCol(mSentryPrivilege.getTableName()));
+ privilege.setColumnName(fromNULLCol(mSentryPrivilege.getColumnName()));
+ privilege.setURI(fromNULLCol(mSentryPrivilege.getURI()));
+ if (mSentryPrivilege.getGrantOption() != null) {
+ privilege.setGrantOption(TSentryGrantOption.valueOf(mSentryPrivilege.getGrantOption().toString().toUpperCase()));
+ } else {
+ privilege.setGrantOption(TSentryGrantOption.UNSET);
+ }
+ }
+
+ /**
+ * Converts thrift object to model object. Additionally does normalization
+ * such as trimming whitespace and setting appropriate case.
+ * @throws SentryInvalidInputException
+ */
+ private MSentryPrivilege convertToMSentryPrivilege(TSentryPrivilege privilege)
+ throws SentryInvalidInputException {
+ MSentryPrivilege mSentryPrivilege = new MSentryPrivilege();
+ mSentryPrivilege.setServerName(toNULLCol(safeTrimLower(privilege.getServerName())));
+ mSentryPrivilege.setDbName(toNULLCol(safeTrimLower(privilege.getDbName())));
+ mSentryPrivilege.setTableName(toNULLCol(safeTrimLower(privilege.getTableName())));
+ mSentryPrivilege.setColumnName(toNULLCol(safeTrimLower(privilege.getColumnName())));
+ mSentryPrivilege.setPrivilegeScope(safeTrim(privilege.getPrivilegeScope()));
+ mSentryPrivilege.setAction(toNULLCol(safeTrimLower(privilege.getAction())));
+ mSentryPrivilege.setCreateTime(System.currentTimeMillis());
+ mSentryPrivilege.setURI(toNULLCol(safeTrim(privilege.getURI())));
+ if ( !privilege.getGrantOption().equals(TSentryGrantOption.UNSET) ) {
+ mSentryPrivilege.setGrantOption(Boolean.valueOf(privilege.getGrantOption().toString()));
+ } else {
+ mSentryPrivilege.setGrantOption(null);
+ }
+ return mSentryPrivilege;
+ }
+ private static String safeTrim(String s) {
+ if (s == null) {
+ return null;
+ }
+ return s.trim();
+ }
+ private static String safeTrimLower(String s) {
+ if (s == null) {
+ return null;
+ }
+ return s.trim().toLowerCase();
+ }
+
+ public String getSentryVersion() throws SentryNoSuchObjectException,
+ SentryAccessDeniedException {
+ MSentryVersion mVersion = getMSentryVersion();
+ return mVersion.getSchemaVersion();
+ }
+
+ public void setSentryVersion(String newVersion, String verComment)
+ throws SentryNoSuchObjectException, SentryAccessDeniedException {
+ MSentryVersion mVersion;
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+
+ try {
+ mVersion = getMSentryVersion();
+ if (newVersion.equals(mVersion.getSchemaVersion())) {
+ // specified version already in there
+ return;
+ }
+ } catch (SentryNoSuchObjectException e) {
+ // if the version doesn't exist, then create it
+ mVersion = new MSentryVersion();
+ }
+ mVersion.setSchemaVersion(newVersion);
+ mVersion.setVersionComment(verComment);
+ try {
+ pm = openTransaction();
+ pm.makePersistent(mVersion);
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private MSentryVersion getMSentryVersion()
+ throws SentryNoSuchObjectException, SentryAccessDeniedException {
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryVersion.class);
+ List<MSentryVersion> mSentryVersions = (List<MSentryVersion>) query
+ .execute();
+ pm.retrieveAll(mSentryVersions);
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ if (mSentryVersions.isEmpty()) {
+ throw new SentryNoSuchObjectException("No matching version found");
+ }
+ if (mSentryVersions.size() > 1) {
+ throw new SentryAccessDeniedException(
+ "Metastore contains multiple versions");
+ }
+ return mSentryVersions.get(0);
+ } catch (JDODataStoreException e) {
+ if (e.getCause() instanceof MissingTableException) {
+ throw new SentryAccessDeniedException("Version table not found. "
+ + "The sentry store is not set or corrupt ");
+ } else {
+ throw e;
+ }
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ /**
+ * Drop given privilege from all roles
+ */
+ public void dropPrivilege(TSentryAuthorizable tAuthorizable)
+ throws SentryNoSuchObjectException, SentryInvalidInputException {
+ PersistenceManager pm = null;
+ boolean rollbackTransaction = true;
+
+ TSentryPrivilege tPrivilege = toSentryPrivilege(tAuthorizable);
+ try {
+ pm = openTransaction();
+
+ if (isMultiActionsSupported(tPrivilege)) {
+ for (String privilegeAction : ALL_ACTIONS) {
+ tPrivilege.setAction(privilegeAction);
+ dropPrivilegeForAllRoles(pm, new TSentryPrivilege(tPrivilege));
+ }
+ } else {
+ dropPrivilegeForAllRoles(pm, new TSentryPrivilege(tPrivilege));
+ }
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ } catch (JDODataStoreException e) {
+ throw new SentryInvalidInputException("Failed to get privileges: "
+ + e.getMessage());
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ /**
+ * Rename given privilege from all roles drop the old privilege and create the new one
+ * @param tAuthorizable
+ * @param newTAuthorizable
+ * @throws SentryNoSuchObjectException
+ * @throws SentryInvalidInputException
+ */
+ public void renamePrivilege(TSentryAuthorizable tAuthorizable,
+ TSentryAuthorizable newTAuthorizable)
+ throws SentryNoSuchObjectException, SentryInvalidInputException {
+ PersistenceManager pm = null;
+ boolean rollbackTransaction = true;
+
+ TSentryPrivilege tPrivilege = toSentryPrivilege(tAuthorizable);
+ TSentryPrivilege newPrivilege = toSentryPrivilege(newTAuthorizable);
+
+ try {
+ pm = openTransaction();
+ // In case of tables or DBs, check all actions
+ if (isMultiActionsSupported(tPrivilege)) {
+ for (String privilegeAction : ALL_ACTIONS) {
+ tPrivilege.setAction(privilegeAction);
+ newPrivilege.setAction(privilegeAction);
+ renamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
+ }
+ } else {
+ renamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
+ }
+ rollbackTransaction = false;
+ commitTransaction(pm);
+ } catch (JDODataStoreException e) {
+ throw new SentryInvalidInputException("Failed to get privileges: "
+ + e.getMessage());
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ // Currently INSERT/SELECT/ALL are supported for Table and DB level privileges
+ private boolean isMultiActionsSupported(TSentryPrivilege tPrivilege) {
+ return tPrivilege.getDbName() != null;
+
+ }
+ // wrapper for dropOrRename
+ private void renamePrivilegeForAllRoles(PersistenceManager pm,
+ TSentryPrivilege tPrivilege,
+ TSentryPrivilege newPrivilege) throws SentryNoSuchObjectException,
+ SentryInvalidInputException {
+ dropOrRenamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
+ }
+
+ /**
+ * Drop given privilege from all roles
+ * @param tPrivilege
+ * @throws SentryNoSuchObjectException
+ * @throws SentryInvalidInputException
+ */
+ private void dropPrivilegeForAllRoles(PersistenceManager pm,
+ TSentryPrivilege tPrivilege)
+ throws SentryNoSuchObjectException, SentryInvalidInputException {
+ dropOrRenamePrivilegeForAllRoles(pm, tPrivilege, null);
+ }
+
+ /**
+ * Drop given privilege from all roles Create the new privilege if asked
+ * @param tPrivilege
+ * @param pm
+ * @throws SentryNoSuchObjectException
+ * @throws SentryInvalidInputException
+ */
+ private void dropOrRenamePrivilegeForAllRoles(PersistenceManager pm,
+ TSentryPrivilege tPrivilege,
+ TSentryPrivilege newTPrivilege) throws SentryNoSuchObjectException,
+ SentryInvalidInputException {
+ HashSet<MSentryRole> roleSet = Sets.newHashSet();
+
+ List<MSentryPrivilege> mPrivileges = getMSentryPrivileges(tPrivilege, pm);
+ if (mPrivileges != null && !mPrivileges.isEmpty()) {
+ for (MSentryPrivilege mPrivilege : mPrivileges) {
+ roleSet.addAll(ImmutableSet.copyOf((mPrivilege.getRoles())));
+ }
+ }
+
+ MSentryPrivilege parent = getMSentryPrivilege(tPrivilege, pm);
+ for (MSentryRole role : roleSet) {
+ // 1. get privilege and child privileges
+ Set<MSentryPrivilege> privilegeGraph = Sets.newHashSet();
+ if (parent != null) {
+ privilegeGraph.add(parent);
+ populateChildren(pm, Sets.newHashSet(role.getRoleName()), parent, privilegeGraph);
+ } else {
+ populateChildren(pm, Sets.newHashSet(role.getRoleName()), convertToMSentryPrivilege(tPrivilege),
+ privilegeGraph);
+ }
+ // 2. revoke privilege and child privileges
+ alterSentryRoleRevokePrivilegeCore(pm, role.getRoleName(), tPrivilege);
+ // 3. add new privilege and child privileges with new tableName
+ if (newTPrivilege != null) {
+ for (MSentryPrivilege m : privilegeGraph) {
+ TSentryPrivilege t = convertToTSentryPrivilege(m);
+ if (newTPrivilege.getPrivilegeScope().equals(PrivilegeScope.DATABASE.name())) {
+ t.setDbName(newTPrivilege.getDbName());
+ } else if (newTPrivilege.getPrivilegeScope().equals(PrivilegeScope.TABLE.name())) {
+ t.setTableName(newTPrivilege.getTableName());
+ }
+ alterSentryRoleGrantPrivilegeCore(pm, role.getRoleName(), t);
+ }
+ }
+ }
+ }
+
+ private TSentryPrivilege toSentryPrivilege(TSentryAuthorizable tAuthorizable)
+ throws SentryInvalidInputException {
+ TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
+ tSentryPrivilege.setDbName(fromNULLCol(tAuthorizable.getDb()));
+ tSentryPrivilege.setServerName(fromNULLCol(tAuthorizable.getServer()));
+ tSentryPrivilege.setTableName(fromNULLCol(tAuthorizable.getTable()));
+ tSentryPrivilege.setColumnName(fromNULLCol(tAuthorizable.getColumn()));
+ tSentryPrivilege.setURI(fromNULLCol(tAuthorizable.getUri()));
+ PrivilegeScope scope;
+ if (!isNULL(tSentryPrivilege.getColumnName())) {
+ scope = PrivilegeScope.COLUMN;
+ } else if (!isNULL(tSentryPrivilege.getTableName())) {
+ scope = PrivilegeScope.TABLE;
+ } else if (!isNULL(tSentryPrivilege.getDbName())) {
+ scope = PrivilegeScope.DATABASE;
+ } else if (!isNULL(tSentryPrivilege.getURI())) {
+ scope = PrivilegeScope.URI;
+ } else {
+ scope = PrivilegeScope.SERVER;
+ }
+ tSentryPrivilege.setPrivilegeScope(scope.name());
+ tSentryPrivilege.setAction(AccessConstants.ALL);
+ return tSentryPrivilege;
+ }
+
+ public static String toNULLCol(String s) {
+ return Strings.isNullOrEmpty(s) ? NULL_COL : s;
+ }
+
+ public static String fromNULLCol(String s) {
+ return isNULL(s) ? "" : s;
+ }
+
+ public static boolean isNULL(String s) {
+ return Strings.isNullOrEmpty(s) || s.equals(NULL_COL);
+ }
+
+ /**
+ * Grant option check
+ * @param pm
+ * @param privilege
+ * @throws SentryUserException
+ */
+ private void grantOptionCheck(PersistenceManager pm, String grantorPrincipal, TSentryPrivilege privilege)
+ throws SentryUserException {
+ MSentryPrivilege mPrivilege = convertToMSentryPrivilege(privilege);
+ if (grantorPrincipal == null) {
+ throw new SentryInvalidInputException("grantorPrincipal should not be null");
+ }
+ Set<String> groups = SentryPolicyStoreProcessor.getGroupsFromUserName(conf, grantorPrincipal);
+ if (groups == null || groups.isEmpty()) {
+ throw new SentryGrantDeniedException(grantorPrincipal
+ + " has no grant!");
+ }
+
+ // if grantor is in adminGroup, don't need to do check
+ Set<String> admins = getAdminGroups();
+ boolean isAdminGroup = false;
+ if (admins != null && !admins.isEmpty()) {
+ for (String g : groups) {
+ if (admins.contains(g)) {
+ isAdminGroup = true;
+ break;
+ }
+ }
+ }
+
+ if (!isAdminGroup) {
+ boolean hasGrant = false;
+ Set<MSentryRole> roles = getRolesForGroups(pm, groups);
+ if (roles != null && !roles.isEmpty()) {
+ for (MSentryRole role: roles) {
+ Set<MSentryPrivilege> privilegeSet = role.getPrivileges();
+ if (privilegeSet != null && !privilegeSet.isEmpty()) {
+ // if role has a privilege p with grant option
+ // and mPrivilege is a child privilege of p
+ for (MSentryPrivilege p : privilegeSet) {
+ if (p.getGrantOption() && p.implies(mPrivilege)) {
+ hasGrant = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (!hasGrant) {
+ throw new SentryGrantDeniedException(grantorPrincipal
+ + " has no grant!");
+ }
+ }
+ }
+
+ // get adminGroups from conf
+ private Set<String> getAdminGroups() {
+ return Sets.newHashSet(conf.getStrings(
+ ServerConfig.ADMIN_GROUPS, new String[]{}));
+ }
+
+ /**
+ * This returns a Mapping of AuthZObj(db/table) -> (Role -> permission)
+ */
+ public Map<String, HashMap<String, String>> retrieveFullPrivilegeImage() {
+ Map<String, HashMap<String, String>> retVal = new HashMap<String, HashMap<String,String>>();
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ String filters = "(serverName != \"__NULL__\") "
+ + "&& (dbName != \"__NULL__\") " + "&& (URI == \"__NULL__\")";
+ query.setFilter(filters.toString());
+ query
+ .setOrdering("serverName ascending, dbName ascending, tableName ascending");
+ List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query
+ .execute();
+ rollbackTransaction = false;
+ for (MSentryPrivilege mPriv : privileges) {
+ String authzObj = mPriv.getDbName();
+ if (!isNULL(mPriv.getTableName())) {
+ authzObj = authzObj + "." + mPriv.getTableName();
+ }
+ HashMap<String, String> pUpdate = retVal.get(authzObj);
+ if (pUpdate == null) {
+ pUpdate = new HashMap<String, String>();
+ retVal.put(authzObj, pUpdate);
+ }
+ for (MSentryRole mRole : mPriv.getRoles()) {
+ String existingPriv = pUpdate.get(mRole.getRoleName());
+ if (existingPriv == null) {
+ pUpdate.put(mRole.getRoleName(), mPriv.getAction().toUpperCase());
+ } else {
+ pUpdate.put(mRole.getRoleName(), existingPriv + ","
+ + mPriv.getAction().toUpperCase());
+ }
+ }
+ }
+ commitTransaction(pm);
+ return retVal;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ /**
+ * This returns a Mapping of Role -> [Groups]
+ */
+ public Map<String, LinkedList<String>> retrieveFullRoleImage() {
+ Map<String, LinkedList<String>> retVal = new HashMap<String, LinkedList<String>>();
+ boolean rollbackTransaction = true;
+ PersistenceManager pm = null;
+ try {
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryGroup.class);
+ List<MSentryGroup> groups = (List<MSentryGroup>) query.execute();
+ for (MSentryGroup mGroup : groups) {
+ for (MSentryRole role : mGroup.getRoles()) {
+ LinkedList<String> rUpdate = retVal.get(role.getRoleName());
+ if (rUpdate == null) {
+ rUpdate = new LinkedList<String>();
+ retVal.put(role.getRoleName(), rUpdate);
+ }
+ rUpdate.add(mGroup.getGroupName());
+ }
+ }
+ commitTransaction(pm);
+ return retVal;
+ } finally {
+ if (rollbackTransaction) {
+ rollbackTransaction(pm);
+ }
+ }
+ }
+
+ /**
+ * This thread exists to clean up "orphaned" privilege rows in the database.
+ * These rows aren't removed automatically due to the fact that there is
+ * a many-to-many mapping between the roles and privileges, and the
+ * detection and removal of orphaned privileges is a wee bit involved.
+ * This thread hangs out until notified by the parent (the outer class)
+ * and then runs a custom SQL statement that detects and removes orphans.
+ */
+ private class PrivCleaner implements Runnable {
+ // Kick off priv orphan removal after this many notifies
+ private static final int NOTIFY_THRESHOLD = 50;
+
+ // How many times we've been notified; reset to zero after orphan removal
+ private int currentNotifies = 0;
+
+ // Internal state for threads
+ private boolean exitRequired = false;
+
+ // This lock and condition are needed to implement a way to drop the
+ // lock inside a while loop, and not hold the lock across the orphan
+ // removal.
+ private final Lock lock = new ReentrantLock();
+ private final Condition cond = lock.newCondition();
+
+ /**
+ * Waits in a loop, running the orphan removal function when notified.
+ * Will exit after exitRequired is set to true by exit(). We are careful
+ * to not hold our lock while removing orphans; that operation might
+ * take a long time. There's also the matter of lock ordering. Other
+ * threads start a transaction first, and then grab our lock; this thread
+ * grabs the lock and then starts a transaction. Handling this correctly
+ * requires explicit locking/unlocking through the loop.
+ */
+ public void run() {
+ while (true) {
+ lock.lock();
+ try {
+ // Check here in case this was set during removeOrphanedPrivileges()
+ if (exitRequired) {
+ return;
+ }
+ while (currentNotifies <= NOTIFY_THRESHOLD) {
+ try {
+ cond.await();
+ } catch (InterruptedException e) {
+ // Interrupted
+ }
+ // Check here in case this was set while waiting
+ if (exitRequired) {
+ return;
+ }
+ }
+ currentNotifies = 0;
+ } finally {
+ lock.unlock();
+ }
+ try {
+ removeOrphanedPrivileges();
+ } catch (Exception e) {
+ LOGGER.warn("Privilege cleaning thread encountered an error: " +
+ e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * This is called when a privilege is removed from a role. This may
+ * or may not mean that the privilege needs to be removed from the
+ * database; there may be more references to it from other roles.
+ * As a result, we'll lazily run the orphan cleaner every
+ * NOTIFY_THRESHOLD times this routine is called.
+ * @param numDeletions The number of potentially orphaned privileges
+ */
+ public void incPrivRemoval(int numDeletions) {
+ if (privCleanerThread != null) {
+ lock.lock();
+ currentNotifies += numDeletions;
+ if (currentNotifies > NOTIFY_THRESHOLD) {
+ cond.signal();
+ }
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Simple form of incPrivRemoval when only one privilege is deleted.
+ */
+ public void incPrivRemoval() {
+ incPrivRemoval(1);
+ }
+
+ /**
+ * Tell this thread to exit. Safe to call multiple times, as it just
+ * notifies the run() loop to finish up.
+ */
+ public void exit() {
+ if (privCleanerThread != null) {
+ lock.lock();
+ try {
+ exitRequired = true;
+ cond.signal();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ /**
+ * Run a SQL query to detect orphaned privileges, and then delete
+ * each one. This is complicated by the fact that datanucleus does
+ * not seem to play well with the mix between a direct SQL query
+ * and operations on the database. The solution that seems to work
+ * is to split the operation into two transactions: the first is
+ * just a read for privileges that look like they're orphans, the
+ * second transaction will go and get each of those privilege objects,
+ * verify that there are no roles attached, and then delete them.
+ */
+ private void removeOrphanedPrivileges() {
+ final String privDB = "SENTRY_DB_PRIVILEGE";
+ final String privId = "DB_PRIVILEGE_ID";
+ final String mapDB = "SENTRY_ROLE_DB_PRIVILEGE_MAP";
+ final String privFilter =
+ "select " + privId +
+ " from " + privDB + " p" +
+ " where not exists (" +
+ " select 1 from " + mapDB + " d" +
+ " where p." + privId + " != d." + privId +
+ " )";
+ boolean rollback = true;
+ int orphansRemoved = 0;
+ ArrayList<Object> idList = new ArrayList<Object>();
+ PersistenceManager pm = pmf.getPersistenceManager();
+
+ // Transaction 1: Perform a SQL query to get things that look like orphans
+ try {
+ Transaction transaction = pm.currentTransaction();
+ transaction.begin();
+ transaction.setRollbackOnly(); // Makes the tx read-only
+ Query query = pm.newQuery("javax.jdo.query.SQL", privFilter);
+ query.setClass(MSentryPrivilege.class);
+ List<MSentryPrivilege> results = (List<MSentryPrivilege>) query.execute();
+ for (MSentryPrivilege orphan : results) {
+ idList.add(pm.getObjectId(orphan));
+ }
+ transaction.rollback();
+ rollback = false;
+ } finally {
+ if (rollback && pm.currentTransaction().isActive()) {
+ pm.currentTransaction().rollback();
+ } else {
+ LOGGER.debug("Found {} potential orphans", idList.size());
+ }
+ }
+
+ if (idList.isEmpty()) {
+ pm.close();
+ return;
+ }
+
+ Preconditions.checkState(!rollback);
+
+ // Transaction 2: For each potential orphan, verify it's really an
+ // orphan and delete it if so
+ rollback = true;
+ try {
+ Transaction transaction = pm.currentTransaction();
+ transaction.begin();
+ pm.refreshAll(); // Try to ensure we really have correct objects
+ for (Object id : idList) {
+ MSentryPrivilege priv = (MSentryPrivilege) pm.getObjectById(id);
+ if (priv.getRoles().isEmpty()) {
+ pm.deletePersistent(priv);
+ orphansRemoved++;
+ }
+ }
+ transaction.commit();
+ pm.close();
+ rollback = false;
+ } finally {
+ if (rollback) {
+ rollbackTransaction(pm);
+ } else {
+ LOGGER.debug("Cleaned up {} orphaned privileges", orphansRemoved);
+ }
+ }
+ }
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/DistributedUtils.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/DistributedUtils.java
new file mode 100644
index 0000000..25d3970
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/DistributedUtils.java
@@ -0,0 +1,84 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import org.apache.hadoop.conf.Configuration;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.config.JoinConfig;
+import com.hazelcast.config.NetworkConfig;
+import com.hazelcast.config.TcpIpConfig;
+import com.hazelcast.config.TopicConfig;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+
+public class DistributedUtils {
+
+ public static final String SENTRY_DISTRIBUTED_TOPIC = "sentryDistributedTopic";
+ public static final String SENTRY_CATCHUP_REQUEST_TOPIC = "sentryCatchUpRequestTopic";
+ public static final String SENTRY_CATCHUP_RESPONSE_QUEUE = "sentryCatchUpResponseQueue_";
+
+ public static final String SENTRY_STORE_SEQID = "sentryStoreSeqId";
+ public static final String SENTRY_STORE_NODEID = "sentryStoreNodeId";
+
+ public static String SENTRY_CATCHUP_WAIT_TIME = "sentry.catchup.wait.time";
+ public static int SENTRY_CATCHUP_WAIT_TIME_DEF = 10000;
+
+ public static String SENTRY_HAZELCAST_PORT_START = "sentry.hazelcast.port.start";
+ public static int SENTRY_HAZELCAST_PORT_START_DEF = 9000;
+ public static String SENTRY_HAZELCAST_MEMBERS = "sentry.hazelcast.members";
+ public static String[] SENTRY_HAZELCAST_MEMBERS_DEF = new String[]{"localhost"};
+ public static String SENTRY_HAZELCAST_INSTANCE_GROUP = "sentry.hazelcast.instance.group";
+ public static String SENTRY_HAZELCAST_INSTANCE_GROUP_DEF = "sentry";
+ public static String SENTRY_HAZELCAST_INSTANCE_PASSWORD = "sentry.hazelcast.instance.password";
+ public static String SENTRY_HAZELCAST_INSTANCE_PASSWORD_DEF = "sentry";
+
+ public static HazelcastInstance getHazelcastInstance(Configuration conf,
+ boolean createNew) {
+ Config cfg = new Config();
+ NetworkConfig netCfg = cfg.getNetworkConfig();
+ netCfg.setPort(conf.getInt(SENTRY_HAZELCAST_PORT_START,
+ SENTRY_HAZELCAST_PORT_START_DEF));
+ netCfg.setPortAutoIncrement(true);
+ JoinConfig joinCfg = netCfg.getJoin();
+ joinCfg.getMulticastConfig().setEnabled(false);
+ TcpIpConfig tcpIpConfig = joinCfg.getTcpIpConfig();
+ for (String member : conf.getStrings(SENTRY_HAZELCAST_MEMBERS,
+ SENTRY_HAZELCAST_MEMBERS_DEF)) {
+ tcpIpConfig.addMember(member);
+ }
+ tcpIpConfig.setEnabled(true);
+
+ cfg.addTopicConfig(new TopicConfig()
+ .setGlobalOrderingEnabled(true)
+ .setName(SENTRY_DISTRIBUTED_TOPIC));
+ cfg.getGroupConfig().setName(
+ conf.get(SENTRY_HAZELCAST_INSTANCE_GROUP,
+ SENTRY_HAZELCAST_INSTANCE_GROUP_DEF));
+ cfg.getGroupConfig().setPassword(
+ conf.get(SENTRY_HAZELCAST_INSTANCE_PASSWORD,
+ SENTRY_HAZELCAST_INSTANCE_PASSWORD_DEF));
+ if (createNew) {
+ return Hazelcast.newHazelcastInstance(cfg);
+ } else {
+ return Hazelcast.getOrCreateHazelcastInstance(cfg);
+ }
+ }
+
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/FileLog.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/FileLog.java
new file mode 100644
index 0000000..9ace37c
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/FileLog.java
@@ -0,0 +1,236 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.provider.db.service.thrift.SentryConfigurationException;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreRecord;
+import org.apache.sentry.provider.db.service.thrift.TStoreSnapshot;
+import org.apache.thrift.TDeserializer;
+import org.apache.thrift.TException;
+import org.apache.thrift.TSerializer;
+import org.apache.thrift.protocol.TCompactProtocol;
+import org.apache.thrift.protocol.TProtocolFactory;
+
+/**
+ * The FileLog class abstracts out the log file and all operations on it
+ * When the FileLog is instantiated, It first checks if there is an existing
+ * log file associated at the configured path. If yes, then the Client will
+ * not be allowed to write to the log unless all existing LogEntries have been
+ * iterated over using the standard iterator abstractions of {@link #hasNext()}
+ * and {@link #next()}. Once all the entries are read out, it will open an
+ * Output stream to the log file and clients can start logging.
+ * The FileLog also support Log snapshots. If it see a special snapshot
+ * record, the current log file is first closed and renamed. Once the snapshot
+ * entry has been successfully written to a new log, it will delete the
+ * old log file.
+ */
+public class FileLog {
+
+ // The default Java ObjectOutputStream cannot be appended to since it
+ // writes a special header whenever you open the stream. We need this header
+ // only when a new file is opened. When a store is shutdown and re-opened
+ // again, subsequent appends should not write the header, else reading the
+ // file again will throw a StreamCorruptedException.
+ public class AppendingObjectOutputStream extends ObjectOutputStream {
+
+ public AppendingObjectOutputStream(OutputStream out) throws IOException {
+ super(out);
+ }
+
+ @Override
+ protected void writeStreamHeader() throws IOException {
+ // do not write a header
+ reset();
+ }
+ }
+
+ public static String SENTRY_FILE_LOG_STORE_LOCATION =
+ "sentry.file.log.store.location";
+
+ private static String COMMIT_LOG_FILE = "commit.log";
+
+ public static class Entry {
+ public final long seqId;
+ public final TSentryStoreRecord record;
+ public Entry(long seqId, TSentryStoreRecord record) {
+ this.seqId = seqId;
+ this.record = record;
+ }
+ }
+
+ private volatile boolean isReady = false;
+ private ObjectInputStream commitOis = null;
+ private Entry nextEntry = null;
+ private File logDir;
+
+ private ObjectOutputStream commitLog;
+ private final TSerializer serializer;
+ private final TDeserializer deserializer;
+
+ public FileLog(Configuration conf)
+ throws SentryConfigurationException, FileNotFoundException, IOException {
+ String currentDir = System.getProperty("user.dir");
+ logDir = new File(conf.get(SENTRY_FILE_LOG_STORE_LOCATION, currentDir));
+ TProtocolFactory protoFactory = new TCompactProtocol.Factory();
+ serializer = new TSerializer(protoFactory);
+ deserializer = new TDeserializer(protoFactory);
+ if (logDir.exists()) {
+ if (!logDir.isDirectory()) {
+ throw new SentryConfigurationException(
+ "Dir [" + logDir.getAbsolutePath() + "] exists and is not a directory !!");
+ } else {
+ if (new File(logDir, COMMIT_LOG_FILE).exists()) {
+ commitOis =
+ new ObjectInputStream(
+ new FileInputStream(new File(logDir, COMMIT_LOG_FILE)));
+ } else {
+ commitLog =
+ new ObjectOutputStream(
+ new FileOutputStream(new File(logDir, COMMIT_LOG_FILE)));
+ isReady = true;
+ }
+ }
+ } else {
+ isReady = true;
+ boolean created = logDir.mkdirs();
+ if (!created) {
+ throw new RuntimeException(
+ "Could not create store directory [" + logDir.getAbsolutePath() + "]");
+ }
+ commitLog =
+ new ObjectOutputStream(new FileOutputStream(new File(logDir,
+ COMMIT_LOG_FILE)));
+ }
+ }
+
+ public boolean hasNext() {
+ if (isReady) {
+ return false;
+ }
+ if (nextEntry != null) {
+ return true;
+ }
+ try {
+ nextEntry = getNextEntry();
+ } catch (EOFException e) {
+ isReady = true;
+ try {
+ commitOis.close();
+ } catch (Exception e2) {
+ System.out.println("Got ex : " + e2.getMessage());
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (TException e) {
+ throw new RuntimeException(e);
+ }
+ return !isReady;
+ }
+
+ private Entry getNextEntry() throws IOException, TException {
+ long seqId = commitOis.readLong();
+ int numRecordBytes = commitOis.readInt();
+ byte[] recBytes = new byte[numRecordBytes];
+ commitOis.readFully(recBytes);
+ TSentryStoreRecord record = new TSentryStoreRecord();
+ deserializer.deserialize(record, recBytes);
+ return new Entry(seqId, record);
+ }
+
+ // Must be called only after a hasNext();
+ public Entry next() {
+ Entry e = nextEntry;
+ nextEntry = null;
+ return e;
+ }
+
+ public void log(long seqId, TSentryStoreRecord record) {
+ if (!isReady) {
+ throw new RuntimeException("FileLog is not ready for writing yet !!");
+ }
+ try {
+ prepareForSnapshotIfNeeded(seqId, record);
+ if (commitLog == null) {
+ commitLog =
+ new AppendingObjectOutputStream(
+ new FileOutputStream(new File(logDir, COMMIT_LOG_FILE), true));
+ }
+ byte[] recBytes = serializer.serialize(record);
+ commitLog.writeLong(seqId);
+ commitLog.writeInt(recBytes.length);
+ commitLog.write(recBytes);
+ commitLog.flush();
+ } catch (Exception e) {
+ throw new RuntimeException(
+ "Could not log record with id [" + seqId + "] !!", e);
+ }
+ commitIfSnapshot(seqId, record);
+ }
+
+ // Truncate current log file and write the snapshot record
+ private void prepareForSnapshotIfNeeded(long seqId, TSentryStoreRecord record)
+ throws IOException {
+ if (record.getSnapshot() != null) {
+ // Close current log
+ if (commitLog != null) {
+ commitLog.flush();
+ commitLog.close();
+ }
+
+ // Copy current log to temp
+ boolean renameSuccess =
+ new File(logDir, COMMIT_LOG_FILE)
+ .renameTo(
+ new File(logDir, COMMIT_LOG_FILE + "_tmp_" + seqId));
+ if (!renameSuccess) {
+ throw new IOException("Could not Prepare for snapshot !!");
+ }
+ commitLog = new ObjectOutputStream(
+ new FileOutputStream(new File(logDir, COMMIT_LOG_FILE), true));;
+ }
+ }
+
+ private void commitIfSnapshot(long seqId, TSentryStoreRecord record) {
+ if (record.getSnapshot() != null) {
+ new File(logDir, COMMIT_LOG_FILE + "_tmp_" + seqId).delete();
+ }
+ }
+
+ public void close() {
+ if (commitLog != null) {
+ try {
+ commitLog.flush();
+ commitLog.close();
+ } catch (IOException e) {
+ System.out.println("Cound not close file : " + e.getMessage());
+ }
+ }
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/HAContext.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/HAContext.java
index 523261e..b95ab52 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/HAContext.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/HAContext.java
@@ -51,6 +51,17 @@
private static final Logger LOGGER = LoggerFactory.getLogger(HAContext.class);
public final static String SENTRY_SERVICE_REGISTER_NAMESPACE = "sentry-service";
+
+ // Implement singleton
+ private static HAContext haContext;
+
+ public synchronized static HAContext get(Configuration conf) throws Exception {
+ if (haContext == null) {
+ haContext = new HAContext(conf);
+ }
+ return haContext;
+ }
+
private final String zookeeperQuorum;
private final int retriesMaxCount;
private final int sleepMsBetweenRetries;
@@ -62,7 +73,7 @@
private final CuratorFramework curatorFramework;
private final RetryPolicy retryPolicy;
- public HAContext(Configuration conf) throws Exception {
+ HAContext(Configuration conf) throws Exception {
this.zookeeperQuorum = conf.get(ServerConfig.SENTRY_HA_ZOOKEEPER_QUORUM,
ServerConfig.SENTRY_HA_ZOOKEEPER_QUORUM_DEFAULT);
this.retriesMaxCount = conf.getInt(ServerConfig.SENTRY_HA_ZOOKEEPER_RETRIES_MAX_COUNT,
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/InMemSentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/InMemSentryStore.java
new file mode 100644
index 0000000..0f42c7b
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/InMemSentryStore.java
@@ -0,0 +1,1216 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.core.common.utils.PathUtils;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.provider.db.SentryAlreadyExistsException;
+import org.apache.sentry.provider.db.SentryGrantDeniedException;
+import org.apache.sentry.provider.db.SentryInvalidInputException;
+import org.apache.sentry.provider.db.SentryNoSuchObjectException;
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessor;
+import org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
+import org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilegeMap;
+import org.apache.sentry.provider.db.service.thrift.TSentryRole;
+import org.apache.sentry.provider.db.service.thrift.TStoreAuthorizable;
+import org.apache.sentry.provider.db.service.thrift.TStorePrivilege;
+import org.apache.sentry.provider.db.service.thrift.TStoreSnapshot;
+import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+/**
+ * In memory implementation of the SentryStore. The privilege model is
+ * implemented as a Tree of {@link Authorizable} objects, this serves two
+ * purposes :
+ * 1) Since all objects have a parent <-> child relationship, using a tree
+ * data-structure makes it easier to traverse and aggregate privilege
+ * information for a request
+ * 2) Improve in-memory storage efficiency since names of the parents are
+ * not duplicated for large number of leaf node.
+ * Each {@link Authorizable} object, in addition to maintaining a list of
+ * children, also maintains a map of all roles and the associated Privileges
+ * Granted to the role for the Authorizable object.
+ *
+ * The Store also maintains a reverse-mapping of role To {@link Authorizable}
+ * to eliminate the need to traverse the tree for requests
+ * that are keyed to a role.
+ *
+ */
+public class InMemSentryStore implements SentryStore {
+
+ static enum GrantOption {
+ UNSET, TRUE, FALSE
+ }
+
+ /**
+ * The Privilege is maintained as a bitset which makes it easier to
+ * handle addition / removal and aggregation of privileges for a role
+ *
+ */
+ static enum Privilege {
+ ALL((short)63),
+ CREATE((short)32),
+ DROP((short)16),
+ INDEX((short)8),
+ LOCK((short)4),
+ SELECT((short)2),
+ INSERT((short)1),
+ NONE((short)0);
+
+ private short code;
+ private Privilege(short code) {
+ this.code = code;
+ }
+
+ static boolean includedIn(Privilege priv, short bitset) {
+ return (bitset & ((short) priv.code)) == priv.code;
+ }
+
+ static short addTo(Privilege priv, short bitset) {
+ return (short)(bitset | ((short) priv.code));
+ }
+
+ static short removeFrom(Privilege priv, short bitset) {
+ return (short)(bitset & ~((short) priv.code));
+ }
+
+ static Privilege fromTSentryPrivilege(TSentryPrivilege priv) {
+ // TODO: maybe better way of doing this ?
+ if (AccessConstants.ACTION_ALL.equalsIgnoreCase(
+ Strings.nullToEmpty(priv.getAction()))) {
+ return ALL;
+ } else if (AccessConstants.ALL.equalsIgnoreCase(
+ Strings.nullToEmpty(priv.getAction()))) {
+ return ALL;
+ } else if (AccessConstants.CREATE.equalsIgnoreCase(
+ Strings.nullToEmpty(priv.getAction()))) {
+ return CREATE;
+ } else if (AccessConstants.DROP.equalsIgnoreCase(
+ Strings.nullToEmpty(priv.getAction()))) {
+ return DROP;
+ } else if (AccessConstants.INDEX.equalsIgnoreCase(
+ Strings.nullToEmpty(priv.getAction()))) {
+ return INDEX;
+ } else if (AccessConstants.LOCK.equalsIgnoreCase(
+ Strings.nullToEmpty(priv.getAction()))) {
+ return LOCK;
+ } else if (AccessConstants.SELECT.equalsIgnoreCase(
+ Strings.nullToEmpty(priv.getAction()))) {
+ return SELECT;
+ } else if (AccessConstants.INSERT.equalsIgnoreCase(
+ Strings.nullToEmpty(priv.getAction()))) {
+ return INSERT;
+ } else {
+ return NONE;
+ }
+ }
+ };
+
+ static class AuthPrivilege {
+ private GrantOption grantOption;
+ private short privilege;
+ AuthPrivilege(short privilege) {
+ this.grantOption = GrantOption.UNSET;
+ this.privilege = privilege;
+ }
+ public GrantOption getGrantOption() {
+ return grantOption;
+ }
+ public void setGrantOption(GrantOption grantOption) {
+ this.grantOption = grantOption;
+ }
+ public short getPrivilege() {
+ return privilege;
+ }
+ public void setPrivilege(short privilege) {
+ this.privilege = privilege;
+ }
+ public boolean implies(Authorizable auth, TSentryPrivilege priv) {
+ if (checkHierarchy(auth, priv)) {
+ if (!Privilege.includedIn(Privilege.ALL, privilege)
+ && !Privilege.includedIn(Privilege.fromTSentryPrivilege(priv), privilege)) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+
+ static enum AuthType {
+ SERVER, DB, URI, TABLE, COLUMN;
+ };
+
+ static Map<AuthType, Set<AuthType>> permissableChildren =
+ ImmutableMap.<AuthType, Set<AuthType>>builder()
+ .put(AuthType.SERVER, Sets.newHashSet(AuthType.DB, AuthType.URI))
+ .put(AuthType.URI, Collections.<AuthType>emptySet())
+ .put(AuthType.DB, Sets.newHashSet(AuthType.TABLE))
+ .put(AuthType.TABLE, Sets.newHashSet(AuthType.COLUMN))
+ .put(AuthType.COLUMN, Collections.<AuthType>emptySet())
+ .build();
+
+ static class Authorizable {
+ private String name;
+ private final AuthType type;
+ private Map<String, AuthPrivilege> privileges = new HashMap<String, AuthPrivilege>();
+ private volatile Map<String, Authorizable> children = new HashMap<String, Authorizable>();
+ private Authorizable parent;
+
+ Authorizable(String name, AuthType type, Authorizable parent) {
+ this.name = name;
+ this.type = type;
+ this.parent = parent;
+ }
+
+ Authorizable addChild(String name, AuthType authType) {
+ Authorizable child = children.get(name);
+ if (child == null) {
+ child = new Authorizable(name, authType, this);
+ children.put(name, child);
+ }
+ return child;
+ }
+
+ Authorizable getChild(String name) {
+ return children.get(name);
+ }
+
+ Authorizable getChild(String name, AuthType type) {
+ if (type == AuthType.URI) {
+ for (Authorizable child : children.values()) {
+ if (child.getAuthType() == AuthType.URI) {
+ if (PathUtils.impliesURI(child.getName(), name)) {
+ return child;
+ }
+ }
+ }
+ }
+ return children.get(name);
+ }
+
+ String getName() {
+ return name;
+ }
+
+ // Needed for rename
+ void setName(String name) {
+ this.name = name;
+ }
+
+ Authorizable getParent() {
+ return parent;
+ }
+
+ AuthType getAuthType() {
+ return type;
+ }
+
+ void addPrivilege(String role, Privilege priv) {
+ AuthPrivilege authPriv = privileges.get(role);
+ if (authPriv == null) {
+ authPriv = new AuthPrivilege(Privilege.NONE.code);
+ privileges.put(role, authPriv);
+ }
+ authPriv.setPrivilege(Privilege.addTo(priv, authPriv.privilege));
+ }
+
+ void setPrivilege(String role, short privBits) {
+ AuthPrivilege authPriv = privileges.get(role);
+ if (authPriv == null) {
+ authPriv = new AuthPrivilege(Privilege.NONE.code);
+ privileges.put(role, authPriv);
+ }
+ authPriv.setPrivilege(privBits);
+ }
+
+ boolean delPrivilege(String role, Privilege priv) {
+ AuthPrivilege authPriv = privileges.get(role);
+ if (authPriv != null) {
+ short newPriv = Privilege.removeFrom(priv, authPriv.privilege);
+ if (newPriv == Privilege.NONE.code) {
+ privileges.remove(role);
+ return true;
+ } else {
+ authPriv.setPrivilege(newPriv);
+ }
+ }
+ return false;
+ }
+
+ AuthPrivilege getPrivilege(String role) {
+ return privileges.get(role);
+ }
+
+ Map<String, AuthPrivilege> getAllPrivileges() {
+ return privileges;
+ }
+
+ Map<String, Authorizable> getChildren() {
+ return children;
+ }
+ }
+
+
+ static class GroupMapper {
+ final Configuration conf;
+
+ @VisibleForTesting
+ GroupMapper(Configuration conf) {
+ this.conf = conf;
+ }
+
+ protected Set<String> getGroupsForUser(String user)
+ throws SentryUserException {
+ return SentryPolicyStoreProcessor.getGroupsFromUserName(conf, user);
+ }
+
+ // get adminGroups from conf
+ protected Set<String> getAdminGroups() {
+ return Sets.newHashSet(conf.getStrings(
+ ServerConfig.ADMIN_GROUPS, new String[]{}));
+ }
+
+ // is Admin group
+ protected boolean isInAdminGroup(Set<String> groups)
+ throws SentryUserException {
+ Set<String> admins = getAdminGroups();
+ if (admins != null && !admins.isEmpty()) {
+ for (String g : groups) {
+ if (admins.contains(g)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+// private static String LOG_FILE = "inmem.log";
+// private final OutputStream logStream;
+ private final UUID serverId = UUID.randomUUID();
+ private final AtomicLong seqId = new AtomicLong(0);
+ private final Configuration conf;
+ private final GroupMapper groupMapper;
+ private String schemaVersion;
+
+ private Map<String, Authorizable> rootAuthrizables =
+ new HashMap<String, Authorizable>();
+ private Map<String, Set<Authorizable>> roleToAuthorizable =
+ new HashMap<String, Set<Authorizable>>();
+ private Map<String, Set<String>> roleToGroups =
+ new HashMap<String, Set<String>>();
+ private Map<String, Set<String>> groupToRoles =
+ new HashMap<String, Set<String>>();
+
+ InMemSentryStore(Configuration conf) throws SentryAccessDeniedException{
+ this(conf, new GroupMapper(conf));
+ }
+
+ @VisibleForTesting
+ InMemSentryStore(Configuration conf, GroupMapper groupMapper)
+ throws SentryAccessDeniedException{
+ this.conf = conf;
+ this.groupMapper = groupMapper;
+ }
+
+ public Configuration getConfiguration() {
+ return conf;
+ }
+
+ @Override
+ public CommitContext createSentryRole(String roleName)
+ throws SentryAlreadyExistsException {
+ if (!doesRoleExists(roleName)) {
+ roleToGroups.put(roleName, new HashSet<String>());
+ roleToAuthorizable.put(roleName, new HashSet<Authorizable>());
+ return new CommitContext(serverId, seqId.getAndIncrement());
+ }
+ throw new SentryAlreadyExistsException(
+ "Role [" + roleName + "] already exists !!");
+ }
+
+ private boolean doesRoleExists(String roleName) {
+ return roleToGroups.containsKey(roleName)
+ || roleToAuthorizable.containsKey(roleName);
+ }
+
+ private static boolean checkHierarchy(Authorizable auth, TSentryPrivilege tPriv) {
+ if (auth == null) return true;
+ if ((auth.getAuthType() == AuthType.COLUMN)
+ &&(!auth.getName().equals(Strings.nullToEmpty(tPriv.getColumnName())))) {
+ return false;
+ }
+ if ((auth.getAuthType() == AuthType.TABLE)
+ &&(!auth.getName().equals(Strings.nullToEmpty(tPriv.getTableName())))) {
+ return false;
+ }
+ if ((auth.getAuthType() == AuthType.DB)
+ &&(!auth.getName().equals(Strings.nullToEmpty(tPriv.getDbName())))) {
+ return false;
+ }
+ if ((auth.getAuthType() == AuthType.URI)
+ &&(!Strings.isNullOrEmpty(tPriv.getURI()))) {
+ if (!PathUtils.impliesURI(auth.getName(), tPriv.getURI())) {
+ return false;
+ }
+ }
+ if ((auth.getAuthType() == AuthType.SERVER)
+ &&(!auth.getName().equals(Strings.nullToEmpty(tPriv.getServerName())))) {
+ return false;
+ }
+ return checkHierarchy(auth.getParent(), tPriv);
+ }
+
+ private LinkedHashMap<AuthType, String> toAuthorizableHierarchy(
+ TSentryAuthorizable tAuthHier) {
+ // TODO : fix this for generic model
+ TSentryPrivilege temp = new TSentryPrivilege("", tAuthHier.getServer(), "");
+ temp.setDbName(tAuthHier.getDb());
+ temp.setURI(tAuthHier.getUri());
+ temp.setTableName(tAuthHier.getTable());
+ temp.setColumnName(tAuthHier.getColumn());
+ return toAuthorizableHierarchy(temp);
+ }
+
+ private LinkedHashMap<AuthType, String> toAuthorizableHierarchy(
+ TSentryPrivilege tPriv) {
+ // TODO : fix this for generic model
+ LinkedHashMap<AuthType, String> map = new LinkedHashMap<AuthType, String>();
+ map.put(AuthType.SERVER, tPriv.getServerName().toLowerCase());
+ if (Strings.nullToEmpty(tPriv.getDbName()) != "") {
+ map.put(AuthType.DB, tPriv.getDbName().toLowerCase());
+ if (Strings.nullToEmpty(tPriv.getTableName()) != "") {
+ map.put(AuthType.TABLE, tPriv.getTableName().toLowerCase());
+ if (Strings.nullToEmpty(tPriv.getColumnName()) != "") {
+ map.put(AuthType.COLUMN, tPriv.getColumnName().toLowerCase());
+ }
+ }
+ } else {
+ if (Strings.nullToEmpty(tPriv.getURI()) != "") {
+ map.put(AuthType.URI, tPriv.getURI());
+ }
+ }
+ return map;
+ }
+
+ private void fillPrivMap(HashMap<String, String> pUpdate, Authorizable auth) {
+ for (Map.Entry<String, AuthPrivilege> e : auth.getAllPrivileges().entrySet()) {
+ String outPriv = "";
+ if (Privilege.includedIn(Privilege.SELECT, e.getValue().privilege)) {
+ outPriv = Privilege.SELECT.toString();
+ }
+ if (Privilege.includedIn(Privilege.INSERT, e.getValue().privilege)) {
+ outPriv = (outPriv.equals("") ? outPriv : ",");
+ outPriv = outPriv + Privilege.INSERT.toString();
+ }
+ pUpdate.put(e.getKey(), outPriv);
+ }
+ }
+
+ private void grantOptionCheck(String grantorPrincipal, TSentryPrivilege inPriv)
+ throws SentryUserException {
+ if (grantorPrincipal == null) {
+ throw new SentryInvalidInputException("grantorPrincipal should not be null");
+ }
+ Set<String> groups = groupMapper.getGroupsForUser(grantorPrincipal);
+ if (groups == null || groups.isEmpty()) {
+ throw new SentryGrantDeniedException(grantorPrincipal
+ + " has no grant!");
+ }
+ // if grantor is in adminGroup, don't need to do check
+ if (!groupMapper.isInAdminGroup(groups)) {
+ boolean hasGrant = false;
+ Set<String> roles = getRoleNamesForGroups(groups);
+ for (String role : roles) {
+ Set<Authorizable> authorizables = roleToAuthorizable.get(role);
+ for (Authorizable auth : authorizables) {
+ AuthPrivilege authPriv = auth.getPrivilege(role);
+ if ((authPriv.getGrantOption() == GrantOption.TRUE)
+ && authPriv.implies(auth, inPriv)) {
+ hasGrant = true;
+ break;
+ }
+ }
+ }
+ if (!hasGrant) {
+ throw new SentryGrantDeniedException(grantorPrincipal
+ + " has no grant!");
+ }
+ }
+ }
+
+ private Authorizable getLeaf(TSentryPrivilege inPriv, boolean createNodes)
+ throws SentryUserException {
+ LinkedHashMap<AuthType,String> authHierarchy =
+ toAuthorizableHierarchy(inPriv);
+ return getLeafCore(createNodes, false, authHierarchy);
+ }
+
+ private Authorizable getLeafCore(boolean createNodes, boolean isParentOk,
+ LinkedHashMap<AuthType, String> authHierarchy) throws SentryUserException {
+ Authorizable parent = null;
+ Authorizable current = null;
+ for (Map.Entry<AuthType, String> e : authHierarchy.entrySet()) {
+ if (e.getKey() == AuthType.SERVER) {
+ current = rootAuthrizables.get(e.getValue());
+ if (current == null) {
+ if (createNodes) {
+ current = new Authorizable(e.getValue(), e.getKey(), null);
+ rootAuthrizables.put(e.getValue(), current);
+ } else {
+ if (isParentOk) {
+ return parent;
+ }
+ throw new SentryUserException(
+ "Invalid authHierarchy [" + authHierarchy + "]");
+ }
+ }
+ } else {
+ // parent cannot be null here
+ if (parent == null) {
+ throw new SentryUserException(
+ "Invalid authHierarchy [" + authHierarchy + "]");
+ } else {
+ current = parent.getChild(e.getValue(), e.getKey());
+ if (current == null) {
+ if (createNodes) {
+ current = parent.addChild(e.getValue(), e.getKey());
+ } else {
+ if (isParentOk) {
+ return parent;
+ }
+ throw new SentryUserException(
+ "Invalid authHierarchy [" + authHierarchy + "]");
+ }
+ }
+ }
+ }
+ parent = current;
+ }
+ return current;
+ }
+
+ public Set<String> getGroupsForRole(String roleName) {
+ return roleToGroups.get(roleName);
+ }
+
+ private Map<String, Set<TSentryPrivilege>> collectPrivileges(Set<String> roleSet,
+ TSentryAuthorizable inAuthHier, boolean isAdmin)
+ throws SentryUserException {
+ // This collects all privileges applicable for the role for
+ // 1) All child objects from the leaf of authHierarchy
+ // 2) All nodes in parent chain of the leaf of authHierarchy
+ Map<String, Set<TSentryPrivilege>> resultMap =
+ new HashMap<String, Set<TSentryPrivilege>>();
+ if (inAuthHier != null) {
+ LinkedHashMap<AuthType,String> authHierarchy =
+ toAuthorizableHierarchy(inAuthHier);
+ Authorizable current = getLeafCore(false, true, authHierarchy);
+ if (current != null) {
+ // If returned node is a parent.. we should not
+ // recurse down..
+ collectPrivileges(current, roleSet, isAdmin, resultMap,
+ !isAParent(authHierarchy, current));
+ Authorizable parent = current.parent;
+ while (parent != null) {
+ collectPrivileges(parent, roleSet, isAdmin, resultMap, false);
+ parent = parent.getParent();
+ }
+
+ }
+ } else {
+ for (Authorizable root : rootAuthrizables.values()) {
+ collectPrivileges(root, roleSet, isAdmin, resultMap, true);
+ }
+ }
+ return resultMap;
+ }
+
+ private boolean isAParent(LinkedHashMap<AuthType, String> authHierarchy,
+ Authorizable current) {
+ Iterator<Entry<AuthType, String>> iterator = authHierarchy.entrySet().iterator();
+ Entry<AuthType, String> ent = null;
+ // get last element
+ while (iterator.hasNext()) {
+ ent = iterator.next();
+ }
+ return (ent.getKey() != current.getAuthType());
+ }
+
+ private void collectPrivileges(Authorizable current, Set<String> roleSet,
+ boolean isAdmin, Map<String, Set<TSentryPrivilege>> resultMap, boolean recurse)
+ throws SentryUserException {
+ addToPrivSet(current, roleSet, isAdmin, resultMap);
+ if (recurse) {
+ for (Authorizable child : current.getChildren().values()) {
+ collectPrivileges(child, roleSet, isAdmin, resultMap, recurse);
+ }
+ }
+ }
+
+ private void addToPrivSet(Authorizable current, Set<String> roleSet,
+ boolean isAdmin, Map<String, Set<TSentryPrivilege>> resultMap) {
+ for (Map.Entry<String, AuthPrivilege> e : current.getAllPrivileges().entrySet()) {
+ String roleName = e.getKey();
+ if (isAdmin || (roleSet.contains(roleName))) {
+ Set<TSentryPrivilege> pSet = resultMap.get(roleName);
+ if (pSet == null) {
+ pSet = new HashSet<TSentryPrivilege>();
+ resultMap.put(roleName, pSet);
+ }
+ pSet.addAll(convertToTSentryPrivileges(current, e.getValue()));
+ }
+ }
+ }
+
+ private Set<TSentryPrivilege> convertToTSentryPrivileges(Authorizable auth, AuthPrivilege authPriv) {
+ Set<TSentryPrivilege> retPrivs = new HashSet<TSentryPrivilege>();
+ for (Privilege privToTest : Privilege.values()) {
+ // These Apply only to DB
+ if (Sets.newHashSet(
+ Privilege.CREATE, Privilege.DROP,
+ Privilege.INDEX, Privilege.LOCK).contains(privToTest)
+ && (auth.getAuthType() != AuthType.DB)) {
+ continue;
+ }
+ if (privToTest == Privilege.NONE) {
+ continue;
+ }
+ if (Privilege.includedIn(privToTest, authPriv.privilege)) {
+ TSentryPrivilege tPriv = new TSentryPrivilege();
+ tPriv.setAction(
+ (privToTest == Privilege.ALL)
+ && (auth.getAuthType() != AuthType.URI) ?
+ "*" : privToTest.toString().toLowerCase());
+ tPriv.setPrivilegeScope(auth.getAuthType().toString());
+ if (auth.getAuthType() == AuthType.SERVER) {
+ tPriv.setServerName(auth.getName());
+ } else if (auth.getAuthType() == AuthType.DB) {
+ tPriv.setServerName(auth.getParent().getName());
+ tPriv.setDbName(auth.getName());
+ } else if (auth.getAuthType() == AuthType.URI) {
+ tPriv.setServerName(auth.getParent().getName());
+ tPriv.setURI(auth.getName());
+ } else if (auth.getAuthType() == AuthType.TABLE) {
+ tPriv.setServerName(auth.getParent().getParent().getName());
+ tPriv.setDbName(auth.getParent().getName());
+ tPriv.setTableName(auth.getName());
+ } else if (auth.getAuthType() == AuthType.COLUMN) {
+ tPriv.setServerName(auth.getParent().getParent().getParent().getName());
+ tPriv.setDbName(auth.getParent().getParent().getName());
+ tPriv.setTableName(auth.getParent().getName());
+ tPriv.setColumnName(auth.getName());
+ }
+ tPriv.setGrantOption(
+ TSentryGrantOption.valueOf(authPriv.getGrantOption().toString()));
+ // Not storing this for the timebeing
+ tPriv.setCreateTime(0);
+ if (privToTest == Privilege.ALL) {
+ // Remove all other privilege objects if ALL
+ retPrivs.clear();
+ retPrivs.add(tPriv);
+ break;
+ }
+ retPrivs.add(tPriv);
+ }
+ }
+ return retPrivs;
+ }
+
+ private void recursiveRevoke(String roleName, Privilege priv,
+ Authorizable authorizable, GrantOption inGrantOption) {
+ AuthPrivilege authPriv = authorizable.getPrivilege(roleName);
+ if (authPriv != null) {
+ boolean doRevoke = true;
+ if (authPriv.getGrantOption() != GrantOption.UNSET) {
+ doRevoke = authPriv.getGrantOption() == inGrantOption;
+ if (inGrantOption == GrantOption.UNSET) {
+ doRevoke = true;
+ }
+ }
+ if (doRevoke) {
+ boolean delPriv = authorizable.delPrivilege(roleName, priv);
+ // Remove from roleToAuth mapping if no privileges
+ if (delPriv) {
+ Set<Authorizable> authSet = roleToAuthorizable.get(roleName);
+ authSet.remove(authorizable);
+ }
+ }
+ }
+ for(Authorizable child : authorizable.getChildren().values()) {
+ recursiveRevoke(roleName, priv, child, inGrantOption);
+ }
+ }
+
+ private Set<String> getRolesToQuery(Set<String> groups,
+ TSentryActiveRoleSet roleSet) {
+ if (roleSet == null) {
+ roleSet = new TSentryActiveRoleSet(true, null);
+ }
+ Set<String> activeRoleNames = StoreUtils.toTrimedLower(roleSet.getRoles());
+ Set<String> roleNamesForGroups = StoreUtils.toTrimedLower(getRoleNamesForGroups(groups));
+ Set<String> rolesToQuery = roleSet.isAll() ? roleNamesForGroups : Sets.intersection(activeRoleNames, roleNamesForGroups);
+ return rolesToQuery;
+ }
+
+ @Override
+ public CommitContext alterSentryRoleGrantPrivilege(String grantorPrincipal,
+ String roleName, TSentryPrivilege inPriv) throws SentryUserException {
+ if (!doesRoleExists(roleName)) {
+ throw new SentryNoSuchObjectException("Role: " + roleName);
+ }
+ grantOptionCheck(grantorPrincipal, inPriv);
+ Authorizable current = getLeaf(inPriv, true);
+ current.addPrivilege(roleName, Privilege.fromTSentryPrivilege(inPriv));
+ if (inPriv.getGrantOption() != null) {
+ current.getPrivilege(roleName).setGrantOption(
+ GrantOption.valueOf(inPriv.getGrantOption().toString()));
+ }
+ Set<Authorizable> authSet = roleToAuthorizable.get(roleName);
+ authSet.add(current);
+ return new CommitContext(serverId, seqId.getAndIncrement());
+ }
+
+
+ @Override
+ public CommitContext alterSentryRoleGrantPrivileges(String grantorPrincipal,
+ String roleName, Set<TSentryPrivilege> privileges)
+ throws SentryUserException {
+ CommitContext ctx = null;
+ for (TSentryPrivilege inPriv : privileges) {
+ ctx = alterSentryRoleGrantPrivilege(grantorPrincipal, roleName, inPriv);
+ }
+ return ctx;
+ }
+
+ @Override
+ public CommitContext alterSentryRoleRevokePrivilege(String grantorPrincipal,
+ String roleName, TSentryPrivilege inPriv) throws SentryUserException {
+ if (!doesRoleExists(roleName)) {
+ throw new SentryNoSuchObjectException("Role: " + roleName);
+ }
+ grantOptionCheck(grantorPrincipal, inPriv);
+ Authorizable current = getLeaf(inPriv, false);
+ // NOTE : look how much simpler this is !!
+ recursiveRevoke(roleName, Privilege.fromTSentryPrivilege(inPriv), current,
+ GrantOption.valueOf(inPriv.getGrantOption().toString()));
+ return new CommitContext(serverId, seqId.getAndIncrement());
+ }
+
+ @Override
+ public CommitContext alterSentryRoleRevokePrivileges(String grantorPrincipal,
+ String roleName, Set<TSentryPrivilege> privileges)
+ throws SentryUserException {
+ CommitContext ctx = null;
+ for (TSentryPrivilege inPriv : privileges) {
+ ctx = alterSentryRoleRevokePrivilege(grantorPrincipal, roleName, inPriv);
+ }
+ return ctx;
+ }
+
+ @Override
+ public CommitContext dropSentryRole(String roleName)
+ throws SentryNoSuchObjectException {
+ if (doesRoleExists(roleName)) {
+ Set<Authorizable> authSet = roleToAuthorizable.get(roleName);
+ for (Authorizable authorizable : authSet) {
+ authorizable.delPrivilege(roleName, Privilege.ALL);
+ }
+ roleToAuthorizable.remove(roleName);
+ Set<String> groups = roleToGroups.get(roleName);
+ for (String group : groups) {
+ Set<String> roleSet = groupToRoles.get(group);
+ if (roleSet != null) {
+ roleSet.remove(roleName);
+ }
+ }
+ roleToGroups.remove(roleName);
+ return new CommitContext(serverId, seqId.getAndIncrement());
+ } else {
+ throw new SentryNoSuchObjectException("Role [" + roleName + "] does not exist !!");
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleAddGroups(String grantorPrincipal,
+ String roleName, Set<TSentryGroup> inGroups)
+ throws SentryNoSuchObjectException {
+ if (!doesRoleExists(roleName)) {
+ throw new SentryNoSuchObjectException(
+ "Role [" + roleName + "] does not exist !!");
+ }
+ Set<String> groups = roleToGroups.get(roleName);
+ for (TSentryGroup inGroup : inGroups) {
+ groups.add(inGroup.getGroupName());
+ Set<String> rSet = groupToRoles.get(inGroup.getGroupName());
+ if (rSet == null) {
+ rSet = new HashSet<String>();
+ groupToRoles.put(inGroup.getGroupName(), rSet);
+ }
+ rSet.add(roleName);
+ }
+ return new CommitContext(serverId, seqId.getAndIncrement());
+ }
+
+ @Override
+ public CommitContext alterSentryRoleDeleteGroups(String roleName,
+ Set<TSentryGroup> inGroups) throws SentryNoSuchObjectException {
+ if (!doesRoleExists(roleName)) {
+ throw new SentryNoSuchObjectException(
+ "Role [" + roleName + "] does not exist !!");
+ }
+ Set<String> groups = roleToGroups.get(roleName);
+ for (TSentryGroup inGroup : inGroups) {
+ groups.remove(inGroup.getGroupName());
+ Set<String> rSet = groupToRoles.get(inGroup.getGroupName());
+ if (rSet != null) {
+ rSet.remove(roleName);
+ }
+ }
+ return new CommitContext(serverId, seqId.getAndIncrement());
+ }
+
+ @Override
+ public TSentryPrivilegeMap listSentryPrivilegesByAuthorizable(
+ Set<String> groups, TSentryActiveRoleSet activeRoles,
+ TSentryAuthorizable tAuthHierarchy, boolean isAdmin)
+ throws SentryInvalidInputException {
+ Map<String, Set<TSentryPrivilege>> resultPrivilegeMap = Maps.newTreeMap();
+ Set<String> roles = Sets.newHashSet();
+ if (groups != null && !groups.isEmpty()) {
+ roles.addAll(getRolesToQuery(groups, activeRoles));
+ }
+ if (activeRoles != null && !activeRoles.isAll()) {
+ // need to check/convert to lowercase here since this is from user input
+ for (String aRole : activeRoles.getRoles()) {
+ roles.add(aRole.toLowerCase());
+ }
+ }
+ try {
+ resultPrivilegeMap = collectPrivileges(roles, tAuthHierarchy, isAdmin);
+ } catch (SentryUserException e) {
+ // Do this quietly
+// throw new SentryInvalidInputException(e.getMessage());
+ }
+
+ return new TSentryPrivilegeMap(resultPrivilegeMap);
+ }
+
+ @Override
+ public Set<TSentryPrivilege> getAllTSentryPrivilegesByRoleName(
+ String roleName) throws SentryNoSuchObjectException {
+ Set<TSentryPrivilege> resultSet = new HashSet<TSentryPrivilege>();
+ Set<Authorizable> auths = roleToAuthorizable.get(roleName);
+ if (auths != null) {
+ for (Authorizable auth : auths) {
+ resultSet.addAll(
+ convertToTSentryPrivileges(auth, auth.getPrivilege(roleName)));
+ }
+ }
+ return resultSet;
+ }
+
+ @Override
+ public Set<TSentryPrivilege> getTSentryPrivileges(Set<String> roleNames,
+ TSentryAuthorizable authHierarchy) throws SentryInvalidInputException {
+ Set<TSentryPrivilege> resultSet = new HashSet<TSentryPrivilege>();
+ try {
+ Map<String, Set<TSentryPrivilege>> allPrivs =
+ collectPrivileges(roleNames, authHierarchy, false);
+ for (Set<TSentryPrivilege> pivSet : allPrivs.values()) {
+ resultSet.addAll(pivSet);
+ }
+ } catch (SentryUserException e) {
+ throw new SentryInvalidInputException(e.getMessage());
+ }
+ return resultSet;
+ }
+
+ @Override
+ public Set<TSentryRole> getTSentryRolesByGroupName(Set<String> groupNames,
+ boolean checkAllGroups) throws SentryNoSuchObjectException {
+ Set<TSentryRole> resultSet = new HashSet<TSentryRole>();
+ Set<String> roleSet = new HashSet<String>();
+ if ((groupNames == null)||(groupNames.size() == 0)) {
+ roleSet.addAll(roleToGroups.keySet());
+ } else {
+ for (String group : groupNames) {
+ if (group == null) {
+ roleSet.addAll(roleToGroups.keySet());
+ break;
+ }
+ Set<String> rSet = groupToRoles.get(group);
+ if (rSet != null) {
+ for (String role : rSet) {
+ roleSet.add(role);
+ }
+ } else {
+ throw new SentryNoSuchObjectException("Group [" + group + "] does not exist !!");
+ }
+ }
+ }
+ for (String role : roleSet) {
+ TSentryRole tRole = new TSentryRole();
+ tRole.setRoleName(role);
+ tRole.setGrantorPrincipal("--");
+ Set<TSentryGroup> tGroups = new HashSet<TSentryGroup>();
+ for (String groupName : roleToGroups.get(role)) {
+ TSentryGroup tSentryGroup = new TSentryGroup();
+ tSentryGroup.setGroupName(groupName);
+ tGroups.add(tSentryGroup);
+ }
+ tRole.setGroups(tGroups);
+ resultSet.add(tRole);
+ }
+ return resultSet;
+ }
+
+ @Override
+ public Set<String> getRoleNamesForGroups(Set<String> groups) {
+ Set<String> roles = new HashSet<String>();
+ for (String group : groups) {
+ Set<String> rs = groupToRoles.get(group);
+ if (rs != null) {
+ roles.addAll(rs);
+ }
+ }
+ return roles;
+ }
+
+ @Override
+ public Set<String> listAllSentryPrivilegesForProvider(Set<String> groups,
+ TSentryActiveRoleSet roleSet) throws SentryInvalidInputException {
+ return listSentryPrivilegesForProvider(groups, roleSet, null);
+ }
+
+ @Override
+ public Set<String> listSentryPrivilegesForProvider(Set<String> groups,
+ TSentryActiveRoleSet roleSet, TSentryAuthorizable authHierarchy)
+ throws SentryInvalidInputException {
+ Set<String> resultSet = new HashSet<String>();
+ TSentryPrivilegeMap privMap =
+ listSentryPrivilegesByAuthorizable(groups, roleSet, authHierarchy, false);
+ for (Set<TSentryPrivilege> privSet : privMap.getPrivilegeMap().values()) {
+ for (TSentryPrivilege tPriv : privSet) {
+ String authorizable =
+ StoreUtils.toAuthorizable(tPriv.getServerName(), tPriv.getDbName(),
+ tPriv.getURI(), tPriv.getTableName(),
+ tPriv.getColumnName(), tPriv.getAction());
+ resultSet.add(authorizable);
+ }
+ }
+ return resultSet;
+ }
+
+ @Override
+ public boolean hasAnyServerPrivileges(Set<String> groups,
+ TSentryActiveRoleSet roleSet, String server) {
+ Set<String> rolesToQuery = getRolesToQuery(groups, roleSet);
+ Authorizable serverAuth = rootAuthrizables.get(server);
+ if (serverAuth != null) {
+ // Do breadth first search and return true immediately
+ LinkedList<Authorizable> lst = new LinkedList<Authorizable>();
+ lst.add(serverAuth);
+ while (!lst.isEmpty()) {
+ Authorizable auth = lst.removeFirst();
+ for (String roleName : rolesToQuery) {
+ if (auth.getPrivilege(roleName) != null) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getSentryVersion() throws SentryNoSuchObjectException,
+ SentryAccessDeniedException {
+ return this.schemaVersion;
+ }
+
+ @Override
+ public void setSentryVersion(String newVersion, String verComment)
+ throws SentryNoSuchObjectException, SentryAccessDeniedException {
+ this.schemaVersion = newVersion;
+ }
+
+ @Override
+ public void dropPrivilege(TSentryAuthorizable tAuthorizable)
+ throws SentryNoSuchObjectException, SentryInvalidInputException {
+ LinkedHashMap<AuthType,String> authHierarchy =
+ toAuthorizableHierarchy(tAuthorizable);
+ try {
+ Authorizable node = null;
+ try {
+ node = getLeafCore(false, false, authHierarchy);
+ } catch (Exception e) {
+ node = null;
+ }
+ if (node != null) {
+ if ((node.getChildren().size() == 0)
+ &&(node.getAllPrivileges().size() == 0)
+ &&(node.getParent() != null)) {
+ node.getParent().getChildren().remove(node.getName());
+ }
+ }
+ } catch (Exception e) {
+ // Ignore for the timebeing
+ }
+ }
+
+ @Override
+ public void renamePrivilege(TSentryAuthorizable tAuthorizable,
+ TSentryAuthorizable newTAuthorizable) throws SentryNoSuchObjectException,
+ SentryInvalidInputException {
+ LinkedHashMap<AuthType, String> oldHier = toAuthorizableHierarchy(tAuthorizable);
+ LinkedHashMap<AuthType, String> newHier = toAuthorizableHierarchy(newTAuthorizable);
+ Iterator<String> iter = newHier.values().iterator();
+ Authorizable parent = null;
+ Authorizable current = null;
+ for (Map.Entry<AuthType, String> e : oldHier.entrySet()) {
+ String newAuthName = iter.next();
+ if (e.getKey() == AuthType.SERVER) {
+ current = rootAuthrizables.get(e.getValue());
+ if (current == null) {
+ throw new SentryNoSuchObjectException(
+ "Invalid authHierarchy [" + oldHier + "]");
+ }
+ } else {
+ // parent cannot be null here
+ if (parent == null) {
+ throw new SentryNoSuchObjectException(
+ "Invalid authHierarchy [" + oldHier + "]");
+ } else {
+ current = parent.getChild(e.getValue());
+ if (current == null) {
+ throw new SentryNoSuchObjectException(
+ "Invalid authHierarchy [" + oldHier + "]");
+ }
+ }
+ }
+ if (!newAuthName.equals(e.getValue())) {
+ if (parent != null) {
+ parent.getChildren().remove(e.getValue());
+ current.setName(newAuthName);
+ }
+ }
+ parent = current;
+ }
+ }
+
+ @Override
+ public Map<String, HashMap<String, String>> retrieveFullPrivilegeImage() {
+ Map<String, HashMap<String, String>> retVal =
+ new HashMap<String, HashMap<String,String>>();
+ for (Authorizable rootA : rootAuthrizables.values()) {
+ // We need jut two levels here (DB and Table)..
+ for (Authorizable db : rootA.getChildren().values()) {
+ HashMap<String, String> pUpdate = new HashMap<String, String>();
+ retVal.put(db.name, pUpdate);
+ fillPrivMap(pUpdate, db);
+ for (Authorizable table : db.getChildren().values()) {
+ pUpdate = new HashMap<String, String>();
+ retVal.put(db.name + "." + table.name, pUpdate);
+ fillPrivMap(pUpdate, table);
+ }
+ }
+ }
+ return retVal;
+ }
+
+ @Override
+ public Map<String, LinkedList<String>> retrieveFullRoleImage() {
+ Map<String, LinkedList<String>> retVal =
+ new HashMap<String, LinkedList<String>>();
+ for (Map.Entry<String, Set<String>> e : roleToGroups.entrySet()) {
+ retVal.put(e.getKey(), new LinkedList<String>(e.getValue()));
+ }
+ return retVal;
+ }
+
+ @Override
+ public long getRoleCount() {
+ return (long)roleToAuthorizable.size();
+ }
+
+ @Override
+ public long getPrivilegeCount() {
+ long count = 0;
+ for (Set<Authorizable> auths : roleToAuthorizable.values()) {
+ count += auths.size();
+ }
+ return count;
+ }
+
+ @Override
+ public long getGroupCount() {
+ return (long)groupToRoles.size();
+ }
+
+ @Override
+ public void stop() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public TStoreSnapshot toSnapshot() {
+ AtomicInteger counter = new AtomicInteger(0);
+ TStoreSnapshot snapshot =
+ new TStoreSnapshot(
+ new HashMap<String, TStoreAuthorizable>(),
+ new HashMap<String, Set<String>>(),
+ new HashMap<Integer, TStoreAuthorizable>());
+ Map<String, TStoreAuthorizable> tRootAuths = snapshot.getRootAuthorizable();
+ for (Map.Entry<String, Authorizable> e : rootAuthrizables.entrySet()) {
+ TStoreAuthorizable tAuthorizabe =
+ new TStoreAuthorizable(e.getKey(), AuthType.SERVER.toString());
+ tAuthorizabe.setChildren(new HashSet<Integer>());
+ tAuthorizabe.setPrivileges(new HashMap<String, TStorePrivilege>());
+ for (Map.Entry<String, AuthPrivilege> priv : e.getValue().getAllPrivileges().entrySet()) {
+ tAuthorizabe.getPrivileges().put(priv.getKey(),
+ new TStorePrivilege(
+ TSentryGrantOption.valueOf(priv.getValue().grantOption.toString()),
+ priv.getValue().privilege));
+ }
+ snapshot.getObjIds().put(counter.getAndIncrement(), tAuthorizabe);
+ cloneTStoreAuthorizable(
+ e.getValue(), tAuthorizabe, counter, snapshot.getObjIds());
+ tRootAuths.put(e.getKey(), tAuthorizabe);
+ }
+ for (Map.Entry<String, Set<String>> e : roleToGroups.entrySet()) {
+ snapshot.getRoleToGroups().put(e.getKey(), new HashSet<String>(e.getValue()));
+ }
+ return snapshot;
+ }
+
+ private void cloneTStoreAuthorizable(Authorizable parent,
+ TStoreAuthorizable tParent, AtomicInteger counter,
+ Map<Integer, TStoreAuthorizable> objIds) {
+ for (Authorizable child : parent.getChildren().values()) {
+ TStoreAuthorizable tChild =
+ new TStoreAuthorizable(child.getName(),
+ child.getAuthType().toString());
+ tChild.setChildren(new HashSet<Integer>());
+ tChild.setPrivileges(new HashMap<String, TStorePrivilege>());
+ for (Map.Entry<String, AuthPrivilege> priv : child.getAllPrivileges().entrySet()) {
+ tChild.getPrivileges().put(priv.getKey(),
+ new TStorePrivilege(
+ TSentryGrantOption.valueOf(priv.getValue().grantOption.toString()),
+ priv.getValue().privilege));
+ }
+ int objId = counter.getAndIncrement();
+ objIds.put(objId, tChild);
+ tParent.addToChildren(objId);
+ cloneTStoreAuthorizable(child, tChild, counter, objIds);
+ }
+ }
+
+ @Override
+ public void fromSnapshot(TStoreSnapshot snapshot) {
+ initializeRolesAndGroups(snapshot);
+ // Should be called only after initializeRolesAndGroups()
+ initializeAuthorizables(snapshot);
+ }
+
+ private void initializeAuthorizables(TStoreSnapshot snapshot) {
+ roleToAuthorizable.clear();
+ for (String role : roleToGroups.keySet()) {
+ roleToAuthorizable.put(role, new HashSet<Authorizable>());
+ }
+ rootAuthrizables.clear();
+ for(Map.Entry<String, TStoreAuthorizable> e : snapshot.getRootAuthorizable().entrySet()) {
+ Authorizable auth =
+ new Authorizable(e.getValue().getName(),
+ AuthType.valueOf(e.getValue().getType()), null);
+ setPrivileges(e.getValue(), auth);
+ createChildren(e.getValue(), auth, snapshot.getObjIds());
+ }
+ }
+
+ private void setPrivileges(TStoreAuthorizable tAuth, Authorizable auth) {
+ for (Map.Entry<String, TStorePrivilege> privEntry : tAuth.getPrivileges().entrySet()) {
+ auth.setPrivilege(privEntry.getKey(), privEntry.getValue().getPrivilege());
+ if (privEntry.getValue().getGrantOption() != null) {
+ auth.getPrivilege(privEntry.getKey()).setGrantOption(
+ GrantOption.valueOf(privEntry.getValue().getGrantOption().toString()));
+ }
+ Set<Authorizable> authSet = roleToAuthorizable.get(privEntry.getKey());
+ if (authSet == null) {
+ authSet = new HashSet<Authorizable>();
+ roleToAuthorizable.put(privEntry.getKey(), authSet);
+ }
+ authSet.add(auth);
+ }
+ }
+
+ private void createChildren(TStoreAuthorizable tParent, Authorizable parent,
+ Map<Integer, TStoreAuthorizable> objIds) {
+ for (Integer id : tParent.getChildren()) {
+ TStoreAuthorizable tChild = objIds.get(id);
+ Authorizable child =
+ parent.addChild(tChild.getName(), AuthType.valueOf(tChild.getType()));
+ setPrivileges(tChild, child);
+ createChildren(tChild, child, objIds);
+ }
+ }
+
+ private void initializeRolesAndGroups(TStoreSnapshot snapshot) {
+ roleToGroups.clear();
+ groupToRoles.clear();
+ for (Map.Entry<String, Set<String>> e : snapshot.getRoleToGroups().entrySet()) {
+ for (String groupName : e.getValue()) {
+ Set<String> roleSet = groupToRoles.get(groupName);
+ if (roleSet == null) {
+ roleSet = new HashSet<String>();
+ groupToRoles.put(groupName, roleSet);
+ }
+ roleSet.add(e.getKey());
+ }
+ roleToGroups.put(e.getKey(), new HashSet<String>(e.getValue()));
+ }
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/LockingSentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/LockingSentryStore.java
new file mode 100644
index 0000000..d343257
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/LockingSentryStore.java
@@ -0,0 +1,446 @@
+package org.apache.sentry.provider.db.service.persistent;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.provider.db.SentryAlreadyExistsException;
+import org.apache.sentry.provider.db.SentryInvalidInputException;
+import org.apache.sentry.provider.db.SentryNoSuchObjectException;
+import org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
+import org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
+import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilegeMap;
+/**
+ * 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.
+ */
+
+import org.apache.sentry.provider.db.service.thrift.TSentryRole;
+import org.apache.sentry.provider.db.service.thrift.TStoreSnapshot;
+
+/**
+ * A Decorator SentryStore that delegates all calls to a provided SentryStore
+ * within a LockContext. The LockContext encapsulates the Locking policy. This
+ * is determined by a subclass. The Subclass is responsible for creating the
+ * LockContext before a method is called and after the method, unlock() is
+ * called on the Context.
+ *
+ * @param <T> A {@link LockContext} which exposes a single unlock() method
+ * a subclass has to implement.
+ */
+public abstract class LockingSentryStore<T extends LockingSentryStore.LockContext>
+ implements SentryStore {
+
+ public static interface LockContext {
+ public void unlock();
+ }
+
+ private final SentryStore sentryStore;
+
+ public LockingSentryStore(SentryStore sentryStore) {
+ this.sentryStore = sentryStore;
+ }
+
+ protected abstract T writeLock();
+ protected abstract T readLock();
+
+
+ @Override
+ public Configuration getConfiguration() {
+ return sentryStore.getConfiguration();
+ }
+
+ @Override
+ public CommitContext createSentryRole(String roleName)
+ throws SentryAlreadyExistsException {
+ T context = writeLock();
+ try {
+ return sentryStore.createSentryRole(roleName);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleGrantPrivilege(String grantorPrincipal,
+ String roleName, TSentryPrivilege privilege) throws SentryUserException {
+ T context = writeLock();
+ try {
+ return sentryStore.alterSentryRoleGrantPrivilege(
+ grantorPrincipal,roleName, privilege);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleGrantPrivileges(String grantorPrincipal,
+ String roleName, Set<TSentryPrivilege> privileges)
+ throws SentryUserException {
+ T context = writeLock();
+ try {
+ return sentryStore.alterSentryRoleGrantPrivileges(
+ grantorPrincipal, roleName, privileges);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleRevokePrivilege(String grantorPrincipal,
+ String roleName, TSentryPrivilege tPrivilege) throws SentryUserException {
+ T context = writeLock();
+ try {
+ return sentryStore.alterSentryRoleRevokePrivilege(
+ grantorPrincipal, roleName, tPrivilege);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleRevokePrivileges(String grantorPrincipal,
+ String roleName, Set<TSentryPrivilege> tPrivileges)
+ throws SentryUserException {
+ T context = writeLock();
+ try {
+ return sentryStore.alterSentryRoleRevokePrivileges(
+ grantorPrincipal, roleName, tPrivileges);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public CommitContext dropSentryRole(String roleName)
+ throws SentryNoSuchObjectException {
+ T context = writeLock();
+ try {
+ return sentryStore.dropSentryRole(roleName);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleAddGroups(String grantorPrincipal,
+ String roleName, Set<TSentryGroup> groupNames)
+ throws SentryNoSuchObjectException {
+ T context = writeLock();
+ try {
+ return sentryStore.alterSentryRoleAddGroups(
+ grantorPrincipal, roleName, groupNames);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleDeleteGroups(String roleName,
+ Set<TSentryGroup> groupNames) throws SentryNoSuchObjectException {
+ T context = writeLock();
+ try {
+ return sentryStore.alterSentryRoleDeleteGroups(roleName, groupNames);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public void dropPrivilege(TSentryAuthorizable tAuthorizable)
+ throws SentryNoSuchObjectException, SentryInvalidInputException {
+ T context = writeLock();
+ try {
+ sentryStore.dropPrivilege(tAuthorizable);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public void renamePrivilege(TSentryAuthorizable tAuthorizable,
+ TSentryAuthorizable newTAuthorizable) throws SentryNoSuchObjectException,
+ SentryInvalidInputException {
+ T context = writeLock();
+ try {
+ sentryStore.renamePrivilege(tAuthorizable, newTAuthorizable);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public void setSentryVersion(String newVersion, String verComment)
+ throws SentryNoSuchObjectException, SentryAccessDeniedException {
+ T context = writeLock();
+ try {
+ sentryStore.setSentryVersion(newVersion, verComment);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public TSentryPrivilegeMap listSentryPrivilegesByAuthorizable(
+ Set<String> groups, TSentryActiveRoleSet activeRoles,
+ TSentryAuthorizable authHierarchy, boolean isAdmin)
+ throws SentryInvalidInputException {
+ T context = readLock();
+ try {
+ return sentryStore.listSentryPrivilegesByAuthorizable(groups, activeRoles,
+ authHierarchy, isAdmin);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Set<TSentryPrivilege>
+ getAllTSentryPrivilegesByRoleName(String roleName)
+ throws SentryNoSuchObjectException {
+ T context = readLock();
+ try {
+ return sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Set<TSentryPrivilege> getTSentryPrivileges(Set<String> roleNames,
+ TSentryAuthorizable authHierarchy) throws SentryInvalidInputException {
+ T context = readLock();
+ try {
+ return sentryStore.getTSentryPrivileges(roleNames, authHierarchy);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Set<TSentryRole> getTSentryRolesByGroupName(Set<String> groupNames,
+ boolean checkAllGroups) throws SentryNoSuchObjectException {
+ T context = readLock();
+ try {
+ return sentryStore.getTSentryRolesByGroupName(groupNames, checkAllGroups);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Set<String> getRoleNamesForGroups(Set<String> groups) {
+ T context = readLock();
+ try {
+ return sentryStore.getRoleNamesForGroups(groups);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Set<String> listAllSentryPrivilegesForProvider(Set<String> groups,
+ TSentryActiveRoleSet roleSet) throws SentryInvalidInputException {
+ T context = readLock();
+ try {
+ return sentryStore.listAllSentryPrivilegesForProvider(groups, roleSet);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Set<String> listSentryPrivilegesForProvider(Set<String> groups,
+ TSentryActiveRoleSet roleSet, TSentryAuthorizable authHierarchy)
+ throws SentryInvalidInputException {
+ T context = readLock();
+ try {
+ return sentryStore.listSentryPrivilegesForProvider(groups, roleSet,
+ authHierarchy);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public boolean hasAnyServerPrivileges(Set<String> groups,
+ TSentryActiveRoleSet roleSet, String server) {
+ LockContext context = readLock();
+ try {
+ return sentryStore.hasAnyServerPrivileges(groups, roleSet, server);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public String getSentryVersion() throws SentryNoSuchObjectException,
+ SentryAccessDeniedException {
+ T context = readLock();
+ try {
+ return sentryStore.getSentryVersion();
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Map<String, HashMap<String, String>> retrieveFullPrivilegeImage() {
+ T context = readLock();
+ try {
+ return sentryStore.retrieveFullPrivilegeImage();
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Map<String, LinkedList<String>> retrieveFullRoleImage() {
+ T context = readLock();
+ try {
+ return sentryStore.retrieveFullRoleImage();
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public Set<String> getGroupsForRole(String roleName) {
+ T context = readLock();
+ try {
+ return sentryStore.getGroupsForRole(roleName);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public long getRoleCount() {
+ T context = readLock();
+ try {
+ return sentryStore.getRoleCount();
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public long getPrivilegeCount() {
+ T context = readLock();
+ try {
+ return sentryStore.getPrivilegeCount();
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public long getGroupCount() {
+ T context = readLock();
+ try {
+ return sentryStore.getGroupCount();
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public void stop() {
+ sentryStore.stop();
+ }
+
+ @Override
+ public TStoreSnapshot toSnapshot() {
+ T context = readLock();
+ try {
+ return sentryStore.toSnapshot();
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+
+ @Override
+ public void fromSnapshot(TStoreSnapshot snapshot) {
+ T context = writeLock();
+ try {
+ sentryStore.fromSnapshot(snapshot);
+ } finally {
+ if (context != null) {
+ context.unlock();
+ }
+ }
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/PersistentSentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/PersistentSentryStore.java
new file mode 100644
index 0000000..5c5df9e
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/PersistentSentryStore.java
@@ -0,0 +1,577 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.provider.db.SentryAlreadyExistsException;
+import org.apache.sentry.provider.db.SentryInvalidInputException;
+import org.apache.sentry.provider.db.SentryNoSuchObjectException;
+import org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
+import org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
+import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilegeMap;
+import org.apache.sentry.provider.db.service.thrift.TSentryRole;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreOp;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreRecord;
+import org.apache.sentry.provider.db.service.thrift.TStoreSnapshot;
+
+import com.google.common.collect.Sets;
+
+/**
+ * A Decorator SentryStore that delegates all calls to a provided SentryStore
+ * after wrapping all writes with a PersistenceContext. The PersistenceContext
+ * encapsulates the Persistence strategy. This is determined by a subclass.
+ * The Subclass is responsible for creating the PersistenceContext before a
+ * method is called and after the method, the {@link #onSuccess(PersistentContext)} or
+ * {@link #onFailure(PersistentContext)} will be called with the context
+ * based on if the operation was successful or not on the underlying
+ * SentryStore
+ *
+ * @param <T> A PersistentContext implementation
+ */
+public abstract class PersistentSentryStore
+<T extends PersistentSentryStore.PersistentContext> implements SentryStore {
+
+ /**
+ * Marker interface to be implemented by a subclass. The Context is passed
+ * back to the subclass in the onSuccess or onFailure calls after the
+ * operation is complete.
+ */
+ public static interface PersistentContext {
+
+ }
+
+ private final SentryStore sentryStore;
+
+ public PersistentSentryStore(SentryStore sentryStore) {
+ this.sentryStore = sentryStore;
+ }
+
+ /**
+ * This Method is called before the write operations. Subclasses would ideally
+ * have to return an implementation of a PersistenceContext
+ * @param record A TSentryStoreRecord that encapsulates the operation and
+ * all arguments
+ * @return A PersistenceContext
+ * @throws IOException
+ */
+ protected abstract T createRecord(TSentryStoreRecord record) throws IOException;
+
+ /**
+ * This method is called if the operation has been successfully applied on
+ * the underlying SentryStore
+ * @param context A PersistenceContext
+ */
+ protected abstract void onSuccess(T context);
+
+ /**
+ * This method is called if the underlying SentryStore rejected the write
+ * operation. The default implementation is to persist a NO-OP record.
+ * (This is so that implementing classes that rely on a monotonically
+ * increment by 1 sequence Ids do not have to deal with gaps in the
+ * sequence Ids)
+ * @param context
+ */
+ protected abstract void onFailure(T context);
+
+ protected SentryStore getStore() {
+ return sentryStore;
+ }
+
+ @Override
+ public Configuration getConfiguration() {
+ return sentryStore.getConfiguration();
+ }
+
+ protected void applyRecord(TSentryStoreRecord record)
+ throws SentryUserException {
+ if ((record.getStoreOp() == TSentryStoreOp.SNAPSHOT) && (record.getSnapshot() != null)) {
+ sentryStore.fromSnapshot(record.getSnapshot());
+ } else if (record.getStoreOp() == TSentryStoreOp.CREATE_ROLE) {
+ sentryStore.createSentryRole(record.getRoleName());
+ } else if (record.getStoreOp() == TSentryStoreOp.DROP_ROLE) {
+ sentryStore.dropSentryRole(record.getRoleName());
+ } else if (record.getStoreOp() == TSentryStoreOp.GRANT_PRIVILEGES) {
+ sentryStore.alterSentryRoleGrantPrivileges(
+ record.getGrantorPrincipal(), record.getRoleName(),
+ record.getPrivileges());
+ } else if (record.getStoreOp() == TSentryStoreOp.REVOKE_PRVILEGES) {
+ sentryStore.alterSentryRoleRevokePrivileges(
+ record.getGrantorPrincipal(), record.getRoleName(),
+ record.getPrivileges());
+ } else if (record.getStoreOp() == TSentryStoreOp.ADD_GROUPS) {
+ Set<TSentryGroup> groups = new HashSet<TSentryGroup>();
+ for (String group : record.getGroups()) {
+ groups.add(new TSentryGroup(group));
+ }
+ sentryStore.alterSentryRoleAddGroups(
+ record.getGrantorPrincipal(), record.getRoleName(),
+ groups);
+ } else if (record.getStoreOp() == TSentryStoreOp.DEL_GROUPS) {
+ Set<TSentryGroup> groups = new HashSet<TSentryGroup>();
+ for (String group : record.getGroups()) {
+ groups.add(new TSentryGroup(group));
+ }
+ sentryStore.alterSentryRoleDeleteGroups(record.getRoleName(), groups);
+ } else if (record.getStoreOp() == TSentryStoreOp.DROP_PRIVILEGE) {
+ sentryStore.dropPrivilege(record.getAuthorizable());
+ } else if (record.getStoreOp() == TSentryStoreOp.RENAME_PRIVILEGE) {
+ sentryStore.renamePrivilege(record.getAuthorizable(),
+ record.getNewAuthorizable());
+ } else if (record.getStoreOp() == TSentryStoreOp.SET_VERSION) {
+ sentryStore.setSentryVersion(record.getVersion(),
+ record.getVersionComment());
+ } else if (record.getStoreOp() == TSentryStoreOp.NO_OP) {
+ // NO-OP
+ } else {
+ throw new RuntimeException("Unknown Sentry Store OP [" + record.getStoreOp() + "]");
+ }
+ }
+
+ @Override
+ public CommitContext createSentryRole(String roleName)
+ throws SentryAlreadyExistsException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.CREATE_ROLE);
+ record.setRoleName(roleName);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ CommitContext retVal = sentryStore.createSentryRole(roleName);
+ opSuccess = true;
+ onSuccess(pContext);
+ return retVal;
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryAlreadyExistsException) {
+ throw (SentryAlreadyExistsException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public CommitContext dropSentryRole(String roleName)
+ throws SentryNoSuchObjectException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.DROP_ROLE);
+ record.setRoleName(roleName);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ CommitContext retVal = sentryStore.dropSentryRole(roleName);
+ opSuccess = true;
+ onSuccess(pContext);
+ return retVal;
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryNoSuchObjectException) {
+ throw (SentryNoSuchObjectException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleGrantPrivilege(String grantorPrincipal,
+ String roleName, TSentryPrivilege privilege) throws SentryUserException {
+ return alterSentryRoleGrantPrivileges(grantorPrincipal, roleName,
+ Sets.newHashSet(privilege));
+ }
+
+ @Override
+ public CommitContext alterSentryRoleGrantPrivileges(String grantorPrincipal,
+ String roleName, Set<TSentryPrivilege> privileges)
+ throws SentryUserException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.GRANT_PRIVILEGES);
+ record.setGrantorPrincipal(grantorPrincipal);
+ record.setRoleName(roleName);
+ record.setPrivileges(privileges);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ CommitContext retVal =
+ sentryStore.alterSentryRoleGrantPrivileges(grantorPrincipal,
+ roleName, privileges);
+ opSuccess = true;
+ onSuccess(pContext);
+ return retVal;
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryUserException) {
+ throw (SentryUserException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleRevokePrivilege(String grantorPrincipal,
+ String roleName, TSentryPrivilege tPrivilege) throws SentryUserException {
+ return alterSentryRoleRevokePrivileges(grantorPrincipal, roleName,
+ Sets.newHashSet(tPrivilege));
+ }
+
+ @Override
+ public CommitContext alterSentryRoleRevokePrivileges(String grantorPrincipal,
+ String roleName, Set<TSentryPrivilege> tPrivileges)
+ throws SentryUserException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.REVOKE_PRVILEGES);
+ record.setGrantorPrincipal(grantorPrincipal);
+ record.setRoleName(roleName);
+ record.setPrivileges(tPrivileges);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ CommitContext retVal =
+ sentryStore.alterSentryRoleRevokePrivileges(grantorPrincipal,
+ roleName, tPrivileges);
+ opSuccess = true;
+ onSuccess(pContext);
+ return retVal;
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryUserException) {
+ throw (SentryUserException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleAddGroups(String grantorPrincipal,
+ String roleName, Set<TSentryGroup> groupNames)
+ throws SentryNoSuchObjectException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.ADD_GROUPS);
+ record.setGrantorPrincipal(grantorPrincipal);
+ record.setRoleName(roleName);
+ Set<String> groups = new HashSet<String>();
+ for (TSentryGroup gr : groupNames) {
+ groups.add(gr.getGroupName());
+ }
+ record.setGroups(groups);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ CommitContext retVal =
+ sentryStore.alterSentryRoleAddGroups(grantorPrincipal,
+ roleName, groupNames);
+ opSuccess = true;
+ onSuccess(pContext);
+ return retVal;
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryNoSuchObjectException) {
+ throw (SentryNoSuchObjectException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public CommitContext alterSentryRoleDeleteGroups(String roleName,
+ Set<TSentryGroup> groupNames) throws SentryNoSuchObjectException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.DEL_GROUPS);
+ record.setRoleName(roleName);
+ Set<String> groups = new HashSet<String>();
+ for (TSentryGroup gr : groupNames) {
+ groups.add(gr.getGroupName());
+ }
+ record.setGroups(groups);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ CommitContext retVal =
+ sentryStore.alterSentryRoleDeleteGroups(roleName, groupNames);
+ opSuccess = true;
+ onSuccess(pContext);
+ return retVal;
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryNoSuchObjectException) {
+ throw (SentryNoSuchObjectException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void dropPrivilege(TSentryAuthorizable tAuthorizable)
+ throws SentryNoSuchObjectException, SentryInvalidInputException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.DROP_PRIVILEGE);
+ record.setAuthorizable(tAuthorizable);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ sentryStore.dropPrivilege(tAuthorizable);
+ opSuccess = true;
+ onSuccess(pContext);
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryNoSuchObjectException) {
+ throw (SentryNoSuchObjectException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void renamePrivilege(TSentryAuthorizable tAuthorizable,
+ TSentryAuthorizable newTAuthorizable) throws SentryNoSuchObjectException,
+ SentryInvalidInputException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.RENAME_PRIVILEGE);
+ record.setAuthorizable(tAuthorizable);
+ record.setNewAuthorizable(newTAuthorizable);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ sentryStore.renamePrivilege(tAuthorizable, newTAuthorizable);
+ opSuccess = true;
+ onSuccess(pContext);
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryNoSuchObjectException) {
+ throw (SentryNoSuchObjectException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void setSentryVersion(String newVersion, String verComment)
+ throws SentryNoSuchObjectException, SentryAccessDeniedException {
+ TSentryStoreRecord record =
+ new TSentryStoreRecord(TSentryStoreOp.SET_VERSION);
+ record.setVersion(newVersion);
+ record.setVersionComment(verComment);
+ T pContext = null;
+ try {
+ pContext = createRecord(record);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not write record to Persistent Store [" + record + "]");
+ }
+ boolean opSuccess = false;
+ try {
+ sentryStore.setSentryVersion(newVersion, verComment);
+ opSuccess = true;
+ onSuccess(pContext);
+ } catch (Exception e) {
+ if (!opSuccess) {
+ onFailure(pContext);
+ }
+ if (e instanceof SentryNoSuchObjectException) {
+ throw (SentryNoSuchObjectException)e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public TSentryPrivilegeMap listSentryPrivilegesByAuthorizable(
+ Set<String> groups, TSentryActiveRoleSet activeRoles,
+ TSentryAuthorizable authHierarchy, boolean isAdmin)
+ throws SentryInvalidInputException {
+ return sentryStore.listSentryPrivilegesByAuthorizable(groups, activeRoles,
+ authHierarchy, isAdmin);
+ }
+
+ @Override
+ public Set<TSentryPrivilege> getAllTSentryPrivilegesByRoleName(String roleName)
+ throws SentryNoSuchObjectException {
+ return sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ }
+
+ @Override
+ public Set<TSentryPrivilege> getTSentryPrivileges(Set<String> roleNames,
+ TSentryAuthorizable authHierarchy) throws SentryInvalidInputException {
+ return sentryStore.getTSentryPrivileges(roleNames, authHierarchy);
+ }
+
+ @Override
+ public Set<TSentryRole> getTSentryRolesByGroupName(Set<String> groupNames,
+ boolean checkAllGroups) throws SentryNoSuchObjectException {
+ return sentryStore.getTSentryRolesByGroupName(groupNames, checkAllGroups);
+ }
+
+ @Override
+ public Set<String> getRoleNamesForGroups(Set<String> groups) {
+ return sentryStore.getRoleNamesForGroups(groups);
+ }
+
+ @Override
+ public Set<String> listAllSentryPrivilegesForProvider(Set<String> groups,
+ TSentryActiveRoleSet roleSet) throws SentryInvalidInputException {
+ return sentryStore.listAllSentryPrivilegesForProvider(groups, roleSet);
+ }
+
+ @Override
+ public Set<String> listSentryPrivilegesForProvider(Set<String> groups,
+ TSentryActiveRoleSet roleSet, TSentryAuthorizable authHierarchy)
+ throws SentryInvalidInputException {
+ return sentryStore.listSentryPrivilegesForProvider(groups, roleSet, authHierarchy);
+ }
+
+ @Override
+ public boolean hasAnyServerPrivileges(Set<String> groups,
+ TSentryActiveRoleSet roleSet, String server) {
+ return sentryStore.hasAnyServerPrivileges(groups, roleSet, server);
+ }
+
+ @Override
+ public String getSentryVersion() throws SentryNoSuchObjectException,
+ SentryAccessDeniedException {
+ return sentryStore.getSentryVersion();
+ }
+
+ @Override
+ public Map<String, HashMap<String, String>> retrieveFullPrivilegeImage() {
+ return sentryStore.retrieveFullPrivilegeImage();
+ }
+
+ @Override
+ public Map<String, LinkedList<String>> retrieveFullRoleImage() {
+ return sentryStore.retrieveFullRoleImage();
+ }
+
+ @Override
+ public long getRoleCount() {
+ return sentryStore.getRoleCount();
+ }
+
+ @Override
+ public long getPrivilegeCount() {
+ return sentryStore.getPrivilegeCount();
+ }
+
+ @Override
+ public long getGroupCount() {
+ return sentryStore.getGroupCount();
+ }
+
+ @Override
+ public Set<String> getGroupsForRole(String roleName) {
+ return sentryStore.getGroupsForRole(roleName);
+ }
+
+ @Override
+ public void stop() {
+ sentryStore.stop();
+ }
+
+ @Override
+ public TStoreSnapshot toSnapshot() {
+ return sentryStore.toSnapshot();
+ }
+
+ @Override
+ public void fromSnapshot(TStoreSnapshot snapshot) {
+ sentryStore.fromSnapshot(snapshot);
+ }
+
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
index 136dab6..83e88e6 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
@@ -18,1932 +18,115 @@
package org.apache.sentry.provider.db.service.persistent;
-import static org.apache.sentry.provider.common.ProviderConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.provider.common.ProviderConstants.KV_JOINER;
-
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
-import java.util.Properties;
import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.jdo.FetchGroup;
-import javax.jdo.JDODataStoreException;
-import javax.jdo.JDOHelper;
-import javax.jdo.PersistenceManager;
-import javax.jdo.PersistenceManagerFactory;
-import javax.jdo.Query;
-import javax.jdo.Transaction;
-
-import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.sentry.SentryUserException;
-import org.apache.sentry.core.model.db.AccessConstants;
-import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
-import org.apache.sentry.provider.common.ProviderConstants;
import org.apache.sentry.provider.db.SentryAccessDeniedException;
import org.apache.sentry.provider.db.SentryAlreadyExistsException;
-import org.apache.sentry.provider.db.SentryGrantDeniedException;
import org.apache.sentry.provider.db.SentryInvalidInputException;
import org.apache.sentry.provider.db.SentryNoSuchObjectException;
-import org.apache.sentry.provider.db.service.model.MSentryGroup;
-import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
-import org.apache.sentry.provider.db.service.model.MSentryRole;
-import org.apache.sentry.provider.db.service.model.MSentryVersion;
-import org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessor;
import org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
import org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
-import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
import org.apache.sentry.provider.db.service.thrift.TSentryPrivilegeMap;
import org.apache.sentry.provider.db.service.thrift.TSentryRole;
-import org.apache.sentry.service.thrift.ServiceConstants.PrivilegeScope;
-import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
-import org.datanucleus.store.rdbms.exceptions.MissingTableException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.codahale.metrics.Gauge;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import org.apache.sentry.provider.db.service.thrift.TStoreSnapshot;
/**
- * SentryStore is the data access object for Sentry data. Strings
- * such as role and group names will be normalized to lowercase
- * in addition to starting and ending whitespace.
+ * Base interface All SentryStore implementations must implement
+ *
*/
-public class SentryStore {
- private static final UUID SERVER_UUID = UUID.randomUUID();
- private static final Logger LOGGER = LoggerFactory
- .getLogger(SentryStore.class);
+public interface SentryStore {
- public static String NULL_COL = "__NULL__";
- static final String DEFAULT_DATA_DIR = "sentry_policy_db";
+ public Configuration getConfiguration();
- private static final Set<String> ALL_ACTIONS = Sets.newHashSet(AccessConstants.ALL,
- AccessConstants.SELECT, AccessConstants.INSERT, AccessConstants.ALTER,
- AccessConstants.CREATE, AccessConstants.DROP, AccessConstants.INDEX,
- AccessConstants.LOCK);
-
- // Now partial revoke just support action with SELECT,INSERT and ALL.
- // e.g. If we REVOKE SELECT from a privilege with action ALL, it will leads to INSERT
- // Otherwise, if we revoke other privilege(e.g. ALTER,DROP...), we will remove it from a role directly.
- private static final Set<String> PARTIAL_REVOKE_ACTIONS = Sets.newHashSet(AccessConstants.ALL,
- AccessConstants.ACTION_ALL.toLowerCase(), AccessConstants.SELECT, AccessConstants.INSERT);
-
- /**
- * Commit order sequence id. This is used by notification handlers
- * to know the order in which events where committed to the database.
- * This instance variable is incremented in incrementGetSequenceId
- * and read in commitUpdateTransaction. Synchronization on this
- * is required to read commitSequenceId.
- */
- private long commitSequenceId;
- private final PersistenceManagerFactory pmf;
- private Configuration conf;
- private PrivCleaner privCleaner = null;
- private Thread privCleanerThread = null;
-
- public SentryStore(Configuration conf) throws SentryNoSuchObjectException,
- SentryAccessDeniedException {
- commitSequenceId = 0;
- this.conf = conf;
- Properties prop = new Properties();
- prop.putAll(ServerConfig.SENTRY_STORE_DEFAULTS);
- String jdbcUrl = conf.get(ServerConfig.SENTRY_STORE_JDBC_URL, "").trim();
- Preconditions.checkArgument(!jdbcUrl.isEmpty(), "Required parameter " +
- ServerConfig.SENTRY_STORE_JDBC_URL + " missing");
- String user = conf.get(ServerConfig.SENTRY_STORE_JDBC_USER, ServerConfig.
- SENTRY_STORE_JDBC_USER_DEFAULT).trim();
- String pass = conf.get(ServerConfig.SENTRY_STORE_JDBC_PASS, ServerConfig.
- SENTRY_STORE_JDBC_PASS_DEFAULT).trim();
- String driverName = conf.get(ServerConfig.SENTRY_STORE_JDBC_DRIVER,
- ServerConfig.SENTRY_STORE_JDBC_DRIVER_DEFAULT);
- prop.setProperty(ServerConfig.JAVAX_JDO_URL, jdbcUrl);
- prop.setProperty(ServerConfig.JAVAX_JDO_USER, user);
- prop.setProperty(ServerConfig.JAVAX_JDO_PASS, pass);
- prop.setProperty(ServerConfig.JAVAX_JDO_DRIVER_NAME, driverName);
- for (Map.Entry<String, String> entry : conf) {
- String key = entry.getKey();
- if (key.startsWith(ServerConfig.SENTRY_JAVAX_JDO_PROPERTY_PREFIX) ||
- key.startsWith(ServerConfig.SENTRY_DATANUCLEUS_PROPERTY_PREFIX)) {
- key = StringUtils.removeStart(key, ServerConfig.SENTRY_DB_PROPERTY_PREFIX);
- prop.setProperty(key, entry.getValue());
- }
- }
-
-
- boolean checkSchemaVersion = conf.get(
- ServerConfig.SENTRY_VERIFY_SCHEM_VERSION,
- ServerConfig.SENTRY_VERIFY_SCHEM_VERSION_DEFAULT).equalsIgnoreCase(
- "true");
- if (!checkSchemaVersion) {
- prop.setProperty("datanucleus.autoCreateSchema", "true");
- prop.setProperty("datanucleus.fixedDatastore", "false");
- }
-
- // Disallow operations outside of transactions
- prop.setProperty("datanucleus.NontransactionalRead", "false");
- prop.setProperty("datanucleus.NontransactionalWrite", "false");
-
- pmf = JDOHelper.getPersistenceManagerFactory(prop);
- verifySentryStoreSchema(conf, checkSchemaVersion);
-
- // Kick off the thread that cleans orphaned privileges (unless told not to)
- privCleaner = this.new PrivCleaner();
- if (conf.get(ServerConfig.SENTRY_STORE_ORPHANED_PRIVILEGE_REMOVAL,
- ServerConfig.SENTRY_STORE_ORPHANED_PRIVILEGE_REMOVAL_DEFAULT)
- .equalsIgnoreCase("true")) {
- privCleanerThread = new Thread(privCleaner);
- privCleanerThread.start();
- }
- }
-
- // ensure that the backend DB schema is set
- private void verifySentryStoreSchema(Configuration serverConf,
- boolean checkVersion)
- throws SentryNoSuchObjectException, SentryAccessDeniedException {
- if (!checkVersion) {
- setSentryVersion(SentryStoreSchemaInfo.getSentryVersion(),
- "Schema version set implicitly");
- } else {
- String currentVersion = getSentryVersion();
- if (!SentryStoreSchemaInfo.getSentryVersion().equals(currentVersion)) {
- throw new SentryAccessDeniedException(
- "The Sentry store schema version " + currentVersion
- + " is different from distribution version "
- + SentryStoreSchemaInfo.getSentryVersion());
- }
- }
- }
-
- public synchronized void stop() {
- if (privCleanerThread != null) {
- privCleaner.exit();
- try {
- privCleanerThread.join();
- } catch (InterruptedException e) {
- // Ignore...
- }
- }
- if (pmf != null) {
- pmf.close();
- }
- }
-
- /**
- * PersistenceManager object and Transaction object have a one to one
- * correspondence. Each PersistenceManager object is associated with a
- * transaction object and vice versa. Hence we create a persistence manager
- * instance when we create a new transaction. We create a new transaction
- * for every store API since we want that unit of work to behave as a
- * transaction.
- *
- * Note that there's only one instance of PersistenceManagerFactory object
- * for the service.
- *
- * Synchronized because we obtain persistence manager
- */
- public synchronized PersistenceManager openTransaction() {
- PersistenceManager pm = pmf.getPersistenceManager();
- Transaction currentTransaction = pm.currentTransaction();
- currentTransaction.begin();
- return pm;
- }
-
- /**
- * Synchronized due to sequence id generation
- */
- public synchronized CommitContext commitUpdateTransaction(PersistenceManager pm) {
- commitTransaction(pm);
- return new CommitContext(SERVER_UUID, incrementGetSequenceId());
- }
-
- /**
- * Increments commitSequenceId which should not be modified outside
- * this method.
- *
- * @return sequence id
- */
- private synchronized long incrementGetSequenceId() {
- return ++commitSequenceId;
- }
-
- public void commitTransaction(PersistenceManager pm) {
- Transaction currentTransaction = pm.currentTransaction();
- try {
- Preconditions.checkState(currentTransaction.isActive(), "Transaction is not active");
- currentTransaction.commit();
- } finally {
- pm.close();
- }
- }
-
- public void rollbackTransaction(PersistenceManager pm) {
- if (pm == null || pm.isClosed()) {
- return;
- }
- Transaction currentTransaction = pm.currentTransaction();
- if (currentTransaction.isActive()) {
- try {
- currentTransaction.rollback();
- } finally {
- pm.close();
- }
- }
- }
- /**
- Get the MSentry object from roleName
- Note: Should be called inside a transaction
- */
- public MSentryRole getMSentryRole(PersistenceManager pm, String roleName) {
- Query query = pm.newQuery(MSentryRole.class);
- query.setFilter("this.roleName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- MSentryRole sentryRole = (MSentryRole) query.execute(roleName);
- return sentryRole;
- }
-
- /**
- * Normalize the string values
- */
- private String trimAndLower(String input) {
- return input.trim().toLowerCase();
- }
- /**
- * Create a sentry role and persist it.
- * @param roleName: Name of the role being persisted
- * @returns commit context used for notification handlers
- * @throws SentryAlreadyExistsException
- */
public CommitContext createSentryRole(String roleName)
- throws SentryAlreadyExistsException {
- roleName = trimAndLower(roleName);
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- pm = openTransaction();
- MSentryRole mSentryRole = getMSentryRole(pm, roleName);
- if (mSentryRole == null) {
- MSentryRole mRole = new MSentryRole(roleName, System.currentTimeMillis());
- pm.makePersistent(mRole);
- CommitContext commit = commitUpdateTransaction(pm);
- rollbackTransaction = false;
- return commit;
- } else {
- throw new SentryAlreadyExistsException("Role: " + roleName);
- }
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- private <T> Long getCount(Class<T> tClass) {
- PersistenceManager pm = null;
- Long size = new Long(-1);
- try {
- pm = openTransaction();
- Query query = pm.newQuery();
- query.setClass(tClass);
- query.setResult("count(this)");
- size = (Long)query.execute();
-
- } finally {
- commitTransaction(pm);
- }
- return size;
- }
- public Gauge<Long> getRoleCountGauge() {
- return new Gauge< Long >() {
- @Override
- public Long getValue() {
- return getCount(MSentryRole.class);
- }
- };
- }
-
- public Gauge<Long> getPrivilegeCountGauge() {
- return new Gauge< Long >() {
- @Override
- public Long getValue() {
- return getCount(MSentryPrivilege.class);
- }
- };
- }
- public Gauge<Long> getGroupCountGauge() {
- return new Gauge< Long >() {
- @Override
- public Long getValue() {
- return getCount(MSentryGroup.class);
- }
- };
- }
-
- /**
- * Lets the test code know how many privs are in the db, so that we know
- * if they are in fact being cleaned up when not being referenced any more.
- * @return The number of rows in the db priv table.
- */
- @VisibleForTesting
- long countMSentryPrivileges() {
- return getCount(MSentryPrivilege.class);
- }
+ throws SentryAlreadyExistsException;
public CommitContext alterSentryRoleGrantPrivilege(String grantorPrincipal,
String roleName, TSentryPrivilege privilege)
- throws SentryUserException {
- return alterSentryRoleGrantPrivileges(grantorPrincipal,
- roleName, Sets.newHashSet(privilege));
- }
-
+ throws SentryUserException;
+
public CommitContext alterSentryRoleGrantPrivileges(String grantorPrincipal,
String roleName, Set<TSentryPrivilege> privileges)
- throws SentryUserException {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- roleName = trimAndLower(roleName);
- try {
- pm = openTransaction();
- for (TSentryPrivilege privilege : privileges) {
- // first do grant check
- grantOptionCheck(pm, grantorPrincipal, privilege);
-
- MSentryPrivilege mPrivilege = alterSentryRoleGrantPrivilegeCore(pm, roleName, privilege);
-
- if (mPrivilege != null) {
- convertToTSentryPrivilege(mPrivilege, privilege);
- }
- }
- CommitContext commit = commitUpdateTransaction(pm);
- rollbackTransaction = false;
- return commit;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- private MSentryPrivilege alterSentryRoleGrantPrivilegeCore(PersistenceManager pm,
- String roleName, TSentryPrivilege privilege)
- throws SentryNoSuchObjectException, SentryInvalidInputException {
- MSentryPrivilege mPrivilege = null;
- MSentryRole mRole = getMSentryRole(pm, roleName);
- if (mRole == null) {
- throw new SentryNoSuchObjectException("Role: " + roleName);
- } else {
-
- if ((!isNULL(privilege.getColumnName())) || (!isNULL(privilege.getTableName()))
- || (!isNULL(privilege.getDbName()))) {
- // If Grant is for ALL and Either INSERT/SELECT already exists..
- // need to remove it and GRANT ALL..
- if (privilege.getAction().equalsIgnoreCase("*")) {
- TSentryPrivilege tNotAll = new TSentryPrivilege(privilege);
- tNotAll.setAction(AccessConstants.SELECT);
- MSentryPrivilege mSelect = getMSentryPrivilege(tNotAll, pm);
- tNotAll.setAction(AccessConstants.INSERT);
- MSentryPrivilege mInsert = getMSentryPrivilege(tNotAll, pm);
- if ((mSelect != null) && (mRole.getPrivileges().contains(mSelect))) {
- mSelect.removeRole(mRole);
- privCleaner.incPrivRemoval();
- pm.makePersistent(mSelect);
- }
- if ((mInsert != null) && (mRole.getPrivileges().contains(mInsert))) {
- mInsert.removeRole(mRole);
- privCleaner.incPrivRemoval();
- pm.makePersistent(mInsert);
- }
- } else {
- // If Grant is for Either INSERT/SELECT and ALL already exists..
- // do nothing..
- TSentryPrivilege tAll = new TSentryPrivilege(privilege);
- tAll.setAction(AccessConstants.ALL);
- MSentryPrivilege mAll = getMSentryPrivilege(tAll, pm);
- if ((mAll != null) && (mRole.getPrivileges().contains(mAll))) {
- return null;
- }
- }
- }
-
- mPrivilege = getMSentryPrivilege(privilege, pm);
- if (mPrivilege == null) {
- mPrivilege = convertToMSentryPrivilege(privilege);
- }
- mPrivilege.appendRole(mRole);
- pm.makePersistent(mRole);
- pm.makePersistent(mPrivilege);
- }
- return mPrivilege;
- }
+ throws SentryUserException;
public CommitContext alterSentryRoleRevokePrivilege(String grantorPrincipal,
- String roleName, TSentryPrivilege tPrivilege) throws SentryUserException {
- return alterSentryRoleRevokePrivileges(grantorPrincipal,
- roleName, Sets.newHashSet(tPrivilege));
- }
+ String roleName, TSentryPrivilege tPrivilege) throws SentryUserException;
public CommitContext alterSentryRoleRevokePrivileges(String grantorPrincipal,
- String roleName, Set<TSentryPrivilege> tPrivileges) throws SentryUserException {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- roleName = safeTrimLower(roleName);
- try {
- pm = openTransaction();
- for (TSentryPrivilege tPrivilege : tPrivileges) {
- // first do revoke check
- grantOptionCheck(pm, grantorPrincipal, tPrivilege);
-
- alterSentryRoleRevokePrivilegeCore(pm, roleName, tPrivilege);
- }
-
- CommitContext commit = commitUpdateTransaction(pm);
- rollbackTransaction = false;
- return commit;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- private void alterSentryRoleRevokePrivilegeCore(PersistenceManager pm,
- String roleName, TSentryPrivilege tPrivilege)
- throws SentryNoSuchObjectException, SentryInvalidInputException {
- Query query = pm.newQuery(MSentryRole.class);
- query.setFilter("this.roleName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- MSentryRole mRole = (MSentryRole) query.execute(roleName);
- if (mRole == null) {
- throw new SentryNoSuchObjectException("Role: " + roleName);
- } else {
- query = pm.newQuery(MSentryPrivilege.class);
- MSentryPrivilege mPrivilege = getMSentryPrivilege(tPrivilege, pm);
- if (mPrivilege == null) {
- mPrivilege = convertToMSentryPrivilege(tPrivilege);
- } else {
- mPrivilege = (MSentryPrivilege) pm.detachCopy(mPrivilege);
- }
-
- Set<MSentryPrivilege> privilegeGraph = Sets.newHashSet();
- if (mPrivilege.getGrantOption() != null) {
- privilegeGraph.add(mPrivilege);
- } else {
- MSentryPrivilege mTure = new MSentryPrivilege(mPrivilege);
- mTure.setGrantOption(true);
- privilegeGraph.add(mTure);
- MSentryPrivilege mFalse = new MSentryPrivilege(mPrivilege);
- mFalse.setGrantOption(false);
- privilegeGraph.add(mFalse);
- }
- // Get the privilege graph
- populateChildren(pm, Sets.newHashSet(roleName), mPrivilege, privilegeGraph);
- for (MSentryPrivilege childPriv : privilegeGraph) {
- revokePrivilegeFromRole(pm, tPrivilege, mRole, childPriv);
- }
- pm.makePersistent(mRole);
- }
- }
-
- /**
- * Roles can be granted ALL, SELECT, and INSERT on tables. When
- * a role has ALL and SELECT or INSERT are revoked, we need to remove the ALL
- * privilege and add SELECT (INSERT was revoked) or INSERT (SELECT was revoked).
- */
- private void revokePartial(PersistenceManager pm,
- TSentryPrivilege requestedPrivToRevoke, MSentryRole mRole,
- MSentryPrivilege currentPrivilege) throws SentryInvalidInputException {
- MSentryPrivilege persistedPriv = getMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege), pm);
- if (persistedPriv == null) {
- persistedPriv = convertToMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege));
- }
-
- if (requestedPrivToRevoke.getAction().equalsIgnoreCase("ALL") || requestedPrivToRevoke.getAction().equalsIgnoreCase("*")) {
- persistedPriv.removeRole(mRole);
- privCleaner.incPrivRemoval();
- pm.makePersistent(persistedPriv);
- } else if (requestedPrivToRevoke.getAction().equalsIgnoreCase(AccessConstants.SELECT)
- && (!currentPrivilege.getAction().equalsIgnoreCase(AccessConstants.INSERT))) {
- revokeRolePartial(pm, mRole, currentPrivilege, persistedPriv, AccessConstants.INSERT);
- } else if (requestedPrivToRevoke.getAction().equalsIgnoreCase(AccessConstants.INSERT)
- && (!currentPrivilege.getAction().equalsIgnoreCase(AccessConstants.SELECT))) {
- revokeRolePartial(pm, mRole, currentPrivilege, persistedPriv, AccessConstants.SELECT);
- }
- }
-
- private void revokeRolePartial(PersistenceManager pm, MSentryRole mRole,
- MSentryPrivilege currentPrivilege, MSentryPrivilege persistedPriv, String addAction)
- throws SentryInvalidInputException {
- // If table / URI, remove ALL
- persistedPriv.removeRole(mRole);
- privCleaner.incPrivRemoval();
- pm.makePersistent(persistedPriv);
-
- currentPrivilege.setAction(AccessConstants.ALL);
- persistedPriv = getMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege), pm);
- if ((persistedPriv != null)&&(mRole.getPrivileges().contains(persistedPriv))) {
- persistedPriv.removeRole(mRole);
- privCleaner.incPrivRemoval();
- pm.makePersistent(persistedPriv);
-
- currentPrivilege.setAction(addAction);
- persistedPriv = getMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege), pm);
- if (persistedPriv == null) {
- persistedPriv = convertToMSentryPrivilege(convertToTSentryPrivilege(currentPrivilege));
- mRole.appendPrivilege(persistedPriv);
- }
- persistedPriv.appendRole(mRole);
- pm.makePersistent(persistedPriv);
- }
- }
-
- /**
- * Revoke privilege from role
- */
- private void revokePrivilegeFromRole(PersistenceManager pm, TSentryPrivilege tPrivilege,
- MSentryRole mRole, MSentryPrivilege mPrivilege) throws SentryInvalidInputException {
- if (PARTIAL_REVOKE_ACTIONS.contains(mPrivilege.getAction())) {
- // if this privilege is in {ALL,SELECT,INSERT}
- // we will do partial revoke
- revokePartial(pm, tPrivilege, mRole, mPrivilege);
- } else {
- // if this privilege is not ALL, SELECT nor INSERT,
- // we will revoke it from role directly
- mPrivilege.removeRole(mRole);
- pm.makePersistent(mPrivilege);
- }
- }
-
- /**
- * Explore Privilege graph and collect child privileges.
- * The responsibility to commit/rollback the transaction should be handled by the caller.
- */
- private void populateChildren(PersistenceManager pm, Set<String> roleNames, MSentryPrivilege priv,
- Set<MSentryPrivilege> children) throws SentryInvalidInputException {
- Preconditions.checkNotNull(pm);
- if ((!isNULL(priv.getServerName())) || (!isNULL(priv.getDbName()))
- || (!isNULL(priv.getTableName()))) {
- // Get all TableLevel Privs
- Set<MSentryPrivilege> childPrivs = getChildPrivileges(pm, roleNames, priv);
- for (MSentryPrivilege childPriv : childPrivs) {
- // Only recurse for table level privs..
- if ((!isNULL(childPriv.getDbName())) && (!isNULL(childPriv.getTableName()))
- && (!isNULL(childPriv.getColumnName()))) {
- populateChildren(pm, roleNames, childPriv, children);
- }
- // The method getChildPrivileges() didn't do filter on "action",
- // if the action is not "All", it should judge the action of children privilege.
- // For example: a user has a privilege “All on Col1”,
- // if the operation is “REVOKE INSERT on table”
- // the privilege should be the child of table level privilege.
- // but the privilege may still have other meaning, likes "SELECT on Col1".
- // and the privileges like "SELECT on Col1" should not be revoke.
- if (!priv.isActionALL()) {
- if (childPriv.isActionALL()) {
- // If the child privilege is All, we should convert it to the same
- // privilege with parent
- childPriv.setAction(priv.getAction());
- }
- // Only include privilege that imply the parent privilege.
- if (!priv.implies(childPriv)) {
- continue;
- }
- }
- children.add(childPriv);
- }
- }
- }
-
- private Set<MSentryPrivilege> getChildPrivileges(PersistenceManager pm, Set<String> roleNames,
- MSentryPrivilege parent) throws SentryInvalidInputException {
- // Column and URI do not have children
- if ((!isNULL(parent.getColumnName())) || (!isNULL(parent.getURI()))) {
- return new HashSet<MSentryPrivilege>();
- }
-
- Query query = pm.newQuery(MSentryPrivilege.class);
- query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
- List<String> rolesFiler = new LinkedList<String>();
- for (String rName : roleNames) {
- rolesFiler.add("role.roleName == \"" + rName.trim().toLowerCase() + "\"");
- }
- StringBuilder filters = new StringBuilder("roles.contains(role) "
- + "&& (" + Joiner.on(" || ").join(rolesFiler) + ")");
- filters.append(" && serverName == \"" + parent.getServerName() + "\"");
- if (!isNULL(parent.getDbName())) {
- filters.append(" && dbName == \"" + parent.getDbName() + "\"");
- if (!isNULL(parent.getTableName())) {
- filters.append(" && tableName == \"" + parent.getTableName() + "\"");
- filters.append(" && columnName != \"__NULL__\"");
- } else {
- filters.append(" && tableName != \"__NULL__\"");
- }
- } else {
- filters.append(" && (dbName != \"__NULL__\" || URI != \"__NULL__\")");
- }
-
- query.setFilter(filters.toString());
- query.setResult("privilegeScope, serverName, dbName, tableName, columnName," +
- " URI, action, grantOption");
- Set<MSentryPrivilege> privileges = new HashSet<MSentryPrivilege>();
- for (Object[] privObj : (List<Object[]>) query.execute()) {
- MSentryPrivilege priv = new MSentryPrivilege();
- priv.setPrivilegeScope((String) privObj[0]);
- priv.setServerName((String) privObj[1]);
- priv.setDbName((String) privObj[2]);
- priv.setTableName((String) privObj[3]);
- priv.setColumnName((String) privObj[4]);
- priv.setURI((String) privObj[5]);
- priv.setAction((String) privObj[6]);
- priv.setGrantOption((Boolean) privObj[7]);
- privileges.add(priv);
- }
- return privileges;
- }
-
- private List<MSentryPrivilege> getMSentryPrivileges(TSentryPrivilege tPriv, PersistenceManager pm) {
- Query query = pm.newQuery(MSentryPrivilege.class);
- StringBuilder filters = new StringBuilder("this.serverName == \""
- + toNULLCol(safeTrimLower(tPriv.getServerName())) + "\" ");
- if (!isNULL(tPriv.getDbName())) {
- filters.append("&& this.dbName == \"" + toNULLCol(safeTrimLower(tPriv.getDbName())) + "\" ");
- if (!isNULL(tPriv.getTableName())) {
- filters.append("&& this.tableName == \"" + toNULLCol(safeTrimLower(tPriv.getTableName())) + "\" ");
- if (!isNULL(tPriv.getColumnName())) {
- filters.append("&& this.columnName == \"" + toNULLCol(safeTrimLower(tPriv.getColumnName())) + "\" ");
- }
- }
- }
- // if db is null, uri is not null
- else if (!isNULL(tPriv.getURI())){
- filters.append("&& this.URI == \"" + toNULLCol(safeTrim(tPriv.getURI())) + "\" ");
- }
- filters.append("&& this.action == \"" + toNULLCol(safeTrimLower(tPriv.getAction())) + "\"");
-
- query.setFilter(filters.toString());
- List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query.execute();
- return privileges;
- }
-
- private MSentryPrivilege getMSentryPrivilege(TSentryPrivilege tPriv, PersistenceManager pm) {
- Query query = pm.newQuery(MSentryPrivilege.class);
- query.setFilter("this.serverName == \"" + toNULLCol(safeTrimLower(tPriv.getServerName())) + "\" "
- + "&& this.dbName == \"" + toNULLCol(safeTrimLower(tPriv.getDbName())) + "\" "
- + "&& this.tableName == \"" + toNULLCol(safeTrimLower(tPriv.getTableName())) + "\" "
- + "&& this.columnName == \"" + toNULLCol(safeTrimLower(tPriv.getColumnName())) + "\" "
- + "&& this.URI == \"" + toNULLCol(safeTrim(tPriv.getURI())) + "\" "
- + "&& this.grantOption == grantOption "
- + "&& this.action == \"" + toNULLCol(safeTrimLower(tPriv.getAction())) + "\"");
- query.declareParameters("Boolean grantOption");
- query.setUnique(true);
- Boolean grantOption = null;
- if (tPriv.getGrantOption().equals(TSentryGrantOption.TRUE)) {
- grantOption = true;
- } else if (tPriv.getGrantOption().equals(TSentryGrantOption.FALSE)) {
- grantOption = false;
- }
- Object obj = query.execute(grantOption);
- if (obj != null)
- return (MSentryPrivilege) obj;
- return null;
- }
+ String roleName, Set<TSentryPrivilege> tPrivileges)
+ throws SentryUserException;
public CommitContext dropSentryRole(String roleName)
- throws SentryNoSuchObjectException {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- roleName = roleName.trim().toLowerCase();
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryRole.class);
- query.setFilter("this.roleName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- MSentryRole sentryRole = (MSentryRole) query.execute(roleName);
- if (sentryRole == null) {
- throw new SentryNoSuchObjectException("Role " + roleName);
- } else {
- pm.retrieve(sentryRole);
- int numPrivs = sentryRole.getPrivileges().size();
- sentryRole.removePrivileges();
- //with SENTRY-398 generic model
- sentryRole.removeGMPrivileges();
- privCleaner.incPrivRemoval(numPrivs);
- pm.deletePersistent(sentryRole);
- }
- CommitContext commit = commitUpdateTransaction(pm);
- rollbackTransaction = false;
- return commit;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- public CommitContext alterSentryRoleAddGroups( String grantorPrincipal, String roleName,
- Set<TSentryGroup> groupNames)
- throws SentryNoSuchObjectException {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- roleName = roleName.trim().toLowerCase();
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryRole.class);
- query.setFilter("this.roleName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- MSentryRole role = (MSentryRole) query.execute(roleName);
- if (role == null) {
- throw new SentryNoSuchObjectException("Role: " + roleName);
- } else {
- query = pm.newQuery(MSentryGroup.class);
- query.setFilter("this.groupName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- List<MSentryGroup> groups = Lists.newArrayList();
- for (TSentryGroup tGroup : groupNames) {
- String groupName = tGroup.getGroupName().trim();
- MSentryGroup group = (MSentryGroup) query.execute(groupName);
- if (group == null) {
- group = new MSentryGroup(groupName, System.currentTimeMillis(),
- Sets.newHashSet(role));
- }
- group.appendRole(role);
- groups.add(group);
- }
- pm.makePersistentAll(groups);
- CommitContext commit = commitUpdateTransaction(pm);
- rollbackTransaction = false;
- return commit;
- }
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
+ throws SentryNoSuchObjectException;
+
+ public CommitContext alterSentryRoleAddGroups(String grantorPrincipal,
+ String roleName, Set<TSentryGroup> groupNames)
+ throws SentryNoSuchObjectException;
public CommitContext alterSentryRoleDeleteGroups(String roleName,
- Set<TSentryGroup> groupNames)
- throws SentryNoSuchObjectException {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- roleName = roleName.trim().toLowerCase();
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryRole.class);
- query.setFilter("this.roleName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- MSentryRole role = (MSentryRole) query.execute(roleName);
- if (role == null) {
- throw new SentryNoSuchObjectException("Role: " + roleName);
- } else {
- query = pm.newQuery(MSentryGroup.class);
- query.setFilter("this.groupName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- List<MSentryGroup> groups = Lists.newArrayList();
- for (TSentryGroup tGroup : groupNames) {
- String groupName = tGroup.getGroupName().trim();
- MSentryGroup group = (MSentryGroup) query.execute(groupName);
- if (group != null) {
- group.removeRole(role);
- groups.add(group);
- }
- }
- pm.makePersistentAll(groups);
- CommitContext commit = commitUpdateTransaction(pm);
- rollbackTransaction = false;
- return commit;
- }
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- @VisibleForTesting
- MSentryRole getMSentryRoleByName(String roleName)
- throws SentryNoSuchObjectException {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- roleName = roleName.trim().toLowerCase();
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryRole.class);
- query.setFilter("this.roleName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- MSentryRole sentryRole = (MSentryRole) query.execute(roleName);
- if (sentryRole == null) {
- throw new SentryNoSuchObjectException("Role " + roleName);
- } else {
- pm.retrieve(sentryRole);
- }
- rollbackTransaction = false;
- commitTransaction(pm);
- return sentryRole;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- private boolean hasAnyServerPrivileges(Set<String> roleNames, String serverName) {
- if ((roleNames.size() == 0)||(roleNames == null)) return false;
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryPrivilege.class);
- query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
- List<String> rolesFiler = new LinkedList<String>();
- for (String rName : roleNames) {
- rolesFiler.add("role.roleName == \"" + rName.trim().toLowerCase() + "\"");
- }
- StringBuilder filters = new StringBuilder("roles.contains(role) "
- + "&& (" + Joiner.on(" || ").join(rolesFiler) + ") ");
- filters.append("&& serverName == \"" + serverName.trim().toLowerCase() + "\"");
- query.setFilter(filters.toString());
- query.setResult("count(this)");
-
- Long numPrivs = (Long) query.execute();
- rollbackTransaction = false;
- commitTransaction(pm);
- return (numPrivs > 0);
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- List<MSentryPrivilege> getMSentryPrivileges(Set<String> roleNames, TSentryAuthorizable authHierarchy) {
- if ((roleNames.size() == 0)||(roleNames == null)) return new ArrayList<MSentryPrivilege>();
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryPrivilege.class);
- query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
- List<String> rolesFiler = new LinkedList<String>();
- for (String rName : roleNames) {
- rolesFiler.add("role.roleName == \"" + rName.trim().toLowerCase() + "\"");
- }
- StringBuilder filters = new StringBuilder("roles.contains(role) "
- + "&& (" + Joiner.on(" || ").join(rolesFiler) + ") ");
- if ((authHierarchy != null) && (authHierarchy.getServer() != null)) {
- filters.append("&& serverName == \"" + authHierarchy.getServer().toLowerCase() + "\"");
- if (authHierarchy.getDb() != null) {
- filters.append(" && ((dbName == \"" + authHierarchy.getDb().toLowerCase() + "\") || (dbName == \"__NULL__\")) && (URI == \"__NULL__\")");
- if ((authHierarchy.getTable() != null)
- && !AccessConstants.ALL
- .equalsIgnoreCase(authHierarchy.getTable())) {
- filters.append(" && ((tableName == \"" + authHierarchy.getTable().toLowerCase() + "\") || (tableName == \"__NULL__\")) && (URI == \"__NULL__\")");
- if ((authHierarchy.getColumn() != null)
- && !AccessConstants.ALL
- .equalsIgnoreCase(authHierarchy.getColumn())) {
- filters.append(" && ((columnName == \"" + authHierarchy.getColumn().toLowerCase() + "\") || (columnName == \"__NULL__\")) && (URI == \"__NULL__\")");
- }
- }
- }
- if (authHierarchy.getUri() != null) {
- filters.append(" && ((URI != \"__NULL__\") && (\"" + authHierarchy.getUri() + "\".startsWith(URI)) || (URI == \"__NULL__\")) && (dbName == \"__NULL__\")");
- }
- }
- query.setFilter(filters.toString());
- List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query.execute();
- rollbackTransaction = false;
- commitTransaction(pm);
- return privileges;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- List<MSentryPrivilege> getMSentryPrivilegesByAuth(Set<String> roleNames, TSentryAuthorizable authHierarchy) {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryPrivilege.class);
- StringBuilder filters = new StringBuilder();
- if ((roleNames.size() == 0)||(roleNames == null)) {
- filters.append(" !roles.isEmpty() ");
- } else {
- query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
- List<String> rolesFiler = new LinkedList<String>();
- for (String rName : roleNames) {
- rolesFiler.add("role.roleName == \"" + rName.trim().toLowerCase() + "\"");
- }
- filters.append("roles.contains(role) "
- + "&& (" + Joiner.on(" || ").join(rolesFiler) + ") ");
- }
- if ((authHierarchy.getServer() != null)) {
- filters.append("&& serverName == \"" +
- authHierarchy.getServer().toLowerCase() + "\"");
- if (authHierarchy.getDb() != null) {
- filters.append(" && (dbName == \"" +
- authHierarchy.getDb().toLowerCase() + "\") && (URI == \"__NULL__\")");
- if (authHierarchy.getTable() != null) {
- filters.append(" && (tableName == \"" +
- authHierarchy.getTable().toLowerCase() + "\")");
- } else {
- filters.append(" && (tableName == \"__NULL__\")");
- }
- } else if (authHierarchy.getUri() != null) {
- filters.append(" && (URI != \"__NULL__\") && (\"" + authHierarchy.getUri() +
- "\".startsWith(URI)) && (dbName == \"__NULL__\")");
- } else {
- filters.append(" && (dbName == \"__NULL__\") && (URI == \"__NULL__\")");
- }
- } else {
- // if no server, then return empty resultset
- return new ArrayList<MSentryPrivilege>();
- }
- FetchGroup grp = pm.getFetchGroup(
- org.apache.sentry.provider.db.service.model.MSentryPrivilege.class,
- "fetchRole");
- grp.addMember("roles");
- pm.getFetchPlan().addGroup("fetchRole");
- query.setFilter(filters.toString());
- List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query.execute();
- rollbackTransaction = false;
- commitTransaction(pm);
- return privileges;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
+ Set<TSentryGroup> groupNames) throws SentryNoSuchObjectException;
public TSentryPrivilegeMap listSentryPrivilegesByAuthorizable(
Set<String> groups, TSentryActiveRoleSet activeRoles,
TSentryAuthorizable authHierarchy, boolean isAdmin)
- throws SentryInvalidInputException {
- Map<String, Set<TSentryPrivilege>> resultPrivilegeMap = Maps.newTreeMap();
- Set<String> roles = Sets.newHashSet();
- if (groups != null && !groups.isEmpty()) {
- roles = getRolesToQuery(groups, new TSentryActiveRoleSet(true, null));
- }
- if (activeRoles != null && !activeRoles.isAll()) {
- // need to check/convert to lowercase here since this is from user input
- for (String aRole : activeRoles.getRoles()) {
- roles.add(aRole.toLowerCase());
- }
- }
-
- // An empty 'roles' is a treated as a wildcard (in case of admin role)..
- // so if not admin, don't return anything if 'roles' is empty..
- if (isAdmin || !roles.isEmpty()) {
- List<MSentryPrivilege> mSentryPrivileges = getMSentryPrivilegesByAuth(roles,
- authHierarchy);
- for (MSentryPrivilege priv : mSentryPrivileges) {
- for (MSentryRole role : priv.getRoles()) {
- TSentryPrivilege tPriv = convertToTSentryPrivilege(priv);
- if (resultPrivilegeMap.containsKey(role.getRoleName())) {
- resultPrivilegeMap.get(role.getRoleName()).add(tPriv);
- } else {
- Set<TSentryPrivilege> tPrivSet = Sets.newTreeSet();
- tPrivSet.add(tPriv);
- resultPrivilegeMap.put(role.getRoleName(), tPrivSet);
- }
- }
- }
- }
- return new TSentryPrivilegeMap(resultPrivilegeMap);
- }
-
- private Set<MSentryPrivilege> getMSentryPrivilegesByRoleName(String roleName)
- throws SentryNoSuchObjectException {
- MSentryRole mSentryRole = getMSentryRoleByName(roleName);
- return mSentryRole.getPrivileges();
- }
-
- /**
- * Gets sentry privilege objects for a given roleName from the persistence layer
- * @param roleName : roleName to look up
- * @return : Set of thrift sentry privilege objects
- * @throws SentryNoSuchObjectException
- */
+ throws SentryInvalidInputException;
public Set<TSentryPrivilege> getAllTSentryPrivilegesByRoleName(String roleName)
- throws SentryNoSuchObjectException {
- return convertToTSentryPrivileges(getMSentryPrivilegesByRoleName(roleName));
- }
+ throws SentryNoSuchObjectException;
+ public Set<TSentryPrivilege> getTSentryPrivileges(Set<String> roleNames,
+ TSentryAuthorizable authHierarchy) throws SentryInvalidInputException;
- /**
- * Gets sentry privilege objects for criteria from the persistence layer
- * @param roleNames : roleNames to look up (required)
- * @param authHierarchy : filter push down based on auth hierarchy (optional)
- * @return : Set of thrift sentry privilege objects
- * @throws SentryNoSuchObjectException
- */
-
- public Set<TSentryPrivilege> getTSentryPrivileges(Set<String> roleNames, TSentryAuthorizable authHierarchy) throws SentryInvalidInputException {
- if (authHierarchy.getServer() == null) {
- throw new SentryInvalidInputException("serverName cannot be null !!");
- }
- if ((authHierarchy.getTable() != null) && (authHierarchy.getDb() == null)) {
- throw new SentryInvalidInputException("dbName cannot be null when tableName is present !!");
- }
- if ((authHierarchy.getColumn() != null) && (authHierarchy.getTable() == null)) {
- throw new SentryInvalidInputException("tableName cannot be null when columnName is present !!");
- }
- if ((authHierarchy.getUri() == null) && (authHierarchy.getDb() == null)) {
- throw new SentryInvalidInputException("One of uri or dbName must not be null !!");
- }
- return convertToTSentryPrivileges(getMSentryPrivileges(roleNames, authHierarchy));
- }
-
-
- private Set<MSentryRole> getMSentryRolesByGroupName(String groupName)
- throws SentryNoSuchObjectException {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- Set<MSentryRole> roles;
- pm = openTransaction();
-
- //If no group name was specified, return all roles
- if (groupName == null) {
- Query query = pm.newQuery(MSentryRole.class);
- roles = new HashSet<MSentryRole>((List<MSentryRole>)query.execute());
- } else {
- Query query = pm.newQuery(MSentryGroup.class);
- MSentryGroup sentryGroup;
- groupName = groupName.trim();
- query.setFilter("this.groupName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- sentryGroup = (MSentryGroup) query.execute(groupName);
- if (sentryGroup == null) {
- throw new SentryNoSuchObjectException("Group " + groupName);
- } else {
- pm.retrieve(sentryGroup);
- }
- roles = sentryGroup.getRoles();
- }
- for ( MSentryRole role: roles) {
- pm.retrieve(role);
- }
- commitTransaction(pm);
- rollbackTransaction = false;
- return roles;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- /**
- * Gets sentry role objects for a given groupName from the persistence layer
- * @param groupName : groupName to look up ( if null returns all roles for all groups)
- * @return : Set of thrift sentry role objects
- * @throws SentryNoSuchObjectException
- */
public Set<TSentryRole> getTSentryRolesByGroupName(Set<String> groupNames,
- boolean checkAllGroups) throws SentryNoSuchObjectException {
- Set<MSentryRole> roleSet = Sets.newHashSet();
- for (String groupName : groupNames) {
- try {
- roleSet.addAll(getMSentryRolesByGroupName(groupName));
- } catch (SentryNoSuchObjectException e) {
- // if we are checking for all the given groups, then continue searching
- if (!checkAllGroups) {
- throw e;
- }
- }
- }
- return convertToTSentryRoles(roleSet);
- }
+ boolean checkAllGroups) throws SentryNoSuchObjectException;
- public Set<String> getRoleNamesForGroups(Set<String> groups) {
- Set<String> result = new HashSet<String>();
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryGroup.class);
- query.setFilter("this.groupName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- for (String group : groups) {
- MSentryGroup sentryGroup = (MSentryGroup) query.execute(group.trim());
- if (sentryGroup != null) {
- for (MSentryRole role : sentryGroup.getRoles()) {
- result.add(role.getRoleName());
- }
- }
- }
- rollbackTransaction = false;
- commitTransaction(pm);
- return result;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
+ public Set<String> getRoleNamesForGroups(Set<String> groups);
- public Set<MSentryRole> getRolesForGroups(PersistenceManager pm, Set<String> groups) {
- Set<MSentryRole> result = new HashSet<MSentryRole>();
- Query query = pm.newQuery(MSentryGroup.class);
- query.setFilter("this.groupName == t");
- query.declareParameters("java.lang.String t");
- query.setUnique(true);
- for (String group : groups) {
- MSentryGroup sentryGroup = (MSentryGroup) query.execute(group.trim());
- if (sentryGroup != null) {
- result.addAll(sentryGroup.getRoles());
- }
- }
- return result;
- }
-
- public Set<String> listAllSentryPrivilegesForProvider(Set<String> groups, TSentryActiveRoleSet roleSet) throws SentryInvalidInputException {
- return listSentryPrivilegesForProvider(groups, roleSet, null);
- }
-
+ public Set<String> listAllSentryPrivilegesForProvider(Set<String> groups,
+ TSentryActiveRoleSet roleSet) throws SentryInvalidInputException;
public Set<String> listSentryPrivilegesForProvider(Set<String> groups,
- TSentryActiveRoleSet roleSet, TSentryAuthorizable authHierarchy) throws SentryInvalidInputException {
- Set<String> result = Sets.newHashSet();
- Set<String> rolesToQuery = getRolesToQuery(groups, roleSet);
- List<MSentryPrivilege> mSentryPrivileges = getMSentryPrivileges(rolesToQuery, authHierarchy);
+ TSentryActiveRoleSet roleSet, TSentryAuthorizable authHierarchy)
+ throws SentryInvalidInputException;
- for (MSentryPrivilege priv : mSentryPrivileges) {
- result.add(toAuthorizable(priv));
- }
-
- return result;
- }
-
-
- public boolean hasAnyServerPrivileges(Set<String> groups, TSentryActiveRoleSet roleSet, String server) {
- Set<String> rolesToQuery = getRolesToQuery(groups, roleSet);
- return hasAnyServerPrivileges(rolesToQuery, server);
- }
-
-
-
- private Set<String> getRolesToQuery(Set<String> groups,
- TSentryActiveRoleSet roleSet) {
- Set<String> activeRoleNames = toTrimedLower(roleSet.getRoles());
-
- Set<String> roleNamesForGroups = toTrimedLower(getRoleNamesForGroups(groups));
- Set<String> rolesToQuery = roleSet.isAll() ? roleNamesForGroups : Sets.intersection(activeRoleNames, roleNamesForGroups);
- return rolesToQuery;
- }
-
- @VisibleForTesting
- static String toAuthorizable(MSentryPrivilege privilege) {
- List<String> authorizable = new ArrayList<String>(4);
- authorizable.add(KV_JOINER.join(AuthorizableType.Server.name().toLowerCase(),
- privilege.getServerName()));
- if (isNULL(privilege.getURI())) {
- if (!isNULL(privilege.getDbName())) {
- authorizable.add(KV_JOINER.join(AuthorizableType.Db.name().toLowerCase(),
- privilege.getDbName()));
- if (!isNULL(privilege.getTableName())) {
- authorizable.add(KV_JOINER.join(AuthorizableType.Table.name().toLowerCase(),
- privilege.getTableName()));
- if (!isNULL(privilege.getColumnName())) {
- authorizable.add(KV_JOINER.join(AuthorizableType.Column.name().toLowerCase(),
- privilege.getColumnName()));
- }
- }
- }
- } else {
- authorizable.add(KV_JOINER.join(AuthorizableType.URI.name().toLowerCase(),
- privilege.getURI()));
- }
- if (!isNULL(privilege.getAction())
- && !privilege.getAction().equalsIgnoreCase(AccessConstants.ALL)) {
- authorizable
- .add(KV_JOINER.join(ProviderConstants.PRIVILEGE_NAME.toLowerCase(),
- privilege.getAction()));
- }
- return AUTHORIZABLE_JOINER.join(authorizable);
- }
-
- @VisibleForTesting
- static Set<String> toTrimedLower(Set<String> s) {
- if (null == s) return new HashSet<String>();
- Set<String> result = Sets.newHashSet();
- for (String v : s) {
- result.add(v.trim().toLowerCase());
- }
- return result;
- }
-
-
- /**
- * Converts model object(s) to thrift object(s).
- * Additionally does normalization
- * such as trimming whitespace and setting appropriate case. Also sets the create
- * time.
- */
-
- private Set<TSentryPrivilege> convertToTSentryPrivileges(Collection<MSentryPrivilege> mSentryPrivileges) {
- Set<TSentryPrivilege> privileges = new HashSet<TSentryPrivilege>();
- for(MSentryPrivilege mSentryPrivilege:mSentryPrivileges) {
- privileges.add(convertToTSentryPrivilege(mSentryPrivilege));
- }
- return privileges;
- }
-
- private Set<TSentryRole> convertToTSentryRoles(Set<MSentryRole> mSentryRoles) {
- Set<TSentryRole> roles = new HashSet<TSentryRole>();
- for(MSentryRole mSentryRole:mSentryRoles) {
- roles.add(convertToTSentryRole(mSentryRole));
- }
- return roles;
- }
-
- private TSentryRole convertToTSentryRole(MSentryRole mSentryRole) {
- TSentryRole role = new TSentryRole();
- role.setRoleName(mSentryRole.getRoleName());
- role.setGrantorPrincipal("--");
- Set<TSentryGroup> sentryGroups = new HashSet<TSentryGroup>();
- for(MSentryGroup mSentryGroup:mSentryRole.getGroups()) {
- TSentryGroup group = convertToTSentryGroup(mSentryGroup);
- sentryGroups.add(group);
- }
-
- role.setGroups(sentryGroups);
- return role;
- }
-
- private TSentryGroup convertToTSentryGroup(MSentryGroup mSentryGroup) {
- TSentryGroup group = new TSentryGroup();
- group.setGroupName(mSentryGroup.getGroupName());
- return group;
- }
-
- private TSentryPrivilege convertToTSentryPrivilege(MSentryPrivilege mSentryPrivilege) {
- TSentryPrivilege privilege = new TSentryPrivilege();
- convertToTSentryPrivilege(mSentryPrivilege, privilege);
- return privilege;
- }
-
- private void convertToTSentryPrivilege(MSentryPrivilege mSentryPrivilege,
- TSentryPrivilege privilege) {
- privilege.setCreateTime(mSentryPrivilege.getCreateTime());
- privilege.setAction(fromNULLCol(mSentryPrivilege.getAction()));
- privilege.setPrivilegeScope(mSentryPrivilege.getPrivilegeScope());
- privilege.setServerName(fromNULLCol(mSentryPrivilege.getServerName()));
- privilege.setDbName(fromNULLCol(mSentryPrivilege.getDbName()));
- privilege.setTableName(fromNULLCol(mSentryPrivilege.getTableName()));
- privilege.setColumnName(fromNULLCol(mSentryPrivilege.getColumnName()));
- privilege.setURI(fromNULLCol(mSentryPrivilege.getURI()));
- if (mSentryPrivilege.getGrantOption() != null) {
- privilege.setGrantOption(TSentryGrantOption.valueOf(mSentryPrivilege.getGrantOption().toString().toUpperCase()));
- } else {
- privilege.setGrantOption(TSentryGrantOption.UNSET);
- }
- }
-
- /**
- * Converts thrift object to model object. Additionally does normalization
- * such as trimming whitespace and setting appropriate case.
- * @throws SentryInvalidInputException
- */
- private MSentryPrivilege convertToMSentryPrivilege(TSentryPrivilege privilege)
- throws SentryInvalidInputException {
- MSentryPrivilege mSentryPrivilege = new MSentryPrivilege();
- mSentryPrivilege.setServerName(toNULLCol(safeTrimLower(privilege.getServerName())));
- mSentryPrivilege.setDbName(toNULLCol(safeTrimLower(privilege.getDbName())));
- mSentryPrivilege.setTableName(toNULLCol(safeTrimLower(privilege.getTableName())));
- mSentryPrivilege.setColumnName(toNULLCol(safeTrimLower(privilege.getColumnName())));
- mSentryPrivilege.setPrivilegeScope(safeTrim(privilege.getPrivilegeScope()));
- mSentryPrivilege.setAction(toNULLCol(safeTrimLower(privilege.getAction())));
- mSentryPrivilege.setCreateTime(System.currentTimeMillis());
- mSentryPrivilege.setURI(toNULLCol(safeTrim(privilege.getURI())));
- if ( !privilege.getGrantOption().equals(TSentryGrantOption.UNSET) ) {
- mSentryPrivilege.setGrantOption(Boolean.valueOf(privilege.getGrantOption().toString()));
- } else {
- mSentryPrivilege.setGrantOption(null);
- }
- return mSentryPrivilege;
- }
- private static String safeTrim(String s) {
- if (s == null) {
- return null;
- }
- return s.trim();
- }
- private static String safeTrimLower(String s) {
- if (s == null) {
- return null;
- }
- return s.trim().toLowerCase();
- }
+ public boolean hasAnyServerPrivileges(Set<String> groups,
+ TSentryActiveRoleSet roleSet, String server);
public String getSentryVersion() throws SentryNoSuchObjectException,
- SentryAccessDeniedException {
- MSentryVersion mVersion = getMSentryVersion();
- return mVersion.getSchemaVersion();
- }
+ SentryAccessDeniedException;
public void setSentryVersion(String newVersion, String verComment)
- throws SentryNoSuchObjectException, SentryAccessDeniedException {
- MSentryVersion mVersion;
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
+ throws SentryNoSuchObjectException, SentryAccessDeniedException;
- try {
- mVersion = getMSentryVersion();
- if (newVersion.equals(mVersion.getSchemaVersion())) {
- // specified version already in there
- return;
- }
- } catch (SentryNoSuchObjectException e) {
- // if the version doesn't exist, then create it
- mVersion = new MSentryVersion();
- }
- mVersion.setSchemaVersion(newVersion);
- mVersion.setVersionComment(verComment);
- try {
- pm = openTransaction();
- pm.makePersistent(mVersion);
- rollbackTransaction = false;
- commitTransaction(pm);
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private MSentryVersion getMSentryVersion()
- throws SentryNoSuchObjectException, SentryAccessDeniedException {
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryVersion.class);
- List<MSentryVersion> mSentryVersions = (List<MSentryVersion>) query
- .execute();
- pm.retrieveAll(mSentryVersions);
- rollbackTransaction = false;
- commitTransaction(pm);
- if (mSentryVersions.isEmpty()) {
- throw new SentryNoSuchObjectException("No matching version found");
- }
- if (mSentryVersions.size() > 1) {
- throw new SentryAccessDeniedException(
- "Metastore contains multiple versions");
- }
- return mSentryVersions.get(0);
- } catch (JDODataStoreException e) {
- if (e.getCause() instanceof MissingTableException) {
- throw new SentryAccessDeniedException("Version table not found. "
- + "The sentry store is not set or corrupt ");
- } else {
- throw e;
- }
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- /**
- * Drop given privilege from all roles
- */
public void dropPrivilege(TSentryAuthorizable tAuthorizable)
- throws SentryNoSuchObjectException, SentryInvalidInputException {
- PersistenceManager pm = null;
- boolean rollbackTransaction = true;
+ throws SentryNoSuchObjectException, SentryInvalidInputException;
- TSentryPrivilege tPrivilege = toSentryPrivilege(tAuthorizable);
- try {
- pm = openTransaction();
-
- if (isMultiActionsSupported(tPrivilege)) {
- for (String privilegeAction : ALL_ACTIONS) {
- tPrivilege.setAction(privilegeAction);
- dropPrivilegeForAllRoles(pm, new TSentryPrivilege(tPrivilege));
- }
- } else {
- dropPrivilegeForAllRoles(pm, new TSentryPrivilege(tPrivilege));
- }
- rollbackTransaction = false;
- commitTransaction(pm);
- } catch (JDODataStoreException e) {
- throw new SentryInvalidInputException("Failed to get privileges: "
- + e.getMessage());
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- /**
- * Rename given privilege from all roles drop the old privilege and create the new one
- * @param tAuthorizable
- * @param newTAuthorizable
- * @throws SentryNoSuchObjectException
- * @throws SentryInvalidInputException
- */
public void renamePrivilege(TSentryAuthorizable tAuthorizable,
TSentryAuthorizable newTAuthorizable)
- throws SentryNoSuchObjectException, SentryInvalidInputException {
- PersistenceManager pm = null;
- boolean rollbackTransaction = true;
+ throws SentryNoSuchObjectException, SentryInvalidInputException;
- TSentryPrivilege tPrivilege = toSentryPrivilege(tAuthorizable);
- TSentryPrivilege newPrivilege = toSentryPrivilege(newTAuthorizable);
+ public Map<String, HashMap<String, String>> retrieveFullPrivilegeImage();
- try {
- pm = openTransaction();
- // In case of tables or DBs, check all actions
- if (isMultiActionsSupported(tPrivilege)) {
- for (String privilegeAction : ALL_ACTIONS) {
- tPrivilege.setAction(privilegeAction);
- newPrivilege.setAction(privilegeAction);
- renamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
- }
- } else {
- renamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
- }
- rollbackTransaction = false;
- commitTransaction(pm);
- } catch (JDODataStoreException e) {
- throw new SentryInvalidInputException("Failed to get privileges: "
- + e.getMessage());
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
+ public Map<String, LinkedList<String>> retrieveFullRoleImage();
- // Currently INSERT/SELECT/ALL are supported for Table and DB level privileges
- private boolean isMultiActionsSupported(TSentryPrivilege tPrivilege) {
- return tPrivilege.getDbName() != null;
+ public Set<String> getGroupsForRole(String roleName);
- }
- // wrapper for dropOrRename
- private void renamePrivilegeForAllRoles(PersistenceManager pm,
- TSentryPrivilege tPrivilege,
- TSentryPrivilege newPrivilege) throws SentryNoSuchObjectException,
- SentryInvalidInputException {
- dropOrRenamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
- }
+ public long getRoleCount();
- /**
- * Drop given privilege from all roles
- * @param tPrivilege
- * @throws SentryNoSuchObjectException
- * @throws SentryInvalidInputException
- */
- private void dropPrivilegeForAllRoles(PersistenceManager pm,
- TSentryPrivilege tPrivilege)
- throws SentryNoSuchObjectException, SentryInvalidInputException {
- dropOrRenamePrivilegeForAllRoles(pm, tPrivilege, null);
- }
+ public long getPrivilegeCount();
- /**
- * Drop given privilege from all roles Create the new privilege if asked
- * @param tPrivilege
- * @param pm
- * @throws SentryNoSuchObjectException
- * @throws SentryInvalidInputException
- */
- private void dropOrRenamePrivilegeForAllRoles(PersistenceManager pm,
- TSentryPrivilege tPrivilege,
- TSentryPrivilege newTPrivilege) throws SentryNoSuchObjectException,
- SentryInvalidInputException {
- HashSet<MSentryRole> roleSet = Sets.newHashSet();
+ public long getGroupCount();
- List<MSentryPrivilege> mPrivileges = getMSentryPrivileges(tPrivilege, pm);
- if (mPrivileges != null && !mPrivileges.isEmpty()) {
- for (MSentryPrivilege mPrivilege : mPrivileges) {
- roleSet.addAll(ImmutableSet.copyOf((mPrivilege.getRoles())));
- }
- }
+ public void stop();
- MSentryPrivilege parent = getMSentryPrivilege(tPrivilege, pm);
- for (MSentryRole role : roleSet) {
- // 1. get privilege and child privileges
- Set<MSentryPrivilege> privilegeGraph = Sets.newHashSet();
- if (parent != null) {
- privilegeGraph.add(parent);
- populateChildren(pm, Sets.newHashSet(role.getRoleName()), parent, privilegeGraph);
- } else {
- populateChildren(pm, Sets.newHashSet(role.getRoleName()), convertToMSentryPrivilege(tPrivilege),
- privilegeGraph);
- }
- // 2. revoke privilege and child privileges
- alterSentryRoleRevokePrivilegeCore(pm, role.getRoleName(), tPrivilege);
- // 3. add new privilege and child privileges with new tableName
- if (newTPrivilege != null) {
- for (MSentryPrivilege m : privilegeGraph) {
- TSentryPrivilege t = convertToTSentryPrivilege(m);
- if (newTPrivilege.getPrivilegeScope().equals(PrivilegeScope.DATABASE.name())) {
- t.setDbName(newTPrivilege.getDbName());
- } else if (newTPrivilege.getPrivilegeScope().equals(PrivilegeScope.TABLE.name())) {
- t.setTableName(newTPrivilege.getTableName());
- }
- alterSentryRoleGrantPrivilegeCore(pm, role.getRoleName(), t);
- }
- }
- }
- }
+ public TStoreSnapshot toSnapshot();
- private TSentryPrivilege toSentryPrivilege(TSentryAuthorizable tAuthorizable)
- throws SentryInvalidInputException {
- TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
- tSentryPrivilege.setDbName(fromNULLCol(tAuthorizable.getDb()));
- tSentryPrivilege.setServerName(fromNULLCol(tAuthorizable.getServer()));
- tSentryPrivilege.setTableName(fromNULLCol(tAuthorizable.getTable()));
- tSentryPrivilege.setColumnName(fromNULLCol(tAuthorizable.getColumn()));
- tSentryPrivilege.setURI(fromNULLCol(tAuthorizable.getUri()));
- PrivilegeScope scope;
- if (!isNULL(tSentryPrivilege.getColumnName())) {
- scope = PrivilegeScope.COLUMN;
- } else if (!isNULL(tSentryPrivilege.getTableName())) {
- scope = PrivilegeScope.TABLE;
- } else if (!isNULL(tSentryPrivilege.getDbName())) {
- scope = PrivilegeScope.DATABASE;
- } else if (!isNULL(tSentryPrivilege.getURI())) {
- scope = PrivilegeScope.URI;
- } else {
- scope = PrivilegeScope.SERVER;
- }
- tSentryPrivilege.setPrivilegeScope(scope.name());
- tSentryPrivilege.setAction(AccessConstants.ALL);
- return tSentryPrivilege;
- }
-
- public static String toNULLCol(String s) {
- return Strings.isNullOrEmpty(s) ? NULL_COL : s;
- }
-
- public static String fromNULLCol(String s) {
- return isNULL(s) ? "" : s;
- }
-
- public static boolean isNULL(String s) {
- return Strings.isNullOrEmpty(s) || s.equals(NULL_COL);
- }
-
- /**
- * Grant option check
- * @param pm
- * @param privilege
- * @throws SentryUserException
- */
- private void grantOptionCheck(PersistenceManager pm, String grantorPrincipal, TSentryPrivilege privilege)
- throws SentryUserException {
- MSentryPrivilege mPrivilege = convertToMSentryPrivilege(privilege);
- if (grantorPrincipal == null) {
- throw new SentryInvalidInputException("grantorPrincipal should not be null");
- }
- Set<String> groups = SentryPolicyStoreProcessor.getGroupsFromUserName(conf, grantorPrincipal);
- if (groups == null || groups.isEmpty()) {
- throw new SentryGrantDeniedException(grantorPrincipal
- + " has no grant!");
- }
-
- // if grantor is in adminGroup, don't need to do check
- Set<String> admins = getAdminGroups();
- boolean isAdminGroup = false;
- if (admins != null && !admins.isEmpty()) {
- for (String g : groups) {
- if (admins.contains(g)) {
- isAdminGroup = true;
- break;
- }
- }
- }
-
- if (!isAdminGroup) {
- boolean hasGrant = false;
- Set<MSentryRole> roles = getRolesForGroups(pm, groups);
- if (roles != null && !roles.isEmpty()) {
- for (MSentryRole role: roles) {
- Set<MSentryPrivilege> privilegeSet = role.getPrivileges();
- if (privilegeSet != null && !privilegeSet.isEmpty()) {
- // if role has a privilege p with grant option
- // and mPrivilege is a child privilege of p
- for (MSentryPrivilege p : privilegeSet) {
- if (p.getGrantOption() && p.implies(mPrivilege)) {
- hasGrant = true;
- break;
- }
- }
- }
- }
- }
-
- if (!hasGrant) {
- throw new SentryGrantDeniedException(grantorPrincipal
- + " has no grant!");
- }
- }
- }
-
- // get adminGroups from conf
- private Set<String> getAdminGroups() {
- return Sets.newHashSet(conf.getStrings(
- ServerConfig.ADMIN_GROUPS, new String[]{}));
- }
-
- /**
- * This returns a Mapping of AuthZObj(db/table) -> (Role -> permission)
- */
- public Map<String, HashMap<String, String>> retrieveFullPrivilegeImage() {
- Map<String, HashMap<String, String>> retVal = new HashMap<String, HashMap<String,String>>();
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryPrivilege.class);
- String filters = "(serverName != \"__NULL__\") "
- + "&& (dbName != \"__NULL__\") " + "&& (URI == \"__NULL__\")";
- query.setFilter(filters.toString());
- query
- .setOrdering("serverName ascending, dbName ascending, tableName ascending");
- List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query
- .execute();
- rollbackTransaction = false;
- for (MSentryPrivilege mPriv : privileges) {
- String authzObj = mPriv.getDbName();
- if (!isNULL(mPriv.getTableName())) {
- authzObj = authzObj + "." + mPriv.getTableName();
- }
- HashMap<String, String> pUpdate = retVal.get(authzObj);
- if (pUpdate == null) {
- pUpdate = new HashMap<String, String>();
- retVal.put(authzObj, pUpdate);
- }
- for (MSentryRole mRole : mPriv.getRoles()) {
- String existingPriv = pUpdate.get(mRole.getRoleName());
- if (existingPriv == null) {
- pUpdate.put(mRole.getRoleName(), mPriv.getAction().toUpperCase());
- } else {
- pUpdate.put(mRole.getRoleName(), existingPriv + ","
- + mPriv.getAction().toUpperCase());
- }
- }
- }
- commitTransaction(pm);
- return retVal;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- /**
- * This returns a Mapping of Role -> [Groups]
- */
- public Map<String, LinkedList<String>> retrieveFullRoleImage() {
- Map<String, LinkedList<String>> retVal = new HashMap<String, LinkedList<String>>();
- boolean rollbackTransaction = true;
- PersistenceManager pm = null;
- try {
- pm = openTransaction();
- Query query = pm.newQuery(MSentryGroup.class);
- List<MSentryGroup> groups = (List<MSentryGroup>) query.execute();
- for (MSentryGroup mGroup : groups) {
- for (MSentryRole role : mGroup.getRoles()) {
- LinkedList<String> rUpdate = retVal.get(role.getRoleName());
- if (rUpdate == null) {
- rUpdate = new LinkedList<String>();
- retVal.put(role.getRoleName(), rUpdate);
- }
- rUpdate.add(mGroup.getGroupName());
- }
- }
- commitTransaction(pm);
- return retVal;
- } finally {
- if (rollbackTransaction) {
- rollbackTransaction(pm);
- }
- }
- }
-
- /**
- * This thread exists to clean up "orphaned" privilege rows in the database.
- * These rows aren't removed automatically due to the fact that there is
- * a many-to-many mapping between the roles and privileges, and the
- * detection and removal of orphaned privileges is a wee bit involved.
- * This thread hangs out until notified by the parent (the outer class)
- * and then runs a custom SQL statement that detects and removes orphans.
- */
- private class PrivCleaner implements Runnable {
- // Kick off priv orphan removal after this many notifies
- private static final int NOTIFY_THRESHOLD = 50;
-
- // How many times we've been notified; reset to zero after orphan removal
- private int currentNotifies = 0;
-
- // Internal state for threads
- private boolean exitRequired = false;
-
- // This lock and condition are needed to implement a way to drop the
- // lock inside a while loop, and not hold the lock across the orphan
- // removal.
- private final Lock lock = new ReentrantLock();
- private final Condition cond = lock.newCondition();
-
- /**
- * Waits in a loop, running the orphan removal function when notified.
- * Will exit after exitRequired is set to true by exit(). We are careful
- * to not hold our lock while removing orphans; that operation might
- * take a long time. There's also the matter of lock ordering. Other
- * threads start a transaction first, and then grab our lock; this thread
- * grabs the lock and then starts a transaction. Handling this correctly
- * requires explicit locking/unlocking through the loop.
- */
- public void run() {
- while (true) {
- lock.lock();
- try {
- // Check here in case this was set during removeOrphanedPrivileges()
- if (exitRequired) {
- return;
- }
- while (currentNotifies <= NOTIFY_THRESHOLD) {
- try {
- cond.await();
- } catch (InterruptedException e) {
- // Interrupted
- }
- // Check here in case this was set while waiting
- if (exitRequired) {
- return;
- }
- }
- currentNotifies = 0;
- } finally {
- lock.unlock();
- }
- try {
- removeOrphanedPrivileges();
- } catch (Exception e) {
- LOGGER.warn("Privilege cleaning thread encountered an error: " +
- e.getMessage());
- }
- }
- }
-
- /**
- * This is called when a privilege is removed from a role. This may
- * or may not mean that the privilege needs to be removed from the
- * database; there may be more references to it from other roles.
- * As a result, we'll lazily run the orphan cleaner every
- * NOTIFY_THRESHOLD times this routine is called.
- * @param numDeletions The number of potentially orphaned privileges
- */
- public void incPrivRemoval(int numDeletions) {
- if (privCleanerThread != null) {
- lock.lock();
- currentNotifies += numDeletions;
- if (currentNotifies > NOTIFY_THRESHOLD) {
- cond.signal();
- }
- lock.unlock();
- }
- }
-
- /**
- * Simple form of incPrivRemoval when only one privilege is deleted.
- */
- public void incPrivRemoval() {
- incPrivRemoval(1);
- }
-
- /**
- * Tell this thread to exit. Safe to call multiple times, as it just
- * notifies the run() loop to finish up.
- */
- public void exit() {
- if (privCleanerThread != null) {
- lock.lock();
- try {
- exitRequired = true;
- cond.signal();
- } finally {
- lock.unlock();
- }
- }
- }
-
- /**
- * Run a SQL query to detect orphaned privileges, and then delete
- * each one. This is complicated by the fact that datanucleus does
- * not seem to play well with the mix between a direct SQL query
- * and operations on the database. The solution that seems to work
- * is to split the operation into two transactions: the first is
- * just a read for privileges that look like they're orphans, the
- * second transaction will go and get each of those privilege objects,
- * verify that there are no roles attached, and then delete them.
- */
- private void removeOrphanedPrivileges() {
- final String privDB = "SENTRY_DB_PRIVILEGE";
- final String privId = "DB_PRIVILEGE_ID";
- final String mapDB = "SENTRY_ROLE_DB_PRIVILEGE_MAP";
- final String privFilter =
- "select " + privId +
- " from " + privDB + " p" +
- " where not exists (" +
- " select 1 from " + mapDB + " d" +
- " where p." + privId + " != d." + privId +
- " )";
- boolean rollback = true;
- int orphansRemoved = 0;
- ArrayList<Object> idList = new ArrayList<Object>();
- PersistenceManager pm = pmf.getPersistenceManager();
-
- // Transaction 1: Perform a SQL query to get things that look like orphans
- try {
- Transaction transaction = pm.currentTransaction();
- transaction.begin();
- transaction.setRollbackOnly(); // Makes the tx read-only
- Query query = pm.newQuery("javax.jdo.query.SQL", privFilter);
- query.setClass(MSentryPrivilege.class);
- List<MSentryPrivilege> results = (List<MSentryPrivilege>) query.execute();
- for (MSentryPrivilege orphan : results) {
- idList.add(pm.getObjectId(orphan));
- }
- transaction.rollback();
- rollback = false;
- } finally {
- if (rollback && pm.currentTransaction().isActive()) {
- pm.currentTransaction().rollback();
- } else {
- LOGGER.debug("Found {} potential orphans", idList.size());
- }
- }
-
- if (idList.isEmpty()) {
- pm.close();
- return;
- }
-
- Preconditions.checkState(!rollback);
-
- // Transaction 2: For each potential orphan, verify it's really an
- // orphan and delete it if so
- rollback = true;
- try {
- Transaction transaction = pm.currentTransaction();
- transaction.begin();
- pm.refreshAll(); // Try to ensure we really have correct objects
- for (Object id : idList) {
- MSentryPrivilege priv = (MSentryPrivilege) pm.getObjectById(id);
- if (priv.getRoles().isEmpty()) {
- pm.deletePersistent(priv);
- orphansRemoved++;
- }
- }
- transaction.commit();
- pm.close();
- rollback = false;
- } finally {
- if (rollback) {
- rollbackTransaction(pm);
- } else {
- LOGGER.debug("Cleaned up {} orphaned privileges", orphansRemoved);
- }
- }
- }
- }
+ public void fromSnapshot(TStoreSnapshot snapshot);
}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreFactory.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreFactory.java
new file mode 100644
index 0000000..5e3a606
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreFactory.java
@@ -0,0 +1,47 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import org.apache.hadoop.conf.Configuration;
+
+public class SentryStoreFactory {
+
+ private static String STORE_TYPE_CONF = "sentry.store.type";
+ private static String STORE_TYPE_DEF = "db";
+
+ public static SentryStore createSentryStore(Configuration conf) {
+ String storeType = conf.get(STORE_TYPE_CONF, STORE_TYPE_DEF);
+ try {
+ if ("db".equals(storeType)) {
+ return new DbSentryStore(conf);
+ } else if ("inmem".equals(storeType)) {
+ return new SentryStoreWithLocalLock(new InMemSentryStore(conf));
+ } else if ("localfile".equals(storeType)){
+ return new SentryStoreWithLocalLock(
+ new SentryStoreWithFileLog(new InMemSentryStore(conf)));
+ } else {
+ return new SentryStoreWithDistributedLock(
+ new SentryStoreWithFileLog(
+ new InMemSentryStore(conf)), HAContext.get(conf));
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Could not instantiate Store !!", e);
+ }
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithDistributedLock.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithDistributedLock.java
new file mode 100644
index 0000000..db76a6a
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithDistributedLock.java
@@ -0,0 +1,97 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+import org.apache.curator.framework.recipes.locks.InterProcessMutex;
+import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
+
+import com.hazelcast.core.HazelcastInstance;
+
+/**
+ * An implementation of {@link LockingSentryStore} that implements the Locking
+ * strategy using a Zookeeper based Lock. It uses the Curator Library for the
+ * globally consistent inter-process read-write lock implementation that it
+ * provides.
+ */
+
+public class SentryStoreWithDistributedLock extends
+ LockingSentryStore<SentryStoreWithDistributedLock.DistributedLockContext> {
+
+ public static final String SENTRY_DISTRIBUTED_LOCK_TIMEOUT_MS =
+ "sentry.distributed.lock.timeout.ms";
+ public static final int SENTRY_DISTRIBUTED_LOCK_TIMEOUT_MS_DEF = 10000;
+ public static final String SENTRY_DISTRIBUTED_LOCK_PATH =
+ "sentry.distributed.lock.path";
+ public static final String SENTRY_DISTRIBUTED_LOCK_PATH_DEF =
+ "/sentryStorePath";
+
+ class DistributedLockContext implements
+ LockingSentryStore.LockContext {
+ final InterProcessMutex mutex;
+
+ DistributedLockContext(InterProcessMutex mutex) {
+ this.mutex = mutex;
+ }
+ @Override
+ public void unlock() {
+ try {
+ mutex.release();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private final InterProcessReadWriteLock lock;
+ private final int lockTimeoutMs;
+
+ public SentryStoreWithDistributedLock(SentryStore sentryStore, HAContext haContext) {
+ super(sentryStore);
+ lockTimeoutMs =
+ getConfiguration().getInt(SENTRY_DISTRIBUTED_LOCK_TIMEOUT_MS,
+ SENTRY_DISTRIBUTED_LOCK_TIMEOUT_MS_DEF);
+ lock = new InterProcessReadWriteLock(haContext.getCuratorFramework(), haContext.getNamespace()
+ + getConfiguration().get(SENTRY_DISTRIBUTED_LOCK_PATH,
+ SENTRY_DISTRIBUTED_LOCK_PATH_DEF));
+ }
+
+ private DistributedLockContext lock(InterProcessMutex mutex) {
+ try {
+ if (mutex.acquire(lockTimeoutMs, TimeUnit.MILLISECONDS)) {
+ return new DistributedLockContext(mutex);
+ }
+ } catch (Exception ie) {
+ throw new RuntimeException(ie);
+ }
+ throw new RuntimeException("Could not acquire lock !!");
+ }
+
+ @Override
+ protected DistributedLockContext writeLock() {
+ return lock(lock.writeLock());
+ }
+
+ @Override
+ protected DistributedLockContext readLock() {
+ return lock(lock.readLock());
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithFileLog.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithFileLog.java
new file mode 100644
index 0000000..8f640a0
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithFileLog.java
@@ -0,0 +1,128 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.provider.db.service.persistent.FileLog.Entry;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreOp;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreRecord;
+import org.apache.thrift.TException;
+
+/**
+ * An implementation of the {@link PersistentSentryStore}. The Persistence
+ * strategy used by this class is to log all write operations to a local file
+ * using the {@link FileLog} log abstraction. Each write operation is stamp
+ * with a monotonically +1 incrementing sequence Id. This guarantees that, after
+ * a restart, the Sentry Store can read the log in the same order it was
+ * written and would return to the same state it was before it was brought down.
+ * The logging is also write-behind (operations are logged only after it has
+ * been accepted by the underlying store) to ensure that erroneous operations
+ * that would bring down the Store are not logged.
+ *
+ * To limit the size of the log file, it requests the underlying SentryStore
+ * to provide it with a snapshot of the store after a configurable number of
+ * operations, which it writes to a new log file and and truncates the old one.
+ *
+ */
+public class SentryStoreWithFileLog extends
+ PersistentSentryStore<SentryStoreWithFileLog.FileLogContext> {
+
+ public static final int SENTRY_STORE_FILE_LOG_SNAPSHOT_THRESHOLD_DEF = 100;
+ public static final String SENTRY_STORE_FILE_LOG_SNAPSHOT_THRESHOLD =
+ "sentry.store.file.log.snapshot.threshold";
+
+ /**
+ * An implementation of the {@link PersistentContext} that is created prior
+ * to the operation and stores the write record.
+ */
+ public static class FileLogContext implements
+ PersistentSentryStore.PersistentContext {
+ final long seqId;
+ final TSentryStoreRecord record;
+
+ FileLogContext(long seqId, TSentryStoreRecord record) {
+ this.seqId = seqId;
+ this.record = record;
+ }
+ }
+
+ protected final FileLog fileLog;
+ protected final AtomicLong lastSeenSeqId = new AtomicLong(0);
+ protected final int snapshotThreshold;
+
+ public SentryStoreWithFileLog(SentryStore sentryStore)
+ throws FileNotFoundException, IOException, TException, SentryUserException {
+ super(sentryStore);
+ snapshotThreshold =
+ getConfiguration().getInt(
+ SENTRY_STORE_FILE_LOG_SNAPSHOT_THRESHOLD,
+ SENTRY_STORE_FILE_LOG_SNAPSHOT_THRESHOLD_DEF);
+ fileLog = new FileLog(getConfiguration());
+ Entry ent = null;
+ while (fileLog.hasNext()) {
+ ent = fileLog.next();
+ applyRecord(ent.record);
+ }
+ if (ent != null) {
+ lastSeenSeqId.set(ent.seqId);
+ }
+ }
+
+ @Override
+ protected FileLogContext createRecord(TSentryStoreRecord record) {
+ return new FileLogContext(lastSeenSeqId.incrementAndGet(), record);
+ }
+
+ @Override
+ protected void onSuccess(FileLogContext context) {
+ fileLog.log(context.seqId,
+ getSnapshotIfRequired(context.seqId, context.record));
+ }
+
+ @Override
+ protected void onFailure(FileLogContext context) {
+ fileLog.log(context.seqId,
+ getSnapshotIfRequired(context.seqId,
+ new TSentryStoreRecord(TSentryStoreOp.NO_OP)));
+ }
+
+ protected TSentryStoreRecord getSnapshotIfRequired(long seqId, TSentryStoreRecord record) {
+ if ((seqId > 0) && (seqId % snapshotThreshold == 0)) {
+ if (record.getStoreOp() == TSentryStoreOp.SNAPSHOT) {
+ return record;
+ }
+ TSentryStoreRecord snapshotRecord = new TSentryStoreRecord(TSentryStoreOp.SNAPSHOT);
+ snapshotRecord.setSnapshot(getStore().toSnapshot());
+ return snapshotRecord;
+ } else {
+ return record;
+ }
+ }
+
+ @Override
+ public void stop() {
+ super.stop();
+ fileLog.close();
+ }
+
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithLocalLock.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithLocalLock.java
new file mode 100644
index 0000000..42f4e7f
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithLocalLock.java
@@ -0,0 +1,65 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * An implementation of {@link LockingSentryStore} that implements the
+ * Locking strategy using the standard
+ * {@link java.util.concurrent.locks.ReentrantReadWriteLock}
+ *
+ */
+public class SentryStoreWithLocalLock extends
+ LockingSentryStore<SentryStoreWithLocalLock.ThreadSafeContext> {
+
+ public static class ThreadSafeContext implements
+ LockingSentryStore.LockContext {
+ final Lock lock;
+
+ public ThreadSafeContext(Lock lock) {
+ this.lock = lock;
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
+ }
+
+ private final ReadWriteLock rwLock;
+
+ public SentryStoreWithLocalLock(SentryStore sentryStore) {
+ super(sentryStore);
+ this.rwLock = new ReentrantReadWriteLock();
+ }
+
+ @Override
+ protected ThreadSafeContext writeLock() {
+ return new ThreadSafeContext(rwLock.writeLock());
+ }
+
+ @Override
+ protected ThreadSafeContext readLock() {
+ return new ThreadSafeContext(rwLock.readLock());
+ }
+
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithReplicatedLog.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithReplicatedLog.java
new file mode 100644
index 0000000..0ecf024
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreWithReplicatedLog.java
@@ -0,0 +1,377 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.hive.com.esotericsoftware.minlog.Log;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.provider.db.service.persistent.FileLog.Entry;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreOp;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreRecord;
+import org.apache.thrift.TDeserializer;
+import org.apache.thrift.TException;
+import org.apache.thrift.TSerializer;
+import org.apache.thrift.protocol.TCompactProtocol;
+import org.apache.thrift.protocol.TProtocolFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.IAtomicLong;
+import com.hazelcast.core.IQueue;
+import com.hazelcast.core.ITopic;
+import com.hazelcast.core.Member;
+import com.hazelcast.core.Message;
+import com.hazelcast.core.MessageListener;
+
+/**
+ * A special subclass of the {@link SentryStoreWithFileLog} that uses the
+ * same persistence strategy but in addition to logging to a local
+ * {@link FileLog} will also publish the record to a distributed topic to be
+ * consumed by other peer Stores in a Sentry cluster.
+ *
+ * The class uses the Hazelcast library for :
+ * 1) Distributed counter for sequence Id
+ * 2) Distributed Topic with global ordering to replicate log entries to peer
+ * SentryStores
+ *
+ * Consistency Guarantees:
+ * Hazelcast counters are globally consistent, but since it is optimized for
+ * availability rather than consistency it can suffer from split-brain issues
+ * in the event of a network partition. This should not be too much of an issue
+ * for small deployments of 2-3 instances deployed in the same availability
+ * zone, But strict consistency can be guaranteed by either:
+ * 1) Wrapping this store with a {@link SentryStoreWithDistributedLock} which
+ * uses the Curator library's distributed read write lock which is based
+ * on Zookeeper. Zookeper has a stricter consistency model since all writes
+ * go thru a master.
+ * 2) Deploying SentryService in active-standy mode which ensures writes are
+ * handled only by the active node. This can be trivially
+ * accomplished by setting the serivce discovery policy in the
+ * SentrtyPolicyServiceClient to 'STICKY' rather than the default
+ * 'ROUND-ROBIN'
+ *
+ * Other Considerations:
+ * This implementation also supports new peers joining an existing cluster.
+ * The new peer will be brought upto speed with the other members of the
+ * cluster in the following manner:
+ * 1) All members listen to a special 'catchupRequest' topic.
+ * 2) When a new member starts-up, it publishes a 'CatchupRequest' to the
+ * 'catchUpRequest' topic. The CatchupRequest contains the last seen
+ * record's sequence number from its local FileLog.
+ * 3) The new member also creates a uniquely named Distributed Queue and waits
+ * for messages on it. This queue name is also included in the
+ * CatchupRequest.
+ * 4) This request is received by all the existing members of the cluster, it
+ * is ignored by all members EXCEPT the oldest member of the cluster which
+ * responds to the request by pushing the required records to the
+ * Distributed queue.
+ */
+
+public class SentryStoreWithReplicatedLog extends SentryStoreWithFileLog {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(SentryStoreWithReplicatedLog.class);
+
+ private static final int WAIT_SLEEP_MS = 500;
+
+ /**
+ * Only successful events are sent to the topic (failed records are sent as
+ * no-op so that no gaps exist in the seqId)
+ * Basically write behind logging.. If the publisher crashes before
+ * writing to log, the update is not applied to the remote nodes.
+ * Think this should be fine (It is similar to the case when Sentry
+ * Service receives a message but dies while/before opening a db transaction)
+ */
+ public static class LogEntry implements Serializable {
+ private static final long serialVersionUID = 8798360797372277777L;
+
+ long seqId = -1;
+ long nodeId = -1;
+ byte[] recordBytes;
+
+ public LogEntry() {}
+
+ public LogEntry(long seqId, long nodeId, byte[] recordBytes) {
+ this.seqId = seqId;
+ this.nodeId = nodeId;
+ this.recordBytes = recordBytes;
+ }
+ }
+
+ public static class CatchUpRequest implements Serializable {
+ private static final long serialVersionUID = -3345746198249394847L;
+
+ long startSeqId = -1;
+ long endSeqId = -1;
+ long nodeId = -1;
+
+ public CatchUpRequest() {}
+
+ public CatchUpRequest(long startSeqId, long endSeqId, long nodeId) {
+ this.startSeqId = startSeqId;
+ this.endSeqId = endSeqId;
+ this.nodeId = nodeId;
+ }
+ }
+
+ class LogEntryWorker implements Runnable{
+ @Override
+ public void run() {
+ while(true) {
+ try {
+ processLogEntry(entryQueue.take());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ } catch (SentryUserException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+ private final TSerializer serializer;
+ private final TDeserializer deserializer;
+ private final BlockingQueue<LogEntry> entryQueue =
+ new LinkedBlockingQueue<LogEntry>();
+ private Thread entryWorker;
+
+ // Distributed stuff
+ private final HazelcastInstance hInst;
+ private final long nodeId;
+ private final IAtomicLong globalSeqId;
+ private final ITopic<LogEntry> dTopic;
+ private final ITopic<CatchUpRequest> catchUpReqTopic;
+
+ public SentryStoreWithReplicatedLog(SentryStore sentryStore)
+ throws FileNotFoundException, IOException, TException,
+ SentryUserException {
+ this(sentryStore,
+ DistributedUtils.getHazelcastInstance(sentryStore.getConfiguration(),
+ true));
+ }
+
+ public SentryStoreWithReplicatedLog(SentryStore sentryStore,
+ final HazelcastInstance hInst) throws FileNotFoundException, IOException,
+ TException, SentryUserException {
+ super(sentryStore);
+ this.hInst = hInst;
+ TProtocolFactory protoFactory = new TCompactProtocol.Factory();
+ serializer = new TSerializer(protoFactory);
+ deserializer = new TDeserializer(protoFactory);
+
+ nodeId = hInst.getIdGenerator(DistributedUtils.SENTRY_STORE_NODEID).newId();
+ globalSeqId = hInst.getAtomicLong(DistributedUtils.SENTRY_STORE_SEQID);
+ dTopic = hInst.getTopic(DistributedUtils.SENTRY_DISTRIBUTED_TOPIC);
+ dTopic.addMessageListener(new MessageListener<SentryStoreWithReplicatedLog.LogEntry>() {
+ @Override
+ public void onMessage(Message<LogEntry> msg) {
+ LogEntry ent = msg.getMessageObject();
+ try {
+ entryQueue.put(ent);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ });
+
+ catchUpReqTopic = hInst.getTopic(DistributedUtils.SENTRY_CATCHUP_REQUEST_TOPIC);
+ requestCatchUpIfRequired();
+ catchUpReqTopic.addMessageListener(new MessageListener<CatchUpRequest>() {
+ @Override
+ public void onMessage(final Message<CatchUpRequest> req) {
+ LOGGER.info("Catchup request received["
+ + req.getMessageObject().startSeqId + ", "
+ + req.getMessageObject().endSeqId + ", "
+ + req.getMessageObject().nodeId + "]");
+ handleCatchupRequest(req.getMessageObject(), hInst);
+ }
+ });
+
+ entryWorker = new Thread(new LogEntryWorker(), "Log Entry Worker");
+ entryWorker.start();
+ }
+
+ private void handleCatchupRequest(CatchUpRequest req, HazelcastInstance hInst) {
+ Member oldestMember = hInst.getCluster().getMembers().iterator().next();
+ // Am I oldest member ?
+ if (oldestMember.localMember()) {
+ long myLastSeen = lastSeenSeqId.get();
+ if (req.endSeqId > myLastSeen) {
+ LOGGER.info("Waiting for seq Id[" + myLastSeen + ", " + req.endSeqId + "]");
+ try {
+ Thread.sleep(getConfiguration().getInt(
+ DistributedUtils.SENTRY_CATCHUP_WAIT_TIME,
+ DistributedUtils.SENTRY_CATCHUP_WAIT_TIME_DEF));
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ // Still not updated ?
+ if (req.endSeqId > myLastSeen) {
+ throw new RuntimeException(
+ "Havnt recieved latest updated.. cannot respond to catchup request !!");
+ }
+ FileLog tempLog = null;
+ try {
+ tempLog = new FileLog(getStore().getConfiguration());
+ } catch (Exception e) {
+ throw new RuntimeException("Could not open FileLog to send catchup entries !!");
+ }
+
+ IQueue<LogEntry> respQueue =
+ hInst.getQueue(DistributedUtils.SENTRY_CATCHUP_RESPONSE_QUEUE + req.nodeId);
+ while (tempLog.hasNext()) {
+ Entry entry = tempLog.next();
+ if ((entry.seqId >= req.startSeqId)&&(entry.seqId <= req.endSeqId)) {
+ try {
+ respQueue.offer(new LogEntry(entry.seqId, nodeId, serializer.serialize(entry.record)));
+ LOGGER.info("Sent Catchup entry [" + entry.seqId + ","
+ + nodeId + ", " + req.nodeId + "]");
+ } catch (TException e) {
+ throw new RuntimeException("Could not send catchup entry !!", e);
+ }
+ }
+ }
+ }
+ }
+
+ private void requestCatchUpIfRequired() throws SentryUserException {
+ long startSeqId = lastSeenSeqId.get() + 1;
+ long endSeqId = globalSeqId.get();
+ if (startSeqId <= endSeqId) {
+ LOGGER.info("Sending Catchup request ["
+ + startSeqId + ", "
+ + endSeqId + ", "
+ + nodeId + "]");
+ // Send request for catchup entries
+ IQueue<LogEntry> respQueue =
+ hInst.getQueue(DistributedUtils.SENTRY_CATCHUP_RESPONSE_QUEUE + nodeId);
+ catchUpReqTopic.publish(
+ new CatchUpRequest(startSeqId, endSeqId, nodeId));
+ receiveCatchUpEntries(respQueue, endSeqId);
+ }
+ }
+
+ private void receiveCatchUpEntries(IQueue<LogEntry> catchUpQueue,
+ long endSeqId) throws SentryUserException {
+ long currSeqId = -1;
+ while (currSeqId < endSeqId) {
+ try {
+ LogEntry entry =
+ catchUpQueue.poll(
+ getConfiguration().getInt(
+ DistributedUtils.SENTRY_CATCHUP_WAIT_TIME,
+ DistributedUtils.SENTRY_CATCHUP_WAIT_TIME_DEF),
+ TimeUnit.MILLISECONDS);
+ if (entry == null) {
+ String msg =
+ "Havnt received all catchup entries [" + currSeqId + ", "
+ + endSeqId + "]!!";
+ LOGGER.error(msg);
+ throw new RuntimeException(msg);
+ }
+ LOGGER.info("Received catchup [" + entry.seqId + ", " + entry.nodeId + "]");
+ currSeqId = entry.seqId;
+ processLogEntry(entry);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ catchUpQueue.destroy();
+ }
+
+ private void processLogEntry(LogEntry ent) throws SentryUserException {
+ TSentryStoreRecord record = new TSentryStoreRecord();
+ try {
+ deserializer.deserialize(record, ent.recordBytes);
+ } catch (TException e) {
+ String msg = "Could not de-serialize record [" + ent.seqId + "]!!";
+ Log.error(msg, e);
+ throw new RuntimeException(msg, e);
+ }
+ // No need to update the publisher (Thats already done)
+ if (ent.nodeId != SentryStoreWithReplicatedLog.this.nodeId) {
+ try {
+ applyRecord(record);
+ fileLog.log(ent.seqId, getSnapshotIfRequired(ent.seqId, record));
+ lastSeenSeqId.set(ent.seqId);
+ } catch (SentryUserException e) {
+ String msg = "Could not apply de-serialized record [" + ent.seqId + "]!!";
+ Log.error(msg, e);
+ throw new RuntimeException(msg, e);
+ }
+ }
+ }
+
+ @Override
+ protected FileLogContext createRecord(TSentryStoreRecord record) {
+ return new FileLogContext(globalSeqId.incrementAndGet(), record);
+ }
+
+ @Override
+ protected void onSuccess(FileLogContext context) {
+ super.onSuccess(context);
+ lastSeenSeqId.set(context.seqId);
+ try {
+ dTopic.publish(new LogEntry(context.seqId, nodeId, serializer
+ .serialize(context.record)));
+ } catch (TException e) {
+ throw new RuntimeException("Could not serialize Sentry record !!");
+ }
+ }
+
+ @Override
+ protected void onFailure(FileLogContext context) {
+ // Publish a NO-OP record (since we dont want any gaps in the seqId)
+ super.onFailure(context);
+ lastSeenSeqId.set(context.seqId);
+ try {
+ dTopic.publish(new LogEntry(context.seqId, nodeId, serializer
+ .serialize(new TSentryStoreRecord(TSentryStoreOp.NO_OP))));
+ } catch (TException e) {
+ throw new RuntimeException("Could not serialize Sentry record !!");
+ }
+ }
+
+ public boolean waitForReplicattionToComplete(long timeInMs) {
+ long totalWait = 0;
+ while (true) {
+ if (lastSeenSeqId.get() == globalSeqId.get()) {
+ return true;
+ }
+ try {
+ Thread.sleep(WAIT_SLEEP_MS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return false;
+ }
+ totalWait += WAIT_SLEEP_MS;
+ if (totalWait >= timeInMs) {
+ return false;
+ }
+ }
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/StoreUtils.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/StoreUtils.java
new file mode 100644
index 0000000..d23685b
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/StoreUtils.java
@@ -0,0 +1,102 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import static org.apache.sentry.provider.common.ProviderConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.provider.common.ProviderConstants.KV_JOINER;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
+import org.apache.sentry.provider.common.ProviderConstants;
+import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
+
+public class StoreUtils {
+
+ public static String NULL_COL = "__NULL__";
+
+ @VisibleForTesting
+ public static String toAuthorizable(MSentryPrivilege privilege) {
+ return toAuthorizable(privilege.getServerName(), privilege.getDbName(),
+ privilege.getURI(), privilege.getTableName(), privilege.getColumnName(),
+ privilege.getAction());
+ }
+
+ @VisibleForTesting
+ public static String toAuthorizable(String serverName, String dbName,
+ String uri, String tableName, String columnName, String action) {
+ List<String> authorizable = new ArrayList<String>(4);
+ authorizable.add(KV_JOINER.join(AuthorizableType.Server.name().toLowerCase(),
+ serverName));
+ if (isNULL(uri)) {
+ if (!isNULL(dbName)) {
+ authorizable.add(KV_JOINER.join(AuthorizableType.Db.name().toLowerCase(),
+ dbName));
+ if (!isNULL(tableName)) {
+ authorizable.add(KV_JOINER.join(AuthorizableType.Table.name().toLowerCase(),
+ tableName));
+ if (!isNULL(columnName)) {
+ authorizable.add(KV_JOINER.join(AuthorizableType.Column.name().toLowerCase(),
+ columnName));
+ }
+ }
+ }
+ } else {
+ authorizable.add(KV_JOINER.join(AuthorizableType.URI.name().toLowerCase(),
+ uri));
+ }
+ if (!isNULL(action)
+ && !action.equalsIgnoreCase(AccessConstants.ALL)) {
+ authorizable
+ .add(KV_JOINER.join(ProviderConstants.PRIVILEGE_NAME.toLowerCase(),
+ action));
+ }
+ return AUTHORIZABLE_JOINER.join(authorizable);
+ }
+
+ @VisibleForTesting
+ public static Set<String> toTrimedLower(Set<String> s) {
+ if (null == s) return new HashSet<String>();
+ Set<String> result = Sets.newHashSet();
+ for (String v : s) {
+ result.add(v.trim().toLowerCase());
+ }
+ return result;
+ }
+
+ public static String toNULLCol(String s) {
+ return Strings.isNullOrEmpty(s) ? NULL_COL : s;
+ }
+
+ public static String fromNULLCol(String s) {
+ return isNULL(s) ? "" : s;
+ }
+
+ public static boolean isNULL(String s) {
+ return Strings.isNullOrEmpty(s) || s.equals(NULL_COL);
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetrics.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetrics.java
index 55bec0b..0dd10f6 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetrics.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryMetrics.java
@@ -28,6 +28,8 @@
import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
+
+import org.apache.sentry.provider.db.service.persistent.DbSentryStore;
import org.apache.sentry.provider.db.service.persistent.SentryStore;
import java.lang.management.ManagementFactory;
@@ -84,15 +86,36 @@
return sentryMetrics;
}
- public void addSentryStoreGauges(SentryStore sentryStore) {
+ public void addSentryStoreGauges(final SentryStore sentryStore) {
if(!gaugesAdded) {
- addGauge(SentryStore.class, "role_count", sentryStore.getRoleCountGauge());
- addGauge(SentryStore.class, "privilege_count", sentryStore.getPrivilegeCountGauge());
- addGauge(SentryStore.class, "group_count", sentryStore.getGroupCountGauge());
+ addGauge(SentryStore.class, "role_count", new Gauge<Long>() {
+ @Override
+ public Long getValue() {
+ return sentryStore.getRoleCount();
+ }});
+ addGauge(SentryStore.class, "privilege_count", new Gauge<Long>() {
+ @Override
+ public Long getValue() {
+ return sentryStore.getPrivilegeCount();
+ }});
+ addGauge(SentryStore.class, "group_count", new Gauge<Long>() {
+ @Override
+ public Long getValue() {
+ return sentryStore.getGroupCount();
+ }});
gaugesAdded = true;
}
}
+//@Override
+//public Gauge<Long> getGroupCountGauge() {
+// return new Gauge< Long >() {
+// @Override
+// public Long getValue() {
+// return getCount(MSentryGroup.class);
+// }
+// };
+//}
/* Should be only called once to initialize the reporters
*/
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
index 29e3131..1ffc496 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
@@ -32,6 +32,7 @@
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.codahale.metrics.Timer;
+
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
@@ -52,8 +53,10 @@
import org.apache.sentry.provider.db.log.util.Constants;
import org.apache.sentry.provider.db.service.persistent.CommitContext;
import org.apache.sentry.provider.db.service.persistent.HAContext;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
import org.apache.sentry.provider.db.service.persistent.ServiceRegister;
+import org.apache.sentry.provider.db.service.persistent.DbSentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreFactory;
import org.apache.sentry.provider.db.service.thrift.PolicyStoreConstants.PolicyStoreServerConfig;
import org.apache.sentry.service.thrift.ServiceConstants.ConfUtilties;
import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig;
@@ -103,13 +106,13 @@
isReady = false;
if(conf.getBoolean(ServerConfig.SENTRY_HA_ENABLED,
ServerConfig.SENTRY_HA_ENABLED_DEFAULT)){
- haContext = new HAContext(conf);
- sentryStore = new SentryStore(conf);
+ haContext = HAContext.get(conf);
+ sentryStore = SentryStoreFactory.createSentryStore(conf);
ServiceRegister reg = new ServiceRegister(haContext);
reg.regService(conf.get(ServerConfig.RPC_ADDRESS),
conf.getInt(ServerConfig.RPC_PORT,ServerConfig.RPC_PORT_DEFAULT));
} else {
- sentryStore = new SentryStore(conf);
+ sentryStore = SentryStoreFactory.createSentryStore(conf);
}
isReady = true;
adminGroups = ImmutableSet.copyOf(toTrimedLower(Sets.newHashSet(conf.getStrings(
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/HAClientInvocationHandler.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/HAClientInvocationHandler.java
index c6e265f..4e371f4 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/HAClientInvocationHandler.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/HAClientInvocationHandler.java
@@ -51,7 +51,7 @@
public HAClientInvocationHandler(Configuration conf) throws Exception {
this.conf = conf;
- manager = new ServiceManager(new HAContext(conf));
+ manager = new ServiceManager(HAContext.get(conf));
checkClientConf();
renewSentryClient();
}
diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift b/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
index 993ea46..23f09d7 100644
--- a/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
+++ b/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
@@ -52,11 +52,65 @@
10: optional string columnName = "",
}
+struct TSentryAuthorizable {
+1: required string server,
+2: optional string uri,
+3: optional string db,
+4: optional string table,
+5: optional string column,
+}
+
+enum TSentryStoreOp {
+ CREATE_ROLE = 0,
+ DROP_ROLE = 1,
+ GRANT_PRIVILEGES = 2,
+ REVOKE_PRVILEGES = 3,
+ ADD_GROUPS = 4,
+ DEL_GROUPS = 5,
+ SET_VERSION = 6,
+ DROP_PRIVILEGE = 7,
+ RENAME_PRIVILEGE = 8,
+ SNAPSHOT = 9,
+ NO_OP = 100
+}
+
+struct TStorePrivilege {
+1: required TSentryGrantOption grantOption,
+2: required i16 privilege
+}
+
+struct TStoreAuthorizable {
+1: required string name,
+2: required string type,
+3: optional map<string, TStorePrivilege> privileges,
+4: optional set<i32> children
+}
+
+struct TStoreSnapshot {
+1: required map<string, TStoreAuthorizable> rootAuthorizable,
+2: required map<string, set<string>> roleToGroups,
+3: required map<i32, TStoreAuthorizable> objIds
+}
+
# TODO can this be deleted? it's not adding value to TAlterSentryRoleAddGroupsRequest
struct TSentryGroup {
1: required string groupName
}
+# Represents a Privilege in transport from the client to the server
+struct TSentryStoreRecord {
+1: required TSentryStoreOp storeOp,
+2: optional string roleName,
+3: optional string grantorPrincipal,
+4: optional set<TSentryPrivilege> privileges,
+5: optional set<string> groups,
+6: optional TSentryAuthorizable authorizable,
+7: optional TSentryAuthorizable newAuthorizable,
+8: optional string version,
+9: optional string versionComment,
+10: optional TStoreSnapshot snapshot
+}
+
# CREATE ROLE r1
struct TCreateSentryRoleRequest {
1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
@@ -143,14 +197,6 @@
2: optional set<TSentryRole> roles
}
-struct TSentryAuthorizable {
-1: required string server,
-2: optional string uri,
-3: optional string db,
-4: optional string table,
-5: optional string column,
-}
-
# SHOW GRANT
struct TListSentryPrivilegesRequest {
1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestFileLog.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestFileLog.java
new file mode 100644
index 0000000..95acd1c
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestFileLog.java
@@ -0,0 +1,77 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.io.File;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreOp;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreRecord;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Files;
+
+public class TestFileLog {
+
+ private String logDir;
+
+ @Before
+ public void setup() {
+ logDir = Files.createTempDir().getAbsolutePath();
+ System.out.println("Creating dir : [" + logDir + "]");
+ }
+
+ @After
+ public void tearDown() {
+ File l = new File(logDir);
+ for (File f : l.listFiles()) {
+ f.delete();
+ }
+ l.delete();
+ }
+
+ @Test
+ public void testReadWriteLog() throws Exception {
+ Configuration conf = new Configuration(false);
+ conf.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir);
+ FileLog fileLog = new FileLog(conf);
+ fileLog.log(1, new TSentryStoreRecord(TSentryStoreOp.CREATE_ROLE));
+ fileLog.log(2, new TSentryStoreRecord(TSentryStoreOp.GRANT_PRIVILEGES));
+ fileLog.log(3, new TSentryStoreRecord(TSentryStoreOp.REVOKE_PRVILEGES));
+ fileLog.log(4, new TSentryStoreRecord(TSentryStoreOp.ADD_GROUPS));
+ fileLog.log(5, new TSentryStoreRecord(TSentryStoreOp.DEL_GROUPS));
+ fileLog.close();
+
+ fileLog = new FileLog(conf);
+ Assert.assertTrue(fileLog.hasNext());
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, fileLog.next().record.getStoreOp());
+ Assert.assertTrue(fileLog.hasNext());
+ Assert.assertEquals(TSentryStoreOp.GRANT_PRIVILEGES, fileLog.next().record.getStoreOp());
+ Assert.assertTrue(fileLog.hasNext());
+ Assert.assertEquals(TSentryStoreOp.REVOKE_PRVILEGES, fileLog.next().record.getStoreOp());
+ Assert.assertTrue(fileLog.hasNext());
+ Assert.assertEquals(TSentryStoreOp.ADD_GROUPS, fileLog.next().record.getStoreOp());
+ Assert.assertTrue(fileLog.hasNext());
+ Assert.assertEquals(TSentryStoreOp.DEL_GROUPS, fileLog.next().record.getStoreOp());
+ fileLog.close();
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestFileLoggingSentryStore.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestFileLoggingSentryStore.java
new file mode 100644
index 0000000..13f459e
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestFileLoggingSentryStore.java
@@ -0,0 +1,166 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import static junit.framework.Assert.assertEquals;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.provider.db.SentryInvalidInputException;
+import org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
+import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestFileLoggingSentryStore extends TestInMemSentryStore{
+
+ private String logDir;
+
+ @Override
+ public void setup() throws Exception {
+ super.setup();
+ logDir = Files.createTempDir().getAbsolutePath();
+ Configuration conf = new Configuration(false);
+ conf.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir);
+ sentryStore = new SentryStoreWithLocalLock(new SentryStoreWithFileLog(sentryStore));
+ }
+
+ @Test
+ public void testPersistence() throws Exception {
+ String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2";
+ String groupName1 = "list-privs-g1", groupName2 = "list-privs-g2";
+ String grantor = "g1";
+ long seqId = sentryStore.createSentryRole(roleName1).getSequenceId();
+ assertEquals(seqId + 1, sentryStore.createSentryRole(roleName2).getSequenceId());
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("TABLE");
+ privilege1.setServerName("server1");
+ privilege1.setDbName("db1");
+ privilege1.setTableName("tbl1");
+ privilege1.setAction("SELECT");
+ privilege1.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege1)
+ .getSequenceId());
+ assertEquals(seqId + 3, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege1)
+ .getSequenceId());
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("SERVER");
+ privilege2.setServerName("server1");
+ privilege2.setAction(AccessConstants.ALL);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 4, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege2)
+ .getSequenceId());
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName(groupName1);
+ groups.add(group);
+ assertEquals(seqId + 5, sentryStore.alterSentryRoleAddGroups(grantor,
+ roleName1, groups).getSequenceId());
+ groups.clear();
+ group = new TSentryGroup();
+ group.setGroupName(groupName2);
+ groups.add(group);
+ // group 2 has both roles 1 and 2
+ assertEquals(seqId + 6, sentryStore.alterSentryRoleAddGroups(grantor,
+ roleName1, groups).getSequenceId());
+ assertEquals(seqId + 7, sentryStore.alterSentryRoleAddGroups(grantor,
+ roleName2, groups).getSequenceId());
+ verifyStore(roleName1, roleName2, groupName1, groupName2);
+
+ // KILL The store and restart using same directory..
+ Configuration conf = new Configuration(false);
+ conf.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir);
+ sentryStore = new SentryStoreWithLocalLock(new SentryStoreWithFileLog(sentryStore));
+
+ verifyStore(roleName1, roleName2, groupName1, groupName2);
+ }
+
+ private void verifyStore(String roleName1, String roleName2,
+ String groupName1, String groupName2) throws SentryInvalidInputException {
+ // group1 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // one active role
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ // unknown active role
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+ // no active roles
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+
+ // group2 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // one active role
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ assertEquals(Sets.newHashSet(
+ "server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
+ // unknown active role
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+ // no active roles
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+
+ // both groups, all active roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // one active role
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ assertEquals(Sets.newHashSet(
+ "server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
+ // unknown active role
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+// // no active roles
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestInMemSentryStore.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestInMemSentryStore.java
new file mode 100644
index 0000000..e99b9fe
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestInMemSentryStore.java
@@ -0,0 +1,1250 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.provider.db.SentryAlreadyExistsException;
+import org.apache.sentry.provider.db.SentryGrantDeniedException;
+import org.apache.sentry.provider.db.SentryNoSuchObjectException;
+import org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
+import org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestInMemSentryStore {
+
+ private File dataDir;
+ private String[] adminGroups = {"adminGroup1"};
+ private PolicyFile policyFile;
+ private File policyFilePath;
+ protected SentryStore sentryStore;
+
+ @Before
+ public void setup() throws Exception {
+ dataDir = new File(Files.createTempDir(), "sentry_policy_db");
+ dataDir.mkdirs();
+ Configuration conf = new Configuration(false);
+ conf.setStrings(ServerConfig.ADMIN_GROUPS, adminGroups);
+ conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING,
+ ServerConfig.SENTRY_STORE_LOCAL_GROUP_MAPPING);
+ policyFilePath = new File(dataDir, "local_policy_file.ini");
+ conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING_RESOURCE,
+ policyFilePath.getPath());
+ policyFile = new PolicyFile();
+ sentryStore = new InMemSentryStore(conf);
+
+ String adminUser = "g1";
+ addGroupsToUser(adminUser, adminGroups);
+ writePolicyFile();
+ }
+
+ @After
+ public void teardown() {
+ if (dataDir != null) {
+ FileUtils.deleteQuietly(dataDir);
+ }
+ }
+
+ protected void addGroupsToUser(String user, String... groupNames) {
+ policyFile.addGroupsToUser(user, groupNames);
+ }
+
+ protected void writePolicyFile() throws Exception {
+ policyFile.write(policyFilePath);
+ }
+
+ @Test
+ public void testCaseInsensitiveRole() throws Exception {
+ String roleName = "newRole";
+ String grantor = "g1";
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName("test-groups-g1");
+ groups.add(group);
+
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName("server1");
+ privilege.setDbName("default");
+ privilege.setTableName("table1");
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups).getSequenceId());
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleDeleteGroups(roleName, groups).getSequenceId());
+ assertEquals(seqId + 3, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
+ assertEquals(seqId + 4, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege).getSequenceId());
+ }
+
+ @Test
+ public void testURI() throws Exception {
+ String roleName = "test-dup-role";
+ String grantor = "g1";
+ String uri = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv1.dat";
+ sentryStore.createSentryRole(roleName);
+ TSentryPrivilege tSentryPrivilege = new TSentryPrivilege("URI", "server1", "ALL");
+ tSentryPrivilege.setURI(uri);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, tSentryPrivilege);
+
+ TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
+ tSentryAuthorizable.setUri(uri);
+ tSentryAuthorizable.setServer("server1");
+
+ Set<TSentryPrivilege> privileges =
+ sentryStore.getTSentryPrivileges(new HashSet<String>(Arrays.asList(roleName)), tSentryAuthorizable);
+
+ assertTrue(privileges.size() == 1);
+
+ Set<TSentryGroup> tSentryGroups = new HashSet<TSentryGroup>();
+ tSentryGroups.add(new TSentryGroup("group1"));
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName, tSentryGroups);
+
+ TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(true, new HashSet<String>(Arrays.asList(roleName)));
+
+ Set<String> privs =
+ sentryStore.listSentryPrivilegesForProvider(new HashSet<String>(Arrays.asList("group1")), thriftRoleSet, tSentryAuthorizable);
+
+ assertTrue(privs.size()==1);
+ assertTrue(privs.contains("server=server1->uri=" + uri + "->action=all"));
+ }
+
+ @Test
+ public void testCreateDuplicateRole() throws Exception {
+ String roleName = "test-dup-role";
+ String grantor = "g1";
+ sentryStore.createSentryRole(roleName);
+ try {
+ sentryStore.createSentryRole(roleName);
+ fail("Expected SentryAlreadyExistsException");
+ } catch(SentryAlreadyExistsException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testCaseSensitiveScope() throws Exception {
+ String roleName = "role1";
+ String grantor = "g1";
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ TSentryPrivilege sentryPrivilege = new TSentryPrivilege("Database", "server1", "all");
+ sentryPrivilege.setDbName("db1");
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, sentryPrivilege).getSequenceId());
+ }
+
+ @Test
+ public void testCreateDropRole() throws Exception {
+ String roleName = "test-drop-role";
+ String grantor = "g1";
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ assertEquals(seqId + 1, sentryStore.dropSentryRole(roleName).getSequenceId());
+ }
+
+ @Test(expected = SentryNoSuchObjectException.class)
+ public void testAddDeleteGroupsNonExistantRole()
+ throws Exception {
+ String roleName = "non-existant-role";
+ String grantor = "g1";
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
+ }
+
+ @Test
+ public void testAddDeleteGroups() throws Exception {
+ String roleName = "test-groups";
+ String grantor = "g1";
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName("test-groups-g1");
+ groups.add(group);
+ group = new TSentryGroup();
+ group.setGroupName("test-groups-g2");
+ groups.add(group);
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleAddGroups(grantor,
+ roleName, groups).getSequenceId());
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleDeleteGroups(roleName, groups)
+ .getSequenceId());
+ assertEquals(Collections.emptySet(), sentryStore.getGroupsForRole(roleName));
+ }
+
+ @Test
+ public void testGrantRevokePrivilege() throws Exception {
+ String roleName = "test-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+ privilege.setAction(AccessConstants.SELECT);
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ // after having ALL and revoking SELECT, we should have INSERT
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+ TSentryPrivilege tPrivilege = Iterables.get(privileges, 0);
+ assertEquals(server, tPrivilege.getServerName());
+ assertEquals(db, tPrivilege.getDbName());
+ assertEquals(table, tPrivilege.getTableName());
+ assertEquals(AccessConstants.INSERT, tPrivilege.getAction());
+ assertEquals(TSentryGrantOption.FALSE, tPrivilege.getGrantOption());
+ }
+
+ @Test
+ public void testGrantRevokeMultiPrivileges() throws Exception {
+ String roleName = "test-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String[] columns = {"c1","c2","c3","c4"};
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ Set<TSentryPrivilege> tPrivileges = Sets.newHashSet();
+ for (String column : columns) {
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("Column");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setColumnName(column);
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ tPrivileges.add(privilege);
+ }
+ assertEquals(seqId + 4, sentryStore.alterSentryRoleGrantPrivileges(grantor, roleName, tPrivileges)
+ .getSequenceId());
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 4, privileges.size());
+
+ tPrivileges = Sets.newHashSet();
+ for (int i = 0; i < 2; i++) {
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("Column");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setColumnName(columns[i]);
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ tPrivileges.add(privilege);
+ }
+ assertEquals(seqId + 6, sentryStore.alterSentryRoleRevokePrivileges(grantor, roleName, tPrivileges)
+ .getSequenceId());
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("Table");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 7, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ // After revoking table scope, we will have 0 privileges
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 0, privileges.size());
+ }
+
+ /**
+ * Regression test for SENTRY-74 and SENTRY-552
+ */
+ @Test
+ public void testGrantRevokePrivilegeWithColumn() throws Exception {
+ String roleName = "test-col-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String column1 = "c1";
+ String column2 = "c2";
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("COLUMN");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setColumnName(column1);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+
+ // Grant ALL on c1 and c2
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ privilege.setColumnName(column2);
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ // Revoke SELECT on c2
+ privilege.setAction(AccessConstants.SELECT);
+ assertEquals(seqId + 3, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+
+ // At this point c1 has ALL privileges and c2 should have INSERT after revoking SELECT
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+ for (TSentryPrivilege mPrivilege: privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertEquals(table, mPrivilege.getTableName());
+ assertEquals(TSentryGrantOption.FALSE, mPrivilege.getGrantOption());
+ if (mPrivilege.getColumnName().equals(column1)) {
+ assertEquals(AccessConstants.ALL, mPrivilege.getAction());
+ } else if (mPrivilege.getColumnName().equals(column2)) {
+ assertEquals(AccessConstants.INSERT, mPrivilege.getAction());
+ } else {
+ fail("Unexpected column name: " + mPrivilege.getColumnName());
+ }
+ }
+
+ // after revoking INSERT table level privilege will remove privileges from column2
+ // and downgrade column1 to SELECT privileges.
+ privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.INSERT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 4, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+ assertEquals(column1, Iterables.get(privileges, 0).getColumnName());
+ assertEquals(AccessConstants.SELECT, Iterables.get(privileges, 0).getAction());
+
+ // Revoke ALL from the table should now remove all the column privileges.
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 5, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 0, privileges.size());
+ }
+
+ /**
+ * Regression test for SENTRY-552
+ */
+ @Test
+ public void testGrantRevokeTablePrivilegeDowngradeByDb() throws Exception {
+ String roleName = "test-table-db-downgrade-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table1 = "tbl1";
+ String table2 = "tbl2";
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ TSentryPrivilege privilegeTable1 = new TSentryPrivilege();
+ privilegeTable1.setPrivilegeScope("TABLE");
+ privilegeTable1.setServerName(server);
+ privilegeTable1.setDbName(db);
+ privilegeTable1.setTableName(table1);
+ privilegeTable1.setAction(AccessConstants.ALL);
+ privilegeTable1.setCreateTime(System.currentTimeMillis());
+ TSentryPrivilege privilegeTable2 = privilegeTable1.deepCopy();;
+ privilegeTable2.setTableName(table2);
+
+ // Grant ALL on table1 and table2
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeTable1)
+ .getSequenceId());
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeTable2)
+ .getSequenceId());
+ Set<TSentryPrivilege> privileges =
+ sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ // Revoke SELECT on table2
+ privilegeTable2.setAction(AccessConstants.SELECT);
+ assertEquals(seqId + 3, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeTable2)
+ .getSequenceId());
+ // after having ALL and revoking SELECT, we should have INSERT
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ // At this point table1 has ALL privileges and table2 should have INSERT after revoking SELECT
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+ for (TSentryPrivilege mPrivilege: privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertEquals(TSentryGrantOption.FALSE, mPrivilege.getGrantOption());
+ if (mPrivilege.getTableName().equals(table1)) {
+ assertEquals(AccessConstants.ALL, mPrivilege.getAction());
+ } else if (mPrivilege.getTableName().equals(table2)) {
+ assertEquals(AccessConstants.INSERT, mPrivilege.getAction());
+ } else {
+ fail("Unexpected table name: " + mPrivilege.getTableName());
+ }
+ }
+
+ // Revoke INSERT on Database
+ privilegeTable2.setAction(AccessConstants.INSERT);
+ privilegeTable2.setPrivilegeScope("DATABASE");
+ privilegeTable2.unsetTableName();
+ assertEquals(seqId + 4, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeTable2)
+ .getSequenceId());
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+
+ // after revoking INSERT database level privilege will remove privileges from table2
+ // and downgrade table1 to SELECT privileges.
+ assertEquals(privileges.toString(), 1, privileges.size());
+ TSentryPrivilege mPrivilege = Iterables.get(privileges, 0);
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertEquals(table1, mPrivilege.getTableName());
+ assertEquals(AccessConstants.SELECT, mPrivilege.getAction());
+ assertEquals(TSentryGrantOption.FALSE, mPrivilege.getGrantOption());
+ }
+
+ /**
+ * Regression test for SENTRY-552
+ */
+ @Test
+ public void testGrantRevokeColumnPrivilegeDowngradeByDb() throws Exception {
+ String roleName = "test-column-db-downgrade-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String column1 = "c1";
+ String column2 = "c2";
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ TSentryPrivilege privilegeCol1 = new TSentryPrivilege();
+ privilegeCol1.setPrivilegeScope("COLUMN");
+ privilegeCol1.setServerName(server);
+ privilegeCol1.setDbName(db);
+ privilegeCol1.setTableName(table);
+ privilegeCol1.setColumnName(column1);
+ privilegeCol1.setAction(AccessConstants.ALL);
+ privilegeCol1.setCreateTime(System.currentTimeMillis());
+ TSentryPrivilege privilegeCol2 = privilegeCol1.deepCopy();;
+ privilegeCol2.setColumnName(column2);
+
+ // Grant ALL on column1 and column2
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeCol1)
+ .getSequenceId());
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeCol2)
+ .getSequenceId());
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ // Revoke SELECT on column2
+ privilegeCol2.setAction(AccessConstants.SELECT);
+ assertEquals(seqId + 3, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeCol2)
+ .getSequenceId());
+ // after having ALL and revoking SELECT, we should have INSERT
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ // At this point column1 has ALL privileges and column2 should have INSERT after revoking SELECT
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 2, privileges.size());
+ for (TSentryPrivilege tPrivilege: privileges) {
+ assertEquals(server, tPrivilege.getServerName());
+ assertEquals(db, tPrivilege.getDbName());
+ assertEquals(table, tPrivilege.getTableName());
+ assertEquals(TSentryGrantOption.FALSE, tPrivilege.getGrantOption());
+ if (tPrivilege.getColumnName().equals(column1)) {
+ assertEquals(AccessConstants.ALL, tPrivilege.getAction());
+ } else if (tPrivilege.getColumnName().equals(column2)) {
+ assertEquals(AccessConstants.INSERT, tPrivilege.getAction());
+ } else {
+ fail("Unexpected column name: " + tPrivilege.getColumnName());
+ }
+ }
+
+ // Revoke INSERT on Database
+ privilegeCol2.setAction(AccessConstants.INSERT);
+ privilegeCol2.setPrivilegeScope("DATABASE");
+ privilegeCol2.unsetTableName();
+ privilegeCol2.unsetColumnName();
+ assertEquals(seqId + 4, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeCol2)
+ .getSequenceId());
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+
+ // after revoking INSERT database level privilege will remove privileges from column2
+ // and downgrade column1 to SELECT privileges.
+ assertEquals(privileges.toString(), 1, privileges.size());
+ TSentryPrivilege tPrivilege = Iterables.get(privileges, 0);
+ assertEquals(server, tPrivilege.getServerName());
+ assertEquals(db, tPrivilege.getDbName());
+ assertEquals(table, tPrivilege.getTableName());
+ assertEquals(column1, tPrivilege.getColumnName());
+ assertEquals(AccessConstants.SELECT, tPrivilege.getAction());
+ assertEquals(TSentryGrantOption.FALSE, tPrivilege.getGrantOption());
+ }
+
+ @Test
+ public void testGrantRevokePrivilegeWithGrantOption() throws Exception {
+ String roleName = "test-grantOption-table";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ TSentryGrantOption grantOption = TSentryGrantOption.TRUE;
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+ privilege.setGrantOption(grantOption);
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+ assertEquals(privilege.getGrantOption(), Iterables.get(privileges, 0).getGrantOption());
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(0, privileges.size());
+
+ roleName = "test-grantOption-db";
+ sentryStore.createSentryRole(roleName);
+ privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("DATABASE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setGrantOption(TSentryGrantOption.TRUE);
+ privilege.setCreateTime(System.currentTimeMillis());
+ privilege.setGrantOption(grantOption);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setGrantOption(TSentryGrantOption.UNSET);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ // after having ALL and revoking SELECT, we should have INSERT
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ Set<String> privActions = new HashSet<String>();
+ assertEquals(privileges.toString(), 5, privileges.size());
+ for (TSentryPrivilege p : privileges) {
+ privActions.add(p.getAction());
+ }
+ TSentryPrivilege tPrivilege = Iterables.get(privileges, 0);
+ assertEquals(server, tPrivilege.getServerName());
+ assertEquals(db, tPrivilege.getDbName());
+ assertFalse(privActions.contains(AccessConstants.SELECT));
+ }
+
+ @Test
+ public void testGrantCheckWithGrantOption() throws Exception {
+ // 1. set local group mapping
+ // user0->group0->role0
+ // user1->group1->role1
+ // user2->group2->role2
+ // user3->group3->role3
+ // user4->group4->role4
+ String grantor = "g1";
+ String[] users = {"user0","user1","user2","user3","user4"};
+ String[] roles = {"role0","role1","role2","role3","role4"};
+ String[] groups = {"group0","group1","group2","group3","group4"};
+ for (int i = 0; i < users.length; i++) {
+ addGroupsToUser(users[i], groups[i]);
+ sentryStore.createSentryRole(roles[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+ }
+ writePolicyFile();
+
+ // 2. g1 grant all on database db1 to role0 with grant option
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String roleName = roles[0];
+ grantor = "g1";
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("DATABASE");
+ privilege1.setServerName(server);
+ privilege1.setDbName(db);
+ privilege1.setAction(AccessConstants.ALL);
+ privilege1.setCreateTime(System.currentTimeMillis());
+ privilege1.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ // 3. user0 grant select on database db1 to role1, with grant option
+ roleName = roles[1];
+ grantor = users[0];
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("DATABASE");
+ privilege2.setServerName(server);
+ privilege2.setDbName(db);
+ privilege2.setAction(AccessConstants.SELECT);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ privilege2.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);
+
+ // 4. user0 grant all on table tb1 to role2, no grant option
+ roleName = roles[2];
+ grantor = users[0];
+ TSentryPrivilege privilege3 = new TSentryPrivilege();
+ privilege3.setPrivilegeScope("TABLE");
+ privilege3.setServerName(server);
+ privilege3.setDbName(db);
+ privilege3.setTableName(table);
+ privilege3.setAction(AccessConstants.ALL);
+ privilege3.setCreateTime(System.currentTimeMillis());
+ privilege3.setGrantOption(TSentryGrantOption.FALSE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege3);
+
+ // 5. user1 has role1, no insert privilege,
+ // grant insert to role3, will throw no grant exception
+ roleName = roles[3];
+ grantor = users[1];
+ TSentryPrivilege privilege4 = new TSentryPrivilege();
+ privilege4.setPrivilegeScope("DATABASE");
+ privilege4.setServerName(server);
+ privilege4.setDbName(db);
+ privilege4.setAction(AccessConstants.INSERT);
+ privilege4.setCreateTime(System.currentTimeMillis());
+ privilege4.setGrantOption(TSentryGrantOption.FALSE);
+ boolean isGrantOptionException = false;
+ try {
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege4);
+ } catch (SentryGrantDeniedException e) {
+ isGrantOptionException = true;
+ System.err.println(e.getMessage());
+ }
+ assertTrue(isGrantOptionException);
+
+ // 6. user2 has role2, no grant option,
+ // grant insert to role4, will throw no grant exception
+ roleName = roles[4];
+ grantor = users[2];
+ TSentryPrivilege privilege5 = new TSentryPrivilege();
+ privilege5.setPrivilegeScope("TABLE");
+ privilege5.setServerName(server);
+ privilege5.setDbName(db);
+ privilege5.setTableName(table);
+ privilege5.setAction(AccessConstants.INSERT);
+ privilege5.setCreateTime(System.currentTimeMillis());
+ privilege5.setGrantOption(TSentryGrantOption.FALSE);
+ isGrantOptionException = false;
+
+ // TODO : FIgure out why this fails !!
+ try {
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege5);
+ } catch (SentryGrantDeniedException e) {
+ isGrantOptionException = true;
+ System.err.println(e.getMessage());
+ }
+ assertTrue(isGrantOptionException);
+ }
+
+ @Test
+ public void testRevokeCheckWithGrantOption() throws Exception {
+ // 1. set local group mapping
+ // user0->group0->role0
+ // user1->group1->role1
+ // user2->group2->role2
+ String grantor = "g1";
+ String[] users = {"user0","user1","user2"};
+ String[] roles = {"role0","role1","role2"};
+ String[] groups = {"group0","group1","group2"};
+ for (int i = 0; i < users.length; i++) {
+ addGroupsToUser(users[i], groups[i]);
+ sentryStore.createSentryRole(roles[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+ }
+ writePolicyFile();
+
+ // 2. g1 grant select on database db1 to role0, with grant option
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String roleName = roles[0];
+ grantor = "g1";
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("DATABASE");
+ privilege1.setServerName(server);
+ privilege1.setDbName(db);
+ privilege1.setAction(AccessConstants.SELECT);
+ privilege1.setCreateTime(System.currentTimeMillis());
+ privilege1.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ // 3. g1 grant all on table tb1 to role1, no grant option
+ roleName = roles[1];
+ grantor = "g1";
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("TABLE");
+ privilege2.setServerName(server);
+ privilege2.setDbName(db);
+ privilege2.setTableName(table);
+ privilege2.setAction(AccessConstants.ALL);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ privilege2.setGrantOption(TSentryGrantOption.FALSE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);
+
+ // 4. g1 grant select on table tb1 to role2, no grant option
+ roleName = roles[2];
+ grantor = "g1";
+ TSentryPrivilege privilege3 = new TSentryPrivilege();
+ privilege3.setPrivilegeScope("TABLE");
+ privilege3.setServerName(server);
+ privilege3.setDbName(db);
+ privilege3.setTableName(table);
+ privilege3.setAction(AccessConstants.SELECT);
+ privilege3.setCreateTime(System.currentTimeMillis());
+ privilege3.setGrantOption(TSentryGrantOption.FALSE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege3);
+
+ // 5. user1 has role1, no grant option,
+ // revoke from role2 will throw no grant exception
+ roleName = roles[2];
+ grantor = users[1];
+ boolean isGrantOptionException = false;
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege3);
+ } catch (SentryGrantDeniedException e) {
+ isGrantOptionException = true;
+ System.err.println(e.getMessage());
+ }
+ assertTrue(isGrantOptionException);
+
+ // 6. user0 has role0, only have select,
+ // revoke all from role1 will throw no grant exception
+ roleName = roles[1];
+ grantor = users[0];
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege2);
+ } catch (SentryGrantDeniedException e) {
+ isGrantOptionException = true;
+ System.err.println(e.getMessage());
+ }
+ assertTrue(isGrantOptionException);
+
+ // 7. user0 has role0, has select and grant option,
+ // revoke select from role2
+ roleName = roles[2];
+ grantor = users[0];
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege3);
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(0, privileges.size());
+ }
+
+ @Test
+ public void testRevokeAllGrantOption() throws Exception {
+ // 1. set local group mapping
+ // user0->group0->role0
+ String grantor = "g1";
+ String[] users = {"user0"};
+ String[] roles = {"role0"};
+ String[] groups = {"group0"};
+ for (int i = 0; i < users.length; i++) {
+ addGroupsToUser(users[i], groups[i]);
+ sentryStore.createSentryRole(roles[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+ }
+ writePolicyFile();
+
+ // 2. g1 grant select on table tb1 to role0, with grant option
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String roleName = roles[0];
+ grantor = "g1";
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ privilege.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+
+ // 3. g1 grant select on table tb1 to role0, no grant option
+ roleName = roles[0];
+ grantor = "g1";
+ privilege.setGrantOption(TSentryGrantOption.FALSE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+
+ // 4. g1 revoke all privilege from role0
+ roleName = roles[0];
+ grantor = "g1";
+ privilege.setGrantOption(TSentryGrantOption.UNSET);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 0, privileges.size());
+ }
+
+ @Test
+ public void testGrantCheckWithColumn() throws Exception {
+ // 1. set local group mapping
+ // user0->group0->role0
+ // user1->group1->role1
+ String grantor = "g1";
+ String[] users = {"user0","user1"};
+ String[] roles = {"role0","role1"};
+ String[] groups = {"group0","group1"};
+ for (int i = 0; i < users.length; i++) {
+ addGroupsToUser(users[i], groups[i]);
+ sentryStore.createSentryRole(roles[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+ }
+ writePolicyFile();
+
+ // 2. g1 grant select on table tb1 to role0, with grant option
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String roleName = roles[0];
+ grantor = "g1";
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("TABLE");
+ privilege1.setServerName(server);
+ privilege1.setDbName(db);
+ privilege1.setTableName(table);
+ privilege1.setAction(AccessConstants.SELECT);
+ privilege1.setCreateTime(System.currentTimeMillis());
+ privilege1.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ // 3. user0 grant select on column tb1.c1 to role1, with grant option
+ roleName = roles[1];
+ grantor = users[0];
+ String column = "c1";
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("COLUMN");
+ privilege2.setServerName(server);
+ privilege2.setDbName(db);
+ privilege2.setTableName(table);
+ privilege2.setColumnName(column);
+ privilege2.setAction(AccessConstants.SELECT);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ privilege2.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);
+
+ // 4. user1 revoke table level privilege from user0, will throw grant denied exception
+ roleName = roles[0];
+ grantor = users[1];
+ boolean isGrantOptionException = false;
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege1);
+ } catch (SentryGrantDeniedException e) {
+ isGrantOptionException = true;
+ System.err.println(e.getMessage());
+ }
+ assertTrue(isGrantOptionException);
+
+ // 5. user0 revoke column level privilege from user1
+ roleName = roles[1];
+ grantor = users[0];
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege2);
+ privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(0, privileges.size());
+ }
+
+ @Test
+ public void testGrantDuplicatePrivilege() throws Exception {
+ String roleName = "test-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 1, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ privilege.setServerName("Server1");
+ privilege.setDbName("DB1");
+ privilege.setTableName("TBL1");
+ assertEquals(seqId + 3, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege)
+ .getSequenceId());
+ Set<TSentryPrivilege> privileges = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(privileges.toString(), 1, privileges.size());
+ }
+
+ @Test
+ public void testListSentryPrivilegesForProvider() throws Exception {
+ String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2";
+ String groupName1 = "list-privs-g1", groupName2 = "list-privs-g2";
+ String grantor = "g1";
+ long seqId = sentryStore.createSentryRole(roleName1).getSequenceId();
+ assertEquals(seqId + 1, sentryStore.createSentryRole(roleName2).getSequenceId());
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("TABLE");
+ privilege1.setServerName("server1");
+ privilege1.setDbName("db1");
+ privilege1.setTableName("tbl1");
+ privilege1.setAction("SELECT");
+ privilege1.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 2, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege1)
+ .getSequenceId());
+ assertEquals(seqId + 3, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege1)
+ .getSequenceId());
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("SERVER");
+ privilege2.setServerName("server1");
+ privilege2.setAction(AccessConstants.ALL);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ assertEquals(seqId + 4, sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege2)
+ .getSequenceId());
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName(groupName1);
+ groups.add(group);
+ assertEquals(seqId + 5, sentryStore.alterSentryRoleAddGroups(grantor,
+ roleName1, groups).getSequenceId());
+ groups.clear();
+ group = new TSentryGroup();
+ group.setGroupName(groupName2);
+ groups.add(group);
+ // group 2 has both roles 1 and 2
+ assertEquals(seqId + 6, sentryStore.alterSentryRoleAddGroups(grantor,
+ roleName1, groups).getSequenceId());
+ assertEquals(seqId + 7, sentryStore.alterSentryRoleAddGroups(grantor,
+ roleName2, groups).getSequenceId());
+ // group1 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // one active role
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ // unknown active role
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+ // no active roles
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+
+ // group2 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // one active role
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ assertEquals(Sets.newHashSet(
+ "server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
+ // unknown active role
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+ // no active roles
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+
+ // both groups, all active roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // one active role
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ assertEquals(Sets.newHashSet(
+ "server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
+ // unknown active role
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+// // no active roles
+ assertEquals(Sets.newHashSet(),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ newHashSet(groupName1, groupName2),
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+ }
+
+ @Test
+ public void testListRole() throws Exception {
+ String roleName1 = "role1", roleName2 = "role2", roleName3 = "role3";
+ String group1 = "group1", group2 = "group2";
+ String grantor = "g1";
+
+ sentryStore.createSentryRole(roleName1);
+ sentryStore.createSentryRole(roleName2);
+ sentryStore.createSentryRole(roleName3);
+
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName1, Sets.newHashSet(new TSentryGroup(group1)));
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName2, Sets.newHashSet(new TSentryGroup(group2)));
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName3,
+ Sets.newHashSet(new TSentryGroup(group1), new TSentryGroup(group2)));
+
+ assertEquals(2, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group1), false).size());
+ assertEquals(2, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group2), false).size());
+ assertEquals(3, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group1,group2), false).size());
+// assertEquals(0,
+// sentryStore.getTSentryRolesByGroupName(Sets.newHashSet("foo"), true)
+// .size());
+ }
+
+ /***
+ * Create roles and assign privileges for same table rename the privileges for
+ * the table and verify the new privileges
+ * @throws Exception
+ */
+ @Test
+ public void testRenameTable() throws Exception {
+ String roleName1 = "role1", roleName2 = "role2", roleName3 = "role3";
+ String grantor = "g1";
+ String table1 = "tbl1", table2 = "tbl2";
+
+ sentryStore.createSentryRole(roleName1);
+ sentryStore.createSentryRole(roleName2);
+ sentryStore.createSentryRole(roleName3);
+
+ TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
+ privilege_tbl1.setPrivilegeScope("TABLE");
+ privilege_tbl1.setServerName("server1");
+ privilege_tbl1.setDbName("db1");
+ privilege_tbl1.setTableName(table1);
+ privilege_tbl1.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl1_insert = new TSentryPrivilege(
+ privilege_tbl1);
+ privilege_tbl1_insert.setAction(AccessConstants.INSERT);
+
+ TSentryPrivilege privilege_tbl1_select = new TSentryPrivilege(
+ privilege_tbl1);
+ privilege_tbl1_select.setAction(AccessConstants.SELECT);
+
+ TSentryPrivilege privilege_tbl1_all = new TSentryPrivilege(privilege_tbl1);
+ privilege_tbl1_all.setAction(AccessConstants.ALL);
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_insert);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege_tbl1_select);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName3, privilege_tbl1_all);
+
+ TSentryAuthorizable oldTable = toTSentryAuthorizable(privilege_tbl1);
+ TSentryAuthorizable newTable = toTSentryAuthorizable(privilege_tbl1);
+ newTable.setTable(table2);
+ sentryStore.renamePrivilege(oldTable, newTable);
+
+ for (String roleName : Sets.newHashSet(roleName1, roleName2, roleName3)) {
+ Set<TSentryPrivilege> privilegeSet = sentryStore
+ .getAllTSentryPrivilegesByRoleName(roleName);
+ assertEquals(1, privilegeSet.size());
+ for (TSentryPrivilege privilege : privilegeSet) {
+ assertTrue(table2.equalsIgnoreCase(privilege.getTableName()));
+ }
+ }
+ }
+
+ @Test
+ public void testSentryRoleSize() throws Exception {
+ for( long i = 0; i< 5; i++ ) {
+ assertEquals(i, sentryStore.getRoleCount());
+ sentryStore.createSentryRole("role" + i);
+ }
+ }
+
+ @Test
+ public void testSentryPrivilegeSize() throws Exception {
+ String role1 = "role1";
+ String role2 = "role2";
+
+ sentryStore.createSentryRole(role1);
+ sentryStore.createSentryRole(role2);
+
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName("server1");
+ privilege.setDbName("db1");
+ privilege.setTableName("tb1");
+ privilege.setCreateTime(System.currentTimeMillis());
+
+ String grantor = "g1";
+
+ assertEquals(0, sentryStore.getPrivilegeCount());
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, role1, privilege);
+ assertEquals(1, sentryStore.getPrivilegeCount());
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, role2, privilege);
+ // TODO : figure out why the discrepency
+ assertEquals(2, sentryStore.getPrivilegeCount());
+
+ privilege.setTableName("tb2");
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, role2, privilege);
+ assertEquals(3, sentryStore.getPrivilegeCount());
+ }
+
+ @Test
+ public void testSentryGroupsSize() throws Exception {
+ String role1 = "role1";
+ String role2 = "role2";
+
+ sentryStore.createSentryRole(role1);
+ sentryStore.createSentryRole(role2);
+
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName("group1");
+ groups.add(group);
+
+ String grantor = "g1";
+
+ sentryStore.alterSentryRoleAddGroups(grantor, role1, groups);
+ assertEquals(1, sentryStore.getGroupCount());
+
+ sentryStore.alterSentryRoleAddGroups(grantor, role2, groups);
+ assertEquals(1, sentryStore.getGroupCount());
+
+ groups.add(new TSentryGroup("group2"));
+ sentryStore.alterSentryRoleAddGroups(grantor, role2, groups);
+ assertEquals(2, sentryStore.getGroupCount());
+ }
+
+ @Test
+ public void testRenameTableWithColumn() throws Exception {
+ String roleName1 = "role1", roleName2 = "role2";
+ String grantor = "g1";
+ String table1 = "tbl1", table2 = "tbl2";
+
+ sentryStore.createSentryRole(roleName1);
+ sentryStore.createSentryRole(roleName2);
+
+ TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
+ privilege_tbl1.setPrivilegeScope("TABLE");
+ privilege_tbl1.setServerName("server1");
+ privilege_tbl1.setDbName("db1");
+ privilege_tbl1.setTableName(table1);
+ privilege_tbl1.setAction(AccessConstants.SELECT);
+ privilege_tbl1.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl1_c1 = new TSentryPrivilege(privilege_tbl1);
+ privilege_tbl1_c1.setPrivilegeScope("COLUMN");
+ privilege_tbl1_c1.setColumnName("c1");
+ privilege_tbl1_c1.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl1_c2 = new TSentryPrivilege(privilege_tbl1);
+ privilege_tbl1_c2.setPrivilegeScope("COLUMN");
+ privilege_tbl1_c2.setColumnName("c2");
+ privilege_tbl1_c2.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl1_c3 = new TSentryPrivilege(privilege_tbl1);
+ privilege_tbl1_c3.setPrivilegeScope("COLUMN");
+ privilege_tbl1_c3.setColumnName("c3");
+ privilege_tbl1_c3.setCreateTime(System.currentTimeMillis());
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_c1);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_c2);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege_tbl1_c3);
+
+ Set<TSentryPrivilege> privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName1);
+ assertEquals(2, privilegeSet.size());
+ privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName2);
+ assertEquals(1, privilegeSet.size());
+
+ TSentryAuthorizable oldTable = toTSentryAuthorizable(privilege_tbl1);
+ TSentryAuthorizable newTable = toTSentryAuthorizable(privilege_tbl1);
+ newTable.setTable(table2);
+ sentryStore.renamePrivilege(oldTable, newTable);
+
+ privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName1);
+ assertEquals(2, privilegeSet.size());
+ for (TSentryPrivilege privilege : privilegeSet) {
+ assertTrue(table2.equalsIgnoreCase(privilege.getTableName()));
+ }
+ privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName2);
+ assertEquals(1, privilegeSet.size());
+ }
+
+ private TSentryAuthorizable toTSentryAuthorizable(
+ TSentryPrivilege tSentryPrivilege) {
+ TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
+ tSentryAuthorizable.setServer(tSentryPrivilege.getServerName());
+ tSentryAuthorizable.setDb(tSentryPrivilege.getDbName());
+ tSentryAuthorizable.setTable(tSentryPrivilege.getTableName());
+ tSentryAuthorizable.setUri(tSentryPrivilege.getURI());
+ return tSentryAuthorizable;
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
index 8fbe3f4..73b4b7b 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
@@ -56,7 +56,7 @@
public class TestSentryStore {
private File dataDir;
- private SentryStore sentryStore;
+ private DbSentryStore sentryStore;
private String[] adminGroups = {"adminGroup1"};
private PolicyFile policyFile;
private File policyFilePath;
@@ -76,7 +76,7 @@
conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING_RESOURCE,
policyFilePath.getPath());
policyFile = new PolicyFile();
- sentryStore = new SentryStore(conf);
+ sentryStore = new DbSentryStore(conf);
String adminUser = "g1";
addGroupsToUser(adminUser, adminGroups);
@@ -1102,65 +1102,65 @@
roleName2, groups).getSequenceId());
// group1 all roles
assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
new TSentryActiveRoleSet(true, new HashSet<String>()))));
// one active role
assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
// unknown active role
assertEquals(Sets.newHashSet(),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
// no active roles
assertEquals(Sets.newHashSet(),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
new TSentryActiveRoleSet(false, new HashSet<String>()))));
// group2 all roles
assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
new TSentryActiveRoleSet(true, new HashSet<String>()))));
// one active role
assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
assertEquals(Sets.newHashSet(
"server=server1->db=db1->table=tbl1->action=select", "server=server1"),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
// unknown active role
assertEquals(Sets.newHashSet(),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
// no active roles
assertEquals(Sets.newHashSet(),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
new TSentryActiveRoleSet(false, new HashSet<String>()))));
// both groups, all active roles
assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
newHashSet(groupName1, groupName2),
new TSentryActiveRoleSet(true, new HashSet<String>()))));
// one active role
assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
newHashSet(groupName1, groupName2),
new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
assertEquals(Sets.newHashSet(
"server=server1->db=db1->table=tbl1->action=select", "server=server1"),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
newHashSet(groupName1, groupName2),
new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
// unknown active role
assertEquals(Sets.newHashSet(),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
newHashSet(groupName1, groupName2),
new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
// no active roles
assertEquals(Sets.newHashSet(),
- SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
+ StoreUtils.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.
newHashSet(groupName1, groupName2),
new TSentryActiveRoleSet(false, new HashSet<String>()))));
}
@@ -1515,7 +1515,7 @@
@Test
public void testSentryRoleSize() throws Exception {
for( long i = 0; i< 5; i++ ) {
- assertEquals((Long)i, sentryStore.getRoleCountGauge().getValue());
+ assertEquals(i, sentryStore.getRoleCount());
sentryStore.createSentryRole("role" + i);
}
}
@@ -1536,17 +1536,17 @@
String grantor = "g1";
- assertEquals(new Long(0), sentryStore.getPrivilegeCountGauge().getValue());
+ assertEquals(0, sentryStore.getPrivilegeCount());
sentryStore.alterSentryRoleGrantPrivilege(grantor, role1, privilege);
- assertEquals(new Long(1), sentryStore.getPrivilegeCountGauge().getValue());
+ assertEquals(1, sentryStore.getPrivilegeCount());
sentryStore.alterSentryRoleGrantPrivilege(grantor, role2, privilege);
- assertEquals(new Long(1), sentryStore.getPrivilegeCountGauge().getValue());
+ assertEquals(1, sentryStore.getPrivilegeCount());
privilege.setTableName("tb2");
sentryStore.alterSentryRoleGrantPrivilege(grantor, role2, privilege);
- assertEquals(new Long(2), sentryStore.getPrivilegeCountGauge().getValue());
+ assertEquals(2, sentryStore.getPrivilegeCount());
}
@Test
@@ -1565,14 +1565,14 @@
String grantor = "g1";
sentryStore.alterSentryRoleAddGroups(grantor, role1, groups);
- assertEquals(new Long(1), sentryStore.getGroupCountGauge().getValue());
+ assertEquals(1, sentryStore.getGroupCount());
sentryStore.alterSentryRoleAddGroups(grantor, role2, groups);
- assertEquals(new Long(1), sentryStore.getGroupCountGauge().getValue());
+ assertEquals(1, sentryStore.getGroupCount());
groups.add(new TSentryGroup("group2"));
sentryStore.alterSentryRoleAddGroups(grantor, role2, groups);
- assertEquals(new Long(2), sentryStore.getGroupCountGauge().getValue());
+ assertEquals(2, sentryStore.getGroupCount());
}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java
index 922cbc2..2e6f190 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java
@@ -32,55 +32,55 @@
public void testServer() {
privilege = new MSentryPrivilege(null, null, "server1", null, null, null, null, null);
assertEquals("server=server1",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
privilege = new MSentryPrivilege(null, null, "server1", null, null, null, null,
AccessConstants.ALL);
assertEquals("server=server1",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
}
@Test
public void testTable() {
privilege = new MSentryPrivilege(null, null, "server1", "db1", "tbl1", null, null, null);
assertEquals("server=server1->db=db1->table=tbl1",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
privilege = new MSentryPrivilege(null, null, "server1", "db1", "tbl1", null, null,
AccessConstants.INSERT);
assertEquals("server=server1->db=db1->table=tbl1->action=insert",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
privilege = new MSentryPrivilege(null, null, "server1", "db1", "tbl1", null, null,
AccessConstants.SELECT);
assertEquals("server=server1->db=db1->table=tbl1->action=select",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
privilege = new MSentryPrivilege(null, null, "server1", "db1", "tbl1", null, null,
AccessConstants.ALL);
assertEquals("server=server1->db=db1->table=tbl1",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
}
@Test
public void testDb() {
privilege = new MSentryPrivilege(null, null, "server1", "db1", null, null, null, null);
assertEquals("server=server1->db=db1",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
privilege = new MSentryPrivilege(null, null, "server1", "db1", null, null, null,
AccessConstants.ALL);
assertEquals("server=server1->db=db1",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
}
@Test
public void testUri() {
privilege = new MSentryPrivilege(null, null, "server1", null, null, null, "file:///", null);
assertEquals("server=server1->uri=file:///",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
privilege = new MSentryPrivilege(null, null, "server1", null, null, null, "file:///",
AccessConstants.SELECT);
assertEquals("server=server1->uri=file:///->action=select",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
privilege = new MSentryPrivilege(null, null, "server1", null, null, null, "file:///",
AccessConstants.ALL);
assertEquals("server=server1->uri=file:///",
- SentryStore.toAuthorizable(privilege));
+ StoreUtils.toAuthorizable(privilege));
}
}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreWithFileLog.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreWithFileLog.java
new file mode 100644
index 0000000..08d212b
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreWithFileLog.java
@@ -0,0 +1,156 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.io.File;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.provider.db.service.persistent.FileLog.Entry;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreOp;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Files;
+
+public class TestSentryStoreWithFileLog {
+
+ private String logDir;
+
+ @Before
+ public void setup() {
+ logDir = Files.createTempDir().getAbsolutePath();
+ System.out.println("Creating dir : [" + logDir + "]");
+ }
+
+ @After
+ public void tearDown() {
+ File l = new File(logDir);
+ for (File f : l.listFiles()) {
+ f.delete();
+ }
+ l.delete();
+ }
+
+ @Test
+ public void testBasicStoreOperations() throws Exception {
+ Configuration conf = new Configuration(false);
+ conf.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir);
+ SentryStoreWithFileLog store = new SentryStoreWithFileLog(new InMemSentryStore(conf));
+ store.createSentryRole("role1");
+ store.createSentryRole("role2");
+ store.createSentryRole("role3");
+ store.stop();
+
+ FileLog fileLog = new FileLog(conf);
+ Assert.assertTrue(fileLog.hasNext());
+ Entry next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role1", next.record.getRoleName());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role2", next.record.getRoleName());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role3", next.record.getRoleName());
+ Assert.assertFalse(fileLog.hasNext());
+ fileLog.close();
+
+ store = new SentryStoreWithFileLog(new InMemSentryStore(conf));
+ Assert.assertEquals(3, store.getRoleCount());
+ store.dropSentryRole("role3");
+ store.dropSentryRole("role2");
+ store.dropSentryRole("role1");
+ store.stop();
+
+ fileLog = new FileLog(conf);
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.DROP_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role3", next.record.getRoleName());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.DROP_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role2", next.record.getRoleName());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.DROP_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role1", next.record.getRoleName());
+ Assert.assertFalse(fileLog.hasNext());
+ fileLog.close();
+
+ store = new SentryStoreWithFileLog(new InMemSentryStore(conf));
+ Assert.assertEquals(0, store.getRoleCount());
+ store.stop();
+ }
+
+ @Test
+ public void testLogSnapshotting() throws Exception {
+ Configuration conf = new Configuration(false);
+ conf.setInt(SentryStoreWithFileLog.SENTRY_STORE_FILE_LOG_SNAPSHOT_THRESHOLD, 2);
+ conf.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir);
+ SentryStoreWithFileLog store = new SentryStoreWithFileLog(new InMemSentryStore(conf));
+ store.createSentryRole("role1");
+ store.createSentryRole("role2");
+ store.createSentryRole("role3");
+ store.createSentryRole("role4");
+ store.createSentryRole("role5");
+ store.stop();
+
+ FileLog fileLog = new FileLog(conf);
+ Assert.assertTrue(fileLog.hasNext());
+ Entry next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.SNAPSHOT, next.record.getStoreOp());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertFalse(fileLog.hasNext());
+ fileLog.close();
+
+ store = new SentryStoreWithFileLog(new InMemSentryStore(conf));
+ Assert.assertEquals(5, store.getRoleCount());
+ store.dropSentryRole("role3");
+ store.dropSentryRole("role2");
+ store.dropSentryRole("role1");
+ store.stop();
+
+ fileLog = new FileLog(conf);
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.SNAPSHOT, next.record.getStoreOp());
+ Assert.assertFalse(fileLog.hasNext());
+ fileLog.close();
+
+ store = new SentryStoreWithFileLog(new InMemSentryStore(conf));
+ Assert.assertEquals(2, store.getRoleCount());
+ store.stop();
+ }
+}
\ No newline at end of file
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreWithReplicatedLog.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreWithReplicatedLog.java
new file mode 100644
index 0000000..04b5906
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreWithReplicatedLog.java
@@ -0,0 +1,187 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.io.File;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.provider.db.service.persistent.FileLog.Entry;
+import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryStoreOp;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+import com.hazelcast.core.HazelcastInstance;
+
+public class TestSentryStoreWithReplicatedLog {
+
+ private String logDir1;
+ private String logDir2;
+ private String logDir3;
+
+ @Before
+ public void setup() {
+ logDir1 = Files.createTempDir().getAbsolutePath();
+ System.out.println("Creating dir1 : [" + logDir1 + "]");
+ logDir2 = Files.createTempDir().getAbsolutePath();
+ System.out.println("Creating dir2 : [" + logDir2 + "]");
+ logDir3 = Files.createTempDir().getAbsolutePath();
+ System.out.println("Creating dir3 : [" + logDir2 + "]");
+ }
+
+ @After
+ public void tearDown() {
+ for (String s : new String[]{logDir1, logDir2, logDir3}) {
+ File l = new File(s);
+ for (File f : l.listFiles()) {
+ f.delete();
+ }
+ l.delete();
+ }
+ }
+
+ @Test
+ public void testSimpleCase() throws Exception {
+ Configuration conf1 = new Configuration(false);
+ conf1.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir1);
+ HazelcastInstance hInst1 = DistributedUtils.getHazelcastInstance(conf1, true);
+ SentryStoreWithReplicatedLog store1 = new SentryStoreWithReplicatedLog(new InMemSentryStore(conf1), hInst1);
+
+ Configuration conf2 = new Configuration(false);
+ conf2.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir2);
+ HazelcastInstance hInst2 = DistributedUtils.getHazelcastInstance(conf2, true);
+ SentryStoreWithReplicatedLog store2 = new SentryStoreWithReplicatedLog(new InMemSentryStore(conf2), hInst2);
+
+ store1.createSentryRole("role1");
+ store1.alterSentryRoleAddGroups("admin", "role1",
+ Sets.newHashSet(
+ new TSentryGroup("group1"),
+ new TSentryGroup("group2")));
+ store1.alterSentryRoleDeleteGroups("role1",
+ Sets.newHashSet(new TSentryGroup("group2")));
+
+ store2.waitForReplicattionToComplete(2000);
+ FileLog fileLog = new FileLog(conf2);
+ Assert.assertTrue(fileLog.hasNext());
+ Entry next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role1", next.record.getRoleName());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.ADD_GROUPS, next.record.getStoreOp());
+ Assert.assertEquals("role1", next.record.getRoleName());
+ Assert.assertEquals(Sets.newHashSet("group1", "group2"), next.record.getGroups());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.DEL_GROUPS, next.record.getStoreOp());
+ Assert.assertEquals("role1", next.record.getRoleName());
+ Assert.assertEquals(Sets.newHashSet("group2"), next.record.getGroups());
+ Assert.assertFalse(fileLog.hasNext());
+ fileLog.close();
+
+ Assert.assertEquals(1, store2.getRoleCount());
+ Assert.assertEquals(Sets.newHashSet("group1"), store2.getGroupsForRole("role1"));
+ hInst1.shutdown();
+ hInst2.shutdown();
+ }
+
+ @Test
+ public void testSecondNodeAfterAWhile() throws Exception {
+ Configuration conf1 = new Configuration(false);
+ conf1.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir1);
+ HazelcastInstance hInst1 = DistributedUtils.getHazelcastInstance(conf1, true);
+ SentryStoreWithReplicatedLog store1 = new SentryStoreWithReplicatedLog(new InMemSentryStore(conf1), hInst1);
+ store1.createSentryRole("role1");
+ store1.createSentryRole("role2");
+ store1.createSentryRole("role3");
+
+ FileLog fileLog = new FileLog(conf1);
+ Assert.assertTrue(fileLog.hasNext());
+ Entry next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role1", next.record.getRoleName());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role2", next.record.getRoleName());
+ Assert.assertTrue(fileLog.hasNext());
+ next = fileLog.next();
+ Assert.assertEquals(TSentryStoreOp.CREATE_ROLE, next.record.getStoreOp());
+ Assert.assertEquals("role3", next.record.getRoleName());
+ Assert.assertFalse(fileLog.hasNext());
+ fileLog.close();
+
+ Configuration conf2 = new Configuration(false);
+ conf2.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir2);
+ HazelcastInstance hInst2 = DistributedUtils.getHazelcastInstance(conf2, true);
+ SentryStoreWithReplicatedLog store2 = new SentryStoreWithReplicatedLog(new InMemSentryStore(conf2), hInst2);
+ Assert.assertEquals(3, store2.getRoleCount());
+ hInst1.shutdown();
+ hInst2.shutdown();
+ }
+
+ @Test
+ public void testThreeNodes() throws Exception {
+ Configuration conf1 = new Configuration(false);
+ conf1.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir1);
+ HazelcastInstance hInst1 = DistributedUtils.getHazelcastInstance(conf1, true);
+ SentryStoreWithReplicatedLog store1 = new SentryStoreWithReplicatedLog(new InMemSentryStore(conf1), hInst1);
+
+ Configuration conf2 = new Configuration(false);
+ conf2.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir2);
+ HazelcastInstance hInst2 = DistributedUtils.getHazelcastInstance(conf2, true);
+ SentryStoreWithReplicatedLog store2 = new SentryStoreWithReplicatedLog(new InMemSentryStore(conf2), hInst2);
+
+ store1.createSentryRole("role1");
+ store1.alterSentryRoleAddGroups("admin", "role1",
+ Sets.newHashSet(
+ new TSentryGroup("group1"),
+ new TSentryGroup("group2")));
+ store1.alterSentryRoleDeleteGroups("role1",
+ Sets.newHashSet(new TSentryGroup("group2")));
+
+ Configuration conf3 = new Configuration(false);
+ conf3.set(FileLog.SENTRY_FILE_LOG_STORE_LOCATION, logDir3);
+ HazelcastInstance hInst3 = DistributedUtils.getHazelcastInstance(conf3, true);
+ SentryStoreWithReplicatedLog store3 = new SentryStoreWithReplicatedLog(new InMemSentryStore(conf3), hInst3);
+
+ store1.createSentryRole("role2");
+ store1.alterSentryRoleAddGroups("admin", "role2",
+ Sets.newHashSet(new TSentryGroup("group3")));
+
+ Thread.sleep(2000);
+ Assert.assertEquals(2, store1.getRoleCount());
+ Assert.assertEquals(Sets.newHashSet("group1"), store1.getGroupsForRole("role1"));
+ Assert.assertEquals(Sets.newHashSet("group3"), store1.getGroupsForRole("role2"));
+ Assert.assertEquals(2, store2.getRoleCount());
+ Assert.assertEquals(Sets.newHashSet("group1"), store2.getGroupsForRole("role1"));
+ Assert.assertEquals(Sets.newHashSet("group3"), store2.getGroupsForRole("role2"));
+ Assert.assertEquals(2, store3.getRoleCount());
+ Assert.assertEquals(Sets.newHashSet("group1"), store3.getGroupsForRole("role1"));
+ Assert.assertEquals(Sets.newHashSet("group3"), store3.getGroupsForRole("role2"));
+ hInst1.shutdown();
+ hInst2.shutdown();
+ hInst3.shutdown();
+ }
+}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryVersion.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryVersion.java
index 0add58b..2428688 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryVersion.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryVersion.java
@@ -52,10 +52,10 @@
@Test
public void testVerifySentryVersionCheck() throws Exception {
conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false");
- SentryStore sentryStore = new SentryStore(conf);
+ DbSentryStore sentryStore = new DbSentryStore(conf);
sentryStore.stop();
conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "true");
- sentryStore = new SentryStore(conf);
+ sentryStore = new DbSentryStore(conf);
}
/**
@@ -65,7 +65,7 @@
*/
@Test(expected = SentryNoSuchObjectException.class)
public void testNegSentrySchemaDefault() throws Exception {
- SentryStore sentryStore = new SentryStore(conf);
+ DbSentryStore sentryStore = new DbSentryStore(conf);
}
/**
@@ -76,7 +76,7 @@
@Test
public void testSentryImplicitVersion() throws Exception {
conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false");
- SentryStore sentryStore = new SentryStore(conf);
+ DbSentryStore sentryStore = new DbSentryStore(conf);
assertEquals(SentryStoreSchemaInfo.getSentryVersion(),
sentryStore.getSentryVersion());
}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestStoreSnapshot.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestStoreSnapshot.java
new file mode 100644
index 0000000..71f2de1
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestStoreSnapshot.java
@@ -0,0 +1,95 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.service.thrift.TStoreSnapshot;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+
+public class TestStoreSnapshot {
+
+ static class DummyGroupMapper extends InMemSentryStore.GroupMapper {
+
+ DummyGroupMapper(Configuration conf) {
+ super(conf);
+ }
+
+ @Override
+ protected Set<String> getGroupsForUser(String user)
+ throws SentryUserException {
+ return Sets.newHashSet("admin");
+ }
+
+ @Override
+ protected Set<String> getAdminGroups() {
+ return Sets.newHashSet("admin");
+ }
+
+ @Override
+ protected boolean isInAdminGroup(Set<String> groups)
+ throws SentryUserException {
+ return true;
+ }
+
+ }
+ @Test
+ public void testSnapshot() throws Exception {
+ Configuration conf = new Configuration(false);
+ InMemSentryStore store1 = new InMemSentryStore(conf, new DummyGroupMapper(conf));
+ store1.createSentryRole("role1");
+ store1.alterSentryRoleAddGroups("grantor", "role1",
+ Sets.newHashSet(
+ new TSentryGroup("group1"),
+ new TSentryGroup("group2")));
+ TSentryPrivilege tPriv = new TSentryPrivilege("SERVER", "server1", AccessConstants.ALL);
+ tPriv.setGrantOption(TSentryGrantOption.TRUE);
+ store1.alterSentryRoleGrantPrivilege("grantor", "role1", tPriv);
+ tPriv = new TSentryPrivilege("DB", "server1", AccessConstants.SELECT);
+ tPriv.setDbName("db1");
+ tPriv.setGrantOption(TSentryGrantOption.FALSE);
+ store1.alterSentryRoleGrantPrivilege("grantor", "role1", tPriv);
+ tPriv = new TSentryPrivilege("TABLE", "server1", AccessConstants.ALL);
+ tPriv.setDbName("db1");
+ tPriv.setTableName("table1");
+ tPriv.setGrantOption(TSentryGrantOption.UNSET);
+ store1.alterSentryRoleGrantPrivilege("grantor", "role1", tPriv);
+ Set<TSentryPrivilege> allPrivs1 = store1.getAllTSentryPrivilegesByRoleName("role1");
+
+ TStoreSnapshot snapshot = store1.toSnapshot();
+ InMemSentryStore store2 = new InMemSentryStore(conf, new DummyGroupMapper(conf));
+ store2.fromSnapshot(snapshot);
+ Assert.assertEquals(
+ Sets.newHashSet("group1", "group2"),
+ store2.getGroupsForRole("role1"));
+ Set<TSentryPrivilege> allPrivs2 = store2.getAllTSentryPrivilegesByRoleName("role1");
+ Assert.assertEquals(allPrivs1, allPrivs2);
+ }
+
+}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
index 4a6cac9..815f1f8 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
@@ -22,12 +22,14 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.TreeSet;
import org.apache.sentry.SentryUserException;
import org.apache.sentry.core.common.ActiveRoleSet;
@@ -268,7 +270,7 @@
client.grantTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", grantOption);
assertEquals(1, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size());
- // Try to revoke the privilege without grantOption and can't revoke the privilege.
+// // Try to revoke the privilege without grantOption and can't revoke the privilege.
client.revokeTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", withoutGrantOption);
assertEquals(1, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size());
@@ -296,8 +298,12 @@
assertEquals(1, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size());
// Grant a privilege without 'Grant Option'.
- client.grantTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", withoutGrantOption);
- assertEquals(2, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size());
+ // TODO : Do not think this is correct.. It shouldnt make sense for a Role
+ // to have both TRUE and FALSE grantoption on the same Authorizable Object..
+
+// client.grantTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", withoutGrantOption);
+// Set<TSentryPrivilege> lst = client.listAllPrivilegesByRoleName(requestorUserName, roleName);
+// assertEquals(2, lst.size());
// Use 'grantOption = null', the two privileges will be revoked.
client.revokeTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", null);
@@ -531,7 +537,7 @@
Map<TSentryAuthorizable, TSentryPrivilegeMap> authPrivMap = client
.listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, null);
- assertEquals(expectedResults, authPrivMap);
+ fuzzyAssertEquals(expectedResults, authPrivMap);
}
@Test
@@ -591,7 +597,7 @@
Map<TSentryAuthorizable, TSentryPrivilegeMap> authPrivMap = client
.listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, null);
- assertEquals(expectedResults, authPrivMap);
+ fuzzyAssertEquals(expectedResults, authPrivMap);
}
/**
@@ -657,32 +663,32 @@
// list privileges with null group and roles
Map<TSentryAuthorizable, TSentryPrivilegeMap> authPrivMap = client
.listPrivilegsbyAuthorizable(user1, authorizableSet, null, null);
- assertEquals(expectedResults, authPrivMap);
+ fuzzyAssertEquals(expectedResults, authPrivMap);
// list privileges with empty group set and null roles
authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
new HashSet<String>(), null);
- assertEquals(expectedResults, authPrivMap);
+ fuzzyAssertEquals(expectedResults, authPrivMap);
// list privileges with null group set and ALL roleset
authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
null, new ActiveRoleSet(true));
- assertEquals(expectedResults, authPrivMap);
+ fuzzyAssertEquals(expectedResults, authPrivMap);
// list privileges with user1's group set and null roles
authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
userGroupNames1, null);
- assertEquals(expectedResults, authPrivMap);
+ fuzzyAssertEquals(expectedResults, authPrivMap);
// list privileges with user1's group set and ALL roles
authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
userGroupNames1, new ActiveRoleSet(true));
- assertEquals(expectedResults, authPrivMap);
+ fuzzyAssertEquals(expectedResults, authPrivMap);
// list privileges with null group and user's specific roles with uppercase name
authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
null, new ActiveRoleSet(Sets.newHashSet(roleName1.toUpperCase())));
- assertEquals(expectedResults, authPrivMap);
+ fuzzyAssertEquals(expectedResults, authPrivMap);
// verify that user1 can't query group2
try {
@@ -762,4 +768,45 @@
// expected
}
}
+
+ private void fuzzyAssertEquals(
+ Map<TSentryAuthorizable, TSentryPrivilegeMap> expectedResults,
+ Map<TSentryAuthorizable, TSentryPrivilegeMap> authPrivMap) {
+ assertEquals(expectedResults.size(), authPrivMap.size());
+ for (Object mKey : expectedResults.keySet()) {
+ assertEquals(expectedResults.get(mKey).getPrivilegeMap().size(),
+ authPrivMap.get(mKey).getPrivilegeMap().size());
+ for (Map.Entry<String, Set<TSentryPrivilege>> e :
+ expectedResults.get(mKey).getPrivilegeMap().entrySet()) {
+ assertTrue(authPrivMap.get(mKey).getPrivilegeMap().containsKey(e.getKey()));
+ Set<TSentryPrivilege> exp = createSpecialSet();
+ exp.addAll(e.getValue());
+ Set<TSentryPrivilege> act = createSpecialSet();
+ act.addAll(authPrivMap.get(mKey).getPrivilegeMap().get(e.getKey()));
+ assertEquals(exp, act);
+ }
+ }
+ }
+
+ private Set<TSentryPrivilege> createSpecialSet() {
+ return new TreeSet<TSentryPrivilege>(new Comparator<TSentryPrivilege>() {
+ @Override
+ public int compare(TSentryPrivilege o1, TSentryPrivilege o2) {
+ if (o1.getServerName().equalsIgnoreCase(o2.getServerName())
+ &&o1.getDbName().equalsIgnoreCase(o2.getDbName())
+ &&o1.getTableName().equalsIgnoreCase(o2.getTableName())
+ &&o1.getColumnName().equalsIgnoreCase(o2.getColumnName())
+ &&o1.getGrantOption().equals(o2.getGrantOption())
+ &&(o1.getAction().equalsIgnoreCase(o2.getAction())
+ ||(o1.getAction().equals("*")&&o2.getAction().equalsIgnoreCase("all"))
+ ||(o2.getAction().equals("*")&&o1.getAction().equalsIgnoreCase("all")))) {
+ return 0;
+ } else {
+ return o1.compareTo(o2);
+ }
+ }
+ });
+ }
+
+
}
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java
index be14afd..44a6290 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java
@@ -147,6 +147,9 @@
dbDir = new File(Files.createTempDir(), "sentry_policy_db");
conf.set(ServerConfig.SENTRY_STORE_JDBC_URL,
"jdbc:derby:;databaseName=" + dbDir.getPath() + ";create=true");
+ // InMem Db
+ dbDir.mkdirs();
+ conf.set("sentry.store.type", "mem");
server = new SentryServiceFactory().create(conf);
conf.set(ClientConfig.SERVER_RPC_ADDRESS, server.getAddress().getHostName());
conf.set(ClientConfig.SERVER_RPC_PORT, String.valueOf(server.getAddress().getPort()));
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java
index 4a475ba..f36dfdd 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java
@@ -52,6 +52,7 @@
@BeforeClass
public static void setupTestStaticConfiguration() throws Exception{
useSentryService = true;
+ useFileStore = true;
AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
}
@@ -128,17 +129,52 @@
@Test
public void testGrantRevokeSELECTonDb() throws Exception {
File dataFile = doSetupForGrantDbTests();
-
+
Connection connection = context.createConnection(ADMIN1);
Statement statement = context.createStatement(connection);
+ // Test Db switch..
+ statement.execute("USE " + DB1);
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection(ADMIN1);
+ statement = context.createStatement(connection);
// Grant only SELECT on Database
statement.execute("GRANT SELECT ON DATABASE " + DB1 + " TO ROLE user_role");
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection(ADMIN1);
+ statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection(ADMIN1);
+ statement = context.createStatement(connection);
statement.execute("GRANT ALL ON URI 'file://" + dataFile.getPath() + "' TO ROLE user_role");
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection(ADMIN1);
+ statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.close();
+ connection.close();
+
+ connection = context.createConnection(ADMIN1);
+ statement = context.createStatement(connection);
statement.execute("GRANT ROLE user_role TO GROUP " + USERGROUP1);
statement.close();
connection.close();
+ connection = context.createConnection(ADMIN1);
+ statement = context.createStatement(connection);
+ statement.execute("USE " + DB1);
+ statement.close();
+ connection.close();
+
connection = context.createConnection(USER1_1);
statement = context.createStatement(connection);
// SELECT is allowed
@@ -275,7 +311,6 @@
statement.execute("CREATE TABLE t2 (c2 string)");
statement.close();
connection.close();
-
return dataFile;
}
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java
index 2cecdfd..af2d3d9 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java
@@ -68,6 +68,7 @@
@BeforeClass
public static void setupTestStaticConfiguration() throws Exception {
+ useInMemDb = true;
useSentryService = true;
AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
Logger logger = Logger.getLogger("sentry.hive.authorization.ddl.logger");
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbEndToEnd.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbEndToEnd.java
index acb789f..dff608a 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbEndToEnd.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbEndToEnd.java
@@ -43,6 +43,7 @@
@BeforeClass
public static void setupTestStaticConfiguration() throws Exception{
+ useInMemDb = true;
useSentryService = true;
AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
}
@@ -233,7 +234,7 @@
// 8
connection = context.createConnection(USER1_1);
statement = context.createStatement(connection);
- statement.execute("USE " + DB2);
+ statement.execute("USE " + DB1);
statement.execute("INSERT OVERWRITE TABLE " +
DB2 + "." + tableName2 + " SELECT * FROM " + DB1
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
index f8cc1d0..b12df39 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
@@ -60,12 +60,15 @@
import org.apache.tools.ant.util.StringUtils;
import org.junit.After;
import org.junit.AfterClass;
+
import static org.junit.Assert.assertTrue;
+
import org.junit.Before;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
@@ -128,6 +131,8 @@
protected static SentryService sentryServer;
protected static Configuration sentryConf;
protected static Context context;
+ protected static boolean useInMemDb;
+ protected static boolean useFileStore;
protected final String semanticException = "SemanticException No valid privileges";
@@ -365,6 +370,17 @@
for (Map.Entry<String, String> entry : properties.entrySet()) {
sentryConf.set(entry.getKey(), entry.getValue());
}
+ // InMem Db
+ if (useInMemDb || !Strings.isNullOrEmpty(System.getenv("USE_IN_MEM"))) {
+ baseDir.mkdirs();
+ sentryConf.set("sentry.store.type", "mem");
+ System.out.println("\n\n\n ****** Using InMem Store *******\n\n\n");
+ } else if (useFileStore || !Strings.isNullOrEmpty(System.getenv("USE_FILE_STORE"))) {
+ baseDir.mkdirs();
+ sentryConf.set("sentry.store.type", "file");
+ System.out.println("\n\n\n ****** Using File Log Store *******\n\n\n");
+ }
+
sentryServer = new SentryServiceFactory().create(sentryConf);
properties.put(ClientConfig.SERVER_RPC_ADDRESS, sentryServer.getAddress()
.getHostName());