From 626480f34c396fe1ce1214a4e9a5cff1428bc665 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 04 Jun 2015 16:49:43 +0000
Subject: [PATCH] Preparation work for OPENDJ-2094: add generic support for upgrade tasks that require confirmation.

---
 opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/AbstractUpgradeTask.java |   10 -
 opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTask.java         |   46 +++------
 opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/Upgrade.java             |   32 ++----
 opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTasks.java        |  200 ++++++++++++---------------------------
 4 files changed, 87 insertions(+), 201 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/AbstractUpgradeTask.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/AbstractUpgradeTask.java
index d0ccfce..568a9be 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/AbstractUpgradeTask.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/AbstractUpgradeTask.java
@@ -42,7 +42,7 @@
 
   /** {@inheritDoc} */
   @Override
-  public void interact(UpgradeContext context)
+  public void prepare(UpgradeContext context)
       throws ClientException
   {
     // Nothing to do.
@@ -57,14 +57,6 @@
 
   /** {@inheritDoc} */
   @Override
-  public void verify(UpgradeContext context)
-      throws ClientException
-  {
-    // Nothing to do.
-  }
-
-  /** {@inheritDoc} */
-  @Override
   public void postUpgrade(UpgradeContext context)
       throws ClientException
   {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/Upgrade.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/Upgrade.java
index f8a13a9..aca4732 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/Upgrade.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/Upgrade.java
@@ -47,7 +47,6 @@
 
 import static com.forgerock.opendj.cli.Utils.*;
 import static javax.security.auth.callback.TextOutputCallback.*;
-
 import static org.opends.messages.ToolMessages.*;
 import static org.opends.server.tools.upgrade.FormattedNotificationCallback.*;
 import static org.opends.server.tools.upgrade.LicenseFile.*;
@@ -180,16 +179,15 @@
         "ds-cfg-strict-format: false"));
 
     register("2.5.0.8214",
-        modifyConfigEntryOptional(INFO_UPGRADE_TASK_8214_SUMMARY.get(),
-        INFO_UPGRADE_TASK_8214_DESCRIPTION.get(),
-        "(ds-cfg-java-class=org.opends.server.extensions."
-            + "IsMemberOfVirtualAttributeProvider)",
-        "add: ds-cfg-filter",
-        "ds-cfg-filter: (|(objectClass=person)(objectClass=groupOfNames)"
-            + "(objectClass=groupOfUniqueNames)(objectClass=groupOfEntries))",
-        "-",
-        "delete: ds-cfg-filter",
-        "ds-cfg-filter: (objectClass=person)"));
+        requireConfirmation(INFO_UPGRADE_TASK_8214_DESCRIPTION.get(),
+            modifyConfigEntry(INFO_UPGRADE_TASK_8214_SUMMARY.get(),
+                "(ds-cfg-java-class=org.opends.server.extensions.IsMemberOfVirtualAttributeProvider)",
+                "add: ds-cfg-filter",
+                "ds-cfg-filter: (|(objectClass=person)(objectClass=groupOfNames)"
+                    + "(objectClass=groupOfUniqueNames)(objectClass=groupOfEntries))",
+                "-",
+                "delete: ds-cfg-filter",
+                "ds-cfg-filter: (objectClass=person)")));
 
     register("2.5.0.8387",
         modifyConfigEntry(INFO_UPGRADE_TASK_8387_SUMMARY.get(),
@@ -479,22 +477,12 @@
     }
 
     /*
-     * Verify tasks requirements. E.g. if a task requires mandatory user
-     * interaction and the application is non-interactive then, the process may
-     * abort immediately.
-     */
-    for (final UpgradeTask task : tasks)
-    {
-      task.verify(context);
-    }
-
-    /*
      * Let tasks interact with the user in order to obtain user's selection.
      */
     context.notify(INFO_UPGRADE_REQUIREMENTS.get(), TITLE_CALLBACK);
     for (final UpgradeTask task : tasks)
     {
-      task.interact(context);
+      task.prepare(context);
     }
 
     // Starts upgrade
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTask.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTask.java
index a1c54a6..869369a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTask.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/upgrade/UpgradeTask.java
@@ -21,7 +21,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2013-2014 ForgeRock AS
+ *      Copyright 2013-2015 ForgeRock AS
  */
 
 package org.opends.server.tools.upgrade;
@@ -61,42 +61,26 @@
   }
 
   /**
+   * Performs any preparation work required before performing the upgrade task, including
+   * interacting with the user where needed (e.g. in order to ask for confirmation), and throw a
+   * {@code ClientException} if the upgrade cannot proceed.
+   *
+   * @param context
+   *          Context through which tasks can interact with the server installation.
+   * @throws ClientException
+   *           If the upgrade cannot proceed.
+   */
+  void prepare(UpgradeContext context) throws ClientException;
+
+  /**
    * Performs this upgrade task.
    *
    * @param context
-   *          Context through which tasks can interact with the server
-   *          installation.
+   *          Context through which tasks can interact with the server installation.
    * @throws ClientException
    *           If an error occurred while performing the task.
    */
