You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by jc...@apache.org on 2016/03/01 02:53:10 UTC

incubator-geode git commit: GEODE-1014: PdxSerializationException Error when putall an object from native client withSecurity enabled

Repository: incubator-geode
Updated Branches:
  refs/heads/develop b4ed2aa50 -> aa92530d3


GEODE-1014: PdxSerializationException Error when putall an object from
native client withSecurity enabled


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/aa92530d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/aa92530d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/aa92530d

Branch: refs/heads/develop
Commit: aa92530d386096feb4ac540c1da240d18f612d42
Parents: b4ed2aa
Author: Jianxia Chen <jc...@pivotal.io>
Authored: Mon Feb 29 17:51:22 2016 -0800
Committer: Jianxia Chen <jc...@pivotal.io>
Committed: Mon Feb 29 17:51:22 2016 -0800

----------------------------------------------------------------------
 .../operations/PutAllOperationContext.java      | 275 +----------------
 .../operations/internal/UpdateOnlyMap.java      | 304 +++++++++++++++++++
 .../cache/tier/sockets/command/PutAll.java      |   4 +
 .../cache/tier/sockets/command/PutAll70.java    |   4 +
 .../cache/tier/sockets/command/PutAll80.java    |   4 +
 .../security/ClientAuthorizationDUnitTest.java  |  29 ++
 .../gemfire/security/SecurityTestUtil.java      |  44 +++
 .../gemfire/codeAnalysis/excludedClasses.txt    |   1 +
 8 files changed, 391 insertions(+), 274 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/aa92530d/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/PutAllOperationContext.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/PutAllOperationContext.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/PutAllOperationContext.java
index b05216b..cc648f7 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/PutAllOperationContext.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/PutAllOperationContext.java
@@ -17,20 +17,10 @@
 
 package com.gemstone.gemfire.cache.operations;
 
-import java.io.Serializable;
-import java.util.AbstractCollection;
-import java.util.AbstractSet;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.Map.Entry;
 
 import com.gemstone.gemfire.cache.operations.OperationContext;
