From 4beea894b2a86570126633b70f2a740b99e86318 Mon Sep 17 00:00:00 2001
From: Gaetan Boismal <gaetan.boismal@forgerock.com>
Date: Wed, 23 Mar 2016 16:54:44 +0000
Subject: [PATCH] OPENDJ-2763 Fix upgrade

---
 opendj-server-legacy/src/main/java/org/opends/server/tools/RebuildIndex.java         |    6 +-
 opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTasks.java |  103 ++++++++++++++++------------------
 opendj-server-legacy/src/messages/org/opends/messages/tool.properties                |    6 +-
 opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeUtils.java |   53 ++++++++++++++---
 4 files changed, 97 insertions(+), 71 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/RebuildIndex.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/RebuildIndex.java
index 0ced14c..5b59d6f 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/RebuildIndex.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/RebuildIndex.java
@@ -26,6 +26,7 @@
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.logging.Level;
 
@@ -645,8 +646,7 @@
    * @return An integer indicating the result of this action.
    */
   public int rebuildIndexesWithinMultipleBackends(
-      final boolean initializeServer, final PrintStream out,
-      final String... args)
+      final boolean initializeServer, final PrintStream out, final Collection<String> args)
   {
     try
     {
@@ -664,7 +664,7 @@
 
       try
       {
-        argParser.parseArguments(args);
+        argParser.parseArguments(args.toArray(new String[args.size()]));
       }
       catch (ArgumentException ae)
       {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTasks.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTasks.java
index 2856dcb..b5a106e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTasks.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTasks.java
@@ -26,6 +26,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
@@ -666,80 +667,72 @@
       @Override
       public void postUpgrade(final UpgradeContext context) throws ClientException
       {
-        LocalizableMessage message;
-        final List<String> args = new LinkedList<>();
+        if (!isRebuildAllIndexesIsPresent && indexesToRebuild.isEmpty())
+        {
+          return;
+        }
 
+        final Map<String, Set<String>> baseDNsForBackends = UpgradeUtils.getBaseDNsPerBackendsFromConfig();
         if (isRebuildAllIndexesTaskAccepted)
         {
-          args.add("--rebuildAll");
-          message = INFO_UPGRADE_REBUILD_ALL.get();
-        }
-        else if (!indexesToRebuild.isEmpty())
-        {
-          message = INFO_UPGRADE_REBUILD_INDEX_STARTS.get(indexesToRebuild);
-
-          // Adding all requested indexes.
-          for (final String indexToRebuild : indexesToRebuild)
+          final Set<String> allBaseDNs = new HashSet<>();
+          for (final Set<String> baseDNsForBackend : baseDNsForBackends.values())
           {
-            args.add("-i");
-            args.add(indexToRebuild);
+            allBaseDNs.addAll(baseDNsForBackend);
+          }
+          rebuildIndex(INFO_UPGRADE_REBUILD_ALL.get(), context, allBaseDNs, Collections.singletonList("--rebuildAll"));
+        }
+        else
+        {
+          for (final Map.Entry<String, Set<String>> backendEntry : baseDNsForBackends.entrySet())
+          {
+            final String backend = backendEntry.getKey();
+            final List<String> filteredIndexes = filterExistingIndexes(indexesToRebuild, backend);
+            if (filteredIndexes.isEmpty())
+            {
+              logger.debug(INFO_UPGRADE_NO_INDEX_TO_REBUILD_FOR_BACKEND.get(backend));
+              continue;
+            }
+
+            final List<String> args = new ArrayList<>();
+            for (final String indexToRebuild : filteredIndexes)
+            {
+              args.add("--index");
+              args.add(indexToRebuild);
+            }
+            final Set<String> baseDNs = backendEntry.getValue();
+            rebuildIndex(INFO_UPGRADE_REBUILD_INDEX_STARTS.get(filteredIndexes, baseDNs), context, baseDNs, args);
           }
         }
-        else
-        {
-          return;
-        }
-        // Startup message.
-        ProgressNotificationCallback pnc = new ProgressNotificationCallback(INFORMATION, message, 25);
-        logger.debug(message);
+      }
+
+      private void rebuildIndex(final LocalizableMessage infoMsg, final UpgradeContext context,
+          final Set<String> baseDNs, final List<String> args) throws ClientException
+      {
+        final ProgressNotificationCallback pnc = new ProgressNotificationCallback(INFORMATION, infoMsg, 25);
+        logger.debug(infoMsg);
         context.notifyProgress(pnc);
 
-        // Sets the arguments like the rebuild index command line.
-        args.addAll(Arrays.asList("-f", CONFIG_FILE_PATH));
-
-        /*
-         * Index(es) could be contained in several backends or none, If none,
-         * the post upgrade tasks succeed and a message is printed in the
-         * upgrade log file.
-         */
-        final List<String> backends = UpgradeUtils.getIndexedBackendsFromConfig();
-        if (backends.isEmpty())
+        args.add("--configFile");
+        args.add(CONFIG_FILE_PATH);
+        for (final String be : baseDNs)
         {
-          logger.debug(INFO_UPGRADE_REBUILD_INDEX_NO_BACKEND_FOUND);
-          logger.debug(INFO_UPGRADE_REBUILD_INDEXES_DECLINED, indexesToRebuild);
-          context.notifyProgress(pnc.setProgress(100));
-          return;
-        }
-
-        for (final String be : backends)
-        {
-          args.add("-b");
+          args.add("--baseDN");
           args.add(be);
         }
-
-        // Displays info about command line args for log only.
         logger.debug(INFO_UPGRADE_REBUILD_INDEX_ARGUMENTS, args);
 
-        /*
-         * The rebuild-index process just display a status ok / fails. The
-         * logger stream contains all the log linked to this process. The
-         * complete process is not displayed in the upgrade console.
-         */
-        final String[] commandLineArgs = args.toArray(new String[args.size()]);
         final int result = new RebuildIndex().rebuildIndexesWithinMultipleBackends(
-            true, UpgradeLog.getPrintStream(), commandLineArgs);
-
-        if (result == 0)
-        {
-          logger.debug(INFO_UPGRADE_REBUILD_INDEX_ENDS);
-          context.notifyProgress(pnc.setProgress(100));
-        }
-        else
+            true, UpgradeLog.getPrintStream(), args);
+        if (result != 0)
         {
           final LocalizableMessage msg = ERR_UPGRADE_PERFORMING_POST_TASKS_FAIL.get();
           context.notifyProgress(pnc.setProgress(-100));
           throw new ClientException(ReturnCode.ERROR_UNEXPECTED, msg);
         }
+
+        logger.debug(INFO_UPGRADE_REBUILD_INDEX_ENDS);
+        context.notifyProgress(pnc.setProgress(100));
       }
 
       @Override
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeUtils.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeUtils.java
index 7595be1..92e6c0d 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeUtils.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeUtils.java
@@ -24,9 +24,11 @@
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.forgerock.i18n.LocalizableMessage;
@@ -336,31 +338,32 @@
   }
 
   /**
-   * Retrieves the backends from the current configuration file. The backends
-   * must be enabled to be listed. No operations should be done within a
-   * disabled backend.
+   * Return a {@link Map} with backend id as key and associated baseDNs as values.
+   * <p>
+   * Disabled backends are not filtered out.
    *
-   * @return A backend list.
+   * @return A {@link Map} of all enabled backends of the server with their baseDNs.
    */
-  static List<String> getIndexedBackendsFromConfig()
+  static Map<String, Set<String>> getBaseDNsPerBackendsFromConfig()
   {
     final SearchRequest sr = Requests.newSearchRequest("", SearchScope.WHOLE_SUBTREE,
             "(&(objectclass=ds-cfg-pluggable-backend)(ds-cfg-enabled=true))",
-            "ds-cfg-base-dn");
-    final List<String> listBackends = new LinkedList<>();
+            "ds-cfg-base-dn", "ds-cfg-backend-id");
+    final Map<String, Set<String>> baseDNs = new HashMap<>();
     try (final EntryReader entryReader = searchConfigFile(sr))
     {
       while (entryReader.hasNext())
       {
         final Entry entry = entryReader.readEntry();
-        listBackends.addAll(entry.parseAttribute("ds-cfg-base-dn").asSetOfString());
+        baseDNs.put(entry.parseAttribute("ds-cfg-backend-id").asString(),
+                    entry.parseAttribute("ds-cfg-base-dn").asSetOfString());
       }
     }
     catch (Exception ex)
     {
       logger.error(LocalizableMessage.raw(ex.getMessage()));
     }
-    return listBackends;
+    return baseDNs;
   }
 
   static EntryReader searchConfigFile(final SearchRequest sr) throws FileNotFoundException
