You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2016/06/21 03:14:27 UTC
[6/9] incubator-geode git commit: client server
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Put65.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Put65.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Put65.java
index 4ccc03a..156fbbc 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Put65.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Put65.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
/**
- *
+ *
*/
package com.gemstone.gemfire.internal.cache.tier.sockets.command;
@@ -35,7 +35,6 @@ import com.gemstone.gemfire.internal.HeapDataOutputStream;
import com.gemstone.gemfire.internal.InternalDataSerializer;
import com.gemstone.gemfire.internal.Version;
import com.gemstone.gemfire.internal.cache.CachedDeserializable;
-import com.gemstone.gemfire.internal.cache.EntryEventImpl;
import com.gemstone.gemfire.internal.cache.EventID;
import com.gemstone.gemfire.internal.cache.EventIDHolder;
import com.gemstone.gemfire.internal.cache.LocalRegion;
@@ -54,6 +53,7 @@ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
import com.gemstone.gemfire.internal.security.AuthorizeRequest;
+import com.gemstone.gemfire.internal.security.GeodeSecurityUtil;
import com.gemstone.gemfire.internal.util.Breadcrumbs;
import com.gemstone.gemfire.security.GemFireSecurityException;
@@ -73,7 +73,7 @@ public class Put65 extends BaseCommand {
@Override
public void cmdExecute(Message msg, ServerConnection servConn, long p_start)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException {
long start = p_start;
Part regionNamePart = null, keyPart = null, valuePart = null, callbackArgPart = null;
String regionName = null;
@@ -87,11 +87,9 @@ public class Put65 extends BaseCommand {
boolean interrupted = Thread.interrupted();
try {
Thread.sleep(crHelper.emulateSlowServer());
- }
- catch (InterruptedException ugh) {
+ } catch (InterruptedException ugh) {
interrupted = true;
- }
- finally {
+ } finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
@@ -110,7 +108,7 @@ public class Put65 extends BaseCommand {
regionNamePart = msg.getPart(idx++);
Operation operation;
try {
- operation = (Operation)msg.getPart(idx++).getObject();
+ operation = (Operation) msg.getPart(idx++).getObject();
if (operation == null) { // native clients send a null since the op is java-serialized
operation = Operation.UPDATE;
}
@@ -134,10 +132,9 @@ public class Put65 extends BaseCommand {
}
keyPart = msg.getPart(idx++);
try {
- isDelta = ((Boolean)msg.getPart(idx).getObject()).booleanValue();
+ isDelta = ((Boolean) msg.getPart(idx).getObject()).booleanValue();
idx += 1;
- }
- catch (Exception e) {
+ } catch (Exception e) {
writeException(msg, MessageType.PUT_DELTA_ERROR, e, false, servConn);
servConn.setAsTrue(RESPONDED);
// CachePerfStats not available here.
@@ -149,19 +146,17 @@ public class Put65 extends BaseCommand {
callbackArgPart = msg.getPart(idx++);
try {
callbackArg = callbackArgPart.getObject();
- }
- catch (Exception e) {
+ } catch (Exception e) {
writeException(msg, e, false, servConn);
servConn.setAsTrue(RESPONDED);
return;
}
}
regionName = regionNamePart.getString();
-
+
try {
key = keyPart.getStringOrObject();
- }
- catch (Exception e) {
+ } catch (Exception e) {
writeException(msg, e, false, servConn);
servConn.setAsTrue(RESPONDED);
return;
@@ -169,7 +164,8 @@ public class Put65 extends BaseCommand {
final boolean isDebugEnabled = logger.isDebugEnabled();
if (isDebugEnabled) {
- logger.debug("{}: Received {}put request ({} bytes) from {} for region {} key {} txId {} posdup: {}", servConn.getName(), (isDelta ? " delta " : " "), msg.getPayloadLength(), servConn.getSocketString(), regionName, key, msg.getTransactionId(), msg.isRetry());
+ logger.debug("{}: Received {}put request ({} bytes) from {} for region {} key {} txId {} posdup: {}", servConn.getName(), (isDelta ? " delta " : " "), msg
+ .getPayloadLength(), servConn.getSocketString(), regionName, key, msg.getTransactionId(), msg.isRetry());
}
// Process the put request
@@ -188,325 +184,304 @@ public class Put65 extends BaseCommand {
}
errMessage.append(putMsg);
}
- writeErrorResponse(msg, MessageType.PUT_DATA_ERROR,
- errMessage.toString(), servConn);
+ writeErrorResponse(msg, MessageType.PUT_DATA_ERROR, errMessage.toString(), servConn);
servConn.setAsTrue(RESPONDED);
+ return;
}
- else {
- LocalRegion region = (LocalRegion)crHelper.getRegion(regionName);
- if (region == null) {
- String reason = " was not found during put request";
- writeRegionDestroyedEx(msg, regionName, reason, servConn);
- servConn.setAsTrue(RESPONDED);
+
+ LocalRegion region = (LocalRegion) crHelper.getRegion(regionName);
+ if (region == null) {
+ String reason = " was not found during put request";
+ writeRegionDestroyedEx(msg, regionName, reason, servConn);
+ servConn.setAsTrue(RESPONDED);
+ return;
+ }
+
+ if (valuePart.isNull() && operation != Operation.PUT_IF_ABSENT && region.containsKey(key)) {
+ // Invalid to 'put' a null value in an existing key
+ String putMsg = " Attempted to put a null value for existing key " + key;
+ if (isDebugEnabled) {
+ logger.debug("{}:{}", servConn.getName(), putMsg);
}
- else if (valuePart.isNull() && operation != Operation.PUT_IF_ABSENT && region.containsKey(key)) {
- // Invalid to 'put' a null value in an existing key
- String putMsg = " Attempted to put a null value for existing key "
- + key;
- if (isDebugEnabled) {
- logger.debug("{}:{}", servConn.getName(), putMsg);
+ errMessage.append(putMsg);
+ writeErrorResponse(msg, MessageType.PUT_DATA_ERROR, errMessage.toString(), servConn);
+ servConn.setAsTrue(RESPONDED);
+ return;
+ }
+
+
+ ByteBuffer eventIdPartsBuffer = ByteBuffer.wrap(eventPart.getSerializedForm());
+ long threadId = EventID.readEventIdPartsFromOptmizedByteArray(eventIdPartsBuffer);
+ long sequenceId = EventID.readEventIdPartsFromOptmizedByteArray(eventIdPartsBuffer);
+
+ EventIDHolder clientEvent = new EventIDHolder(new EventID(servConn.getEventMemberIDByteArray(), threadId, sequenceId));
+
+ Breadcrumbs.setEventId(clientEvent.getEventId());
+
+ // msg.isRetry might be set by v7.0 and later clients
+ if (msg.isRetry()) {
+ // if (logger.isDebugEnabled()) {
+ // logger.debug("DEBUG: encountered isRetry in Put65");
+ // }
+ clientEvent.setPossibleDuplicate(true);
+ if (region.getAttributes().getConcurrencyChecksEnabled()) {
+ // recover the version tag from other servers
+ clientEvent.setRegion(region);
+ if (!recoverVersionTagForRetriedOperation(clientEvent)) {
+ clientEvent.setPossibleDuplicate(false); // no-one has seen this event
}
- errMessage.append(putMsg);
- writeErrorResponse(msg, MessageType.PUT_DATA_ERROR, errMessage
- .toString(), servConn);
- servConn.setAsTrue(RESPONDED);
}
- else {
- // try {
- // this.eventId = (EventID)eventPart.getObject();
- ByteBuffer eventIdPartsBuffer = ByteBuffer.wrap(eventPart
- .getSerializedForm());
- long threadId = EventID
- .readEventIdPartsFromOptmizedByteArray(eventIdPartsBuffer);
- long sequenceId = EventID
- .readEventIdPartsFromOptmizedByteArray(eventIdPartsBuffer);
+ }
- EventIDHolder clientEvent = new EventIDHolder(
- new EventID(servConn.getEventMemberIDByteArray(),
- threadId, sequenceId));
-
- Breadcrumbs.setEventId(clientEvent.getEventId());
+ boolean result = false;
+ boolean sendOldValue = false;
+ boolean oldValueIsObject = true;
+ Object oldValue = null;
- // msg.isRetry might be set by v7.0 and later clients
- if (msg.isRetry()) {
-// if (logger.isDebugEnabled()) {
-// logger.debug("DEBUG: encountered isRetry in Put65");
-// }
- clientEvent.setPossibleDuplicate(true);
- if (region.getAttributes().getConcurrencyChecksEnabled()) {
- // recover the version tag from other servers
- clientEvent.setRegion(region);
- if (!recoverVersionTagForRetriedOperation(clientEvent)) {
- clientEvent.setPossibleDuplicate(false); // no-one has seen this event
- }
- }
+ try {
+ Object value = null;
+ if (!isDelta) {
+ value = valuePart.getSerializedForm();
+ }
+ boolean isObject = valuePart.isObject();
+ boolean isMetaRegion = region.isUsedForMetaRegion();
+ msg.setMetaRegion(isMetaRegion);
+ AuthorizeRequest authzRequest = null;
+ if (!isMetaRegion) {
+ authzRequest = servConn.getAuthzRequest();
+ }
+ if (authzRequest != null) {
+ // TODO SW: This is to handle DynamicRegionFactory create
+ // calls. Rework this when the semantics of DynamicRegionFactory are
+ // cleaned up.
+ if (DynamicRegionFactory.regionIsDynamicRegionList(regionName)) {
+ authzRequest.createRegionAuthorize((String) key);
+ }
+ // Allow PUT operations on meta regions (bug #38961)
+ else {
+ PutOperationContext putContext = authzRequest.putAuthorize(regionName, key, value, isObject, callbackArg);
+ value = putContext.getValue();
+ isObject = putContext.isObject();
+ callbackArg = putContext.getCallbackArg();
}
-
- boolean result = false;
- boolean sendOldValue = false;
- boolean oldValueIsObject = true;
- Object oldValue = null;
+ }
+ if (isDebugEnabled) {
+ logger.debug("processing put65 with operation={}", operation);
+ }
- try {
- Object value = null;
- if (!isDelta) {
- value = valuePart.getSerializedForm();
- }
- boolean isObject = valuePart.isObject();
- boolean isMetaRegion = region.isUsedForMetaRegion();
- msg.setMetaRegion(isMetaRegion);
- AuthorizeRequest authzRequest = null;
- if (!isMetaRegion) {
- authzRequest = servConn.getAuthzRequest();
- }
- if (authzRequest != null) {
- // TODO SW: This is to handle DynamicRegionFactory create
- // calls. Rework this when the semantics of DynamicRegionFactory are
- // cleaned up.
- if (DynamicRegionFactory.regionIsDynamicRegionList(regionName)) {
- authzRequest.createRegionAuthorize((String)key);
- }
- // Allow PUT operations on meta regions (bug #38961)
- else {
- PutOperationContext putContext = authzRequest.putAuthorize(
- regionName, key, value, isObject, callbackArg);
- value = putContext.getValue();
- isObject = putContext.isObject();
- callbackArg = putContext.getCallbackArg();
- }
- }
+ GeodeSecurityUtil.authorizeRegionWrite(regionName, key.toString());
+
+ // If the value is 1 byte and the byte represents null,
+ // attempt to create the entry. This test needs to be
+ // moved to DataSerializer or DataSerializer.NULL needs
+ // to be publicly accessible.
+ if (operation == Operation.PUT_IF_ABSENT) {
+ // try {
+ if (msg.isRetry() && clientEvent.getVersionTag() != null) {
+ // bug #46590 the operation was successful the last time since it
+ // was applied to the cache, so return success and the recovered
+ // version tag
if (isDebugEnabled) {
- logger.debug("processing put65 with operation={}", operation);
+ logger.debug("putIfAbsent operation was successful last time with version {}", clientEvent.getVersionTag());
}
- // If the value is 1 byte and the byte represents null,
- // attempt to create the entry. This test needs to be
- // moved to DataSerializer or DataSerializer.NULL needs
- // to be publicly accessible.
- if (operation == Operation.PUT_IF_ABSENT) {
-// try {
- if (msg.isRetry() && clientEvent.getVersionTag() != null) {
- // bug #46590 the operation was successful the last time since it
- // was applied to the cache, so return success and the recovered
- // version tag
- if (isDebugEnabled) {
- logger.debug("putIfAbsent operation was successful last time with version {}", clientEvent.getVersionTag());
- }
- // invoke basicBridgePutIfAbsent anyway to ensure that the event is distributed to all
- // servers - bug #51664
- region.basicBridgePutIfAbsent(key, value, isObject,
- callbackArg, servConn.getProxyID(), true, clientEvent);
- oldValue = null;
- } else {
- oldValue = region.basicBridgePutIfAbsent(key, value, isObject,
- callbackArg, servConn.getProxyID(), true, clientEvent);
- }
- sendOldValue = true;
- oldValueIsObject = true;
- Version clientVersion = servConn.getClientVersion();
- if (oldValue instanceof CachedDeserializable) {
- oldValue = ((CachedDeserializable)oldValue).getSerializedValue();
- } else if (oldValue instanceof byte[]) {
- oldValueIsObject = false;
- } else if ((oldValue instanceof Token)
- && clientVersion.compareTo(Version.GFE_651) <= 0) {
- // older clients don't know that Token is now a DSFID class, so we
- // put the token in a serialized form they can consume
- HeapDataOutputStream str = new HeapDataOutputStream(Version.CURRENT);
- DataOutput dstr = new DataOutputStream(str);
- InternalDataSerializer.writeSerializableObject(oldValue, dstr);
- oldValue = str.toByteArray();
- }
- result = true;
-// } catch (Exception e) {
-// writeException(msg, e, false, servConn);
-// servConn.setAsTrue(RESPONDED);
-// return;
-// }
-
- } else if (operation == Operation.REPLACE) {
-// try {
- if (requireOldValue) { // <V> replace(<K>, <V>)
- if (msg.isRetry() && clientEvent.isConcurrencyConflict()
- && clientEvent.getVersionTag() != null) {
- if (isDebugEnabled) {
- logger.debug("replace(k,v) operation was successful last time with version {}", clientEvent.getVersionTag());
- }
- }
- oldValue = region.basicBridgeReplace(key, value, isObject,
- callbackArg, servConn.getProxyID(), true, clientEvent);
- sendOldValue = !clientEvent.isConcurrencyConflict();
- oldValueIsObject = true;
- Version clientVersion = servConn.getClientVersion();
- if (oldValue instanceof CachedDeserializable) {
- oldValue = ((CachedDeserializable)oldValue).getSerializedValue();
- } else if (oldValue instanceof byte[]) {
- oldValueIsObject = false;
- } else if ((oldValue instanceof Token)
- && clientVersion.compareTo(Version.GFE_651) <= 0) {
- // older clients don't know that Token is now a DSFID class, so we
- // put the token in a serialized form they can consume
- HeapDataOutputStream str = new HeapDataOutputStream(Version.CURRENT);
- DataOutput dstr = new DataOutputStream(str);
- InternalDataSerializer.writeSerializableObject(oldValue, dstr);
- oldValue = str.toByteArray();
- }
- if (isDebugEnabled) {
- logger.debug("returning {} from replace(K,V)", oldValue);
- }
- result = true;
- } else { // boolean replace(<K>, <V>, <V>) {
- boolean didPut;
- didPut = region.basicBridgeReplace(key, expectedOldValue,
- value, isObject, callbackArg, servConn.getProxyID(), true, clientEvent);
- if (msg.isRetry() && clientEvent.getVersionTag() != null) {
- if (isDebugEnabled) {
- logger.debug("replace(k,v,v) operation was successful last time with version {}", clientEvent.getVersionTag());
- }
- didPut = true;
- }
- sendOldValue = true;
- oldValueIsObject = true;
- oldValue = didPut? Boolean.TRUE : Boolean.FALSE;
- if (isDebugEnabled) {
- logger.debug("returning {} from replace(K,V,V)", oldValue);
- }
- result = true;
- }
-// } catch (Exception e) {
-// writeException(msg, e, false, servConn);
-// servConn.setAsTrue(RESPONDED);
-// return;
-// }
-
- } else if (value == null && !isDelta) {
- // Create the null entry. Since the value is null, the value of the
- // isObject
- // the true after null doesn't matter and is not used.
- result = region.basicBridgeCreate(key, null, true, callbackArg,
- servConn.getProxyID(), true, clientEvent, false);
- if (msg.isRetry() && clientEvent.isConcurrencyConflict()
- && clientEvent.getVersionTag() != null) {
- result = true;
- if (isDebugEnabled) {
- logger.debug("create(k,null) operation was successful last time with version {}", clientEvent.getVersionTag());
- }
+ // invoke basicBridgePutIfAbsent anyway to ensure that the event is distributed to all
+ // servers - bug #51664
+ region.basicBridgePutIfAbsent(key, value, isObject, callbackArg, servConn.getProxyID(), true, clientEvent);
+ oldValue = null;
+ } else {
+ oldValue = region.basicBridgePutIfAbsent(key, value, isObject, callbackArg, servConn.getProxyID(), true, clientEvent);
+ }
+ sendOldValue = true;
+ oldValueIsObject = true;
+ Version clientVersion = servConn.getClientVersion();
+ if (oldValue instanceof CachedDeserializable) {
+ oldValue = ((CachedDeserializable) oldValue).getSerializedValue();
+ } else if (oldValue instanceof byte[]) {
+ oldValueIsObject = false;
+ } else if ((oldValue instanceof Token) && clientVersion.compareTo(Version.GFE_651) <= 0) {
+ // older clients don't know that Token is now a DSFID class, so we
+ // put the token in a serialized form they can consume
+ HeapDataOutputStream str = new HeapDataOutputStream(Version.CURRENT);
+ DataOutput dstr = new DataOutputStream(str);
+ InternalDataSerializer.writeSerializableObject(oldValue, dstr);
+ oldValue = str.toByteArray();
+ }
+ result = true;
+ // } catch (Exception e) {
+ // writeException(msg, e, false, servConn);
+ // servConn.setAsTrue(RESPONDED);
+ // return;
+ // }
+
+ } else if (operation == Operation.REPLACE) {
+ // try {
+ if (requireOldValue) { // <V> replace(<K>, <V>)
+ if (msg.isRetry() && clientEvent.isConcurrencyConflict() && clientEvent.getVersionTag() != null) {
+ if (isDebugEnabled) {
+ logger.debug("replace(k,v) operation was successful last time with version {}", clientEvent.getVersionTag());
}
}
- else {
- // Put the entry
- byte[] delta = null;
- if (isDelta) {
- delta = valuePart.getSerializedForm();
- }
- TXManagerImpl txMgr = (TXManagerImpl)servConn.getCache().getCacheTransactionManager();
- // bug 43068 - use create() if in a transaction and op is CREATE
- if (txMgr.getTXState() != null && operation.isCreate()) {
- result = region.basicBridgeCreate(key, (byte[])value, isObject, callbackArg,
- servConn.getProxyID(), true, clientEvent, true);
- } else {
- result = region.basicBridgePut(key, value, delta, isObject,
- callbackArg, servConn.getProxyID(), true, clientEvent);
- }
- if (msg.isRetry() && clientEvent.isConcurrencyConflict()
- && clientEvent.getVersionTag() != null) {
- if (isDebugEnabled) {
- logger.debug("put(k,v) operation was successful last time with version {}", clientEvent.getVersionTag());
- }
- result = true;
- }
+ oldValue = region.basicBridgeReplace(key, value, isObject, callbackArg, servConn.getProxyID(), true, clientEvent);
+ sendOldValue = !clientEvent.isConcurrencyConflict();
+ oldValueIsObject = true;
+ Version clientVersion = servConn.getClientVersion();
+ if (oldValue instanceof CachedDeserializable) {
+ oldValue = ((CachedDeserializable) oldValue).getSerializedValue();
+ } else if (oldValue instanceof byte[]) {
+ oldValueIsObject = false;
+ } else if ((oldValue instanceof Token) && clientVersion.compareTo(Version.GFE_651) <= 0) {
+ // older clients don't know that Token is now a DSFID class, so we
+ // put the token in a serialized form they can consume
+ HeapDataOutputStream str = new HeapDataOutputStream(Version.CURRENT);
+ DataOutput dstr = new DataOutputStream(str);
+ InternalDataSerializer.writeSerializableObject(oldValue, dstr);
+ oldValue = str.toByteArray();
}
- if (result) {
- servConn.setModificationInfo(true, regionName, key);
+ if (isDebugEnabled) {
+ logger.debug("returning {} from replace(K,V)", oldValue);
}
- else {
- String message = servConn.getName()
- + ": Failed to put entry for region " + regionName
- + " key " + key + " value " + valuePart;
+ result = true;
+ } else { // boolean replace(<K>, <V>, <V>) {
+ boolean didPut;
+ didPut = region.basicBridgeReplace(key, expectedOldValue, value, isObject, callbackArg, servConn.getProxyID(), true, clientEvent);
+ if (msg.isRetry() && clientEvent.getVersionTag() != null) {
if (isDebugEnabled) {
- logger.debug(message);
+ logger.debug("replace(k,v,v) operation was successful last time with version {}", clientEvent.getVersionTag());
}
- throw new Exception(message);
+ didPut = true;
}
+ sendOldValue = true;
+ oldValueIsObject = true;
+ oldValue = didPut ? Boolean.TRUE : Boolean.FALSE;
+ if (isDebugEnabled) {
+ logger.debug("returning {} from replace(K,V,V)", oldValue);
+ }
+ result = true;
}
- catch (RegionDestroyedException rde) {
- writeException(msg, rde, false, servConn);
- servConn.setAsTrue(RESPONDED);
- return;
- }
- catch (ResourceException re) {
- writeException(msg, re, false, servConn);
- servConn.setAsTrue(RESPONDED);
- return;
- }
- catch (InvalidDeltaException ide) {
- logger.info(LocalizedMessage.create(LocalizedStrings.UpdateOperation_ERROR_APPLYING_DELTA_FOR_KEY_0_OF_REGION_1,new Object[] { key, regionName }));
- writeException(msg, MessageType.PUT_DELTA_ERROR, ide, false, servConn);
- servConn.setAsTrue(RESPONDED);
- region.getCachePerfStats().incDeltaFullValuesRequested();
- return;
- }
- catch (Exception ce) {
- // If an interrupted exception is thrown , rethrow it
- checkForInterrupt(servConn, ce);
+ // } catch (Exception e) {
+ // writeException(msg, e, false, servConn);
+ // servConn.setAsTrue(RESPONDED);
+ // return;
+ // }
- // If an exception occurs during the put, preserve the connection
- writeException(msg, ce, false, servConn);
- servConn.setAsTrue(RESPONDED);
- if (ce instanceof GemFireSecurityException) {
- // Fine logging for security exceptions since these are already
- // logged by the security logger
- if (isDebugEnabled) {
- logger.debug("{}: Unexpected Security exception", servConn.getName(), ce);
- }
- }
- else if (isDebugEnabled) {
- logger.debug("{}: Unexpected Exception", servConn.getName(), ce);
+ } else if (value == null && !isDelta) {
+ // Create the null entry. Since the value is null, the value of the
+ // isObject
+ // the true after null doesn't matter and is not used.
+ result = region.basicBridgeCreate(key, null, true, callbackArg, servConn.getProxyID(), true, clientEvent, false);
+ if (msg.isRetry() && clientEvent.isConcurrencyConflict() && clientEvent.getVersionTag() != null) {
+ result = true;
+ if (isDebugEnabled) {
+ logger.debug("create(k,null) operation was successful last time with version {}", clientEvent.getVersionTag());
}
- return;
}
- finally {
- long oldStart = start;
- start = DistributionStats.getStatTime();
- stats.incProcessPutTime(start - oldStart);
+ } else {
+ // Put the entry
+ byte[] delta = null;
+ if (isDelta) {
+ delta = valuePart.getSerializedForm();
}
-
- // Increment statistics and write the reply
- if (region instanceof PartitionedRegion) {
- PartitionedRegion pr = (PartitionedRegion)region;
- if (pr.isNetworkHop().byteValue() != (byte)0) {
- writeReplyWithRefreshMetadata(msg, servConn, pr, sendOldValue, oldValueIsObject,
- oldValue, pr.isNetworkHop().byteValue(), clientEvent.getVersionTag());
- pr.setIsNetworkHop((byte)0);
- pr.setMetadataVersion(Byte.valueOf((byte)0));
- }
- else {
- writeReply(msg, servConn, sendOldValue, oldValueIsObject, oldValue, clientEvent.getVersionTag());
+ TXManagerImpl txMgr = (TXManagerImpl) servConn.getCache().getCacheTransactionManager();
+ // bug 43068 - use create() if in a transaction and op is CREATE
+ if (txMgr.getTXState() != null && operation.isCreate()) {
+ result = region.basicBridgeCreate(key, (byte[]) value, isObject, callbackArg, servConn.getProxyID(), true, clientEvent, true);
+ } else {
+ result = region.basicBridgePut(key, value, delta, isObject, callbackArg, servConn.getProxyID(), true, clientEvent);
+ }
+ if (msg.isRetry() && clientEvent.isConcurrencyConflict() && clientEvent.getVersionTag() != null) {
+ if (isDebugEnabled) {
+ logger.debug("put(k,v) operation was successful last time with version {}", clientEvent.getVersionTag());
}
+ result = true;
}
- else {
- writeReply(msg, servConn, sendOldValue, oldValueIsObject, oldValue, clientEvent.getVersionTag());
+ }
+ if (result) {
+ servConn.setModificationInfo(true, regionName, key);
+ } else {
+ String message = servConn.getName() + ": Failed to put entry for region " + regionName + " key " + key + " value " + valuePart;
+ if (isDebugEnabled) {
+ logger.debug(message);
}
- servConn.setAsTrue(RESPONDED);
+ throw new Exception(message);
+ }
+ } catch (RegionDestroyedException rde) {
+ writeException(msg, rde, false, servConn);
+ servConn.setAsTrue(RESPONDED);
+ return;
+ } catch (ResourceException re) {
+ writeException(msg, re, false, servConn);
+ servConn.setAsTrue(RESPONDED);
+ return;
+ } catch (InvalidDeltaException ide) {
+ logger.info(LocalizedMessage.create(LocalizedStrings.UpdateOperation_ERROR_APPLYING_DELTA_FOR_KEY_0_OF_REGION_1, new Object[] {
+ key,
+ regionName
+ }));
+ writeException(msg, MessageType.PUT_DELTA_ERROR, ide, false, servConn);
+ servConn.setAsTrue(RESPONDED);
+ region.getCachePerfStats().incDeltaFullValuesRequested();
+ return;
+ } catch (Exception ce) {
+ // If an interrupted exception is thrown , rethrow it
+ checkForInterrupt(servConn, ce);
+
+ // If an exception occurs during the put, preserve the connection
+ writeException(msg, ce, false, servConn);
+ servConn.setAsTrue(RESPONDED);
+ if (ce instanceof GemFireSecurityException) {
+ // Fine logging for security exceptions since these are already
+ // logged by the security logger
if (isDebugEnabled) {
- logger.debug("{}: Sent put response back to {} for region {} key {} value {}", servConn.getName(), servConn.getSocketString(), regionName, key, valuePart);
+ logger.debug("{}: Unexpected Security exception", servConn.getName(), ce);
}
- stats.incWritePutResponseTime(DistributionStats.getStatTime() - start);
+ } else if (isDebugEnabled) {
+ logger.debug("{}: Unexpected Exception", servConn.getName(), ce);
}
+ return;
+ } finally {
+ long oldStart = start;
+ start = DistributionStats.getStatTime();
+ stats.incProcessPutTime(start - oldStart);
}
+ // Increment statistics and write the reply
+ if (region instanceof PartitionedRegion) {
+ PartitionedRegion pr = (PartitionedRegion) region;
+ if (pr.isNetworkHop().byteValue() != (byte) 0) {
+ writeReplyWithRefreshMetadata(msg, servConn, pr, sendOldValue, oldValueIsObject, oldValue, pr.isNetworkHop()
+ .byteValue(), clientEvent
+ .getVersionTag());
+ pr.setIsNetworkHop((byte) 0);
+ pr.setMetadataVersion(Byte.valueOf((byte) 0));
+ } else {
+ writeReply(msg, servConn, sendOldValue, oldValueIsObject, oldValue, clientEvent.getVersionTag());
+ }
+ } else {
+ writeReply(msg, servConn, sendOldValue, oldValueIsObject, oldValue, clientEvent.getVersionTag());
+ }
+ servConn.setAsTrue(RESPONDED);
+ if (isDebugEnabled) {
+ logger.debug("{}: Sent put response back to {} for region {} key {} value {}", servConn.getName(), servConn.getSocketString(), regionName, key, valuePart);
+ }
+ stats.incWritePutResponseTime(DistributionStats.getStatTime() - start);
+
+
}
- protected void writeReply(Message origMsg, ServerConnection servConn,
- boolean sendOldValue, boolean oldValueIsObject, Object oldValue,
- VersionTag tag)
- throws IOException {
+
+ protected void writeReply(Message origMsg,
+ ServerConnection servConn,
+ boolean sendOldValue,
+ boolean oldValueIsObject,
+ Object oldValue,
+ VersionTag tag) throws IOException {
Message replyMsg = servConn.getReplyMessage();
servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
replyMsg.setMessageType(MessageType.REPLY);
- replyMsg.setNumberOfParts(sendOldValue? 3 : 1);
+ replyMsg.setNumberOfParts(sendOldValue ? 3 : 1);
replyMsg.setTransactionId(origMsg.getTransactionId());
replyMsg.addBytesPart(OK_BYTES);
if (sendOldValue) {
- replyMsg.addIntPart(oldValueIsObject?1:0);
+ replyMsg.addIntPart(oldValueIsObject ? 1 : 0);
replyMsg.addObjPart(oldValue);
}
replyMsg.send(servConn);
@@ -514,25 +489,30 @@ public class Put65 extends BaseCommand {
logger.trace("{}: rpl tx: {} parts={}", servConn.getName(), origMsg.getTransactionId(), replyMsg.getNumberOfParts());
}
}
+
protected void writeReplyWithRefreshMetadata(Message origMsg,
- ServerConnection servConn, PartitionedRegion pr,
- boolean sendOldValue, boolean oldValueIsObject, Object oldValue, byte nwHopType,
- VersionTag tag)
- throws IOException {
+ ServerConnection servConn,
+ PartitionedRegion pr,
+ boolean sendOldValue,
+ boolean oldValueIsObject,
+ Object oldValue,
+ byte nwHopType,
+ VersionTag tag) throws IOException {
Message replyMsg = servConn.getReplyMessage();
servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
replyMsg.setMessageType(MessageType.REPLY);
- replyMsg.setNumberOfParts(sendOldValue? 3 : 1);
+ replyMsg.setNumberOfParts(sendOldValue ? 3 : 1);
replyMsg.setTransactionId(origMsg.getTransactionId());
- replyMsg.addBytesPart(new byte[]{pr.getMetadataVersion().byteValue(), nwHopType});
+ replyMsg.addBytesPart(new byte[] { pr.getMetadataVersion().byteValue(), nwHopType });
if (sendOldValue) {
- replyMsg.addIntPart(oldValueIsObject?1:0);
+ replyMsg.addIntPart(oldValueIsObject ? 1 : 0);
replyMsg.addObjPart(oldValue);
}
replyMsg.send(servConn);
pr.getPrStats().incPRMetaDataSentCount();
if (logger.isTraceEnabled()) {
- logger.trace("{}: rpl with REFRESH_METADAT tx: {} parts={}", servConn.getName(), origMsg.getTransactionId(), replyMsg.getNumberOfParts());
+ logger.trace("{}: rpl with REFRESH_METADAT tx: {} parts={}", servConn.getName(), origMsg.getTransactionId(), replyMsg
+ .getNumberOfParts());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll80.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll80.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll80.java
index 4552c95..0c2a86c 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll80.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll80.java
@@ -52,6 +52,7 @@ import com.gemstone.gemfire.internal.cache.versions.VersionTag;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
import com.gemstone.gemfire.internal.security.AuthorizeRequest;
+import com.gemstone.gemfire.internal.security.GeodeSecurityUtil;
import com.gemstone.gemfire.internal.util.Breadcrumbs;
public class PutAll80 extends BaseCommand {
@@ -140,7 +141,9 @@ public class PutAll80 extends BaseCommand {
servConn.setAsTrue(RESPONDED);
return;
}
-
+
+ GeodeSecurityUtil.authorizeRegionWrite(regionName);
+
final int BASE_PART_COUNT = getBasePartCount();
// part 1: eventID
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Query.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Query.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Query.java
index 68f6a51..1b5265e 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Query.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Query.java
@@ -23,14 +23,12 @@ import java.io.IOException;
import java.util.Set;
import com.gemstone.gemfire.cache.operations.QueryOperationContext;
-import com.gemstone.gemfire.cache.query.QueryException;
import com.gemstone.gemfire.cache.query.QueryExecutionLowMemoryException;
import com.gemstone.gemfire.cache.query.QueryInvalidException;
import com.gemstone.gemfire.cache.query.QueryService;
import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import com.gemstone.gemfire.internal.cache.tier.Command;
-import com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand;
import com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommandQuery;
import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
@@ -71,31 +69,31 @@ public class Query extends BaseCommandQuery {
logger.debug("{}: Received query request from {} queryString: {}", servConn.getName(), servConn.getSocketString(), queryString);
}
try {
- // Create query
+ // Create query
QueryService queryService = ((GemFireCacheImpl)servConn.getCachedRegionHelper().getCache())
- .getLocalQueryService();
- com.gemstone.gemfire.cache.query.Query query = queryService
- .newQuery(queryString);
- Set regionNames = ((DefaultQuery)query).getRegionsInQuery(null);
+ .getLocalQueryService();
+ com.gemstone.gemfire.cache.query.Query query = queryService
+ .newQuery(queryString);
+ Set regionNames = ((DefaultQuery)query).getRegionsInQuery(null);
- // Authorization check
- QueryOperationContext queryContext = null;
- AuthorizeRequest authzRequest = servConn.getAuthzRequest();
- if (authzRequest != null) {
- queryContext = authzRequest.queryAuthorize(queryString, regionNames);
- String newQueryString = queryContext.getQuery();
- if (queryString != null && !queryString.equals(newQueryString)) {
- query = queryService.newQuery(newQueryString);
- queryString = newQueryString;
- regionNames = queryContext.getRegionNames();
- if (regionNames == null) {
- regionNames = ((DefaultQuery)query).getRegionsInQuery(null);
+ // Authorization check
+ QueryOperationContext queryContext = null;
+ AuthorizeRequest authzRequest = servConn.getAuthzRequest();
+ if (authzRequest != null) {
+ queryContext = authzRequest.queryAuthorize(queryString, regionNames);
+ String newQueryString = queryContext.getQuery();
+ if (queryString != null && !queryString.equals(newQueryString)) {
+ query = queryService.newQuery(newQueryString);
+ queryString = newQueryString;
+ regionNames = queryContext.getRegionNames();
+ if (regionNames == null) {
+ regionNames = ((DefaultQuery)query).getRegionsInQuery(null);
+ }
}
}
- }
- processQuery(msg, query, queryString, regionNames, start, null,
- queryContext, servConn, true);
+ processQuery(msg, query, queryString, regionNames, start, null,
+ queryContext, servConn, true);
} catch (QueryInvalidException e) {
throw new QueryInvalidException(e.getMessage()
+ queryString );
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java
index fa499d9..17bfec0 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java
@@ -21,6 +21,7 @@ import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
import java.lang.reflect.Method;
import java.security.AccessController;
+import java.security.Principal;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Callable;
@@ -54,6 +55,7 @@ import com.gemstone.gemfire.security.GeodePermission;
import com.gemstone.gemfire.security.GeodePermission.Operation;
import com.gemstone.gemfire.security.GeodePermission.Resource;
import com.gemstone.gemfire.security.NotAuthorizedException;
+import com.gemstone.gemfire.security.PostProcessor;
public class GeodeSecurityUtil {
@@ -212,21 +214,37 @@ public class GeodeSecurityUtil {
authorize("DATA", "MANAGE", regionName);
}
+ public static void authorizeRegionManage(String regionName, String key) {
+ authorize("DATA", "MANAGE", regionName, key);
+ }
+
public static void authorizeRegionWrite(String regionName) {
authorize("DATA", "WRITE", regionName);
}
+ public static void authorizeRegionWrite(String regionName, String key) {
+ authorize("DATA", "WRITE", regionName, key);
+ }
+
public static void authorizeRegionRead(String regionName) {
authorize("DATA", "READ", regionName);
}
+ public static void authorizeRegionRead(String regionName, String key) {
+ authorize("DATA", "READ", regionName, key);
+ }
+
public static void authorize(String resource, String operation) {
authorize(resource, operation, null);
}
- private static void authorize(String resource, String operation, String regionName) {
+ private static void authorize(String resource, String operation, String regionName){
+ authorize(resource, operation, regionName, null);
+ }
+
+ private static void authorize(String resource, String operation, String regionName, String key) {
regionName = StringUtils.stripStart(regionName, "/");
- authorize(new GeodePermission(resource, operation, regionName));
+ authorize(new GeodePermission(resource, operation, regionName, key));
}
public static void authorize(GeodePermission context) {
@@ -247,8 +265,8 @@ public class GeodeSecurityUtil {
currentUser.checkPermission(context);
}
catch (ShiroException e) {
- logger.info(currentUser.getPrincipal() + " not authorized for " + context);
- throw new NotAuthorizedException(e.getMessage(), e);
+ String msg = currentUser.getPrincipal() + " not authorized for " + context;
+ throw new NotAuthorizedException(msg, e);
}
}
@@ -262,6 +280,8 @@ public class GeodeSecurityUtil {
return true;
}
+ private static PostProcessor postProcessor;
+
/**
* initialize Shiro's Security Manager and Security Utilities
* @param securityProps
@@ -274,8 +294,7 @@ public class GeodeSecurityUtil {
String shiroConfig = securityProps.getProperty(SECURITY_SHIRO_INIT);
String customAuthenticator = securityProps.getProperty(SECURITY_CLIENT_AUTHENTICATOR);
- Object auth = getAuthenticatorObject(customAuthenticator);
-
+ Object authenticatorObject = getObject(customAuthenticator);
if (!com.gemstone.gemfire.internal.lang.StringUtils.isBlank(shiroConfig)) {
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:" + shiroConfig);
@@ -289,26 +308,46 @@ public class GeodeSecurityUtil {
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
}
+
// only set up shiro realm if user has implemented ExternalSecurity
- else if (auth != null && auth instanceof ExternalSecurity) {
- ExternalSecurity externalSecurity = (ExternalSecurity) auth;
- externalSecurity.init(securityProps);
- Realm realm = new CustomAuthRealm(externalSecurity);
+ else if (authenticatorObject != null && authenticatorObject instanceof ExternalSecurity) {
+ ExternalSecurity authenticator = (ExternalSecurity) authenticatorObject;
+ authenticator.init(securityProps);
+ Realm realm = new CustomAuthRealm(authenticator);
SecurityManager securityManager = new DefaultSecurityManager(realm);
SecurityUtils.setSecurityManager(securityManager);
}
else {
SecurityUtils.setSecurityManager(null);
}
+
+ // this initializes the post processor
+ String customPostProcessor = securityProps.getProperty(SECURITY_CLIENT_ACCESSOR_PP);
+ Object postProcessObject = getObject(customPostProcessor);
+ if(postProcessObject instanceof PostProcessor){
+ postProcessor = (PostProcessor) postProcessObject;
+ postProcessor.init(securityProps);
+ }
}
- public static Object getAuthenticatorObject(String authenticatorFactoryName) {
- if (StringUtils.isBlank(authenticatorFactoryName)) {
+ public static Object postProcess(String regionPath, Object key, Object result){
+ if(postProcessor == null)
+ return result;
+
+ Subject subject = getSubject();
+
+ if(subject == null)
+ return result;
+
+ return postProcessor.processRegionValue((Principal)subject.getPrincipal(), regionPath, key, result);
+ }
+
+ public static Object getObject(String factoryName) {
+ if (StringUtils.isBlank(factoryName)) {
return null;
}
-
try {
- Method instanceGetter = ClassLoadUtil.methodFromName(authenticatorFactoryName);
+ Method instanceGetter = ClassLoadUtil.methodFromName(factoryName);
return instanceGetter.invoke(null, (Object[]) null);
}
catch (Exception ex) {
@@ -317,7 +356,7 @@ public class GeodeSecurityUtil {
}
public static boolean isIntegratedSecurity(String authenticatorFactoryName) {
- Object auth = getAuthenticatorObject(authenticatorFactoryName);
+ Object auth = getObject(authenticatorFactoryName);
return (auth instanceof ExternalSecurity);
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
index 060878d..cb3b116 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
@@ -19,12 +19,6 @@ package com.gemstone.gemfire.internal.security.shiro;
import java.security.Principal;
import java.util.Properties;
-import com.gemstone.gemfire.internal.security.GeodeSecurityUtil;
-import com.gemstone.gemfire.management.internal.security.ResourceConstants;
-import com.gemstone.gemfire.security.ExternalSecurity;
-import com.gemstone.gemfire.security.GemFireSecurityException;
-import com.gemstone.gemfire.security.GeodePermission;
-
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
@@ -37,6 +31,12 @@ import org.apache.shiro.authz.Permission;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
+import com.gemstone.gemfire.internal.security.GeodeSecurityUtil;
+import com.gemstone.gemfire.management.internal.security.ResourceConstants;
+import com.gemstone.gemfire.security.ExternalSecurity;
+import com.gemstone.gemfire.security.GemFireSecurityException;
+import com.gemstone.gemfire.security.GeodePermission;
+
public class CustomAuthRealm extends AuthorizingRealm{
public static final String REALM_NAME = "CUSTOMAUTHREALM";
@@ -49,7 +49,7 @@ public class CustomAuthRealm extends AuthorizingRealm{
public CustomAuthRealm (String authenticatorFactory) {
- Object auth = GeodeSecurityUtil.getAuthenticatorObject(authenticatorFactory);
+ Object auth = GeodeSecurityUtil.getObject(authenticatorFactory);
if(!(auth instanceof ExternalSecurity)){
throw new GemFireSecurityException("Integrated Security requires ExternalSecurity interface.");
@@ -57,7 +57,7 @@ public class CustomAuthRealm extends AuthorizingRealm{
externalSecurity = (ExternalSecurity) auth;
}
- @Override
+ @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken authToken = (UsernamePasswordToken) token;
String username = authToken.getUsername();
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java
index cd802a9..a727b5c 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java
@@ -30,6 +30,11 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
import com.gemstone.gemfire.LogWriter;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheClosedException;
@@ -75,11 +80,6 @@ import com.gemstone.gemfire.management.internal.security.ResourceOperation;
import com.gemstone.gemfire.security.GeodePermission.Operation;
import com.gemstone.gemfire.security.GeodePermission.Resource;
-import org.springframework.shell.core.CommandMarker;
-import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-
/**
*
* @since GemFire 7.0
@@ -1027,7 +1027,7 @@ public class DataCommands implements CommandMarker {
@CliOption(key = { CliStrings.GET__VALUEKLASS }, help = CliStrings.GET__VALUEKLASS__HELP) String valueClass,
@CliOption(key = CliStrings.GET__LOAD, unspecifiedDefaultValue = "true", specifiedDefaultValue = "true", help = CliStrings.GET__LOAD__HELP) Boolean loadOnCacheMiss)
{
- GeodeSecurityUtil.authorizeRegionRead(regionPath);
+ GeodeSecurityUtil.authorizeRegionRead(regionPath, key);
Cache cache = CacheFactory.getAnyInstance();
DataCommandResult dataResult = null;
@@ -1069,6 +1069,10 @@ public class DataCommands implements CommandMarker {
dataResult.setKeyClass(keyClass);
if (valueClass != null)
dataResult.setValueClass(valueClass);
+
+ Object result = GeodeSecurityUtil.postProcess(regionPath, key, dataResult.getGetResult());
+ dataResult.setGetResult(result);
+
return makePresentationResult(dataResult);
}
@@ -1083,8 +1087,8 @@ public class DataCommands implements CommandMarker {
@CliOption(key = { CliStrings.LOCATE_ENTRY__VALUEKLASS }, help = CliStrings.LOCATE_ENTRY__VALUEKLASS__HELP) String valueClass,
@CliOption(key = { CliStrings.LOCATE_ENTRY__RECURSIVE }, help = CliStrings.LOCATE_ENTRY__RECURSIVE__HELP, unspecifiedDefaultValue = "false") boolean recursive) {
- GeodeSecurityUtil.authorizeRegionRead(regionPath);
- // Cache cache = CacheFactory.getAnyInstance();
+ GeodeSecurityUtil.authorizeRegionRead(regionPath, key);
+
DataCommandResult dataResult = null;
if (regionPath == null || regionPath.isEmpty()) {
@@ -1118,6 +1122,7 @@ public class DataCommands implements CommandMarker {
dataResult.setKeyClass(keyClass);
if (valueClass != null)
dataResult.setValueClass(valueClass);
+
return makePresentationResult(dataResult);
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java
index 48cc83a..3f1eb21 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java
@@ -26,6 +26,10 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.commons.lang.StringUtils;
+import org.apache.logging.log4j.Logger;
+import org.json.JSONArray;
+
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.CacheFactory;
@@ -77,10 +81,6 @@ import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
import com.gemstone.gemfire.management.internal.cli.util.JsonUtil;
import com.gemstone.gemfire.pdx.PdxInstance;
-import org.apache.commons.lang.StringUtils;
-import org.apache.logging.log4j.Logger;
-import org.json.JSONArray;
-
/***
*
* since 7.0
@@ -930,6 +930,21 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt
request.setQuery(query);
dataResult = DataCommands.callFunctionForRegion(request, function, members);
dataResult.setInputQuery(query);
+
+ // post process, iterate through the result for post processing
+ List<SelectResultRow> rows = dataResult.getSelectResult();
+ for(Iterator<SelectResultRow> itr = rows.iterator(); itr.hasNext();){
+ SelectResultRow row = itr.next();
+ Object newValue = GeodeSecurityUtil.postProcess(null, null, row.getValue());
+ // user is not supposed to see this row
+ if(newValue==null){
+ itr.remove();
+ }
+ else{
+ row.setValue(newValue);
+ }
+ }
+
return (dataResult);
} else {
return (dataResult = DataCommandResult.createSelectInfoResult(null, null, -1, null,
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/security/GeodePermission.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/GeodePermission.java b/geode-core/src/main/java/com/gemstone/gemfire/security/GeodePermission.java
index 95ef2c8..fab8b74 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/security/GeodePermission.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/GeodePermission.java
@@ -22,6 +22,7 @@ import org.apache.shiro.authz.permission.WildcardPermission;
public class GeodePermission extends WildcardPermission {
public static String ALL_REGIONS = "*";
+ public static String ALL_KEYS = "*";
public enum Resource {
NULL,
@@ -48,45 +49,61 @@ public class GeodePermission extends WildcardPermission {
return regionName;
}
+ public String getKey() {
+ return key;
+ }
+
// these default values are used when creating a lock around an operation
private Resource resource = Resource.NULL;
private Operation operation = Operation.NULL;
private String regionName = ALL_REGIONS;
+ private String key = ALL_KEYS;
public GeodePermission() {
this(Resource.NULL, Operation.NULL);
}
public GeodePermission(String resource, String operation) {
- this(Resource.valueOf(resource), Operation.valueOf(operation));
- }
-
- public GeodePermission(Resource resource, Operation operation){
this(resource, operation, ALL_REGIONS);
}
public GeodePermission(String resource, String operation, String regionName) {
- if(resource != null) this.resource = Resource.valueOf(resource);
- if(operation != null) this.operation = Operation.valueOf(operation);
- if(regionName != null) this.regionName = regionName;
+ this(resource, operation, regionName, ALL_KEYS);
+ }
- setParts(this.resource+":"+this.operation+":"+this.regionName, true);
+ public GeodePermission(String resource, String operation, String regionName, String key) {
+ this((resource==null) ? Resource.NULL : Resource.valueOf(resource),
+ (operation == null) ? Operation.NULL : Operation.valueOf(operation),
+ regionName,
+ key);
+ }
+
+ public GeodePermission(Resource resource, Operation operation){
+ this(resource, operation, ALL_REGIONS);
}
public GeodePermission(Resource resource, Operation operation, String regionName){
+ this(resource, operation, regionName, ALL_KEYS);
+ }
+
+ public GeodePermission(Resource resource, Operation operation, String regionName, String key){
if(resource != null) this.resource = resource;
if(operation != null) this.operation = operation;
if(regionName != null) this.regionName = regionName;
+ if(key != null) this.key = key;
- setParts(this.resource+":"+this.operation+":"+this.regionName, true);
+ setParts(this.resource+":"+this.operation+":"+this.regionName+":"+this.key, true);
}
@Override
public String toString() {
- if (ALL_REGIONS.equals(getRegionName())) {
+ if (ALL_REGIONS.equals(regionName)) {
return getResource() + ":" + getOperation();
- } else {
- return getResource() + ":" + getOperation() + ":" + getRegionName();
+ } else if(ALL_KEYS.equals(key)) {
+ return resource + ":" + operation + ":" + regionName;
+ }
+ else{
+ return resource + ":" + operation + ":" + regionName + ":" + key;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/security/PostProcessor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/PostProcessor.java b/geode-core/src/main/java/com/gemstone/gemfire/security/PostProcessor.java
new file mode 100644
index 0000000..7f959e9
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/PostProcessor.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.gemstone.gemfire.security;
+
+import java.security.Principal;
+import java.util.Properties;
+
+public interface PostProcessor {
+ void init(Properties securityProps);
+ Object processRegionValue(Principal principal, String regionPath, Object key, Object value);
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleJsonAuthorization.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleJsonAuthorization.java b/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleJsonAuthorization.java
index 3922d99..a86c871 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleJsonAuthorization.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleJsonAuthorization.java
@@ -31,11 +31,14 @@ import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
+
import javax.management.remote.JMXPrincipal;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.gemstone.gemfire.internal.logging.LogService;
+import org.apache.commons.io.IOUtils;
+import org.apache.shiro.authz.Permission;
+
import com.gemstone.gemfire.management.internal.security.ResourceConstants;
import com.gemstone.gemfire.security.AccessControl;
import com.gemstone.gemfire.security.AuthenticationFailedException;
@@ -44,9 +47,6 @@ import com.gemstone.gemfire.security.ExternalSecurity;
import com.gemstone.gemfire.security.GeodePermission;
import com.gemstone.gemfire.security.NotAuthorizedException;
-import org.apache.commons.io.IOUtils;
-import org.apache.shiro.authz.Permission;
-
/**
* This class provides a sample implementation for authentication and authorization via the {@link AccessControl}
* and {@link Authenticator} interfaces.
@@ -163,6 +163,7 @@ public class SampleJsonAuthorization implements ExternalSecurity {
Role role = new Role();
role.name = r.get("name").asText();
String regionNames = null;
+ String keys = null;
JsonNode regions = r.get("regions");
if (regions != null) {
@@ -179,8 +180,16 @@ public class SampleJsonAuthorization implements ExternalSecurity {
String[] parts = op.asText().split(":");
String resourcePart = (parts.length > 0) ? parts[0] : null;
String operationPart = (parts.length > 1) ? parts[1] : null;
+ if(parts.length>2){
+ regionNames = parts[2];
+ }
+ if(parts.length>3){
+ keys = parts[3];
+ }
String regionPart = (regionNames != null) ? regionNames : "*";
- role.permissions.add(new GeodePermission(resourcePart, operationPart, regionPart));
+ String keyPart = (keys !=null) ? keys : "*";
+
+ role.permissions.add(new GeodePermission(resourcePart, operationPart, regionPart, keyPart));
}
roleMap.put(role.name, role);
@@ -232,7 +241,6 @@ public class SampleJsonAuthorization implements ExternalSecurity {
throw new AuthenticationFailedException("Wrong username/password");
}
- LogService.getLogger().info("User=" + user + " pwd=" + pwd);
if (user != null && !userObj.pwd.equals(pwd) && !"".equals(user)) {
throw new AuthenticationFailedException("Wrong username/password");
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SamplePostProcessor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SamplePostProcessor.java b/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SamplePostProcessor.java
new file mode 100644
index 0000000..1adfb9f
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SamplePostProcessor.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.gemstone.gemfire.security.templates;
+
+import java.security.Principal;
+import java.util.Properties;
+
+import com.gemstone.gemfire.security.PostProcessor;
+
+public class SamplePostProcessor implements PostProcessor{
+ public static String MASK = "****";
+
+ public static SamplePostProcessor create(){
+ return new SamplePostProcessor();
+ }
+
+ @Override
+ public void init(final Properties securityProps) {
+
+ }
+
+ @Override
+ public Object processRegionValue(Principal principal,
+ String regionPath,
+ Object key,
+ Object value) {
+ return MASK;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/GfshParserJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/GfshParserJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/GfshParserJUnitTest.java
index 95e4943..852c230 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/GfshParserJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/GfshParserJUnitTest.java
@@ -16,7 +16,6 @@
*/
package com.gemstone.gemfire.management.internal.cli;
-import static com.gemstone.gemfire.cache.operations.OperationContext.*;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
@@ -49,6 +48,8 @@ import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
import com.gemstone.gemfire.management.internal.cli.parser.SyntaxConstants;
import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
import com.gemstone.gemfire.management.internal.security.ResourceOperation;
+import com.gemstone.gemfire.security.GeodePermission.Operation;
+import com.gemstone.gemfire.security.GeodePermission.Resource;
import com.gemstone.gemfire.test.junit.categories.UnitTest;
/**
@@ -688,7 +689,7 @@ public class GfshParserJUnitTest {
static class Commands implements CommandMarker {
@CliCommand(value = { COMMAND1_NAME, COMMAND1_NAME_ALIAS }, help = COMMAND1_HELP)
- @ResourceOperation(resource = Resource.CLUSTER, operation = OperationCode.READ)
+ @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public static String command1(@CliArgument(name = ARGUMENT1_NAME, argumentContext = ARGUMENT1_CONTEXT, help = ARGUMENT1_HELP, mandatory = true) String argument1,
@CliArgument(name = ARGUMENT2_NAME, argumentContext = ARGUMENT2_CONTEXT, help = ARGUMENT2_HELP, mandatory = false, unspecifiedDefaultValue = ARGUMENT2_UNSPECIFIED_DEFAULT_VALUE, systemProvided = false) String argument2,
@CliOption(key = {
@@ -704,13 +705,13 @@ public class GfshParserJUnitTest {
}
@CliCommand(value = { COMMAND2_NAME })
- @ResourceOperation(resource = Resource.CLUSTER, operation = OperationCode.READ)
+ @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public static String command2() {
return null;
}
@CliCommand(value = { "testParamConcat" })
- @ResourceOperation(resource = Resource.CLUSTER, operation = OperationCode.READ)
+ @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public static Result testParamConcat(@CliOption(key = { "string" }) String string,
@CliOption(key = { "stringArray" }) @CliMetaData(valueSeparator = ",") String[] stringArray,
@CliOption(key = { "stringList" }, optionContext = ConverterHint.STRING_LIST) @CliMetaData(valueSeparator = ",") List<String> stringList,
@@ -720,7 +721,7 @@ public class GfshParserJUnitTest {
}
@CliCommand(value = { "testMultiWordArg" })
- @ResourceOperation(resource = Resource.CLUSTER, operation = OperationCode.READ)
+ @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public static Result testMultiWordArg(@CliArgument(name = "arg1") String arg1,
@CliArgument(name = "arg2") String arg2) {
return null;
@@ -778,13 +779,13 @@ public class GfshParserJUnitTest {
static final String C2_MSG_AVAILABLE = C2_NAME + " is available.";
@CliCommand(value = { C1_NAME })
- @ResourceOperation(resource = Resource.CLUSTER, operation = OperationCode.READ)
+ @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public Result command1() {
return ResultBuilder.createInfoResult(C1_MSG_AVAILABLE);
}
@CliCommand(value = { C2_NAME })
- @ResourceOperation(resource = Resource.CLUSTER, operation = OperationCode.READ)
+ @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public Result command2() {
return ResultBuilder.createInfoResult(C2_MSG_AVAILABLE);
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java
index 5edca36..55284b4 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java
@@ -21,18 +21,18 @@ import static org.junit.Assert.*;
import java.util.List;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
import com.gemstone.gemfire.internal.AvailablePort;
import com.gemstone.gemfire.internal.logging.LogService;
import com.gemstone.gemfire.management.MemberMXBean;
import com.gemstone.gemfire.security.NotAuthorizedException;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
-
import com.gemstone.gemfire.test.junit.categories.SecurityTest;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
/**
*/
@@ -88,5 +88,4 @@ public class CliCommandsSecurityTest {
}
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsPostProcessorTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsPostProcessorTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsPostProcessorTest.java
new file mode 100644
index 0000000..2cfd496
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsPostProcessorTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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 com.gemstone.gemfire.management.internal.security;
+
+import static com.gemstone.gemfire.internal.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh;
+import com.gemstone.gemfire.security.templates.SamplePostProcessor;
+import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class GfshCommandsPostProcessorTest {
+ protected static int jmxPort = AvailablePortHelper.getRandomAvailableTCPPort();
+
+ private HeadlessGfsh gfsh = null;
+
+ @ClassRule
+ public static JsonAuthorizationCacheStartRule serverRule = new JsonAuthorizationCacheStartRule(
+ jmxPort, "cacheServer.json", SamplePostProcessor.class);
+
+ @Rule
+ public GfshShellConnectionRule gfshConnection;
+
+ public GfshCommandsPostProcessorTest(){
+ gfshConnection = new GfshShellConnectionRule(jmxPort);
+ }
+
+ @Before
+ public void before(){
+ gfsh = gfshConnection.getGfsh();
+ }
+
+ @Test
+ @JMXConnectionConfiguration(user = "data-user", password = "1234567")
+ public void testGetPostProcess() throws Exception {
+ gfsh.executeCommand("put --region=region1 --key=key1 --value=value1");
+ gfsh.executeCommand("put --region=region1 --key=key2 --value=value2");
+ gfsh.executeCommand("put --region=region1 --key=key3 --value=value3");
+
+ // for get command, assert the return value is processed
+ gfsh.executeCommand("get --region=region1 --key=key1");
+ assertTrue(gfsh.outputString.contains("Value : ****"), gfsh.outputString);
+
+ // for query command, assert the return values are processed
+ gfsh.executeCommand("query --query=\"select * from /region1\"");
+ assertTrue(gfsh.outputString.contains("****\n****\n****"), gfsh.outputString);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java
index 9e24317..dda844e 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java
@@ -21,6 +21,13 @@ import static org.junit.Assert.*;
import java.util.List;
+import org.apache.shiro.authz.permission.WildcardPermission;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
import com.gemstone.gemfire.internal.AvailablePortHelper;
import com.gemstone.gemfire.internal.logging.LogService;
import com.gemstone.gemfire.management.cli.Result;
@@ -30,13 +37,6 @@ import com.gemstone.gemfire.management.internal.cli.result.ErrorResultData;
import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
-import org.apache.shiro.authz.permission.WildcardPermission;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
@Category(IntegrationTest.class)
public class GfshCommandsSecurityTest {
protected static int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
@@ -172,5 +172,17 @@ public class GfshCommandsSecurityTest {
}
}
+ @Test
+ @JMXConnectionConfiguration(user = "data-user", password = "1234567")
+ public void testGetPostProcess() throws Exception {
+ gfsh.executeCommand("put --region=region1 --key=key2 --value=value2");
+ gfsh.executeCommand("put --region=region1 --key=key2 --value=value2");
+ gfsh.executeCommand("put --region=region1 --key=key3 --value=value3");
+
+ //gfsh.executeCommand("get --region=region1 --key=key1");
+ gfsh.executeCommand("query --query=\"select * from /region1\"");
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java
index d0f33d9..5183e7a 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java
@@ -48,6 +48,10 @@ public class GfshShellConnectionRule extends DescribedExternalResource {
this.useHttp = useHttp;
}
+ public GfshShellConnectionRule(int jmxPort) {
+ this.jmxPort = jmxPort;
+ }
+
protected void before(Description description) throws Throwable {
JMXConnectionConfiguration config = description.getAnnotation(JMXConnectionConfiguration.class);
if(config==null)
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java
index 223ff91..4714016 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java
@@ -16,21 +16,31 @@
*/
package com.gemstone.gemfire.management.internal.security;
-import com.gemstone.gemfire.cache.Cache;
-import com.gemstone.gemfire.cache.CacheFactory;
-import org.junit.rules.ExternalResource;
+import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
import java.util.Properties;
-import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
+import org.junit.rules.ExternalResource;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
public class JsonAuthorizationCacheStartRule extends ExternalResource {
private Cache cache;
private int jmxManagerPort = 0;
private int httpPort = 0;
private String jsonFile;
+ private Class postProcessor;
private boolean doAuthorization;
+ public JsonAuthorizationCacheStartRule(int jmxManagerPort, String jsonFile, Class postProcessor) {
+ this.jmxManagerPort = jmxManagerPort;
+ this.jsonFile = jsonFile;
+ this.doAuthorization = true;
+ this.postProcessor = postProcessor;
+ }
+
+
public JsonAuthorizationCacheStartRule(int jmxManagerPort, String jsonFile) {
this.jmxManagerPort = jmxManagerPort;
this.jsonFile = jsonFile;
@@ -64,10 +74,16 @@ public class JsonAuthorizationCacheStartRule extends ExternalResource {
if (doAuthorization) {
properties.put(SECURITY_CLIENT_ACCESSOR, JSONAuthorization.class.getName() + ".create");
}
+ if(postProcessor!=null){
+ properties.put(SECURITY_CLIENT_ACCESSOR_PP, postProcessor.getName()+".create");
+ }
+
JSONAuthorization.setUpWithJsonFile(jsonFile);
cache = new CacheFactory(properties).create();
cache.addCacheServer().start();
+
+ cache.createRegionFactory().create("region1");
}
public Cache getCache(){
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c6e7a3bd/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MultiUserDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MultiUserDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MultiUserDUnitTest.java
index e6dd1d5..644e9f8 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MultiUserDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MultiUserDUnitTest.java
@@ -17,6 +17,19 @@
package com.gemstone.gemfire.management.internal.security;
+import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import com.jayway.awaitility.Awaitility;
+import org.json.JSONException;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
import com.gemstone.gemfire.internal.logging.LogService;
import com.gemstone.gemfire.management.cli.Result.Status;
import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh;
@@ -30,18 +43,6 @@ import com.gemstone.gemfire.test.dunit.IgnoredException;
import com.gemstone.gemfire.test.dunit.VM;
import com.gemstone.gemfire.test.junit.categories.DistributedTest;
import com.gemstone.gemfire.test.junit.categories.SecurityTest;
-import com.jayway.awaitility.Awaitility;
-import org.json.JSONException;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.*;
-import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
@Category({ DistributedTest.class, SecurityTest.class })
public class MultiUserDUnitTest extends CliCommandTestBase {
@@ -97,7 +98,7 @@ public class MultiUserDUnitTest extends CliCommandTestBase {
((ErrorResultData) result.getResultData()).getErrorCode());
String resultMessage = result.getContent().toString();
String permString = command.getPermission().toString();
- assertTrue(resultMessage + " does not contain " + permString, resultMessage.contains("[" + permString + "]"));
+ assertTrue(resultMessage + " does not contain " + permString, resultMessage.contains(permString));
}
LogService.getLogger().info("vm 2 done!");
});
@@ -136,6 +137,9 @@ public class MultiUserDUnitTest extends CliCommandTestBase {
vm2Invoke.join();
vm3Invoke.join();
+ vm2Invoke.checkException();
+ vm3Invoke.checkException();
+
IgnoredException.removeAllExpectedExceptions();
}