-import com.gemstone.gemfire.internal.cache.CachedDeserializable;
-import com.gemstone.gemfire.internal.cache.Token;
+import com.gemstone.gemfire.cache.operations.internal.UpdateOnlyMap;
 
 /**
  * Encapsulates a {@link com.gemstone.gemfire.cache.operations.OperationContext.OperationCode#PUTALL} operation for both the
@@ -141,267 +131,4 @@ public class PutAllOperationContext extends OperationContext {
   public void setCallbackArg(Object callbackArg) {
     this.callbackArg = callbackArg;
   }
-  
-  /**
-   * This map only allows updates. No creates or removes.
-   * It was adapted from UnmodifiableMap in the jdk's Collections class.
-   * It was added to fix bug 51604.
-   * It also make sure that customers do not see Token.INVALID and
-   * CachedDeserializable to fix bug 51625.
-   * @author dschneider
-   */
-  private static class UpdateOnlyMap implements Map, Serializable {
-    private static final long serialVersionUID = -1034234728574286014L;
-
-    private final Map m;
-
-    UpdateOnlyMap(Map m) {
-      if (m==null) {
-        throw new NullPointerException();
-      }
-      this.m = m;
-    }
-
-    public int size()                        {return m.size();}
-    public boolean isEmpty()                 {return m.isEmpty();}
-    public boolean containsKey(Object key)   {return m.containsKey(key);}
-    public boolean containsValue(Object val) {
-      return values().contains(val);
-    }
-    public Object get(Object key) {
-      return exportValue(m.get(key));
-    }
-    
-    private static Object exportValue(Object v) {
-      Object result;
-      if (v == Token.INVALID) {
-        result = null;
-      } else if (v instanceof CachedDeserializable) {
-        result = ((CachedDeserializable) v).getDeserializedForReading();
-      } else {
-        result = v;
-      }
-      return result;
-    }
-
-    public Object put(Object key, Object value) {
-      if (containsKey(key)) {
-        return m.put(key,  value);
-      } else {
-        throw new UnsupportedOperationException("can not add the key \"" + key + "\"");
-      }
-    }
-    public void putAll(Map m) {
-      if (m != null) {
-        for (Object i: m.entrySet()) {
-          Map.Entry me = (Map.Entry) i;
-          put(me.getKey(), me.getValue());
-        }
-      }
-    }
-    public Object remove(Object key) {
-        throw new UnsupportedOperationException();
-    }
-    public void clear() {
-        throw new UnsupportedOperationException();
-    }
-
-    private transient Set keySet = null;
-    private transient Set entrySet = null;
-    private transient Collection values = null;
-
-    public Set keySet() {
-      if (keySet==null) {
-        keySet = Collections.unmodifiableSet(m.keySet());
-      }
-      return keySet;
-    }
-
-    public Set entrySet() {
-      if (entrySet==null) {
-        entrySet = Collections.unmodifiableSet(new EntrySet());
-      }
-      return entrySet;
-    }
-
-    private final class EntrySet extends AbstractSet {
-      public Iterator iterator() {
-          return new EntryIterator();
-      }
-      @Override
-      public int size() {
-          return m.size();
-      }
-    }
-    private class EntryIterator implements Iterator {
-      private Iterator mIterator = m.entrySet().iterator();
-
-      @Override
-      public boolean hasNext() {
-          return this.mIterator.hasNext();
-      }
-
-      @Override
-      public Object next() {
-        Entry me = (Entry) this.mIterator.next();
-        return new ExportableEntry(me);
-      }
-
-      @Override
-      public void remove() {
-        throw new UnsupportedOperationException();
-      }
-    }
-    private static class ExportableEntry implements Map.Entry {
-      private final Map.Entry e;
-
-      ExportableEntry(Map.Entry e) {
-        this.e = e;
-      }
-      public Object getKey() {
-        return this.e.getKey();
-      }
-      public Object getValue() {
-        return exportValue(this.e.getValue());
-      }
-      public Object setValue(Object value) {
-        return exportValue(this.e.setValue(value));
-      }
-      public int hashCode() {
-        return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
-      }
-      public boolean equals(Object o) {
-        if (this == o) {
-          return true;
-        }
-        if (!(o instanceof Map.Entry)) {
-          return false;
-        }
-        Entry other = (Entry) o;
-        return eq(getKey(), other.getKey()) && eq(getValue(), other.getValue());
-      }
-      public String toString() {
-        return getKey() + "=" + getValue();
-      }
-    }
-    private static boolean eq(Object o1, Object o2) {
-      return o1==null ? o2==null : o1.equals(o2);
-    }
-    
-    public Collection values() {
-      if (values==null) {
-        values = Collections.unmodifiableCollection(new Values());
-      }
-      return values;
-    }
-    
-    private final class Values extends AbstractCollection {
-      @Override
-      public Iterator iterator() {
-        return new ValueIterator();
-      }
-      @Override
-      public int size() {
-        return m.size();
-      }
-    }
-    private class ValueIterator implements Iterator {
-      private Iterator mIterator = m.values().iterator();
-
-      @Override
-      public boolean hasNext() {
-          return this.mIterator.hasNext();
-      }
-
-      @Override
-      public Object next() {
-        return exportValue(this.mIterator.next());
-      }
-
-      @Override
-      public void remove() {
-        throw new UnsupportedOperationException();
-      }
-    }
-
-    
-    /**
-     * equals is over-ridden to make sure it is based on
-     * the objects we expose and not the internal CachedDeserializables.
-     */
-    @Override
-    public boolean equals(Object o) {
-      if (o == this) {
-        return true;
-      }
-
-      if (!(o instanceof Map)) {
-        return false;
-      }
-      Map m = (Map) o;
-      if (m.size() != size()) {
-        return false;
-      }
-
-      try {
-        Iterator<Entry> i = entrySet().iterator();
-        while (i.hasNext()) {
-          Entry e = i.next();
-          Object key = e.getKey();
-          Object value = e.getValue();
-          if (value == null) {
-            if (!(m.get(key)==null && m.containsKey(key))) {
-              return false;
-            }
-          } else {
-            if (!value.equals(m.get(key))) {
-              return false;
-            }
-          }
-        }
-      } catch (ClassCastException unused) {
-        return false;
-      } catch (NullPointerException unused) {
-        return false;
-      }
-
-      return true;
-  }
-
-  /**
-   * hashCode is over-ridden to make sure it is based on
-   * the objects we expose and not the internal CachedDeserializables.
-   */
-  @Override
-  public int hashCode() {
-    int h = 0;
-    Iterator<Entry> i = entrySet().iterator();
-    while (i.hasNext()) {
-      h += i.next().hashCode();
-    }
-    return h;
-  }
-
-    @Override
-    public String toString() {
-      Iterator<Entry> i = entrySet().iterator();
-      if (! i.hasNext()) {
-        return "{}";
-      }
-      StringBuilder sb = new StringBuilder();
-      sb.append('{');
-      for (;;) {
-        Entry e = i.next();
-        Object key = e.getKey();
-        Object value = e.getValue();
-        sb.append(key   == this ? "(this Map)" : key);
-        sb.append('=');
-        sb.append(value == this ? "(this Map)" : value);
-        if (! i.hasNext()) {
-          return sb.append('}').toString();
-        }
-        sb.append(',').append(' ');
-      }
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/aa92530d/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/UpdateOnlyMap.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/UpdateOnlyMap.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/UpdateOnlyMap.java
new file mode 100644
index 0000000..8063841
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/UpdateOnlyMap.java
@@ -0,0 +1,304 @@
+/*
+ * 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.cache.operations.internal;
+
+import java.io.Serializable;
+
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+import com.gemstone.gemfire.internal.cache.Token;
+
+/**
+ * This map only allows updates. No creates or removes.
+ * It was adapted from UnmodifiableMap in the jdk's Collections class.
+ * It was added to fix bug 51604.
+ * It also make sure that customers do not see Token.INVALID and
+ * CachedDeserializable to fix bug 51625.
+ * @author dschneider
+ */
+public class UpdateOnlyMap implements Map, Serializable {
+  private static final long serialVersionUID = -1034234728574286014L;
+
+  private final Map m;
+
+  public UpdateOnlyMap(Map m) {
+    if (m==null) {
+      throw new NullPointerException();
+    }
+    this.m = m;
+  }
+
+  /**
+   * Only called by internal code
+   * to bypass exportValue() method
+   * @return internal map
+   */
+  public Map getInternalMap() {
+    return this.m;
+  }
+  
+  public int size()                        {return m.size();}
+  public boolean isEmpty()                 {return m.isEmpty();}
+  public boolean containsKey(Object key)   {return m.containsKey(key);}
+  public boolean containsValue(Object val) {
+    return values().contains(val);
+  }
+  public Object get(Object key) {
+    return exportValue(m.get(key));
+  }
+  
+  private static Object exportValue(Object v) {
+    Object result;
+    if (v == Token.INVALID) {
+      result = null;
+    } else if (v instanceof CachedDeserializable) {
+      result = ((CachedDeserializable) v).getDeserializedForReading();
+    } else {
+      result = v;
+    }
+    return result;
+  }
+
+  public Object put(Object key, Object value) {
+    if (containsKey(key)) {
+      return m.put(key,  value);
+    } else {
+      throw new UnsupportedOperationException("can not add the key \"" + key + "\"");
+    }
+  }
+  public void putAll(Map m) {
+    if (m != null) {
+      for (Object i: m.entrySet()) {
+        Map.Entry me = (Map.Entry) i;
+        put(me.getKey(), me.getValue());
+      }
+    }
+  }
+  public Object remove(Object key) {
+      throw new UnsupportedOperationException();
+  }
+  public void clear() {
+      throw new UnsupportedOperationException();
+  }
+
+  private transient Set keySet = null;
+  private transient Set entrySet = null;
+  private transient Collection values = null;
+
+  public Set keySet() {
+    if (keySet==null) {
+      keySet = Collections.unmodifiableSet(m.keySet());
+    }
+    return keySet;
+  }
+
+  public Set entrySet() {
+    if (entrySet==null) {
+      entrySet = Collections.unmodifiableSet(new EntrySet());
+    }
+    return entrySet;
+  }
+
+  private final class EntrySet extends AbstractSet {
+    public Iterator iterator() {
+        return new EntryIterator();
+    }
+    @Override
+    public int size() {
+        return m.size();
+    }
+  }
+  private class EntryIterator implements Iterator {
+    private Iterator mIterator = m.entrySet().iterator();
+
+    @Override
+    public boolean hasNext() {
+        return this.mIterator.hasNext();
+    }
+
+    @Override
+    public Object next() {
+      Entry me = (Entry) this.mIterator.next();
+      return new ExportableEntry(me);
+    }
+
+    @Override
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+  private static class ExportableEntry implements Map.Entry {
+    private final Map.Entry e;
+
+    ExportableEntry(Map.Entry e) {
+      this.e = e;
+    }
+    public Object getKey() {
+      return this.e.getKey();
+    }
+    public Object getValue() {
+      return exportValue(this.e.getValue());
+    }
+    public Object setValue(Object value) {
+      return exportValue(this.e.setValue(value));
+    }
+    public int hashCode() {
+      return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
+    }
+    public boolean equals(Object o) {
+      if (this == o) {
+        return true;
+      }
+      if (!(o instanceof Map.Entry)) {
+        return false;
+      }
+      Entry other = (Entry) o;
+      return eq(getKey(), other.getKey()) && eq(getValue(), other.getValue());
+    }
+    public String toString() {
+      return getKey() + "=" + getValue();
+    }
+  }
+  private static boolean eq(Object o1, Object o2) {
+    return o1==null ? o2==null : o1.equals(o2);
+  }
+  
+  public Collection values() {
+    if (values==null) {
+      values = Collections.unmodifiableCollection(new Values());
+    }
+    return values;
+  }
+  
+  private final class Values extends AbstractCollection {
+    @Override
+    public Iterator iterator() {
+      return new ValueIterator();
+    }
+    @Override
+    public int size() {
+      return m.size();
+    }
+  }
+  private class ValueIterator implements Iterator {
+    private Iterator mIterator = m.values().iterator();
+
+    @Override
+    public boolean hasNext() {
+        return this.mIterator.hasNext();
+    }
+
+    @Override
+    public Object next() {
+      return exportValue(this.mIterator.next());
+    }
+
+    @Override
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  
+  /**
+   * equals is over-ridden to make sure it is based on
+   * the objects we expose and not the internal CachedDeserializables.
+   */
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+
+    if (!(o instanceof Map)) {
+      return false;
+    }
+    Map m = (Map) o;
+    if (m.size() != size()) {
+      return false;
+    }
+
+    try {
+      Iterator<Entry> i = entrySet().iterator();
+      while (i.hasNext()) {
+        Entry e = i.next();
+        Object key = e.getKey();
+        Object value = e.getValue();
+        if (value == null) {
+          if (!(m.get(key)==null && m.containsKey(key))) {
+            return false;
+          }
+        } else {
+          if (!value.equals(m.get(key))) {
+            return false;
+          }
+        }
+      }
+    } catch (ClassCastException unused) {
+      return false;
+    } catch (NullPointerException unused) {
+      return false;
+    }
+
+    return true;
+}
+
+/**
+ * hashCode is over-ridden to make sure it is based on
+ * the objects we expose and not the internal CachedDeserializables.
+ */
+@Override
+public int hashCode() {
+  int h = 0;
+  Iterator<Entry> i = entrySet().iterator();
+  while (i.hasNext()) {
+    h += i.next().hashCode();
+  }
+  return h;
+}
+
+  @Override
+  public String toString() {
+    Iterator<Entry> i = entrySet().iterator();
+    if (! i.hasNext()) {
+      return "{}";
+    }
+    StringBuilder sb = new StringBuilder();
+    sb.append('{');
+    for (;;) {
+      Entry e = i.next();
+      Object key = e.getKey();
+      Object value = e.getValue();
+      sb.append(key   == this ? "(this Map)" : key);
+      sb.append('=');
+      sb.append(value == this ? "(this Map)" : value);
+      if (! i.hasNext()) {
+        return sb.append('}').toString();
+      }
+      sb.append(',').append(' ');
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/aa92530d/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll.java
index 5d2f5ca..1f668e4 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll.java
@@ -37,6 +37,7 @@ import com.gemstone.gemfire.cache.DynamicRegionFactory;
 import com.gemstone.gemfire.cache.RegionDestroyedException;
 import com.gemstone.gemfire.cache.ResourceException;
 import com.gemstone.gemfire.cache.operations.PutAllOperationContext;
+import com.gemstone.gemfire.cache.operations.internal.UpdateOnlyMap;
 import com.gemstone.gemfire.distributed.internal.DistributionStats;
 
 import java.io.IOException;
@@ -189,6 +190,9 @@ public class PutAll extends BaseCommand {
           PutAllOperationContext putAllContext = authzRequest.putAllAuthorize(
               regionName, map, null);
           map = putAllContext.getMap();
+          if (map instanceof UpdateOnlyMap) {
+            map = ((UpdateOnlyMap) map).getInternalMap();
+          }
         }
       } else {
         // no auth, so update the map based on isObjectMap here

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/aa92530d/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll70.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll70.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll70.java
index 7507299..4b13ecd 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll70.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/PutAll70.java
@@ -28,6 +28,7 @@ import com.gemstone.gemfire.cache.DynamicRegionFactory;
 import com.gemstone.gemfire.cache.RegionDestroyedException;
 import com.gemstone.gemfire.cache.ResourceException;
 import com.gemstone.gemfire.cache.operations.PutAllOperationContext;
+import com.gemstone.gemfire.cache.operations.internal.UpdateOnlyMap;
 import com.gemstone.gemfire.distributed.internal.DistributionStats;
 import com.gemstone.gemfire.internal.Version;
 import com.gemstone.gemfire.internal.cache.CachedDeserializableFactory;
@@ -235,6 +236,9 @@ public class PutAll70 extends BaseCommand {
           PutAllOperationContext putAllContext = authzRequest.putAllAuthorize(
               regionName, map, null);
           map = putAllContext.getMap();
+          if (map instanceof UpdateOnlyMap) {
+            map = ((UpdateOnlyMap) map).getInternalMap();
+          }
         }
       } else {
         // no auth, so update the map based on isObjectMap here

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/aa92530d/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 6a2b072..4552c95 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
@@ -29,6 +29,7 @@ import com.gemstone.gemfire.cache.RegionDestroyedException;
 import com.gemstone.gemfire.cache.ResourceException;
 import com.gemstone.gemfire.cache.client.internal.PutAllOp;
 import com.gemstone.gemfire.cache.operations.PutAllOperationContext;
+import com.gemstone.gemfire.cache.operations.internal.UpdateOnlyMap;
 import com.gemstone.gemfire.distributed.internal.DistributionStats;
 import com.gemstone.gemfire.internal.cache.CachedDeserializableFactory;
 import com.gemstone.gemfire.internal.cache.EventID;
@@ -275,6 +276,9 @@ public class PutAll80 extends BaseCommand {
           PutAllOperationContext putAllContext = authzRequest.putAllAuthorize(
               regionName, map, callbackArg);
           map = putAllContext.getMap();
+          if (map instanceof UpdateOnlyMap) {
+            map = ((UpdateOnlyMap) map).getInternalMap();
+          }
           callbackArg = putAllContext.getCallbackArg();
         }
       } else {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/aa92530d/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java
index 0e46da5..1d0b481 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/security/ClientAuthorizationDUnitTest.java
@@ -254,6 +254,35 @@ public class ClientAuthorizationDUnitTest extends ClientAuthorizationTestBase {
           new Integer(2), new Integer(SecurityTestUtil.NO_EXCEPTION) ));
   }
 
+  public void testPutAllWithSecurity() {
+    AuthzCredentialGenerator gen = getXmlAuthzGenerator();
+    CredentialGenerator cGen = gen.getCredentialGenerator();
+    Properties extraAuthProps = cGen.getSystemProperties();
+    Properties javaProps = cGen.getJavaProperties();
+    Properties extraAuthzProps = gen.getSystemProperties();
+    String authenticator = cGen.getAuthenticator();
+    String authInit = cGen.getAuthInit();
+    String accessor = gen.getAuthorizationCallback();
+
+    LogWriterUtils.getLogWriter().info("testPutAllWithSecurity: Using authinit: " + authInit);
+    LogWriterUtils.getLogWriter().info("testPutAllWithSecurity: Using authenticator: " + authenticator);
+    LogWriterUtils.getLogWriter().info("testPutAllWithSecurity: Using accessor: " + accessor);
+
+    // Start servers with all required properties
+    Properties serverProps = buildProperties(authenticator, accessor, false, extraAuthProps, extraAuthzProps);
+    Integer port1 = createServer1(javaProps, serverProps);
+    Integer port2 = createServer2(javaProps, serverProps);
+
+    // Start client1 with valid CREATE credentials
+    Properties createCredentials = gen.getAllowedCredentials(new OperationCode[] { OperationCode.PUTALL }, new String[] { regionName }, 1);
+    javaProps = cGen.getJavaProperties();
+    LogWriterUtils.getLogWriter().info("testPutAllWithSecurity: For first client credentials: " + createCredentials);
+    createClient1NoException(javaProps, authInit, port1, port2, createCredentials);
+
+    // Perform some put all operations from client1
+    client1.invoke(() -> SecurityTestUtil.doPutAllP());
+  }
+  
   protected void createClient2NoException(Properties javaProps, String authInit,
       Integer port1, Integer port2, Properties getCredentials) {
     client2.invoke(() -> ClientAuthenticationDUnitTest.createCacheClient( authInit, getCredentials, javaProps, port1, port2,

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/aa92530d/geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java b/geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
index ad9b3e1..d3c379f 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/security/SecurityTestUtil.java
@@ -29,6 +29,7 @@ import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -78,6 +79,9 @@ import com.gemstone.gemfire.internal.AvailablePort;
 import com.gemstone.gemfire.internal.logging.InternalLogWriter;
 import com.gemstone.gemfire.internal.logging.PureLogWriter;
 import com.gemstone.gemfire.internal.util.Callable;
+import com.gemstone.gemfire.pdx.PdxReader;
+import com.gemstone.gemfire.pdx.PdxSerializable;
+import com.gemstone.gemfire.pdx.PdxWriter;
 import com.gemstone.gemfire.test.dunit.Assert;
 import com.gemstone.gemfire.test.dunit.DistributedTestCase;
 import com.gemstone.gemfire.test.dunit.DistributedTestUtils;
@@ -831,6 +835,46 @@ public class SecurityTestUtil extends DistributedTestCase {
     }
   }
 
+  public static class Employee implements PdxSerializable
+  {
+    private Long Id;
+    private String fname;
+    private String lname;
+    
+    public Employee() {}
+    
+    public Employee(Long id, String fn, String ln){
+      this.Id = id;
+      this.fname = fn;
+      this.lname = ln;
+    }
+        
+    /**
+     * For test purpose, to make sure
+     * the object is not deserialized
+     */
+    @Override
+    public void fromData(PdxReader in) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void toData(PdxWriter out) {
+      out.writeLong("Id", Id);
+      out.writeString("fname", fname);
+      out.writeString("lname", lname);
+    }
+    
+  }
+  
+  public static void doPutAllP() throws Exception {    
+    Region region = getCache().getRegion(regionName);
+    assertNotNull(region);
+    Map map = new LinkedHashMap();
+    map.put("1010L", new Employee(1010L, "John", "Doe"));
+    region.putAll(map);
+  }
+  
   private static void doGetAllP(Integer multiUserIndex,
       Integer expectedResult, boolean useTX) {
     Region region = null;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/aa92530d/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt
----------------------------------------------------------------------
diff --git a/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt b/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt
index 2097878..d5682a6 100644
--- a/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt
+++ b/geode-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/excludedClasses.txt
@@ -116,3 +116,4 @@ com/gemstone/org/apache/logging/log4j/core/config/xml/GemFireXmlConfiguration$Er
 com/gemstone/gemfire/internal/ra/GFConnectionFactoryImpl
 com/gemstone/gemfire/internal/ra/GFConnectionImpl
 com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionFactory
+com/gemstone/gemfire/cache/operations/internal/UpdateOnlyMap
\ No newline at end of file