-  void perform(UpgradeContext context)
-      throws ClientException;
-
-  /**
-   * Verifies that this upgrade task can be completed or not.
-   *
-   * @param context
-   *          Context through which tasks can interact with the server
-   *          installation.
-   * @throws ClientException
-   *           If the upgrade cannot proceed.
-   */
-  void verify(UpgradeContext context)
-      throws ClientException;
-
-  /**
-   * Interacts with the user where needed (e.g. in order to ask for
-   * confirmation), and throw a {@code ClientException} if the upgrade cannot
-   * proceed.
-   *
-   * @param context
-   *          Context through which tasks can interact with the server
-   *          installation.
-   * @throws ClientException
-   *           If the upgrade cannot proceed.
-   */
-  void interact(UpgradeContext context)
-      throws ClientException;
+  void perform(UpgradeContext context) throws ClientException;
 
   /**
    * This method will be invoked after all upgrade tasks have completed
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 1799315..d9929c4 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
@@ -46,7 +46,6 @@
 import com.forgerock.opendj.cli.ReturnCode;
 
 import static javax.security.auth.callback.ConfirmationCallback.*;
-
 import static org.opends.messages.ToolMessages.*;
 import static org.opends.server.tools.upgrade.FileManager.*;
 import static org.opends.server.tools.upgrade.Installation.*;
@@ -86,26 +85,7 @@
   public static UpgradeTask addConfigEntry(final LocalizableMessage summary,
       final String... ldif)
   {
-    return addConfigEntry0(summary, summary, false, ldif);
-  }
-
-  /**
-   * Returns a new upgrade task which applies an LDIF record to all
-   * configuration entries matching the provided filter.
-   *
-   * @param summary
-   *          The summary of this upgrade task.
-   * @param description
-   *          The detailed description of this upgrade task.
-   * @param ldif
-   *          The LDIF record which will be applied to matching entries.
-   * @return A new upgrade task which applies an LDIF record to all
-   *         configuration entries matching the provided filter.
-   */
-  public static UpgradeTask addConfigEntryOptional(final LocalizableMessage summary,
-      final LocalizableMessage description, final String... ldif)
-  {
-    return addConfigEntry0(summary, description, true, ldif);
+    return updateConfigEntry(summary, null, ChangeOperationType.ADD, ldif);
   }
 
   /**
@@ -208,14 +188,7 @@
   public static UpgradeTask deleteConfigEntry(final LocalizableMessage summary,
       final String dnInLDIF)
   {
-    return new AbstractUpgradeTask()
-    {
-      @Override
-      public void perform(final UpgradeContext context) throws ClientException
-      {
-        perform0(summary, null, ChangeOperationType.DELETE, context, dnInLDIF);
-      }
-    };
+    return updateConfigEntry(summary, null, ChangeOperationType.DELETE, dnInLDIF);
   }
 
   /**
@@ -234,28 +207,7 @@
   public static UpgradeTask modifyConfigEntry(final LocalizableMessage summary,
       final String filter, final String... ldif)
   {
-    return modifyConfigEntry(summary, summary, false, filter, ldif);
-  }
-
-  /**
-   * Returns a new upgrade task which applies an LDIF record to all
-   * configuration entries matching the provided filter.
-   *
-   * @param summary
-   *          The summary of this upgrade task.
-   * @param description
-   *          The detailed description of this upgrade task.
-   * @param filter
-   *          The LDAP filter which configuration entries must match.
-   * @param ldif
-   *          The LDIF record which will be applied to matching entries.
-   * @return A new upgrade task which applies an LDIF record to all
-   *         configuration entries matching the provided filter.
-   */
-  public static UpgradeTask modifyConfigEntryOptional(final LocalizableMessage summary,
-      final LocalizableMessage description, final String filter, final String... ldif)
-  {
-    return modifyConfigEntry(summary, description, true, filter, ldif);
+    return updateConfigEntry(summary, filter, ChangeOperationType.MODIFY, ldif);
   }
 
   /**
@@ -398,41 +350,73 @@
    * @return An upgrade task which will only be invoked if the current version
    *         is more recent than the provided version.
    */
