From 06a665502134376a74cb03b1bd0fa6b29e22462e Mon Sep 17 00:00:00 2001
From: mrossign <mrossign@localhost>
Date: Wed, 18 Mar 2009 16:09:02 +0000
Subject: [PATCH] Fix for #3877: unexpected error occurred when enabling safe_data mode
---
opends/src/server/org/opends/server/replication/server/NotAssuredUpdateMsg.java | 318 ++++++++++++++++++++++++++++++++--------------------
1 files changed, 195 insertions(+), 123 deletions(-)
diff --git a/opends/src/server/org/opends/server/replication/server/NotAssuredUpdateMsg.java b/opends/src/server/org/opends/server/replication/server/NotAssuredUpdateMsg.java
index 961c8f1..2d7bf14 100644
--- a/opends/src/server/org/opends/server/replication/server/NotAssuredUpdateMsg.java
+++ b/opends/src/server/org/opends/server/replication/server/NotAssuredUpdateMsg.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
package org.opends.server.replication.server;
@@ -52,15 +52,198 @@
// The real update message this message represents
private UpdateMsg realUpdateMsg = null;
+ // V1 serialized form of the real message with assured flag set to false.
+ // Ready to be sent.
+ private byte[] realUpdateMsgNotAssuredBytesV1 = null;
+
+ // V2 serialized form of the real message with assured flag set to false.
+ // Ready to be sent.
+ private byte[] realUpdateMsgNotAssuredBytesV2 = null;
+
/**
* Creates a new empty UpdateMsg.
* This class is only used by replication server code so constructor is not
* public by security.
* @param updateMsg The real underlying update message this object represents.
+ * @throws UnsupportedEncodingException When the pre-encoding of the message
+ * failed because the UTF-8 encoding is not supported or the
+ * requested protocol version to use is not supported by this PDU.
+ *
*/
- NotAssuredUpdateMsg(UpdateMsg updateMsg)
+ NotAssuredUpdateMsg(UpdateMsg updateMsg) throws UnsupportedEncodingException
{
realUpdateMsg = updateMsg;
+
+ /**
+ * Prepare serialized forms
+ */
+ if (realUpdateMsg instanceof LDAPUpdateMsg)
+ {
+ /**
+ * Prepare V1 serialized form of the message:
+ * Get the encoding form of the real message then overwrite the assured
+ * flag to always be false.
+ */
+ byte[] origBytes = realUpdateMsg.getBytes(
+ ProtocolVersion.REPLICATION_PROTOCOL_V1);
+ // Clone the byte array to be able to modify it without problems
+ // (ModifyMsg messages for instance do not return a cloned version of
+ // their byte array)
+ byte[] bytes = new byte[origBytes.length];
+ System.arraycopy(origBytes, 0, bytes, 0, origBytes.length);
+
+ int maxLen = bytes.length;
+ int pos = -1;
+ int nZeroFound = 0; // Number of 0 value found
+ boolean found = false;
+
+ /* Look for assured flag position:
+ * The message header is stored in the form :
+ * <operation type><changenumber><dn><assured><entryuuid><change>
+ * the length of result byte array is therefore :
+ * 1 + change number length + 1 + dn length + 1 + 1 +
+ * uuid length + 1 + additional_length
+ * See LDAPUpdateMsg.encodeHeader_V1() for more information
+ */
+ // Find end of change number then end of dn
+ for (pos = 1; pos < maxLen; pos++)
+ {
+ if (bytes[pos] == (byte) 0)
+ {
+ nZeroFound++;
+ if (nZeroFound == 2) // 2 end of string to find
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ throw new UnsupportedEncodingException("Could not find end of " +
+ "change number.");
+ pos++;
+ if (pos >= maxLen)
+ throw new UnsupportedEncodingException("Reached end of packet.");
+ // Force assured flag to false
+ bytes[pos] = (byte) 0;
+
+ // Store computed V1 serialized form
+ realUpdateMsgNotAssuredBytesV1 = bytes;
+
+ /**
+ * Prepare V2 serialized form of the message:
+ * Get the encoding form of the real message then overwrite the assured
+ * flag to always be false.
+ */
+ origBytes = realUpdateMsg.getBytes(
+ ProtocolVersion.REPLICATION_PROTOCOL_V2);
+ // Clone the byte array to be able to modify it without problems
+ // (ModifyMsg messages for instance do not return a cloned version of
+ // their byte array)
+ bytes = new byte[origBytes.length];
+ System.arraycopy(origBytes, 0, bytes, 0, origBytes.length);
+
+ maxLen = bytes.length;
+ pos = -1;
+ nZeroFound = 0; // Number of 0 value found
+ found = false;
+
+ /* Look for assured flag position:
+ * The message header is stored in the form :
+ * <operation type><protocol version><changenumber><dn><entryuuid>
+ * <assured> <assured mode> <safe data level>
+ * the length of result byte array is therefore :
+ * 1 + 1 + change number length + 1 + dn length + 1 + uuid length +
+ * 1 + 1 + 1 + 1 + additional_length
+ * See LDAPUpdateMsg.encodeHeader() for more information
+ */
+ // Find end of change number then end of dn then end of uuid
+ for (pos = 2; pos < maxLen; pos++)
+ {
+ if (bytes[pos] == (byte) 0)
+ {
+ nZeroFound++;
+ if (nZeroFound == 3) // 3 end of string to find
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ throw new UnsupportedEncodingException("Could not find end of " +
+ "change number.");
+ pos++;
+ if (pos >= maxLen)
+ throw new UnsupportedEncodingException("Reached end of packet.");
+ // Force assured flag to false
+ bytes[pos] = (byte) 0;
+
+ // Store computed V2 serialized form
+ realUpdateMsgNotAssuredBytesV2 = bytes;
+
+ } else
+ {
+ if (!(realUpdateMsg instanceof UpdateMsg))
+ {
+ // Should never happen
+ throw new UnsupportedEncodingException(
+ "Unknown underlying real message type.");
+ }
+
+ /**
+ * Prepare V2 serialized form of the message:
+ * Get the encoding form of the real message then overwrite the assured
+ * flag to always be false.
+ */
+ byte[] origBytes = realUpdateMsg.getBytes(
+ ProtocolVersion.REPLICATION_PROTOCOL_V2);
+ // Clone the byte array to be able to modify it without problems
+ // (ModifyMsg messages for instance do not return a cloned version of
+ // their byte array)
+ byte[] bytes = new byte[origBytes.length];
+ System.arraycopy(origBytes, 0, bytes, 0, origBytes.length);
+
+ int maxLen = bytes.length;
+ int pos = -1;
+ int nZeroFound = 0; // Number of 0 value found
+ boolean found = false;
+
+ // This is a generic update message
+ /* Look for assured flag position:
+ * The message header is stored in the form :
+ * <operation type><protocol version><changenumber><assured>
+ * <assured mode> <safe data level>
+ * the length of result byte array is therefore :
+ * 1 + 1 + change number length + 1 + 1
+ * + 1 + 1 + additional_length
+ * See UpdateMsg.encodeHeader() for more information
+ */
+ // Find end of change number
+ for (pos = 2; pos < maxLen; pos++)
+ {
+ if (bytes[pos] == (byte) 0)
+ {
+ nZeroFound++;
+ if (nZeroFound == 1) // 1 end of string to find
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ throw new UnsupportedEncodingException("Could not find end of " +
+ "change number.");
+ pos++;
+ if (pos >= maxLen)
+ throw new UnsupportedEncodingException("Reached end of packet.");
+ // Force assured flag to false
+ bytes[pos] = (byte) 0;
+
+ // Store computed V2 serialized form
+ realUpdateMsgNotAssuredBytesV2 = bytes;
+ }
}
/**
@@ -137,127 +320,16 @@
public byte[] getBytes(short reqProtocolVersion)
throws UnsupportedEncodingException
{
- // Get the encoding of the real message then overwrite the assured flag byte
- // to always be false
- byte[] bytes = realUpdateMsg.getBytes(reqProtocolVersion);
- int maxLen = bytes.length;
- int pos = -1;
- int nZeroFound = 0; // Number of 0 value found
- boolean found = false;
-
- /**
- * Overwrite the assured flag at the right position according to
- * message type.
- */
- // Look for assured flag position
- if (realUpdateMsg instanceof LDAPUpdateMsg)
+ switch (reqProtocolVersion)
{
- // LDAP update message
- switch (reqProtocolVersion)
- {
- case ProtocolVersion.REPLICATION_PROTOCOL_V1:
- /* The message header is stored in the form :
- * <operation type><changenumber><dn><assured><entryuuid><change>
- * the length of result byte array is therefore :
- * 1 + change number length + 1 + dn length + 1 + 1 +
- * uuid length + 1 + additional_length
- * See LDAPUpdateMsg.encodeHeader_V1() for more information
- */
- // Find end of change number then end of dn
- for (pos = 1 ; pos < maxLen ; pos++ ) {
- if (bytes[pos] == (byte)0)
- {
- nZeroFound++;
- if (nZeroFound == 2) // 2 end of string to find
- {
- found = true;
- break;
- }
- }
- }
- if (!found)
- throw new UnsupportedEncodingException("Could not find end of " +
- "change number.");
- pos++;
- if (pos >= maxLen)
- throw new UnsupportedEncodingException("Reached end of packet.");
- // Force assured flag to false
- bytes[pos] = (byte)0;
- break;
- case ProtocolVersion.REPLICATION_PROTOCOL_V2:
- /* The message header is stored in the form :
- * <operation type><protocol version><changenumber><dn><entryuuid>
- * <assured> <assured mode> <safe data level>
- * the length of result byte array is therefore :
- * 1 + 1 + change number length + 1 + dn length + 1 + uuid length +
- * 1 + 1 + 1 + 1 + additional_length
- * See LDAPUpdateMsg.encodeHeader() for more information
- */
- // Find end of change number then end of dn then end of uuid
- for (pos = 2 ; pos < maxLen ; pos++ ) {
- if (bytes[pos] == (byte)0)
- {
- nZeroFound++;
- if (nZeroFound == 3) // 3 end of string to find
- {
- found = true;
- break;
- }
- }
- }
- if (!found)
- throw new UnsupportedEncodingException("Could not find end of " +
- "change number.");
- pos++;
- if (pos >= maxLen)
- throw new UnsupportedEncodingException("Reached end of packet.");
- // Force assured flag to false
- bytes[pos] = (byte)0;
- break;
- default:
- throw new UnsupportedEncodingException("Unsupported requested " +
- " protocol version: " + reqProtocolVersion);
- }
- } else
- {
- if (!(realUpdateMsg instanceof UpdateMsg))
- {
- // Should never happen
- throw new UnsupportedEncodingException(
- "Unknown underlying real message type.");
- }
- // This is a generic update message
- /* The message header is stored in the form :
- * <operation type><protocol version><changenumber><assured>
- * <assured mode> <safe data level>
- * the length of result byte array is therefore :
- * 1 + 1 + change number length + 1 + 1
- * + 1 + 1 + additional_length
- * See UpdateMsg.encodeHeader() for more information
- */
- // Find end of change number
- for (pos = 2 ; pos < maxLen ; pos++ )
- {
- if (bytes[pos] == (byte)0)
- {
- nZeroFound++;
- if (nZeroFound == 1) // 1 end of string to find
- {
- found = true;
- break;
- }
- }
- }
- if (!found)
- throw new UnsupportedEncodingException("Could not find end of " +
- "change number.");
- pos++;
- if (pos >= maxLen)
- throw new UnsupportedEncodingException("Reached end of packet.");
- // Force assured flag to false
- bytes[pos] = (byte) 0;
+ case ProtocolVersion.REPLICATION_PROTOCOL_V1:
+ return realUpdateMsgNotAssuredBytesV1;
+ case ProtocolVersion.REPLICATION_PROTOCOL_V2:
+ return realUpdateMsgNotAssuredBytesV2;
+ default:
+ throw new UnsupportedEncodingException("Unsupported requested " +
+ " protocol version: " + reqProtocolVersion);
}
- return bytes;
}
/**
@@ -332,7 +404,7 @@
protected byte[] encodeHeader(byte type, int additionalLength)
throws UnsupportedEncodingException
{
- // No called as only used by constructors using bytes
+ // Not called as only used by constructors using bytes
return null;
}
@@ -343,7 +415,7 @@
public int decodeHeader(byte type, byte[] encodedMsg)
throws DataFormatException
{
- // No called as only used by getBytes methods
+ // Not called as only used by getBytes methods
return -1;
}
--
Gitblit v1.10.0