mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Ludovic Poitou
23.41.2011 3d79ba1c83df1be51983cb4ef719834aa368b61d
Fix issue OPENDJ-213.
Processing of the string based cookie was not handling errors consistently, as code was duplicated between the constructor and another parsing method.
The fix required some minor refactoring.
All nightlytests have been successfully passing on my development machine.
7 files modified
128 ■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/replication/common/MultiDomainServerState.java 79 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ECLUpdateMsg.java 6 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/replication/server/DraftCNDbHandler.java 4 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/replication/server/ECLServerHandler.java 5 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServer.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java 30 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/replication/common/MultiDomainServerState.java
@@ -23,12 +23,15 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 */
package org.opends.server.replication.common;
import java.util.HashMap;
import java.util.Iterator;
import static org.opends.messages.ReplicationMessages.*;
import java.util.Map;
import java.util.TreeMap;
import java.util.Iterator;
import org.opends.messages.Category;
import org.opends.messages.Message;
@@ -47,7 +50,7 @@
  /**
   * The list of (domain service id, ServerState).
   */
  private TreeMap<String, ServerState> list;
  private Map<String, ServerState> list;
  /**
   * Creates a new empty object.
@@ -58,6 +61,18 @@
  }
  /**
   * Create an object from a string representation.
   * @param mdss The provided string representation of the state.
   * @throws DirectoryException when the string has an invalid format
   */
  public MultiDomainServerState(String mdss)
          throws DirectoryException
  {
    list = splitGenStateToServerStates(mdss);
  }
  /**
   * Empty the object..
   * After this call the object will be in the same state as if it
   * was just created.
@@ -117,40 +132,10 @@
  }
  /**
   * Create an object from a string representation.
   * @param mdss The provided string representation of the state.
   */
  public MultiDomainServerState(String mdss)
  {
    list = new TreeMap<String, ServerState>();
    if ((mdss != null) &&
        (mdss.length()>0))
    {
      String[] domains = mdss.split(";");
      for (String domain : domains)
      {
        String[] fields = domain.split(":");
        String name = fields[0];
        ServerState ss = new ServerState();
        if (fields.length>1)
        {
          String strState = fields[1].trim();
          String[] strCN = strState.split(" ");
          for (String sr : strCN)
          {
            ChangeNumber fromChangeNumber = new ChangeNumber(sr);
            ss.update(fromChangeNumber);
          }
        }
        this.list.put(name, ss);
      }
    }
  }
  /**
   * Returns a string representation of this object.
   * @return The string representation.
   */
  @Override
  public String toString()
  {
    String res = "";
@@ -226,16 +211,19 @@
  /**
   * Splits the provided generalizedServerState being a String with the
   * following syntax: "domain1:state1;domain2:state2;..."
   * to a hashmap of (domain DN, domain ServerState).
   * to a TreeMap of (domain DN, domain ServerState).
   * @param multidomainserverstate the provided state
   * @exception DirectoryException when an error occurs
   * @return the splited state.
   * @return the split state.
   */
  public static HashMap<String,ServerState> splitGenStateToServerStates(
  public static Map<String,ServerState> splitGenStateToServerStates(
      String multidomainserverstate)
      throws DirectoryException
  {
    HashMap<String,ServerState> startStates = new HashMap<String,ServerState>();
    Map<String, ServerState> startStates = new TreeMap<String, ServerState>();
    if ((multidomainserverstate != null)
        && (multidomainserverstate.length() > 0))
    {
    try
    {
      // Split the provided multidomainserverstate into domains
@@ -247,6 +235,11 @@
        ServerState serverStateByDomain = new ServerState();
        String[] fields = domain.split(":");
          if (fields.length == 0)
          {
            throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
                ERR_INVALID_COOKIE_SYNTAX.get());
          }
        String domainBaseDN = fields[0];
        if (fields.length>1)
        {
@@ -261,13 +254,19 @@
        startStates.put(domainBaseDN, serverStateByDomain);
      }
    }
      catch (DirectoryException de)
      {
        throw de;
      }
    catch(Exception e)
    {
      throw new DirectoryException(
          ResultCode.OPERATIONS_ERROR,
          Message.raw(Category.SYNC, Severity.INFORMATION,"Exception raised: "),
            ResultCode.PROTOCOL_ERROR,
            Message.raw(Category.SYNC, Severity.INFORMATION,
            "Exception raised: " + e),
          e);
    }
    }
    return startStates;
  }
}
opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ECLUpdateMsg.java
@@ -23,11 +23,13 @@
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 */
package org.opends.server.replication.protocol;
import java.io.UnsupportedEncodingException;
import java.util.zip.DataFormatException;
import org.opends.server.types.DirectoryException;
import org.opends.server.replication.common.MultiDomainServerState;
/**
@@ -114,6 +116,10 @@
            encodedMsg, ProtocolVersion.getCurrentVersion());
      this.updateMsg = (LDAPUpdateMsg)rmsg;
    }
    catch(DirectoryException de)
    {
      throw new DataFormatException(de.toString());
    }
    catch (UnsupportedEncodingException e)
    {
      throw new DataFormatException("UTF-8 is not supported by this jvm.");
opendj-sdk/opends/src/server/org/opends/server/replication/server/DraftCNDbHandler.java
@@ -50,7 +50,7 @@
import org.opends.server.types.InitializationException;
import com.sleepycat.je.DatabaseException;
import java.util.HashMap;
import java.util.Map;
import org.opends.server.replication.common.MultiDomainServerState;
/**
@@ -396,7 +396,7 @@
          ServerState cnVector = null;
          try
          {
            HashMap<String,ServerState> cnStartStates =
            Map<String,ServerState> cnStartStates =
                MultiDomainServerState.splitGenStateToServerStates(
                        cursor.currentValue());
            cnVector = cnStartStates.get(serviceID);
opendj-sdk/opends/src/server/org/opends/server/replication/server/ECLServerHandler.java
@@ -37,6 +37,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.zip.DataFormatException;
@@ -696,7 +697,7 @@
    // At the end, normally the map should be empty.
    // Depending on allowUnknownDomains provided flag, a non empty map will
    // be considered as an error when allowUnknownDomains is false.
    HashMap<String,ServerState> startStatesFromProvidedCookie =
    Map<String,ServerState> startStatesFromProvidedCookie =
      new HashMap<String,ServerState>();
    ReplicationServer rs = this.replicationServer;
@@ -1053,7 +1054,7 @@
    {
      TRACER.debugCaught(DebugLogLevel.ERROR, e);
      throw new DirectoryException(
          ResultCode.UNWILLING_TO_PERFORM,
          ResultCode.PROTOCOL_ERROR,
          ERR_INVALID_COOKIE_SYNTAX.get());
    }
opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationServer.java
@@ -1866,7 +1866,7 @@
    // Get the first DraftCN from the DraftCNdb
    firstDraftCN = draftCNDbH.getFirstKey();
    HashMap<String,ServerState> domainsServerStateForLastSeqnum = null;
    Map<String,ServerState> domainsServerStateForLastSeqnum = null;
    ChangeNumber changeNumberForLastSeqnum = null;
    String domainForLastSeqnum = null;
    if (firstDraftCN < 1)
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
@@ -27,10 +27,7 @@
 */
