geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bschucha...@apache.org
Subject incubator-geode git commit: GEODE-478: Message class length field overflows if size is > 2GB
Date Mon, 22 Feb 2016 16:16:22 GMT
Repository: incubator-geode
Updated Branches:
  refs/heads/develop 9899940bb -> 1e3f89ddc


GEODE-478: Message class length field overflows if size is > 2GB

Message size is now restricted to 1GB.  If this is exceeded a
MessageTooLargeException is thrown.

I think the original intent of this ticket was to have messaging handle
the carving up of the message into multiple Messages somehow, but I think
this is the correct approach.  This will ensure that the problem doesn't
cause the current connection to be terminated and the operation retried
on another server and make sure that the exception gets back to the point
of initiation.

Barry already has a way to avoid large messages in WAN senders that can
be ported to Geode.


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

Branch: refs/heads/develop
Commit: 1e3f89ddcd4bfebe0e3e9c3e0f61478826d5fdde
Parents: 9899940
Author: Bruce Schuchardt <bschuchardt@pivotal.io>
Authored: Mon Feb 22 08:14:56 2016 -0800
Committer: Bruce Schuchardt <bschuchardt@pivotal.io>
Committed: Mon Feb 22 08:14:56 2016 -0800

----------------------------------------------------------------------
 .../cache/client/internal/OpExecutorImpl.java   | 14 +++-
 .../internal/DistributionManager.java           |  2 +-
 .../gms/mgr/GMSMembershipManager.java           |  3 -
 .../cache/tier/sockets/BaseCommand.java         | 40 ++++------
 .../cache/tier/sockets/CacheClientProxy.java    |  8 +-
 .../internal/cache/tier/sockets/Message.java    | 78 ++++++++++++--------
 .../tier/sockets/MessageTooLargeException.java  | 29 ++++++++
 .../internal/cache/tier/sockets/Part.java       |  6 +-
 .../command/TXSynchronizationCommand.java       |  5 +-
 .../gemfire/distributed/LocatorDUnitTest.java   | 11 ++-
 .../cache/tier/sockets/MessageJUnitTest.java    | 47 ++++++++++--
 .../codeAnalysis/sanctionedSerializables.txt    |  1 +
 12 files changed, 168 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
index ca14b76..5d05fe5 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
@@ -35,6 +35,7 @@ import com.gemstone.gemfire.CancelCriterion;
 import com.gemstone.gemfire.CancelException;
 import com.gemstone.gemfire.CopyException;
 import com.gemstone.gemfire.GemFireException;
+import com.gemstone.gemfire.GemFireIOException;
 import com.gemstone.gemfire.SerializationException;
 import com.gemstone.gemfire.cache.CacheRuntimeException;
 import com.gemstone.gemfire.cache.RegionDestroyedException;
@@ -59,6 +60,7 @@ import com.gemstone.gemfire.internal.cache.TXManagerImpl;
 import com.gemstone.gemfire.internal.cache.TXStateProxy;
 import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
 import com.gemstone.gemfire.internal.cache.tier.BatchException;
+import com.gemstone.gemfire.internal.cache.tier.sockets.MessageTooLargeException;
 import com.gemstone.gemfire.internal.cache.wan.BatchException70;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
@@ -167,6 +169,8 @@ public class OpExecutorImpl implements ExecutablePool {
           Object result = executeWithPossibleReAuthentication(conn, op);
           success = true;
           return result;
+        } catch (MessageTooLargeException e) {
+          throw new GemFireIOException("unable to transmit message to server", e);
         }
         catch (Exception e) {
           //This method will throw an exception if we need to stop
@@ -655,7 +659,15 @@ public class OpExecutorImpl implements ExecutablePool {
         logger.debug("OpExecutor.handleException on Connection to {}", conn.getServer(),e);
       }
     }
