http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/service/thrift/TSentryResponseStatus.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/service/thrift/TSentryResponseStatus.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/service/thrift/TSentryResponseStatus.java deleted file mode 100644 index 81abd90..0000000 --- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/service/thrift/TSentryResponseStatus.java +++ /dev/null @@ -1,594 +0,0 @@ -/** - * 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.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 TSentryResponseStatus implements org.apache.thrift.TBase<TSentryResponseStatus, TSentryResponseStatus._Fields>, java.io.Serializable, Cloneable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSentryResponseStatus"); - - private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.I32, (short)1); - private static final org.apache.thrift.protocol.TField MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("message", org.apache.thrift.protocol.TType.STRING, (short)2); - private static final org.apache.thrift.protocol.TField STACK_FIELD_DESC = new org.apache.thrift.protocol.TField("stack", org.apache.thrift.protocol.TType.STRING, (short)3); - - private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TSentryResponseStatusStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TSentryResponseStatusTupleSchemeFactory()); - } - - private int value; // required - private String message; // required - private String stack; // 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 { - VALUE((short)1, "value"), - MESSAGE((short)2, "message"), - STACK((short)3, "stack"); - - 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: // VALUE - return VALUE; - case 2: // MESSAGE - return MESSAGE; - case 3: // STACK - return STACK; - 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 __VALUE_ISSET_ID = 0; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.STACK}; - 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.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.REQUIRED, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("message", org.apache.thrift.TFieldRequirementType.REQUIRED, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.STACK, new org.apache.thrift.meta_data.FieldMetaData("stack", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSentryResponseStatus.class, metaDataMap); - } - - public TSentryResponseStatus() { - } - - public TSentryResponseStatus( - int value, - String message) - { - this(); - this.value = value; - setValueIsSet(true); - this.message = message; - } - - /** - * Performs a deep copy on <i>other</i>. - */ - public TSentryResponseStatus(TSentryResponseStatus other) { - __isset_bitfield = other.__isset_bitfield; - this.value = other.value; - if (other.isSetMessage()) { - this.message = other.message; - } - if (other.isSetStack()) { - this.stack = other.stack; - } - } - - public TSentryResponseStatus deepCopy() { - return new TSentryResponseStatus(this); - } - - @Override - public void clear() { - setValueIsSet(false); - this.value = 0; - this.message = null; - this.stack = null; - } - - public int getValue() { - return this.value; - } - - public void setValue(int value) { - this.value = value; - setValueIsSet(true); - } - - public void unsetValue() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __VALUE_ISSET_ID); - } - - /** Returns true if field value is set (has been assigned a value) and false otherwise */ - public boolean isSetValue() { - return EncodingUtils.testBit(__isset_bitfield, __VALUE_ISSET_ID); - } - - public void setValueIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __VALUE_ISSET_ID, value); - } - - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - public void unsetMessage() { - this.message = null; - } - - /** Returns true if field message is set (has been assigned a value) and false otherwise */ - public boolean isSetMessage() { - return this.message != null; - } - - public void setMessageIsSet(boolean value) { - if (!value) { - this.message = null; - } - } - - public String getStack() { - return this.stack; - } - - public void setStack(String stack) { - this.stack = stack; - } - - public void unsetStack() { - this.stack = null; - } - - /** Returns true if field stack is set (has been assigned a value) and false otherwise */ - public boolean isSetStack() { - return this.stack != null; - } - - public void setStackIsSet(boolean value) { - if (!value) { - this.stack = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case VALUE: - if (value == null) { - unsetValue(); - } else { - setValue((Integer)value); - } - break; - - case MESSAGE: - if (value == null) { - unsetMessage(); - } else { - setMessage((String)value); - } - break; - - case STACK: - if (value == null) { - unsetStack(); - } else { - setStack((String)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case VALUE: - return Integer.valueOf(getValue()); - - case MESSAGE: - return getMessage(); - - case STACK: - return getStack(); - - } - 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 VALUE: - return isSetValue(); - case MESSAGE: - return isSetMessage(); - case STACK: - return isSetStack(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TSentryResponseStatus) - return this.equals((TSentryResponseStatus)that); - return false; - } - - public boolean equals(TSentryResponseStatus that) { - if (that == null) - return false; - - boolean this_present_value = true; - boolean that_present_value = true; - if (this_present_value || that_present_value) { - if (!(this_present_value && that_present_value)) - return false; - if (this.value != that.value) - return false; - } - - boolean this_present_message = true && this.isSetMessage(); - boolean that_present_message = true && that.isSetMessage(); - if (this_present_message || that_present_message) { - if (!(this_present_message && that_present_message)) - return false; - if (!this.message.equals(that.message)) - return false; - } - - boolean this_present_stack = true && this.isSetStack(); - boolean that_present_stack = true && that.isSetStack(); - if (this_present_stack || that_present_stack) { - if (!(this_present_stack && that_present_stack)) - return false; - if (!this.stack.equals(that.stack)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - HashCodeBuilder builder = new HashCodeBuilder(); - - boolean present_value = true; - builder.append(present_value); - if (present_value) - builder.append(value); - - boolean present_message = true && (isSetMessage()); - builder.append(present_message); - if (present_message) - builder.append(message); - - boolean present_stack = true && (isSetStack()); - builder.append(present_stack); - if (present_stack) - builder.append(stack); - - return builder.toHashCode(); - } - - public int compareTo(TSentryResponseStatus other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - TSentryResponseStatus typedOther = (TSentryResponseStatus)other; - - lastComparison = Boolean.valueOf(isSetValue()).compareTo(typedOther.isSetValue()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetValue()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, typedOther.value); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetMessage()).compareTo(typedOther.isSetMessage()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetMessage()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.message, typedOther.message); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStack()).compareTo(typedOther.isSetStack()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStack()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stack, typedOther.stack); - 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("TSentryResponseStatus("); - boolean first = true; - - sb.append("value:"); - sb.append(this.value); - first = false; - if (!first) sb.append(", "); - sb.append("message:"); - if (this.message == null) { - sb.append("null"); - } else { - sb.append(this.message); - } - first = false; - if (isSetStack()) { - if (!first) sb.append(", "); - sb.append("stack:"); - if (this.stack == null) { - sb.append("null"); - } else { - sb.append(this.stack); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - if (!isSetValue()) { - throw new org.apache.thrift.protocol.TProtocolException("Required field 'value' is unset! Struct:" + toString()); - } - - if (!isSetMessage()) { - throw new org.apache.thrift.protocol.TProtocolException("Required field 'message' 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 TSentryResponseStatusStandardSchemeFactory implements SchemeFactory { - public TSentryResponseStatusStandardScheme getScheme() { - return new TSentryResponseStatusStandardScheme(); - } - } - - private static class TSentryResponseStatusStandardScheme extends StandardScheme<TSentryResponseStatus> { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TSentryResponseStatus 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: // VALUE - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.value = iprot.readI32(); - struct.setValueIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // MESSAGE - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.message = iprot.readString(); - struct.setMessageIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // STACK - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.stack = iprot.readString(); - struct.setStackIsSet(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, TSentryResponseStatus struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - oprot.writeFieldBegin(VALUE_FIELD_DESC); - oprot.writeI32(struct.value); - oprot.writeFieldEnd(); - if (struct.message != null) { - oprot.writeFieldBegin(MESSAGE_FIELD_DESC); - oprot.writeString(struct.message); - oprot.writeFieldEnd(); - } - if (struct.stack != null) { - if (struct.isSetStack()) { - oprot.writeFieldBegin(STACK_FIELD_DESC); - oprot.writeString(struct.stack); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TSentryResponseStatusTupleSchemeFactory implements SchemeFactory { - public TSentryResponseStatusTupleScheme getScheme() { - return new TSentryResponseStatusTupleScheme(); - } - } - - private static class TSentryResponseStatusTupleScheme extends TupleScheme<TSentryResponseStatus> { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TSentryResponseStatus struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - oprot.writeI32(struct.value); - oprot.writeString(struct.message); - BitSet optionals = new BitSet(); - if (struct.isSetStack()) { - optionals.set(0); - } - oprot.writeBitSet(optionals, 1); - if (struct.isSetStack()) { - oprot.writeString(struct.stack); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TSentryResponseStatus struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - struct.value = iprot.readI32(); - struct.setValueIsSet(true); - struct.message = iprot.readString(); - struct.setMessageIsSet(true); - BitSet incoming = iprot.readBitSet(1); - if (incoming.get(0)) { - struct.stack = iprot.readString(); - struct.setStackIsSet(true); - } - } - } - -} -
http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/service/thrift/sentry_common_serviceConstants.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/service/thrift/sentry_common_serviceConstants.java b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/service/thrift/sentry_common_serviceConstants.java deleted file mode 100644 index 4fdeaeb..0000000 --- a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/service/thrift/sentry_common_serviceConstants.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * 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.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 sentry_common_serviceConstants { - - public static final int TSENTRY_SERVICE_V1 = 1; - - public static final int TSENTRY_STATUS_OK = 0; - - public static final int TSENTRY_STATUS_ALREADY_EXISTS = 1; - - public static final int TSENTRY_STATUS_NO_SUCH_OBJECT = 2; - - public static final int TSENTRY_STATUS_RUNTIME_ERROR = 3; - - public static final int TSENTRY_STATUS_INVALID_INPUT = 4; - - public static final int TSENTRY_STATUS_ACCESS_DENIED = 5; - -} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/UpdateForwarder.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/UpdateForwarder.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/UpdateForwarder.java new file mode 100644 index 0000000..037cfe7 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/UpdateForwarder.java @@ -0,0 +1,227 @@ +/** + * 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; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.apache.sentry.hdfs.Updateable; + +import com.google.common.collect.Lists; + +public class UpdateForwarder<K extends Updateable.Update> implements + Updateable<K> { + + public static interface ExternalImageRetriever<K> { + + public K retrieveFullImage(long currSeqNum); + + } + + private final AtomicLong lastSeenSeqNum = new AtomicLong(0); + private final AtomicLong lastCommittedSeqNum = new AtomicLong(0); + // Updates should be handled in order + private final Executor updateHandler = Executors.newSingleThreadExecutor(); + + // Update log is used when propagate updates to a downstream cache. + // The preUpdate log stores all commits that were applied to this cache. + // When the update log is filled to capacity (updateLogSize), all + // entries are cleared and a compact image if the state of the cache is + // appended to the log. + // The first entry in an update log (consequently the first preUpdate a + // downstream cache sees) will be a full image. All subsequent entries are + // partial edits + private final LinkedList<K> updateLog = new LinkedList<K>(); + // UpdateLog is dissabled when updateLogSize = 0; + private final int updateLogSize; + + private final ExternalImageRetriever<K> imageRetreiver; + + private volatile Updateable<K> updateable; + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private static final long INIT_SEQ_NUM = -2; + + public UpdateForwarder(Updateable<K> updateable, + ExternalImageRetriever<K> imageRetreiver, int updateLogSize) { + this.updateLogSize = updateLogSize; + this.imageRetreiver = imageRetreiver; + K fullImage = imageRetreiver.retrieveFullImage(INIT_SEQ_NUM); + appendToUpdateLog(fullImage); + this.updateable = updateable.updateFull(fullImage); + } + + /** + * Handle notifications from HMS plug-in or upstream Cache + * @param update + */ + public void handleUpdateNotification(final K update) { + // Correct the seqNums on the first update + if (lastCommittedSeqNum.get() == INIT_SEQ_NUM) { + K firstUpdate = updateLog.peek(); + long firstSeqNum = update.getSeqNum() - 1; + firstUpdate.setSeqNum(firstSeqNum); + lastCommittedSeqNum.set(firstSeqNum); + lastSeenSeqNum.set(firstSeqNum); + } + final boolean editNotMissed = + lastSeenSeqNum.incrementAndGet() == update.getSeqNum(); + if (!editNotMissed) { + lastSeenSeqNum.set(update.getSeqNum()); + } + Runnable task = new Runnable() { + @Override + public void run() { + K toUpdate = update; + if (update.hasFullImage()) { + updateable = updateable.updateFull(update); + } else { + if (editNotMissed) { + // apply partial preUpdate + updateable.updatePartial(Lists.newArrayList(update), lock); + } else { + // Retrieve full update from External Source and + toUpdate = imageRetreiver + .retrieveFullImage(update.getSeqNum()); + updateable = updateable.updateFull(toUpdate); + } + } + appendToUpdateLog(toUpdate); + } + }; + updateHandler.execute(task); + } + + private void appendToUpdateLog(K update) { + synchronized (updateLog) { + if (updateLogSize > 0) { + if (update.hasFullImage() || (updateLog.size() == updateLogSize)) { + // Essentially a log compaction + updateLog.clear(); + updateLog.add(update.hasFullImage() ? update + : createFullImageUpdate(update.getSeqNum())); + } else { + updateLog.add(update); + } + } + lastCommittedSeqNum.set(update.getSeqNum()); + } + } + + /** + * Return all updates from requested seqNum (inclusive) + * @param seqNum + * @return + */ + public List<K> getAllUpdatesFrom(long seqNum) { + List<K> retVal = new LinkedList<K>(); + synchronized (updateLog) { + long currSeqNum = lastCommittedSeqNum.get(); + if (updateLogSize == 0) { + // no updatelog configured.. + return retVal; + } + K head = updateLog.peek(); + if (seqNum > currSeqNum + 1) { + // This process has probably restarted since downstream + // recieved last update + retVal.addAll(updateLog); + return retVal; + } + if (head.getSeqNum() > seqNum) { + // Caller has diverged greatly.. + if (head.hasFullImage()) { + // head is a refresh(full) image + // Send full image along with partial updates + for (K u : updateLog) { + retVal.add(u); + } + } else { + // Create a full image + // clear updateLog + // add fullImage to head of Log + // NOTE : This should ideally never happen + K fullImage = createFullImageUpdate(currSeqNum); + updateLog.clear(); + updateLog.add(fullImage); + retVal.add(fullImage); + } + } else { + // increment iterator to requested seqNum + Iterator<K> iter = updateLog.iterator(); + K u = null; + while (iter.hasNext()) { + u = iter.next(); + if (u.getSeqNum() == seqNum) { + break; + } + } + // add all updates from requestedSeq + // to committedSeqNum + for (long seq = seqNum; seq <= currSeqNum; seq ++) { + retVal.add(u); + if (iter.hasNext()) { + u = iter.next(); + } else { + break; + } + } + } + } + return retVal; + } + + public boolean areAllUpdatesCommited() { + return lastCommittedSeqNum.get() == lastSeenSeqNum.get(); + } + + public long getLastCommitted() { + return lastCommittedSeqNum.get(); + } + + public long getLastSeen() { + return lastSeenSeqNum.get(); + } + + @Override + public Updateable<K> updateFull(K update) { + return updateable.updateFull(update); + } + + @Override + public void updatePartial(Iterable<K> updates, ReadWriteLock lock) { + updateable.updatePartial(updates, lock); + } + + @Override + public long getLastUpdatedSeqNum() { + return updateable.getLastUpdatedSeqNum(); + } + + @Override + public K createFullImageUpdate(long currSeqNum) { + return updateable.createFullImageUpdate(currSeqNum); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/UpdateablePermissions.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/UpdateablePermissions.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/UpdateablePermissions.java new file mode 100644 index 0000000..a91cd9c --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/UpdateablePermissions.java @@ -0,0 +1,62 @@ +/** + * 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; + +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReadWriteLock; + +import org.apache.sentry.hdfs.PermissionsUpdate; +import org.apache.sentry.hdfs.Updateable; +import org.apache.sentry.provider.db.service.UpdateForwarder.ExternalImageRetriever; + +public class UpdateablePermissions implements Updateable<PermissionsUpdate>{ + + private AtomicLong seqNum = new AtomicLong(); + private final ExternalImageRetriever<PermissionsUpdate> imageRetreiver; + + public UpdateablePermissions( + ExternalImageRetriever<PermissionsUpdate> imageRetreiver) { + this.imageRetreiver = imageRetreiver; + } + + @Override + public PermissionsUpdate createFullImageUpdate(long currSeqNum) { + return imageRetreiver.retrieveFullImage(currSeqNum); + } + + @Override + public long getLastUpdatedSeqNum() { + return seqNum.get(); + } + + @Override + public void updatePartial(Iterable<PermissionsUpdate> update, + ReadWriteLock lock) { + for (PermissionsUpdate permsUpdate : update) { + seqNum.set(permsUpdate.getSeqNum()); + } + } + + @Override + public Updateable<PermissionsUpdate> updateFull(PermissionsUpdate update) { + UpdateablePermissions other = new UpdateablePermissions(imageRetreiver); + other.seqNum.set(update.getSeqNum()); + return other; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java ---------------------------------------------------------------------- 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 718306d..6e66823 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 @@ -23,6 +23,7 @@ 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; @@ -40,20 +41,25 @@ import javax.jdo.Transaction; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.permission.FsAction; 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.hdfs.PermissionsUpdate; 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.UpdateForwarder.ExternalImageRetriever; 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.TPrivilegeChanges; +import org.apache.sentry.provider.db.service.thrift.TRoleChanges; 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; @@ -79,11 +85,21 @@ import com.google.common.collect.Sets; * such as role and group names will be normalized to lowercase * in addition to starting and ending whitespace. */ -public class SentryStore { +public class SentryStore implements ExternalImageRetriever<PermissionsUpdate> { private static final UUID SERVER_UUID = UUID.randomUUID(); public static String NULL_COL = "__NULL__"; static final String DEFAULT_DATA_DIR = "sentry_policy_db"; + + public static Map<String, FsAction> ACTION_MAPPING = new HashMap<String, FsAction>(); + static { + ACTION_MAPPING.put("ALL", FsAction.ALL); + ACTION_MAPPING.put(AccessConstants.ALL, FsAction.ALL); + ACTION_MAPPING.put(AccessConstants.SELECT, FsAction.READ); + ACTION_MAPPING.put("SELECT", FsAction.READ); + ACTION_MAPPING.put(AccessConstants.INSERT, FsAction.WRITE); + ACTION_MAPPING.put("INSERT", FsAction.WRITE); + } /** * Commit order sequence id. This is used by notification handlers * to know the order in which events where committed to the database. @@ -714,7 +730,6 @@ public class SentryStore { } } - List<MSentryPrivilege> getMSentryPrivileges(Set<String> roleNames, TSentryAuthorizable authHierarchy) { if ((roleNames.size() == 0)||(roleNames == null)) return new ArrayList<MSentryPrivilege>(); boolean rollbackTransaction = true; @@ -1369,4 +1384,56 @@ public class SentryStore { return Sets.newHashSet(conf.getStrings( ServerConfig.ADMIN_GROUPS, new String[]{})); } + + @Override + public PermissionsUpdate retrieveFullImage(long seqNum) { + PermissionsUpdate retVal = new PermissionsUpdate(seqNum, true); + 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(); + } + TPrivilegeChanges pUpdate = retVal.addPrivilegeUpdate(authzObj); + for (MSentryRole mRole : mPriv.getRoles()) { + String existingPriv = pUpdate.getAddPrivileges().get(mRole.getRoleName()); + if (existingPriv == null) { + pUpdate.putToAddPrivileges(mRole.getRoleName(), + ACTION_MAPPING.get(mPriv.getAction()).SYMBOL); + } else { + pUpdate.putToAddPrivileges( + mRole.getRoleName(), + FsAction.getFsAction(existingPriv) + .or(ACTION_MAPPING.get(mPriv.getAction())).SYMBOL); + } + } + } + query = pm.newQuery(MSentryGroup.class); + List<MSentryGroup> groups = (List<MSentryGroup>) query.execute(); + for (MSentryGroup mGroup : groups) { + for (MSentryRole role : mGroup.getRoles()) { + TRoleChanges rUpdate = retVal.addRoleUpdate(role.getRoleName()); + rUpdate.addToAddGroups(mGroup.getGroupName()); + } + } + commitTransaction(pm); + return retVal; + } finally { + if (rollbackTransaction) { + rollbackTransaction(pm); + } + } + } + } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java index 6358289..4a079d6 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java @@ -38,13 +38,14 @@ import org.apache.sentry.core.common.ActiveRoleSet; import org.apache.sentry.core.common.Authorizable; import org.apache.sentry.core.model.db.AccessConstants; import org.apache.sentry.core.model.db.DBModelAuthorizable; +import org.apache.sentry.hdfs.PathsUpdate; import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig; import org.apache.sentry.service.thrift.ServiceConstants.PrivilegeScope; import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig; import org.apache.sentry.service.thrift.ServiceConstants.ThriftConstants; import org.apache.sentry.service.thrift.Status; import org.apache.thrift.TException; -import org.apache.thrift.protocol.TBinaryProtocol; +import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TMultiplexedProtocol; import org.apache.thrift.transport.TSaslClientTransport; import org.apache.thrift.transport.TSocket; @@ -156,7 +157,7 @@ public class SentryPolicyServiceClient { } LOGGER.debug("Successfully opened transport: " + transport + " to " + serverAddress); TMultiplexedProtocol protocol = new TMultiplexedProtocol( - new TBinaryProtocol(transport), + new TCompactProtocol(transport), SentryPolicyStoreProcessor.SENTRY_POLICY_SERVICE_NAME); client = new SentryPolicyService.Client(protocol); LOGGER.debug("Successfully created client"); @@ -571,6 +572,15 @@ TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, } } + public synchronized void notifyHMSUpdate(PathsUpdate update) + throws SentryUserException { + try { + client.handle_hms_notification(update.getThriftObject()); + } catch (Exception e) { + throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e); + } + } + public void close() { if (transport != null) { transport.close(); http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java ---------------------------------------------------------------------- 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 070c494..685c906 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 @@ -18,15 +18,32 @@ package org.apache.sentry.provider.db.service.thrift; +import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.metastore.HiveMetaStoreClient; +import org.apache.hadoop.hive.metastore.api.Database; +import org.apache.hadoop.hive.metastore.api.Partition; +import org.apache.hadoop.hive.metastore.api.Table; import org.apache.sentry.SentryUserException; import org.apache.sentry.core.model.db.AccessConstants; +import org.apache.sentry.hdfs.ExtendedMetastoreClient; +import org.apache.sentry.hdfs.HMSPaths; +import org.apache.sentry.hdfs.MetastoreClient; +import org.apache.sentry.hdfs.PathsUpdate; +import org.apache.sentry.hdfs.PermissionsUpdate; +import org.apache.sentry.hdfs.UpdateableAuthzPaths; import org.apache.sentry.provider.common.GroupMappingService; import org.apache.sentry.provider.db.SentryAccessDeniedException; import org.apache.sentry.provider.db.SentryAlreadyExistsException; @@ -34,6 +51,9 @@ import org.apache.sentry.provider.db.SentryInvalidInputException; import org.apache.sentry.provider.db.SentryNoSuchObjectException; import org.apache.sentry.provider.db.log.entity.JsonLogEntityFactory; import org.apache.sentry.provider.db.log.util.Constants; +import org.apache.sentry.provider.db.service.UpdateForwarder; +import org.apache.sentry.provider.db.service.UpdateForwarder.ExternalImageRetriever; +import org.apache.sentry.provider.db.service.UpdateablePermissions; import org.apache.sentry.provider.db.service.persistent.CommitContext; import org.apache.sentry.provider.db.service.persistent.SentryStore; import org.apache.sentry.provider.db.service.thrift.PolicyStoreConstants.PolicyStoreServerConfig; @@ -65,6 +85,13 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { private final ImmutableSet<String> adminGroups; private boolean isReady; + private final UpdateForwarder<PathsUpdate> pathsUpdater; + private final UpdateForwarder<PermissionsUpdate> permsUpdater; + + // Initialized to some value > 1 so that the first update notification + // will trigger a full Image fetch + private final AtomicLong permSeqNum = new AtomicLong(5); + public SentryPolicyStoreProcessor(String name, Configuration conf) throws Exception { super(); this.name = name; @@ -76,6 +103,55 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { isReady = true; adminGroups = ImmutableSet.copyOf(toTrimedLower(Sets.newHashSet(conf.getStrings( ServerConfig.ADMIN_GROUPS, new String[]{})))); + HiveConf hiveConf = new HiveConf(conf, Configuration.class); + if (conf.getBoolean(ServerConfig.SENTRY_HDFS_INTEGRATION_ENABLE, true)) { + final MetastoreClient hmsClient = new ExtendedMetastoreClient(hiveConf); + final String[] pathPrefixes = conf + .getStrings(ServerConfig.SENTRY_HDFS_INTEGRATION_PATH_PREFIXES, new String[]{"/"}); + pathsUpdater = new UpdateForwarder<PathsUpdate>(new UpdateableAuthzPaths( + pathPrefixes), createHMSImageRetriever(pathPrefixes, hmsClient), 100); + permsUpdater = new UpdateForwarder<PermissionsUpdate>( + new UpdateablePermissions(sentryStore), sentryStore, 100); + } else { + pathsUpdater = null; + permsUpdater = null; + } + } + + private ExternalImageRetriever<PathsUpdate> createHMSImageRetriever( + final String[] pathPrefixes, final MetastoreClient hmsClient) { + return new ExternalImageRetriever<PathsUpdate>() { + @Override + public PathsUpdate retrieveFullImage(long currSeqNum) { + PathsUpdate tempUpdate = new PathsUpdate(currSeqNum, false); + List<Database> allDatabases = hmsClient.getAllDatabases(); + for (Database db : allDatabases) { + tempUpdate.newPathChange(db.getName()).addToAddPaths( + PathsUpdate.cleanPath(db.getLocationUri())); + List<Table> allTables = hmsClient.getAllTablesOfDatabase(db); + for (Table tbl : allTables) { + TPathChanges tblPathChange = tempUpdate.newPathChange(tbl + .getDbName() + "." + tbl.getTableName()); + List<Partition> tblParts = hmsClient.listAllPartitions(db, tbl); + tblPathChange.addToAddPaths(PathsUpdate.cleanPath(tbl.getSd() + .getLocation() == null ? db.getLocationUri() : tbl + .getSd().getLocation())); + for (Partition part : tblParts) { + tblPathChange.addToAddPaths(PathsUpdate.cleanPath(part.getSd() + .getLocation())); + } + } + } + UpdateableAuthzPaths tmpAuthzPaths = new UpdateableAuthzPaths( + pathPrefixes); + tmpAuthzPaths.updatePartial(Lists.newArrayList(tempUpdate), + new ReentrantReadWriteLock()); + PathsUpdate retUpdate = new PathsUpdate(currSeqNum, true); + retUpdate.getThriftObject().setPathsDump( + tmpAuthzPaths.getPathsDump().createPathsDump()); + return retUpdate; + } + }; } public void stop() { @@ -183,6 +259,16 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { response.setStatus(Status.OK()); notificationHandlerInvoker.alter_sentry_role_grant_privilege(commitContext, request, response); + String authzObj = getAuthzObj(request.getPrivilege()); + if (authzObj != null) { + PermissionsUpdate update = new PermissionsUpdate(permSeqNum.incrementAndGet(), false); + update.addPrivilegeUpdate(authzObj).putToAddPrivileges( + request.getRoleName(), + SentryStore.ACTION_MAPPING.get(request.getPrivilege().getAction()) + .SYMBOL); + permsUpdater.handleUpdateNotification(update); + LOGGER.info("Authz Perm preUpdate [" + update.getSeqNum() + "].."); + } } catch (SentryNoSuchObjectException e) { String msg = "Role: " + request.getRoleName() + " doesn't exist."; LOGGER.error(msg, e); @@ -215,6 +301,16 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { response.setStatus(Status.OK()); notificationHandlerInvoker.alter_sentry_role_revoke_privilege(commitContext, request, response); + String authzObj = getAuthzObj(request.getPrivilege()); + if (authzObj != null) { + PermissionsUpdate update = new PermissionsUpdate(permSeqNum.incrementAndGet(), false); + update.addPrivilegeUpdate(authzObj).putToDelPrivileges( + request.getRoleName(), + SentryStore.ACTION_MAPPING.get(request.getPrivilege().getAction()) + .SYMBOL); + permsUpdater.handleUpdateNotification(update); + LOGGER.info("Authz Perm preUpdate [" + update.getSeqNum() + ", " + authzObj + "].."); + } } catch (SentryNoSuchObjectException e) { String msg = "Privilege: [server=" + request.getPrivilege().getServerName() + ",db=" + request.getPrivilege().getDbName() + @@ -253,6 +349,12 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { response.setStatus(Status.OK()); notificationHandlerInvoker.drop_sentry_role(commitContext, request, response); + PermissionsUpdate update = new PermissionsUpdate(permSeqNum.incrementAndGet(), false); + update.addPrivilegeUpdate(PermissionsUpdate.ALL_AUTHZ_OBJ).putToDelPrivileges( + request.getRoleName(), PermissionsUpdate.ALL_AUTHZ_OBJ); + update.addRoleUpdate(request.getRoleName()).addToDelGroups(PermissionsUpdate.ALL_GROUPS); + permsUpdater.handleUpdateNotification(update); + LOGGER.info("Authz Perm preUpdate [" + update.getSeqNum() + ", " + request.getRoleName() + "].."); } catch (SentryNoSuchObjectException e) { String msg = "Role :" + request + " does not exist."; LOGGER.error(msg, e); @@ -283,6 +385,13 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { response.setStatus(Status.OK()); notificationHandlerInvoker.alter_sentry_role_add_groups(commitContext, request, response); + PermissionsUpdate update = new PermissionsUpdate(permSeqNum.incrementAndGet(), false); + TRoleChanges rUpdate = update.addRoleUpdate(request.getRoleName()); + for (TSentryGroup group : request.getGroups()) { + rUpdate.addToAddGroups(group.getGroupName()); + } + permsUpdater.handleUpdateNotification(update); + LOGGER.info("Authz Perm preUpdate [" + update.getSeqNum() + ", " + request.getRoleName() + "].."); } catch (SentryNoSuchObjectException e) { String msg = "Role: " + request + " does not exist."; LOGGER.error(msg, e); @@ -313,6 +422,13 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { response.setStatus(Status.OK()); notificationHandlerInvoker.alter_sentry_role_delete_groups(commitContext, request, response); + PermissionsUpdate update = new PermissionsUpdate(permSeqNum.incrementAndGet(), false); + TRoleChanges rUpdate = update.addRoleUpdate(request.getRoleName()); + for (TSentryGroup group : request.getGroups()) { + rUpdate.addToDelGroups(group.getGroupName()); + } + permsUpdater.handleUpdateNotification(update); + LOGGER.info("Authz Perm preUpdate [" + update.getSeqNum() + ", " + request.getRoleName() + "].."); } catch (SentryNoSuchObjectException e) { String msg = "Role: " + request + " does not exist."; LOGGER.error(msg, e); @@ -491,6 +607,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { authorize(request.getRequestorUserName(), adminGroups); sentryStore.dropPrivilege(request.getAuthorizable()); response.setStatus(Status.OK()); + // TODO : Sentry - HDFS : Have to handle this } catch (SentryAccessDeniedException e) { LOGGER.error(e.getMessage(), e); response.setStatus(Status.AccessDenied(e.getMessage(), e)); @@ -512,6 +629,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { sentryStore.renamePrivilege(request.getOldAuthorizable(), request.getNewAuthorizable(), request.getRequestorUserName()); response.setStatus(Status.OK()); + // TODO : Sentry - HDFS : Have to handle this } catch (SentryAccessDeniedException e) { LOGGER.error(e.getMessage(), e); response.setStatus(Status.AccessDenied(e.getMessage(), e)); @@ -524,4 +642,76 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { return response; } + @Override + public void handle_hms_notification(TPathsUpdate update) throws TException { + if (pathsUpdater == null) { + throw new TException("HiveMetastore Path Cache not enabled !!"); + } + try { + PathsUpdate hmsUpdate = new PathsUpdate(update); + pathsUpdater.handleUpdateNotification(hmsUpdate); + LOGGER.info("Authz Path preUpdate [" + hmsUpdate.getSeqNum() + "].."); + } catch (Exception e) { + LOGGER.error("Error handling notification from HMS", e); + throw new TException(e); + } + } + + @Override + public TAuthzUpdateResponse get_all_authz_updates_from(long permSeqNum, long pathSeqNum) throws TException { + if (pathsUpdater == null) { + throw new TException("HiveMetastore Path Cache not enabled !!"); + } + List<PathsUpdate> pathUpdates = pathsUpdater.getAllUpdatesFrom(pathSeqNum); + List<PermissionsUpdate> permUpdates = permsUpdater.getAllUpdatesFrom(permSeqNum); + TAuthzUpdateResponse retVal = new TAuthzUpdateResponse(); + retVal.setAuthzPathUpdate(new LinkedList<TPathsUpdate>()); + retVal.setAuthzPermUpdate(new LinkedList<TPermissionsUpdate>()); + try { + for (PathsUpdate update : pathUpdates) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("### Sending PATH preUpdate seq [" + update.getSeqNum() + "] ###"); + LOGGER.debug("### Sending PATH preUpdate [" + update.getThriftObject() + "] ###"); + } + retVal.getAuthzPathUpdate().add(update.getThriftObject()); + } + for (PermissionsUpdate update : permUpdates) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("### Sending PERM preUpdate seq [" + update.getSeqNum() + "] ###"); + LOGGER.debug("### Sending PERM preUpdate [" + update.getThriftObject() + "] ###"); + } + retVal.getAuthzPermUpdate().add(update.getThriftObject()); + } + } catch (Exception e) { + LOGGER.error("Error Sending updates to downstream Cache", e); + throw new TException(e); + } + return retVal; + } + + @Override + public Map<String, List<String>> get_all_related_paths(String path, + boolean exactMatch) throws TException { + if (pathsUpdater == null) { + throw new TException("HiveMetastore Path Cache not enabled !!"); + } +// Map<String, LinkedList<String>> relatedPaths = hmsPathCache +// .getAllRelatedPaths(path, exactMatch); + return new HashMap<String, List<String>>(); + } + + private String getAuthzObj(TSentryPrivilege privilege) { + String authzObj = null; + if (!SentryStore.isNULL(privilege.getDbName())) { + String dbName = privilege.getDbName(); + String tblName = privilege.getTableName(); + if (tblName == null) { + authzObj = dbName; + } else { + authzObj = dbName + "." + tblName; + } + } + return authzObj; + } + } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java index 6843e80..6c08431 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryService.java @@ -49,6 +49,7 @@ import org.apache.sentry.service.thrift.ServiceConstants.ConfUtilties; import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig; import org.apache.thrift.TMultiplexedProcessor; import org.apache.thrift.protocol.TBinaryProtocol; +import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TThreadPoolServer; import org.apache.thrift.transport.TSaslServerTransport; @@ -207,7 +208,7 @@ public class SentryService implements Callable { TThreadPoolServer.Args args = new TThreadPoolServer.Args( serverTransport).processor(processor) .transportFactory(transportFactory) - .protocolFactory(new TBinaryProtocol.Factory()) + .protocolFactory(new TCompactProtocol.Factory()) .minWorkerThreads(minThreads).maxWorkerThreads(maxThreads); thriftServer = new TThreadPoolServer(args); LOGGER.info("Serving on " + address); http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java deleted file mode 100644 index 52eaeed..0000000 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java +++ /dev/null @@ -1,150 +0,0 @@ -/** - * 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.service.thrift; - -import java.util.HashMap; -import java.util.Map; - -import javax.security.sasl.Sasl; - -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableMap; - -public class ServiceConstants { - - private static final ImmutableMap<String, String> SASL_PROPERTIES; - - static { - Map<String, String> saslProps = new HashMap<String, String>(); - saslProps.put(Sasl.SERVER_AUTH, "true"); - saslProps.put(Sasl.QOP, "auth-conf"); - SASL_PROPERTIES = ImmutableMap.copyOf(saslProps); - } - - public static class ConfUtilties { - public static final Splitter CLASS_SPLITTER = Splitter.onPattern("[\\s,]") - .trimResults().omitEmptyStrings(); - } - public static class ServiceArgs { - public static final String CONFIG_FILE_SHORT = "c"; - public static final String CONFIG_FILE_LONG = "conffile"; - } - - public static class ServerConfig { - public static final ImmutableMap<String, String> SASL_PROPERTIES = ServiceConstants.SASL_PROPERTIES; - /** - * This configuration parameter is only meant to be used for testing purposes. - */ - public static final String SECURITY_MODE = "sentry.service.security.mode"; - public static final String SECURITY_MODE_KERBEROS = "kerberos"; - public static final String SECURITY_MODE_NONE = "none"; - public static final String SECURITY_USE_UGI_TRANSPORT = "sentry.service.security.use.ugi"; - public static final String ADMIN_GROUPS = "sentry.service.admin.group"; - public static final String PRINCIPAL = "sentry.service.server.principal"; - public static final String KEY_TAB = "sentry.service.server.keytab"; - public static final String RPC_PORT = "sentry.service.server.rpc-port"; - public static final int RPC_PORT_DEFAULT = 8038; - public static final String RPC_ADDRESS = "sentry.service.server.rpc-address"; - public static final String RPC_ADDRESS_DEFAULT = "0.0.0.0"; - public static final String RPC_MAX_THREADS = "sentry.service.server-max-threads"; - public static final int RPC_MAX_THREADS_DEFAULT = 500; - public static final String RPC_MIN_THREADS = "sentry.service.server-min-threads"; - public static final int RPC_MIN_THREADS_DEFAULT = 10; - public static final String ALLOW_CONNECT = "sentry.service.allow.connect"; - public static final String PROCESSOR_FACTORIES = "sentry.service.processor.factories"; - public static final String PROCESSOR_FACTORIES_DEFAULT = - "org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessorFactory"; - public static final String SENTRY_STORE_JDBC_URL = "sentry.store.jdbc.url"; - public static final String SENTRY_STORE_JDBC_USER = "sentry.store.jdbc.user"; - public static final String SENTRY_STORE_JDBC_USER_DEFAULT = "Sentry"; - public static final String SENTRY_STORE_JDBC_PASS = "sentry.store.jdbc.password"; - public static final String SENTRY_STORE_JDBC_PASS_DEFAULT = "Sentry"; - public static final String SENTRY_STORE_JDBC_DRIVER = "sentry.store.jdbc.driver"; - public static final String SENTRY_STORE_JDBC_DRIVER_DEFAULT = "org.apache.derby.jdbc.EmbeddedDriver"; - - public static final String JAVAX_JDO_URL = "javax.jdo.option.ConnectionURL"; - public static final String JAVAX_JDO_USER = "javax.jdo.option.ConnectionUserName"; - public static final String JAVAX_JDO_PASS = "javax.jdo.option.ConnectionPassword"; - public static final String JAVAX_JDO_DRIVER_NAME = "javax.jdo.option.ConnectionDriverName"; - - public static final String SENTRY_DB_PROPERTY_PREFIX = "sentry."; - public static final String SENTRY_JAVAX_JDO_PROPERTY_PREFIX = SENTRY_DB_PROPERTY_PREFIX + "javax.jdo"; - public static final String SENTRY_DATANUCLEUS_PROPERTY_PREFIX = SENTRY_DB_PROPERTY_PREFIX + "datanucleus"; - - public static final String SENTRY_VERIFY_SCHEM_VERSION = "sentry.verify.schema.version"; - public static final String SENTRY_VERIFY_SCHEM_VERSION_DEFAULT = "true"; - - public static final String SENTRY_SERVICE_NAME = "sentry.service.name"; - public static final String SENTRY_SERVICE_NAME_DEFAULT = "Sentry-Service"; - - public static final String SENTRY_STORE_GROUP_MAPPING = "sentry.store.group.mapping"; - public static final String SENTRY_STORE_GROUP_MAPPING_RESOURCE = "sentry.store.group.mapping.resource"; - public static final String SENTRY_STORE_HADOOP_GROUP_MAPPING = "org.apache.sentry.provider.common.HadoopGroupMappingService"; - public static final String SENTRY_STORE_LOCAL_GROUP_MAPPING = "org.apache.sentry.provider.file.LocalGroupMappingService"; - public static final String SENTRY_STORE_GROUP_MAPPING_DEFAULT = SENTRY_STORE_HADOOP_GROUP_MAPPING; - - public static final ImmutableMap<String, String> SENTRY_STORE_DEFAULTS = - ImmutableMap.<String, String>builder() - .put("datanucleus.connectionPoolingType", "BoneCP") - .put("datanucleus.validateTables", "false") - .put("datanucleus.validateColumns", "false") - .put("datanucleus.validateConstraints", "false") - .put("datanucleus.storeManagerType", "rdbms") - .put("datanucleus.autoCreateSchema", "false") - .put("datanucleus.fixedDatastore", "true") - .put("datanucleus.autoStartMechanismMode", "checked") - .put("datanucleus.transactionIsolation", "read-committed") - .put("datanucleus.cache.level2", "false") - .put("datanucleus.cache.level2.type", "none") - .put("datanucleus.identifierFactory", "datanucleus1") - .put("datanucleus.rdbms.useLegacyNativeValueStrategy", "true") - .put("datanucleus.plugin.pluginRegistryBundleCheck", "LOG") - .put("javax.jdo.PersistenceManagerFactoryClass", - "org.datanucleus.api.jdo.JDOPersistenceManagerFactory") - .put("javax.jdo.option.DetachAllOnCommit", "true") - .put("javax.jdo.option.NonTransactionalRead", "false") - .put("javax.jdo.option.NonTransactionalWrite", "false") - .put("javax.jdo.option.Multithreaded", "true") - .build(); - - } - public static class ClientConfig { - public static final ImmutableMap<String, String> SASL_PROPERTIES = ServiceConstants.SASL_PROPERTIES; - public static final String SERVER_RPC_PORT = "sentry.service.client.server.rpc-port"; - public static final int SERVER_RPC_PORT_DEFAULT = ServerConfig.RPC_PORT_DEFAULT; - public static final String SERVER_RPC_ADDRESS = "sentry.service.client.server.rpc-address"; - public static final String SERVER_RPC_CONN_TIMEOUT = "sentry.service.client.server.rpc-connection-timeout"; - public static final int SERVER_RPC_CONN_TIMEOUT_DEFAULT = 200000; - } - - /** - * Thrift generates terrible constant class names - */ - public static class ThriftConstants extends org.apache.sentry.service.thrift.sentry_common_serviceConstants { - public static final int TSENTRY_SERVICE_VERSION_CURRENT = TSENTRY_SERVICE_V1; - } - - /* Privilege operation scope */ - public static enum PrivilegeScope { - SERVER, - URI, - DATABASE, - TABLE, - COLUMN - } -} http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift b/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift deleted file mode 100644 index 9456274..0000000 --- a/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/local/bin/thrift -java - -/** - * 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. - */ - -include "share/fb303/if/fb303.thrift" - -namespace java org.apache.sentry.service.thrift -namespace php sentry.service.thrift -namespace cpp Apache.Sentry.Service.Thrift - -const i32 TSENTRY_SERVICE_V1 = 1; - -const i32 TSENTRY_STATUS_OK = 0; -const i32 TSENTRY_STATUS_ALREADY_EXISTS = 1; -const i32 TSENTRY_STATUS_NO_SUCH_OBJECT = 2; -const i32 TSENTRY_STATUS_RUNTIME_ERROR = 3; -const i32 TSENTRY_STATUS_INVALID_INPUT = 4; -const i32 TSENTRY_STATUS_ACCESS_DENIED = 5; - -struct TSentryResponseStatus { -1: required i32 value, -// message will be set to empty string when status is OK -2: required string message -3: optional string stack -} - http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/0eb6645e/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift ---------------------------------------------------------------------- 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 deleted file mode 100644 index b14616b..0000000 --- a/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift +++ /dev/null @@ -1,223 +0,0 @@ -#!/usr/local/bin/thrift -java - -/** - * 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. - */ - -# -# Thrift Service that the MetaStore is built on -# - -include "share/fb303/if/fb303.thrift" -include "sentry_common_service.thrift" - -namespace java org.apache.sentry.provider.db.service.thrift -namespace php sentry.provider.db.service.thrift -namespace cpp Apache.Sentry.Provider.Db.Service.Thrift - -enum TSentryGrantOption { - TRUE = 1, - FALSE = 0, - # UNSET is used for revoke privilege, the component like 'hive' - # didn't support getting grant option, so use UNSET is stand - # for revoke both privileges with grant option and without grant - # option. - UNSET = -1 -} - -# Represents a Privilege in transport from the client to the server -struct TSentryPrivilege { -1: required string privilegeScope, # Valid values are SERVER, DATABASE, TABLE -3: required string serverName, -4: optional string dbName = "", -5: optional string tableName = "", -6: optional string URI = "", -7: required string action = "", -8: optional i64 createTime, # Set on server side -9: optional string grantorPrincipal, # Set on server side -10: optional TSentryGrantOption grantOption = TSentryGrantOption.FALSE -} - -# TODO can this be deleted? it's not adding value to TAlterSentryRoleAddGroupsRequest -struct TSentryGroup { -1: required string groupName -} - -# CREATE ROLE r1 -struct TCreateSentryRoleRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: required string roleName, # TSentryRole is not required for this request -} -struct TCreateSentryRoleResponse { -1: required sentry_common_service.TSentryResponseStatus status -} - -# DROP ROLE r1 -struct TDropSentryRoleRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: required string roleName # role to drop -} -struct TDropSentryRoleResponse { -1: required sentry_common_service.TSentryResponseStatus status -} - -# GRANT ROLE r1 TO GROUP g1 -struct TAlterSentryRoleAddGroupsRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: required string roleName, -5: required set<TSentryGroup> groups -} - -struct TAlterSentryRoleAddGroupsResponse { -1: required sentry_common_service.TSentryResponseStatus status -} - -# REVOLE ROLE r1 FROM GROUP g1 -struct TAlterSentryRoleDeleteGroupsRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: required string roleName, -5: required set<TSentryGroup> groups -} -struct TAlterSentryRoleDeleteGroupsResponse { -1: required sentry_common_service.TSentryResponseStatus status -} - -# GRANT ... ON ... TO ROLE ... -struct TAlterSentryRoleGrantPrivilegeRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: required string roleName, -5: required TSentryPrivilege privilege -} -struct TAlterSentryRoleGrantPrivilegeResponse { -1: required sentry_common_service.TSentryResponseStatus status -} - -# REVOKE ... ON ... FROM ROLE ... -struct TAlterSentryRoleRevokePrivilegeRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: required string roleName, -5: required TSentryPrivilege privilege -} -struct TAlterSentryRoleRevokePrivilegeResponse { -1: required sentry_common_service.TSentryResponseStatus status -} - -# SHOW ROLE GRANT -struct TListSentryRolesRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: optional string groupName # for this group, or all roles for all groups if null -} -# used only for TListSentryRolesResponse -struct TSentryRole { -1: required string roleName, -2: required set<TSentryGroup> groups, -3: required string grantorPrincipal -} -struct TListSentryRolesResponse { -1: required sentry_common_service.TSentryResponseStatus status -2: optional set<TSentryRole> roles -} - -struct TSentryAuthorizable { -1: required string server, -2: optional string uri, -3: optional string db, -4: optional string table, -} - -# SHOW GRANT -struct TListSentryPrivilegesRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -4: required string roleName, # get privileges assigned for this role -5: optional TSentryAuthorizable authorizableHierarchy # get privileges assigned for this role -} -struct TListSentryPrivilegesResponse { -1: required sentry_common_service.TSentryResponseStatus status -2: optional set<TSentryPrivilege> privileges -} - -# Drop privilege -struct TDropPrivilegesRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: required TSentryAuthorizable authorizable -} - -struct TDropPrivilegesResponse { -1: required sentry_common_service.TSentryResponseStatus status -} - -struct TRenamePrivilegesRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required string requestorUserName, # user on whose behalf the request is issued -3: required TSentryAuthorizable oldAuthorizable -4: required TSentryAuthorizable newAuthorizable -} - -struct TRenamePrivilegesResponse { -1: required sentry_common_service.TSentryResponseStatus status -} - -# This API was created specifically for ProviderBackend.getPrivileges -# and is not mean for general purpose privilege retrieval. -# This request/response pair are created specifically so we can -# efficiently obtain the specific privilges for a user query -struct TSentryActiveRoleSet { -1: required bool all, -2: required set<string> roles, -} -struct TListSentryPrivilegesForProviderRequest { -1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, -2: required set<string> groups, -3: required TSentryActiveRoleSet roleSet, -4: optional TSentryAuthorizable authorizableHierarchy, -} -struct TListSentryPrivilegesForProviderResponse { -1: required sentry_common_service.TSentryResponseStatus status -2: required set<string> privileges -} - -service SentryPolicyService -{ - TCreateSentryRoleResponse create_sentry_role(1:TCreateSentryRoleRequest request) - TDropSentryRoleResponse drop_sentry_role(1:TDropSentryRoleRequest request) - - TAlterSentryRoleGrantPrivilegeResponse alter_sentry_role_grant_privilege(1:TAlterSentryRoleGrantPrivilegeRequest request) - TAlterSentryRoleRevokePrivilegeResponse alter_sentry_role_revoke_privilege(1:TAlterSentryRoleRevokePrivilegeRequest request) - - TAlterSentryRoleAddGroupsResponse alter_sentry_role_add_groups(1:TAlterSentryRoleAddGroupsRequest request) - TAlterSentryRoleDeleteGroupsResponse alter_sentry_role_delete_groups(1:TAlterSentryRoleDeleteGroupsRequest request) - - TListSentryRolesResponse list_sentry_roles_by_group(1:TListSentryRolesRequest request) - - TListSentryPrivilegesResponse list_sentry_privileges_by_role(1:TListSentryPrivilegesRequest request) - - # For use with ProviderBackend.getPrivileges only - TListSentryPrivilegesForProviderResponse list_sentry_privileges_for_provider(1:TListSentryPrivilegesForProviderRequest request) - - TDropPrivilegesResponse drop_sentry_privilege(1:TDropPrivilegesRequest request); - - TRenamePrivilegesResponse rename_sentry_privilege(1:TRenamePrivilegesRequest request); -}