package org.opends.server.replication;
import static org.opends.messages.ReplicationMessages.ERR_INVALID_COOKIE_SYNTAX;
import static org.opends.messages.ReplicationMessages.ERR_RESYNC_REQUIRED_MISSING_DOMAIN_IN_PROVIDED_COOKIE;
import static org.opends.messages.ReplicationMessages.ERR_RESYNC_REQUIRED_TOO_OLD_DOMAIN_IN_PROVIDED_COOKIE;
import static org.opends.messages.ReplicationMessages.ERR_RESYNC_REQUIRED_UNKNOWN_DOMAIN_IN_PROVIDED_COOKIE;
import static org.opends.messages.ReplicationMessages.*;
import static org.opends.server.TestCaseUtils.TEST_ROOT_DN_STRING;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
@@ -44,6 +41,7 @@
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.net.ServerSocket;
@@ -128,6 +126,7 @@
import org.opends.server.types.SearchScope;
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.ServerConstants;
import org.opends.server.util.StaticUtils;
import org.opends.server.util.TimeThread;
import org.opends.server.workflowelement.externalchangelog.ECLSearchOperation;
import org.opends.server.workflowelement.externalchangelog.ECLWorkflowElement;
@@ -199,7 +198,7 @@
          replicationServerPort, "ExternalChangeLogTestDb",
          0, 71, 0, maxWindow, null);
    replicationServer = new ReplicationServer(conf1);;
    replicationServer = new ReplicationServer(conf1);
    debugInfo("configure", "ReplicationServer created"+replicationServer);
  }
@@ -596,7 +595,7 @@
      assertEquals(op2.getEntriesSent(), 1);
      debugInfo(tn, "Ending test successfully");
    }
    catch(LDAPException e)
    catch(Exception e)
    {
      fail("Ending test " + tn + " with exception e="
          +  stackTraceToSingleLineString(e));
@@ -609,6 +608,7 @@
   * @return The built list of controls.
   */
  private ArrayList<Control> createControls(String cookie)
          throws DirectoryException
  {
    ExternalChangelogRequestControl control =
      new ExternalChangelogRequestControl(true,
@@ -1131,7 +1131,7 @@
      controls,
      null);
      waitOpResult(searchOp, ResultCode.UNWILLING_TO_PERFORM);
      waitOpResult(searchOp, ResultCode.PROTOCOL_ERROR);
      assertEquals(searchOp.getSearchEntries().size(), 0);
      assertTrue(searchOp.getErrorMessage().toString().equals(
          ERR_INVALID_COOKIE_SYNTAX.get().toString()),
@@ -1163,11 +1163,7 @@
      waitOpResult(searchOp, ResultCode.UNWILLING_TO_PERFORM);
      assertEquals(searchOp.getSearchEntries().size(), 0);
      assertTrue(searchOp.getErrorMessage().toString().startsWith(
          ERR_RESYNC_REQUIRED_UNKNOWN_DOMAIN_IN_PROVIDED_COOKIE.get("{o=test6=}").toString().replace(")","")),
          searchOp.getErrorMessage().toString());
      // The cookie value is not tested because it is build from a hashmap in
      // the server and the order of domains is not predictable.
      // Test missing domain in provided cookie
      newCookie = lastCookie.substring(lastCookie.indexOf(';')+1);
      control =
@@ -2628,13 +2624,11 @@
   */
  protected void shutdown() throws Exception
  {
    if (replicationServer != null)
    if (replicationServer != null) {
      replicationServer.remove();
    /*
    TestCaseUtils.dsconfig(
        "delete-replication-server",
        "--provider-name", "Multimaster Synchronization");
     */
      StaticUtils.recursiveDelete(new File(DirectoryServer.getInstanceRoot(),
            replicationServer.getDbDirName()));
    }
    replicationServer = null;
  }
  /**
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ReplicationTestCase.java
@@ -222,7 +222,7 @@
          throws Exception, SocketException
  {
    return openReplicationSession(baseDn, serverId, window_size,
        port, timeout, emptyOldChanges, getGenerationId(baseDn));
        port, timeout, emptyOldChanges, getGenerationId(baseDn), null);
  }
  /**