-    if (e instanceof NotSerializableException) {
+    
+    // first take care of all exceptions that should not invalidate the
+    // connection and do not need to be logged
+    
+    if (e instanceof MessageTooLargeException) {
+      title = null;
+      exToThrow = new GemFireIOException("message is too large to transmit", e);
+    }
+    else if (e instanceof NotSerializableException) {
       title = null; //no message
       exToThrow = new SerializationException("Pool message failure", e);
     }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
index 51bfb53..24b0697 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionManager.java
@@ -2630,7 +2630,7 @@ public class DistributionManager
     // "RMI TCP Connection(259)-10.80.10.55":
     //  waiting to lock monitor 0x080f6598 (object 0xe3bacd90, a com.gemstone.gemfire.distributed.internal.membership.jgroup.JGroupMembershipManager$ViewLock),
     //  which is held by "View Message Processor"
-    // NEED to sync on viewLock first.
+    // NEED to prevent view changes while installing a listener.
     DistributionChannel ch = this.channel;
     if (ch != null) {
       MembershipManager mgr = ch.getMembershipManager();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
index edfee10..3d554fa 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/mgr/GMSMembershipManager.java
@@ -1393,9 +1393,6 @@ public class GMSMembershipManager implements MembershipManager, Manager
    * @return the current membership view coordinator
    */
   public DistributedMember getCoordinator() {
-    // note - we go straight to JoinLeave because the
-    // DistributionManager queues view changes in a serial executor, where
-    // they're asynchronously installed.  The DS may still see the old coordinator
     latestViewLock.readLock().lock();
     try {
       return latestView == null? null : latestView.getCoordinator();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
index dd13f19..bef4bf1 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommand.java
@@ -176,6 +176,16 @@ public abstract class BaseCommand implements Command {
       }
       
     }   
+    catch (TransactionException
+        | CopyException
+        | SerializationException
+        | CacheWriterException
+        | CacheLoaderException
+        | GemFireSecurityException
+        | PartitionOfflineException
+        | MessageTooLargeException e) {
+      handleExceptionNoDisconnect(msg, servConn, e);
+    }
     catch (EOFException eof) {
       BaseCommand.handleEOFException(msg, servConn, eof);
       // TODO:Asif: Check if there is any need for explicitly returning
@@ -183,35 +193,13 @@ public abstract class BaseCommand implements Command {
     }
     catch (InterruptedIOException e) { // Solaris only
       BaseCommand.handleInterruptedIOException(msg, servConn, e);
-      return;
     }
     catch (IOException e) {
       BaseCommand.handleIOException(msg, servConn, e);
-      return;
     }
     catch (DistributedSystemDisconnectedException e) {
       BaseCommand.handleShutdownException(msg, servConn, e);
-      return;
-    }
-    catch (PartitionOfflineException e) { // fix for bug #42225
-      handleExceptionNoDisconnect(msg, servConn, e);
-    }
-    catch (GemFireSecurityException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
     }
-    catch (CacheLoaderException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    }
-    catch (CacheWriterException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    } catch (SerializationException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    } catch (CopyException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    } catch (TransactionException e) {
-      handleExceptionNoDisconnect(msg, servConn, e);
-    }
-    
     catch (VirtualMachineError err) {
       SystemFailure.initiateFailure(err);
       // If this ever returns, rethrow the error.  We're poisoned
@@ -223,11 +211,6 @@ public abstract class BaseCommand implements Command {
     } finally {
       EntryLogger.clearSource();
     }
-    /*
-     * finally { // Keep track of the fact that a message is no longer being //
-     * processed. servConn.setNotProcessingMessage();
-     * servConn.clearRequestMsg(); }
-     */
   }
 
   /**
@@ -656,6 +639,9 @@ public abstract class BaseCommand implements Command {
     if (logger.isDebugEnabled()) {
       logger.debug("{}: Wrote exception: {}", servConn.getName(), e.getMessage(), e);
     }
+    if (e instanceof MessageTooLargeException) {
+      throw (IOException)e;
+    }
   }
 
   protected static void writeErrorResponse(Message origMsg, int messageType,

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
index 69ae6d8..f650fee 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java
@@ -2616,8 +2616,9 @@ public class CacheClientProxy implements ClientSession {
             }
           }
           clientMessage = null;
-        }
-        catch (IOException e) {
+        } catch (MessageTooLargeException e) {
+          logger.warn("Message too large to send to client: {}, {}", clientMessage, e.getMessage());
+        } catch (IOException e) {
           // Added the synchronization below to ensure that exception handling
           // does not occur while stopping the dispatcher and vice versa.
           synchronized (this._stopDispatchingLock) {
@@ -2960,6 +2961,9 @@ public class CacheClientProxy implements ClientSession {
         }
         // The exception handling code was modeled after the MessageDispatcher
         // run method
+      } catch (MessageTooLargeException e) {
+        logger.warn("Message too large to send to client: {}, {}", clientMessage, e.getMessage());
+
       } catch (IOException e) {
         synchronized (this._stopDispatchingLock) {
           // Pause or unregister proxy

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
index 4bfd44b..a6495e2 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Message.java
@@ -82,6 +82,11 @@ import com.gemstone.gemfire.internal.util.BlobHelper;
  */
 public class Message  {
 
+  /**
+   * maximum size of an outgoing message.  See GEODE-478
+   */
+  static final int MAX_MESSAGE_SIZE = Integer.getInteger("gemfire.client.max-message-size",
1073741824).intValue();
+
   private static final Logger logger = LogService.getLogger();
   
   private static final int PART_HEADER_SIZE = 5; // 4 bytes for length, 1 byte for isObject
@@ -197,6 +202,14 @@ public class Message  {
       this.partsList = newPartsList;
     }
   }
+  
+  /**
+   * For boundary testing we may need to inject mock parts
+   * @param parts
+   */
+  void setParts(Part[] parts) {
+    this.partsList = parts;
+  }
 
   public void setTransactionId(int transactionId) {
     this.messageModified = true;
@@ -521,57 +534,60 @@ public class Message  {
       if (cb == null) {
         throw new IOException("No buffer");
       }
+      int msgLen = 0;
       synchronized(cb) {
-        int numOfSecureParts = 0;
-        Part securityPart = this.getSecurityPart();
-        boolean isSecurityHeader = false;
+        long totalPartLen = 0;
+        long headerLen = 0;
+        int partsToTransmit = this.numberOfParts;
         
-        if (securityPart != null) {
-          isSecurityHeader = true;
-          numOfSecureParts = 1;
-        }
-        else if (this.securePart != null) {
-          // This is a client sending this message.
-          securityPart = this.securePart;
-          isSecurityHeader = true;
-          numOfSecureParts = 1;          
-        }
-
-        int totalPartLen = 0;
-        for (int i=0;i<this.numberOfParts;i++){
+        for (int i=0; i < this.numberOfParts; i++) {
           Part part = this.partsList[i];
+          headerLen += PART_HEADER_SIZE;
           totalPartLen += part.getLength();
         }
 
-        if(numOfSecureParts == 1) {
+        Part securityPart = this.getSecurityPart();
+        if (securityPart == null) {
+          securityPart = this.securePart;
+        }
+        if (securityPart != null) {
+          headerLen += PART_HEADER_SIZE;
           totalPartLen += securityPart.getLength();
+          partsToTransmit++;
         }
-        int msgLen = (PART_HEADER_SIZE * (this.numberOfParts + numOfSecureParts)) + totalPartLen;
+
+        if ( (headerLen + totalPartLen) > Integer.MAX_VALUE ) {
+          throw new MessageTooLargeException("Message size (" + (headerLen + totalPartLen)

+              + ") exceeds maximum integer value");
+        }
+        
+        msgLen = (int)(headerLen + totalPartLen);
+        
+        if (msgLen > MAX_MESSAGE_SIZE) {
+          throw new MessageTooLargeException("Message size(" + msgLen
+              + ") exceeds gemfire.client.max-message-size setting (" + MAX_MESSAGE_SIZE
+ ")");
+        }
+        
         cb.clear();
-        packHeaderInfoForSending(msgLen, isSecurityHeader);
-        for (int i=0;i<this.numberOfParts + numOfSecureParts;i++) {
-          Part part = null;
-          if(i == this.numberOfParts) {
-            part = securityPart;
-          }
-          else {
-            part = partsList[i];
-          }
+        packHeaderInfoForSending(msgLen, (securityPart != null));
+        for (int i=0; i < partsToTransmit; i++) {
+          Part part = (i == this.numberOfParts) ? securityPart : partsList[i];
+
           if (cb.remaining() < PART_HEADER_SIZE) {
             flushBuffer();
           }
+          
           int partLen = part.getLength();
           cb.putInt(partLen);
           cb.put(part.getTypeCode());
           if (partLen <= cb.remaining()) {
-            part.sendTo(cb);
+            part.writeTo(cb);
           } else {
             flushBuffer();
-            // send partBytes
             if (this.sockCh != null) {
-              part.sendTo(this.sockCh, cb);
+              part.writeTo(this.sockCh, cb);
             } else {
-              part.sendTo(this.os, cb);
+              part.writeTo(this.os, cb);
             }
             if (this.msgStats != null) {
               this.msgStats.incSentBytes(partLen);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
new file mode 100755
index 0000000..e5cac59
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.internal.cache.tier.sockets;
+
+import java.io.IOException;
+
+public class MessageTooLargeException extends IOException {
+
+  private static final long serialVersionUID = -8970585803331525833L;
+  
+  public MessageTooLargeException(String message) {
+    super(message);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
index c681621..80b5c0a 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/Part.java
@@ -284,7 +284,7 @@ public class Part {
    * A stream is used because the client is configured for old IO (instead of nio).
    * @param buf the buffer to use if any data needs to be copied to one
    */
-  public final void sendTo(OutputStream out, ByteBuffer buf) throws IOException {
+  public final void writeTo(OutputStream out, ByteBuffer buf) throws IOException {
     if (getLength() > 0) {
       if (this.part instanceof byte[]) {
         byte[] bytes = (byte[])this.part;
@@ -318,7 +318,7 @@ public class Part {
    * Precondition: caller has already checked the length of this part
    * and it will fit into "buf".
    */
-  public final void sendTo(ByteBuffer buf) {
+  public final void writeTo(ByteBuffer buf) {
     if (getLength() > 0) {
       if (this.part instanceof byte[]) {
         buf.put((byte[])this.part);
@@ -350,7 +350,7 @@ public class Part {
    * so they need to be written directly to the socket.
    * Precondition: buf contains nothing that needs to be sent
    */
-  public final void sendTo(SocketChannel sc, ByteBuffer buf) throws IOException {
+  public final void writeTo(SocketChannel sc, ByteBuffer buf) throws IOException {
     if (getLength() > 0) {
       final int BUF_MAX = buf.capacity();
       if (this.part instanceof byte[]) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
index 82e8114..1975601 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
@@ -30,6 +30,7 @@ import com.gemstone.gemfire.internal.cache.tier.Command;
 import com.gemstone.gemfire.internal.cache.tier.MessageType;
 import com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand;
 import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
+import com.gemstone.gemfire.internal.cache.tier.sockets.MessageTooLargeException;
 import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
 import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
 
@@ -153,8 +154,8 @@ public class TXSynchronizationCommand extends BaseCommand {
                       txMgr.removeHostedTXState(txState.getTxId());
                     } catch (IOException e) {
                       // not much can be done here
-                      if (isDebugEnabled) {
-                        logger.debug("Problem writing reply to client", e);
+                      if (isDebugEnabled || (e instanceof MessageTooLargeException)) {
+                        logger.warn("Problem writing reply to client", e);
                       }
                     }
                     servConn.setAsTrue(RESPONDED);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
index b3f627a..3095885 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/LocatorDUnitTest.java
@@ -114,6 +114,14 @@ public class LocatorDUnitTest extends DistributedTestCase {
   
   ////////  Test Methods
 
+  public void testRepeat() throws Exception {
+    long giveup = System.currentTimeMillis() + (120 * 60000);
+    do {
+      testCollocatedLocatorWithSecurity();
+      tearDown(); setUp();
+    } while (System.currentTimeMillis() < giveup);
+  }
+
   
   /**
    * SQLFire uses a colocated locator in a dm-type=normal VM.  This tests that
@@ -209,7 +217,8 @@ public class LocatorDUnitTest extends DistributedTestCase {
       properties.put("start-locator", locators);
       properties.put("log-level", LogWriterUtils.getDUnitLogLevel());
       system = (InternalDistributedSystem)DistributedSystem.connect(properties);
-      System.out.println("done connecting distributed system");
+      System.out.println("done connecting distributed system.  Membership view is " +
+        MembershipManagerHelper.getMembershipManager(system).getView());
       
       assertEquals("should be the coordinator", system.getDistributedMember(), MembershipManagerHelper.getCoordinator(system));
       NetView view = MembershipManagerHelper.getMembershipManager(system).getView();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
index 3dc5a7d..b7bd47a 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/MessageJUnitTest.java
@@ -38,15 +38,17 @@ public class MessageJUnitTest {
   Socket mockSocket;
   MessageStats mockStats;
   ByteBuffer msgBuffer;
+  ServerConnection mockServerConnection;
   
   @Before
   public void setUp() throws Exception {
     mockSocket = mock(Socket.class);
-    message = new Message(5, Version.CURRENT);
-    assertEquals(5, message.getNumberOfParts());
+    message = new Message(2, Version.CURRENT);
+    assertEquals(2, message.getNumberOfParts());
     mockStats = mock(MessageStats.class);
     msgBuffer = ByteBuffer.allocate(1000);
-    message.setComms(mockSocket, msgBuffer, mockStats);
+    mockServerConnection = mock(ServerConnection.class);
+    message.setComms(mockServerConnection, mockSocket, msgBuffer, mockStats);
   }
 
   @Test
@@ -60,8 +62,8 @@ public class MessageJUnitTest {
   @Test
   public void numberOfPartsIsAdjusted() {
     int numParts = message.getNumberOfParts();
-    message.setNumberOfParts(2*numParts);
-    assertEquals(2*numParts, message.getNumberOfParts());
+    message.setNumberOfParts(2*numParts+1);
+    assertEquals(2*numParts+1, message.getNumberOfParts());
     message.addBytesPart(new byte[1]);
     message.addIntPart(2);
     message.addLongPart(3);
@@ -70,6 +72,41 @@ public class MessageJUnitTest {
     assertEquals(5, message.getNextPartNumber());
   }
   
+  @Test
+  public void messageLongerThanMaxIntIsRejected() throws Exception {
+    Part[] parts = new Part[2];
+    Part mockPart1 = mock(Part.class);
+    when(mockPart1.getLength()).thenReturn(Integer.MAX_VALUE/2);
+    parts[0] = mockPart1;
+    parts[1] = mockPart1;
+    message.setParts(parts);
+    try {
+      message.send();
+    } catch (MessageTooLargeException e) {
+      assertTrue(e.getMessage().contains("exceeds maximum integer value"));
+      return;
+    }
+    fail("expected an exception but none was thrown");
+  }
+  
+  @Test
+  public void maxMessageSizeIsRespected() throws Exception {
+    Part[] parts = new Part[2];
+    Part mockPart1 = mock(Part.class);
+    when(mockPart1.getLength()).thenReturn(Message.MAX_MESSAGE_SIZE/2);
+    parts[0] = mockPart1;
+    parts[1] = mockPart1;
+    message.setParts(parts);
+    try {
+      message.send();
+    } catch (MessageTooLargeException e) {
+      assertFalse(e.getMessage().contains("exceeds maximum integer value"));
+      return;
+    }
+    fail("expected an exception but none was thrown");
+  }
+  
+  
   // TODO many more tests are needed
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1e3f89dd/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
b/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
index 3747416..f3c1c5d 100644
--- a/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
+++ b/gemfire-core/src/test/resources/com/gemstone/gemfire/codeAnalysis/sanctionedSerializables.txt
@@ -376,6 +376,7 @@ com/gemstone/gemfire/internal/cache/tier/BatchException,true,-670707410779130556
 com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientNotifier$2,false,this$0:com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientNotifier
 com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy$MessageDispatcher$1,true,0,this$0:com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy$MessageDispatcher
 com/gemstone/gemfire/internal/cache/tier/sockets/ClientTombstoneMessage$TOperation,false
+com/gemstone/gemfire/internal/cache/tier/sockets/MessageTooLargeException,true,-8970585803331525833
 com/gemstone/gemfire/internal/cache/tier/sockets/UnregisterAllInterest,true,5026160621257178459
 com/gemstone/gemfire/internal/cache/tx/TransactionalOperation$ServerRegionOperation,false
 com/gemstone/gemfire/internal/cache/versions/ConcurrentCacheModificationException,false


Mime
View raw message