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

jvergara
12.05.2009 1a7d0e846f81abb5e9b108e1df65f9225a893b32
Fix for issue 4172 (dsreplication: disable + enable causes SSL connection error)

The code assumed that if the two registries were equal, then they were replicated. This was wrong, if we disabled replication for one server, only the disabled server was unregistered from the ADS and this caused the problem (since the certificate of the previously unregistered server was not seeded). The fix consists of two parts (even though just one of them would be enough to fix the issue, I think that having both will help the code to handle more scenarios):

1. Check that if the registries are equal, they actually are replicated (in terms of configuration of the replication).
2. Unregister ALL the servers from the ADS of the server where replication is being disabled if we have to unregister the server itself.
1 files modified
226 ■■■■ changed files
opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliMain.java 226 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliMain.java
@@ -5039,20 +5039,12 @@
          adsCtx2.readServerRegistry();
        if (registry2.size() <= 1)
        {
          // Only the server itself registered.
          if (!hasAdministrator(adsCtx1.getDirContext(), uData))
          {
            adsCtx1.createAdministrator(getAdministratorProperties(uData));
          }
          if (!ADSContext.isRegistered(server2, registry2))
          {
            server2.updateAdsPropertiesWithServerProperties();
            registerServer(adsCtx1, server2.getAdsProperties());
          }
          else
          {
            registerServer(adsCtx1, registry2.iterator().next());
          }
          server2.updateAdsPropertiesWithServerProperties();
          registerServer(adsCtx1, server2.getAdsProperties());
          if (!ADSContext.isRegistered(server1, registry1))
          {
            server1.updateAdsPropertiesWithServerProperties();
@@ -5065,20 +5057,13 @@
        }
        else if (registry1.size() <= 1)
        {
          // Only the server itself registered.
          if (!hasAdministrator(adsCtx2.getDirContext(), uData))
          {
            adsCtx2.createAdministrator(getAdministratorProperties(uData));
          }
          if (!ADSContext.isRegistered(server1, registry1))
          {
            server1.updateAdsPropertiesWithServerProperties();
            registerServer(adsCtx2, server1.getAdsProperties());
          }
          else
          {
            registerServer(adsCtx2, registry1.iterator().next());
          }
          server1.updateAdsPropertiesWithServerProperties();
          registerServer(adsCtx2, server1.getAdsProperties());
          if (!ADSContext.isRegistered(server2, registry2))
          {
            server2.updateAdsPropertiesWithServerProperties();
@@ -5109,7 +5094,72 @@
        {
          // They are already replicated: nothing to do in terms of ADS
          // initialization or ADS update data
          adsAlreadyReplicated = true;
          adsAlreadyReplicated = isBaseDNReplicated(server1, server2,
              ADSContext.getAdministrationSuffixDN());
          if (!adsAlreadyReplicated)
          {
            // Try to merge if both are replicated
            boolean isADS1Replicated = isBaseDNReplicated(server1,
                ADSContext.getAdministrationSuffixDN());
            boolean isADS2Replicated = isBaseDNReplicated(server2,
                ADSContext.getAdministrationSuffixDN());
            if (isADS1Replicated && isADS2Replicated)
            {
              // Merge
              printProgress(formatter.getFormattedDone());
              printlnProgress();
              boolean isFirstSource = mergeRegistries(adsCtx1, adsCtx2);
              if (isFirstSource)
              {
                ctxSource = ctx1;
              }
              else
              {
                ctxSource = ctx2;
              }
              adsMergeDone = true;
            }
            else if (isADS1Replicated || !isADS2Replicated)
            {
              // The case where only the first ADS is replicated or none
              // is replicated.
              if (!hasAdministrator(adsCtx1.getDirContext(), uData))
              {
                adsCtx1.createAdministrator(getAdministratorProperties(uData));
              }
              server2.updateAdsPropertiesWithServerProperties();
              registerServer(adsCtx1, server2.getAdsProperties());
              if (!ADSContext.isRegistered(server1, registry1))
              {
                server1.updateAdsPropertiesWithServerProperties();
                registerServer(adsCtx1, server1.getAdsProperties());
              }
              ctxSource = ctx1;
              ctxDestination = ctx2;
              adsCtxSource = adsCtx1;
            }
            else if (isADS2Replicated)
            {
              if (!hasAdministrator(adsCtx2.getDirContext(), uData))
              {
                adsCtx2.createAdministrator(getAdministratorProperties(uData));
              }
              server1.updateAdsPropertiesWithServerProperties();
              registerServer(adsCtx2, server1.getAdsProperties());
              if (!ADSContext.isRegistered(server2, registry2))
              {
                server2.updateAdsPropertiesWithServerProperties();
                registerServer(adsCtx2, server2.getAdsProperties());
              }
              ctxSource = ctx2;
              ctxDestination = ctx1;
              adsCtxSource = adsCtx2;
            }
          }
        }
      }
      else if (!adsCtx1.hasAdminData() && adsCtx2.hasAdminData())
@@ -5877,7 +5927,7 @@
      }
      catch (ADSContextException adce)
      {
        LOG.log(Level.INFO, "Error unregistering server: "+
        LOG.log(Level.SEVERE, "Error unregistering server: "+
            server.getAdsProperties(), adce);
        if (adce.getError() != ADSContextException.ErrorType.NOT_YET_REGISTERED)
        {
@@ -6022,28 +6072,6 @@
        {
        }
      }
      else if (disableReplicationServer)
      {
        for (ServerDescriptor s: serversToUpdate)
        {
          try
          {
            adsCtx.unregisterServer(s.getAdsProperties());
          }
          catch (ADSContextException adce)
          {
            LOG.log(Level.WARNING, "Error unregistering server: "+
                s.getAdsProperties(), adce);
            if (adce.getError() !=
              ADSContextException.ErrorType.NOT_YET_REGISTERED)
            {
              throw new ReplicationCliException(
                  ERR_REPLICATION_UPDATING_ADS.get(adce.getMessageObject()),
                  ERROR_READING_ADS, adce);
            }
          }
        }
      }
    }
    if (disableReplicationServer && !replicationServerDisabled)
    {
@@ -6099,6 +6127,34 @@
            ERROR_UPDATING_ADS, t);
      }
    }
    else if (disableAllBaseDns &&
        (disableReplicationServer || !server.isReplicationServer()))
    {
      // Unregister the servers from the ADS of the local server.
      try
      {
        Set<Map<ADSContext.ServerProperty, Object>> registry =
          adsCtx.readServerRegistry();
        for (Map<ADSContext.ServerProperty, Object> s : registry)
        {
          adsCtx.unregisterServer(s);
        }
        try
        {
          // To be sure that the change gets propagated
          Thread.sleep(2000);
        }
        catch (Throwable t)
        {
        }
      }
      catch (ADSContextException adce)
      {
        // This is not critical, do not send an error
        LOG.log(Level.WARNING, "Error unregistering server: "+
            server.getAdsProperties(), adce);
      }
    }
  }
  /**
@@ -9969,7 +10025,6 @@
  private boolean mergeRegistries(ADSContext adsCtx1, ADSContext adsCtx2)
  throws ReplicationCliException
  {
    PointAdder pointAdder = new PointAdder();
    try
    {
@@ -10310,6 +10365,87 @@
        filter);
    return loader.createContext();
  }
  /**
   * Returns <CODE>true</CODE> if the provided baseDN is replicated in the
   * provided server, <CODE>false</CODE> otherwise.
   * @param server the server.
   * @param baseDN the base DN.
   * @return <CODE>true</CODE> if the provided baseDN is replicated in the
   * provided server, <CODE>false</CODE> otherwise.
   */
  private boolean isBaseDNReplicated(ServerDescriptor server, String baseDN)
  {
    boolean isReplicated = false;
    for (ReplicaDescriptor replica : server.getReplicas())
    {
      if (Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN))
      {
        isReplicated = replica.isReplicated();
        break;
      }
    }
    return isReplicated;
  }
  /**
   * Returns <CODE>true</CODE> if the provided baseDN is replicated between
   * both servers, <CODE>false</CODE> otherwise.
   * @param server1 the first server.
   * @param server2 the second server.
   * @param baseDN the base DN.
   * @return <CODE>true</CODE> if the provided baseDN is replicated between
   * both servers, <CODE>false</CODE> otherwise.
   */
  private boolean isBaseDNReplicated(ServerDescriptor server1,
      ServerDescriptor server2, String baseDN)
  {
    boolean isReplicatedInBoth = false;
    ReplicaDescriptor replica1 = null;
    ReplicaDescriptor replica2 = null;
    for (ReplicaDescriptor replica : server1.getReplicas())
    {
      if (Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN))
      {
        replica1 = replica;
        break;
      }
    }
    if (replica1 != null && replica1.isReplicated())
    {
      for (ReplicaDescriptor replica : server2.getReplicas())
      {
        if (Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN))
        {
          replica2 = replica;
          if (replica2.isReplicated())
          {
            Set<String> replServers1 =
              replica1.getSuffix().getReplicationServers();
            Set<String> replServers2 =
              replica1.getSuffix().getReplicationServers();
            for (String replServer1 : replServers1)
            {
              for (String replServer2 : replServers2)
              {
                if (replServer1.equalsIgnoreCase(replServer2))
                {
                  isReplicatedInBoth = true;
                  break;
                }
              }
              if (isReplicatedInBoth)
              {
                break;
              }
            }
          }
          break;
        }
      }
    }
    return isReplicatedInBoth;
  }
}