-  public static UpgradeTask regressionInVersion(final String versionString,
-      final UpgradeTask... tasks)
+  public static UpgradeTask regressionInVersion(final String versionString, final UpgradeTask... tasks)
   {
     final BuildVersion version = BuildVersion.valueOf(versionString);
+    return conditionalUpgradeTasks(new UpgradeCondition()
+    {
+      @Override
+      public boolean shouldPerformUpgradeTasks(final UpgradeContext context) throws ClientException
+      {
+        return context.getFromVersion().compareTo(version) >= 0;
+      }
+    }, tasks);
+  }
+
+  /**
+   * Creates a group of tasks which will only be invoked if the user confirms agreement. This may be
+   * useful in cases where a feature is deprecated and the upgrade is capable of migrating the
+   * configuration to the new replacement feature.
+   *
+   * @param message
+   *          The confirmation message.
+   * @param tasks
+   *          The group of tasks to invoke if the user agrees.
+   * @return An upgrade task which will only be invoked if the user confirms agreement.
+   */
+  public static UpgradeTask requireConfirmation(final LocalizableMessage message, final UpgradeTask... tasks)
+  {
+    return conditionalUpgradeTasks(new UpgradeCondition()
+    {
+      @Override
+      public boolean shouldPerformUpgradeTasks(final UpgradeContext context) throws ClientException
+      {
+        return context.confirmYN(INFO_UPGRADE_TASK_NEEDS_USER_CONFIRM.get(message), YES) == YES;
+      }
+    }, tasks);
+  }
+
+  /**
+   * Determines whether conditional tasks should be performed.
+   */
+  private static interface UpgradeCondition
+  {
+    boolean shouldPerformUpgradeTasks(final UpgradeContext context) throws ClientException;
+  }
+
+  private static UpgradeTask conditionalUpgradeTasks(final UpgradeCondition condition, final UpgradeTask... tasks)
+  {
     return new AbstractUpgradeTask()
     {
+      private boolean shouldPerformUpgradeTasks = true;
 
       @Override
-      public void verify(UpgradeContext context) throws ClientException
+      public void prepare(final UpgradeContext context) throws ClientException
       {
-        if (currentVersionEqualToOrMoreRecentThan(context, version))
+        shouldPerformUpgradeTasks = condition.shouldPerformUpgradeTasks(context);
+        if (shouldPerformUpgradeTasks)
         {
           for (UpgradeTask task : tasks)
           {
-            task.verify(context);
+            task.prepare(context);
           }
         }
       }
 
       @Override
-      public void interact(UpgradeContext context) throws ClientException
+      public void perform(final UpgradeContext context) throws ClientException
       {
-        if (currentVersionEqualToOrMoreRecentThan(context, version))
-        {
-          for (UpgradeTask task : tasks)
-          {
-            task.interact(context);
-          }
-        }
-      }
-
-      @Override
-      public void perform(UpgradeContext context) throws ClientException
-      {
-        if (currentVersionEqualToOrMoreRecentThan(context, version))
+        if (shouldPerformUpgradeTasks)
         {
           for (UpgradeTask task : tasks)
           {
@@ -444,7 +428,7 @@
       @Override
       public void postUpgrade(UpgradeContext context) throws ClientException
       {
-        if (currentVersionEqualToOrMoreRecentThan(context, version))
+        if (shouldPerformUpgradeTasks)
         {
           boolean isOk = true;
           for (final UpgradeTask task : tasks)
@@ -469,12 +453,6 @@
         }
       }
 
-
-      private boolean currentVersionEqualToOrMoreRecentThan(
-          UpgradeContext context, final BuildVersion version)
-      {
-        return context.getFromVersion().compareTo(version) >= 0;
-      }
     };
   }
 
@@ -492,7 +470,7 @@
       private boolean isATaskToPerform = false;
 
       @Override
-      public void interact(UpgradeContext context) throws ClientException
+      public void prepare(UpgradeContext context) throws ClientException
       {
         Upgrade.setHasPostUpgradeTask(true);
         // Requires answer from the user.
@@ -544,7 +522,7 @@
       private boolean isATaskToPerform = false;
 
       @Override
-      public void interact(UpgradeContext context) throws ClientException
+      public void prepare(UpgradeContext context) throws ClientException
       {
         Upgrade.setHasPostUpgradeTask(true);
         // Requires answer from the user.
@@ -759,40 +737,6 @@
     };
   }
 
-  private static UpgradeTask addConfigEntry0(final LocalizableMessage summary,
-      final LocalizableMessage description, final boolean needsUserConfirmation,
-      final String... ldif)
-  {
-    return new AbstractUpgradeTask()
-    {
-      private boolean userConfirmation = true;
-
-      @Override
-      public void interact(final UpgradeContext context) throws ClientException
-      {
-        if (needsUserConfirmation)
-        {
-          // Process needs to have user's response to perform the current modification.
-          LocalizableMessage msg = INFO_UPGRADE_TASK_NEEDS_USER_CONFIRM.get(description);
-          if (context.confirmYN(msg, YES) == NO)
-          {
-            // The user refuses to perform this task.
-            userConfirmation = false;
-          }
-        }
-      }
-
-      @Override
-      public void perform(final UpgradeContext context) throws ClientException
-      {
-        if (userConfirmation)
-        {
-          perform0(summary, null, ChangeOperationType.ADD, context, ldif);
-        }
-      }
-    };
-  }
-
   private static void displayChangeCount(final String fileName,
       final int changeCount)
   {
@@ -833,42 +777,20 @@
     }
   }
 
-  private static UpgradeTask modifyConfigEntry(final LocalizableMessage summary,
-      final LocalizableMessage description, final boolean needsUserConfirmation,
-      final String filter, final String... ldif)
+  private static UpgradeTask updateConfigEntry(final LocalizableMessage summary, final String filter,
+      final ChangeOperationType changeOperationType, final String... ldif)
   {
     return new AbstractUpgradeTask()
     {
-      private boolean userConfirmation = true;
-
-      @Override
-      public void interact(final UpgradeContext context) throws ClientException
-      {
-        if (needsUserConfirmation)
-        {
-          // Process needs to have user's response to perform the current modification
-          LocalizableMessage msg = INFO_UPGRADE_TASK_NEEDS_USER_CONFIRM.get(description);
-          if (context.confirmYN(msg, YES) == NO)
-          {
-            // The user refuses to perform this task.
-            userConfirmation = false;
-          }
-        }
-      }
-
       @Override
       public void perform(final UpgradeContext context) throws ClientException
       {
-        if (userConfirmation)
-        {
-          perform0(summary, filter, ChangeOperationType.MODIFY, context, ldif);
-        }
+        performConfigFileUpdate(summary, filter, changeOperationType, context, ldif);
       }
-
     };
   }
 
-  private static void perform0(final LocalizableMessage summary, final String filter,
+  private static void performConfigFileUpdate(final LocalizableMessage summary, final String filter,
       final ChangeOperationType changeOperationType,
       final UpgradeContext context, final String... ldif)
       throws ClientException

--
Gitblit v1.10.0