@@ -796,6 +799,36 @@
     return modifiedLines;
   }
 
+  /** Filter provided list of indexes name to return indexes which are present in the provided backend. */
+  static List<String> filterExistingIndexes(final Set<String> candidateIndexes, final String backendID)
+  {
+    final List<String> indexesToRebuild = new ArrayList<>();
+    try (final LDIFEntryReader entryReader = new LDIFEntryReader(new FileInputStream(CONFIG_FILE_PATH)))
+    {
+      while (entryReader.hasNext())
+      {
+        final Entry entry = entryReader.readEntry();
+        if (entry.containsAttribute("objectClass", "ds-cfg-backend-index")
+            && entry.getName().toString().contains("ds-cfg-backend-id=" + backendID))
+        {
+          for (final String indexName : candidateIndexes)
+          {
+            if (entry.containsAttribute("ds-cfg-attribute", indexName))
+            {
+              indexesToRebuild.add(indexName);
+            }
+          }
+        }
+      }
+    }
+    catch (final IOException unlikely)
+    {
+      logger.error(ERR_UPGRADE_READING_CONF_FILE.get(unlikely.getMessage()));
+    }
+
+    return indexesToRebuild;
+  }
+
   /** Prevent instantiation. */
   private UpgradeUtils()
   {
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/tool.properties b/opendj-server-legacy/src/messages/org/opends/messages/tool.properties
index 2afca86..42026e0 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/tool.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/tool.properties
@@ -2393,7 +2393,7 @@
 configuration file '%s': %s
 ERR_UPGRADE_RENAME_SNMP_SECURITY_CONFIG_FILE_1838=An error occurred when \
 trying to rename the SNMP security config file: %s
-INFO_UPGRADE_REBUILD_INDEX_STARTS_1839=Rebuilding index(es) %s
+INFO_UPGRADE_REBUILD_INDEX_STARTS_1839=Rebuilding index(es) '%s' for base dn(s) '%s'
 INFO_UPGRADE_REBUILD_INDEX_ENDS_1840=Rebuild index task ends
 INFO_UPGRADE_PERFORMING_POST_TASKS_1841=Performing post upgrade tasks
 INFO_UPGRADE_POST_TASKS_COMPLETE_1842=Post upgrade tasks complete
@@ -2408,8 +2408,7 @@
 INFO_UPGRADE_REBUILD_ALL_1848=Rebuilding all indexes
 INFO_UPGRADE_PROCESS_END_1849=End of the upgrade process
 ERR_UPGRADE_CORRUPTED_TEMPLATE_1850='%s' is missing or empty, it is probably corrupted
-INFO_UPGRADE_REBUILD_INDEX_NO_BACKEND_FOUND_1851=No backend found. The rebuild index task \
-stops
+INFO_UPGRADE_NO_INDEX_TO_REBUILD_FOR_BACKEND=No indexes to rebuild for backend '%s'
 INFO_UPGRADE_CLASSES_FOLDER_RENAMED_1852=The classes folder has been renamed to \
 '%s' to avoid compatibility issues
 ERR_UPGRADE_DSJAVAPROPERTIES_FAILED_1853=The dsjavaproperties tool failed to run. \
@@ -2718,3 +2717,4 @@
 ERR_TRUSTING_CERTIFICATE=Unable to trust the certificate because: %s
 ERR_TRUSTING_CERTIFICATE_PERMANENTLY=Unable to trust the certificate permanently, \
  certificate will be trusted only for this session. Error details: %s
+ERR_UPGRADE_READING_CONF_FILE=An error occurred while reading configuration file: %s

--
Gitblit v1.10.0