From c4b9bc65a899b18c2b7a4b8c38e7eeab51027700 Mon Sep 17 00:00:00 2001
From: kenneth_suter <kenneth_suter@localhost>
Date: Mon, 30 Apr 2007 21:31:38 +0000
Subject: [PATCH] This commit is mainly intended to prevent the sort of false positives that occur when the upgrader assumes the server has been upgraded properly but leaves the server in a corrupt state (see issues 1546 and 1559).  The following changes are introduced:

---
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java               |  119 +++++++----
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/WelcomePanel.java        |    2 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/OperationOutput.java            |   76 +++++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java            |    5 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java |    3 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/BuildInformation.java                |  205 ++++++++++++++++++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java          |   36 +--
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties       |    5 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java                    |   83 ++------
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java     |    5 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java           |   49 ++++
 11 files changed, 457 insertions(+), 131 deletions(-)

diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java
index 06a6591..0362cac 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java
@@ -89,6 +89,11 @@
     APPLICATION,
 
     /**
+     * Error invoking an OpenDS tool.
+     */
+    TOOL_ERROR,
+
+    /**
      * A bug (for instance when we throw an IllegalStateException).
      */
     BUG
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/BuildInformation.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/BuildInformation.java
new file mode 100644
index 0000000..4cf2405
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/BuildInformation.java
@@ -0,0 +1,205 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.quicksetup;
+
+import org.opends.quicksetup.util.Utils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.io.InputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+/**
+ * Represents information about the current build that is
+ * publicly obtainable by invoking start-ds -F.
+ */
+public class BuildInformation implements Comparable {
+
+  static private final String NAME = "Name";
+  static private final String BUILD_ID = "Build ID";
+  static private final String MAJOR_VERSION = "Major Version";
+  static private final String MINOR_VERSION = "Minor Version";
+  static private final String POINT_VERSION = "Point Version";
+  static private final String REVISION_NUMBER = "Revision Number";
+
+  /**
+   * Reads build information for a particular installation by reading the
+   * output from invoking the start-ds tool with the full information option.
+   * @param installation from which to gather build information
+   * @return BuildInformation object populated with information
+   * @throws ApplicationException if all or some important information could
+   * not be determined
+   */
+  static public BuildInformation create(Installation installation)
+          throws ApplicationException {
+    BuildInformation bi = new BuildInformation();
+    List<String> args = new ArrayList<String>();
+    args.add(Utils.getPath(installation.getServerStartCommandFile()));
+    args.add("-F"); // full verbose
+    ProcessBuilder pb = new ProcessBuilder(args);
+    InputStream is = null;
+    try {
+      Process process = pb.start();
+      is = process.getInputStream();
+      BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+      String line = reader.readLine();
+      bi.values.put(NAME, line);
+      while (null != (line = reader.readLine())) {
+        int colonIndex = line.indexOf(':');
+        if (-1 != colonIndex) {
+          String name = line.substring(0, colonIndex).trim();
+          String value = line.substring(colonIndex + 1).trim();
+          bi.values.put(name, value);
+        }
+      }
+    } catch (IOException e) {
+      throw new ApplicationException(ApplicationException.Type.START_ERROR,
+              "Error creating build info", e);
+    } finally {
+      if (is != null) {
+        try {
+          is.close();
+        } catch (IOException e) {
+          // ignore;
+        }
+      }
+    }
+    // Make sure we got values for import properties
+    checkNotNull(bi.values,
+            NAME,
+            MAJOR_VERSION,
+            MINOR_VERSION,
+            POINT_VERSION,
+            REVISION_NUMBER);
+    return bi;
+  }
+
+  private Map<String, String> values = new HashMap<String, String>();
+
+  /**
+   * Gets the name of this build.  This is the first line of the output
+   * from invoking start-ds -F.
+   * @return String representing the name of the build
+   */
+  public String getName() {
+    return values.get(NAME);
+  }
+
+  /**
+   * Gets the build ID which is the 14 digit number code like 20070420110336.
+   *
+   * @return String representing the build ID
+   */
+  public String getBuildId() {
+    return values.get(BUILD_ID);
+  }
+
+  /**
+   * Gets the major version.
+   *
+   * @return String representing the major version
+   */
+  public Integer getMajorVersion() {
+    return new Integer(values.get(MAJOR_VERSION));
+  }
+
+  /**
+   * Gets the minor version.
+   *
+   * @return String representing the minor version
+   */
+  public Integer getMinorVersion() {
+    return new Integer(values.get(MINOR_VERSION));
+  }
+
+  /**
+   * Gets the point version.
+   *
+   * @return String representing the point version
+   */
+  public Integer getPointVersion() {
+    return new Integer(values.get(POINT_VERSION));
+  }
+
+  /**
+   * Gets the SVN revision number.
+   *
+   * @return Integer representing the SVN revision number
+   */
+  public Integer getRevisionNumber() {
+    return new Integer(values.get(REVISION_NUMBER));
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public String toString() {
+    return getName();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public int compareTo(Object o) {
+    BuildInformation bi = (BuildInformation) o;
+    if (getMajorVersion().equals(bi.getMajorVersion())) {
+      if (getMinorVersion().equals(bi.getMinorVersion())) {
+        if (getPointVersion().equals(bi.getPointVersion())) {
+          if (getRevisionNumber().equals(bi.getRevisionNumber())) {
+            return 0;
+          } else if (getRevisionNumber() < bi.getRevisionNumber()) {
+            return -1;
+          }
+        } else if (getPointVersion() < bi.getPointVersion()) {
+          return -1;
+        }
+      } else if (getMinorVersion() < bi.getMinorVersion()) {
+        return -1;
+      }
+    } else if (getMajorVersion() < bi.getMajorVersion()) {
+      return -1;
+    }
+    return 1;
+  }
+
+  static private void checkNotNull(Map values, String... props)
+          throws ApplicationException {
+    for (String prop : props) {
+      if (null == values.get(prop)) {
+        throw new ApplicationException(ApplicationException.Type.TOOL_ERROR,
+                "'" + prop + "' could not be determined", null);
+      }
+    }
+
+  }
+
+}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java
index 5a79706..b78276a 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java
@@ -29,8 +29,6 @@
 
 import java.io.*;
 import java.util.*;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
 
 import org.opends.quicksetup.util.Utils;
 
@@ -209,7 +207,9 @@
           throws IllegalArgumentException {
     // TODO:  i18n
     String failureReason = null;
-    if (!rootDirectory.exists()) {
+    if (rootDirectory == null) {
+      failureReason = "root directory is null";
+    } else if (!rootDirectory.exists()) {
       failureReason = "is not a directory";
     } else if (!rootDirectory.isDirectory()) {
       failureReason = "does not exist";
@@ -230,7 +230,7 @@
     }
     if (failureReason != null) {
       throw new IllegalArgumentException("Install root '" +
-              Utils.getPath(rootDirectory) +
+              (rootDirectory != null ? Utils.getPath(rootDirectory) : "null") +
               "' is not an OpenDS installation root: " +
               " " + failureReason);
     }
@@ -244,7 +244,7 @@
 
   private Configuration baseConfiguration;
 
-  private String buildId;
+  private BuildInformation buildInformation;
 
   /**
    * Creates a new instance from a root directory specified as a string.
@@ -278,14 +278,10 @@
    * Sets the root directory of this installation.
    *
    * @param rootDirectory File of this installation
-   * @throws NullPointerException if root directory is null
    */
-  public void setRootDirectory(File rootDirectory) throws NullPointerException {
-    if (rootDirectory == null) {
-      throw new NullPointerException("Install root cannot be null");
-    }
+  public void setRootDirectory(File rootDirectory) {
 
-    // Hold off on doing more validation of rootDirectory since
+    // Hold off on doing validation of rootDirectory since
     // some applications (like the Installer) create an Installation
     // before the actual bits have been laid down on the filesyste.
 
@@ -456,46 +452,6 @@
   }
 
   /**
-   * Gets the build ID which is the 14 digit number code like 20070420110336.
-   * @return String representing the build ID
-   * @throws ApplicationException if something goes wrong
-   */
-  public String getBuildId() throws ApplicationException {
-    if (buildId == null) {
-      List<String> args = new ArrayList<String>();
-      args.add(Utils.getPath(getServerStartCommandFile()));
-      args.add("-V"); // verbose
-      ProcessBuilder pb = new ProcessBuilder(args);
-      InputStream is = null;
-      try {
-        Process process = pb.start();
-        is = process.getInputStream();
-        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-        String line = null;
-        Pattern p = Pattern.compile("(Build )(\\d{14})");
-        while (null != (line = reader.readLine())) {
-          Matcher m = p.matcher(line);
-          if (m.matches()) {
-            buildId = line.substring(m.start(2), m.end(2));
-          }
-        }
-      } catch (IOException e) {
-        throw new ApplicationException(ApplicationException.Type.START_ERROR,
-                "Error attempting to determine build ID", e);
-      } finally {
-        if (is != null) {
-          try {
-            is.close();
-          } catch (IOException e) {
-            // ignore;
-          }
-        }
-      }
-    }
-    return buildId;
-  }
-
-  /**
    * Returns the path to the configuration file of the directory server.  Note
    * that this method assumes that this code is being run locally.
    *
@@ -542,15 +498,6 @@
   }
 
   /**
-   * Returns the path to the LDIF files under the install path.
-   *
-   * @return the path to the LDIF files under the install path.
-   */
-  public File geLdifDirectory() {
-    return new File(getRootDirectory(), LDIFS_PATH_RELATIVE);
-  }
-
-  /**
    * Returns the path to the config files under the install path.
    *
    * @return the path to the config files under the install path.
@@ -725,4 +672,18 @@
     }
     return statusPanelCommandFile;
   }
-}
+
+  /**
+   * Gets information about the build that was used to produce the bits
+   * for this installation.
+   * @return BuildInformation object describing this installation
+   * @throws ApplicationException if there is a problem obtaining the
+   * build information
+   */
+  public BuildInformation getBuildInformation() throws ApplicationException {
+    if (buildInformation == null) {
+      buildInformation = BuildInformation.create(this);
+    }
+    return buildInformation;
+  }
+}
\ No newline at end of file
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
index a9ce247..89682d0 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -779,6 +779,7 @@
 summary-upgrade-extracting=Extracting Build...
 summary-upgrade-backing-up-db=Backing Up Data...
 summary-upgrade-backing-up-files=Backing Up Files...
+summary-upgrade-check-server-health=Checking Server Health...
 summary-upgrade-calculating-schema-customization=Calculating Schema \
   Customizations...
 summary-upgrade-calculating-config-customization=Calculating Configuration \
@@ -798,7 +799,7 @@
 summary-upgrade-finished-successfully-cli=OpenDS QuickSetup Completed \
   Successfully.  The OpenDS installation at {0} has now been upgraded \
   to version {1}.
-summary-upgrade-finished-with-errors=Upgrade Finished with Errors
+summary-upgrade-finished-with-errors=Upgrade Operation Aborted
 
 #
 # Progress messages
@@ -903,7 +904,7 @@
 upgrade-hypothetical-reversion-failure=Reversion from version {0} to version \
   {1} is not supported.  To revert versions you must uninstall the current \
   server, install the new server, and manually migrate your data.
-upgrade-hypothetical-versions-the-same=This operation is unnecessary.  Both \
+upgrade-hypothetical-versions-the-same=Both \
   new current and proposed version numbers are the same: {0}
 upgrade-mod-no-schema=Processed server modifications \
   (schema checking disabled): {0}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java
index 5d4eff3..0933e11 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java
@@ -68,10 +68,13 @@
    * Creates an instance.
    * @param app using this tool
    * @param url base context for an OpenDS build list
+   * @param proxy Proxy to use for connections; can be null if not proxy is
+   * to be used
    */
-  public RemoteBuildManager(Application app, URL url) {
+  public RemoteBuildManager(Application app, URL url, Proxy proxy) {
     this.app = app;
     this.buildListUrl = url;
+    this.proxy = proxy;
   }
 
   /**
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java
index 3ea00eb..7f2e2cc 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java
@@ -28,6 +28,7 @@
 package org.opends.quicksetup.upgrader;
 
 import org.opends.quicksetup.i18n.ResourceProvider;
+import org.opends.quicksetup.BuildInformation;
 
 /**
  * This class can answer questions important upgrade/reversion questions
@@ -35,18 +36,18 @@
  */
 public class UpgradeOracle {
 
-  private Integer currentVersion;
-  private Integer newVersion;
+  private BuildInformation currentBuildInfo;
+  private BuildInformation newBuildInfo;
 
   /**
    * Creates a new instance that can analyze a hypothetical upgrade/reversion
    * operation from one version to another.
-   * @param currentVersion Integer representing the current version
-   * @param newVersion Integer representing the proposed next version
+   * @param current BuildInformation representing the current version
+   * @param neu BuildInformation representing the proposed next version
    */
-  public UpgradeOracle(Integer currentVersion, Integer newVersion) {
-    this.currentVersion = currentVersion;
-    this.newVersion = newVersion;
+  public UpgradeOracle(BuildInformation current, BuildInformation neu) {
+    this.currentBuildInfo = current;
+    this.newBuildInfo = neu;
   }
 
   /**
@@ -56,7 +57,7 @@
    *         false indicates that this would be a reversion.
    */
   public boolean isUpgrade() {
-    return newVersion > currentVersion;
+    return currentBuildInfo.compareTo(newBuildInfo) < 0;
   }
 
   /**
@@ -66,7 +67,7 @@
    *         false indicates that this would be an upgrade.
    */
   public boolean isReversion() {
-    return newVersion < currentVersion;
+    return currentBuildInfo.compareTo(newBuildInfo) < 0;
   }
 
   /**
@@ -76,14 +77,7 @@
    * an operation will succeed
    */
   public boolean isSupported() {
-    boolean supported;
-    if (// newVersion.equals(currentVersion) || // support this for reinstall?
-        newVersion < 1565) {
-      supported = false;
-    }else {
-      supported = true;
-    }
-    return supported;
+    return isUpgrade();
   }
 
   /**
@@ -95,8 +89,8 @@
    */
   public String getSummaryMessage() {
     String msg;
-    String[] args = { currentVersion.toString(),
-            newVersion.toString() };
+    String[] args = { currentBuildInfo.toString(),
+            currentBuildInfo.toString() };
     ResourceProvider rp = ResourceProvider.getInstance();
     if (isSupported()) {
       if (isUpgrade()) {
@@ -109,8 +103,10 @@
     } else {
       if (isUpgrade()) {
         msg = rp.getMsg("upgrade-hypothetical-upgrade-failure", args);
-      } else {
+      } else if (isReversion()) {
         msg = rp.getMsg("upgrade-hypothetical-reversion-failure", args);
+      } else {
+        msg = rp.getMsg("upgrade-hypothetical-versions-the-same", args);
       }
     }
     return msg;
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
index b321017..7817743 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -35,6 +35,7 @@
 import org.opends.quicksetup.util.FileManager;
 import org.opends.quicksetup.util.ServerController;
 import org.opends.quicksetup.util.ZipExtractor;
+import org.opends.quicksetup.util.OperationOutput;
 import org.opends.quicksetup.ui.*;
 
 import java.awt.event.WindowEvent;
@@ -44,6 +45,9 @@
 import java.io.*;
 import java.net.URL;
 import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.SocketAddress;
+import java.net.InetSocketAddress;
 
 import static org.opends.quicksetup.Installation.*;
 
@@ -93,6 +97,8 @@
 
     INITIALIZING("summary-upgrade-initializing"),
 
+    CHECK_SERVER_HEALTH("summary-upgrade-check-server-health"),
+
     CALCULATING_SCHEMA_CUSTOMIZATIONS(
             "summary-upgrade-calculating-schema-customization"),
 
@@ -246,9 +252,24 @@
           listUrlString = "http://www.opends.org/upgrade-builds";
         }
         URL buildRepo = new URL(listUrlString);
-        remoteBuildManager = new RemoteBuildManager(this, buildRepo);
+
+        // See if system properties dictate use of a proxy
+        Proxy proxy = null;
+        String proxyHost = System.getProperty("http.proxyHost");
+        String proxyPort = System.getProperty("http.proxyPort");
+        if (proxyHost != null && proxyPort != null) {
+          try {
+            SocketAddress addr =
+                    new InetSocketAddress(proxyHost, new Integer(proxyPort));
+            proxy = new Proxy(Proxy.Type.HTTP, addr);
+          } catch (NumberFormatException nfe) {
+            LOG.log(Level.INFO, "Illegal proxy port number " + proxyPort);
+          }
+        }
+
+        remoteBuildManager = new RemoteBuildManager(this, buildRepo, proxy);
       } catch (MalformedURLException e) {
-        LOG.log(Level.INFO, "error", e);
+        LOG.log(Level.INFO, "", e);
       }
     }
     return remoteBuildManager;
@@ -438,7 +459,7 @@
             new Thread(new Runnable() {
               public void run() {
                 try {
-                  installation.getBuildId();
+                  installation.getBuildInformation().getBuildId();
                 } catch (ApplicationException e) {
                   LOG.log(Level.INFO, "error", e);
                 }
@@ -609,27 +630,12 @@
         throw e;
       }
 
-      // If the server has never been started and schema changes
-      // have been made, the server will have never had the chance
-      // to write schema.current.
-      if (!getInstallation().getStatus().isServerRunning()) {
-        try {
-          startServerWithoutConnectionHandlers();
-          getServerController().stopServerInProcess();
-        } catch (ApplicationException e) {
-          LOG.log(Level.INFO, "Error starting server to insure configuration" +
-                  " changes have been written to the filesystem", e);
-          throw e;
-        }
-      }
-
-      if (getInstallation().getStatus().isServerRunning()) {
-        try {
-          new ServerController(this).stopServer();
-        } catch (ApplicationException e) {
-          LOG.log(Level.INFO, "Error stopping server", e);
-          throw e;
-        }
+      try {
+        setCurrentProgressStep(UpgradeProgressStep.CHECK_SERVER_HEALTH);
+        checkServerHealth();
+      } catch (ApplicationException e) {
+        LOG.log(Level.INFO, "Server failed initial health check", e);
+        throw e;
       }
 
       try {
@@ -819,12 +825,41 @@
   }
 
   /**
-   * Abort this upgrade and repair the installation.
-   *
-   * @param lastStep ProgressStep indicating how much work we will have to
-   *                 do to get the installation back like we left it
-   * @throws ApplicationException of something goes wrong
+   * Stops and starts the server checking for serious errors.  Also
+   * has the side effect of having the server write schema.current
+   * if it has never done so.
    */
+  private void checkServerHealth() throws ApplicationException {
+    Installation installation = getInstallation();
+    ServerController control = new ServerController(this, installation);
+    try {
+      if (installation.getStatus().isServerRunning()) {
+        control.stopServer();
+      }
+      OperationOutput op = control.startServer();
+      List<String> errors = op.getErrors();
+      if (errors != null) {
+        throw new ApplicationException(
+                ApplicationException.Type.APPLICATION,
+                "The server currently starts with errors with must" +
+                        "be resolved before an upgrade can occur: " +
+                        Utils.listToString(errors, " "),
+                null);
+      }
+      control.stopServer();
+    } catch (Exception e) {
+      throw new ApplicationException(ApplicationException.Type.APPLICATION,
+              "Server health check failed", e);
+    }
+  }
+
+    /**
+    * Abort this upgrade and repair the installation.
+    *
+    * @param lastStep ProgressStep indicating how much work we will have to
+    *                 do to get the installation back like we left it
+    * @throws ApplicationException of something goes wrong
+    */
   private void abort(ProgressStep lastStep) throws ApplicationException {
     UpgradeProgressStep lastUpgradeStep = (UpgradeProgressStep) lastStep;
     EnumSet<UpgradeProgressStep> stepsStarted =
@@ -866,11 +901,13 @@
   }
 
   private void verifyUpgrade() throws ApplicationException {
-    try {
-      new ServerController(this).startServer();
-    } catch (ApplicationException e) {
-      LOG.log(Level.INFO, "Error starting server: " +
-              e.getLocalizedMessage(), e);
+    ServerController sc = new ServerController(this);
+    OperationOutput op = sc.startServer();
+    if (op.getErrors() != null) {
+      throw new ApplicationException(ApplicationException.Type.APPLICATION,
+              "Upgraded server failed verification test by signaling " +
+                      "errors during startup: " +
+                      Utils.listToString(op.getErrors(), " "), null);
     }
   }
 
@@ -1253,24 +1290,24 @@
    * day' types of changes to the codebase.
    */
   private void insureUpgradability() throws ApplicationException {
-    Integer currentVersion;
-    Integer newVersion;
+    BuildInformation currentVersion;
+    BuildInformation newVersion;
 
     try {
-      currentVersion = getInstallation().getSvnRev();
+      currentVersion = getInstallation().getBuildInformation();
     } catch (ApplicationException e) {
       LOG.log(Level.INFO, "error", e);
       throw ApplicationException.createFileSystemException(
-              "Could not determine current version number: " +
+              "Could not determine current build information: " +
               e.getLocalizedMessage(), e);
     }
 
     try {
-      newVersion = getStagedInstallation().getSvnRev();
+      newVersion = getStagedInstallation().getBuildInformation();
     } catch (Exception e) {
       LOG.log(Level.INFO, "error", e);
       throw ApplicationException.createFileSystemException(
-              "Could not determine upgrade version number: " +
+              "Could not determine upgrade build information: " +
               e.getLocalizedMessage(), e);
     }
 
@@ -1346,7 +1383,7 @@
     String installPath = Utils.getPath(getInstallation().getRootDirectory());
     String newVersion = null;
     try {
-      newVersion = getInstallation().getBuildId();
+      newVersion = getInstallation().getBuildInformation().getBuildId();
     } catch (ApplicationException e) {
       newVersion = getMsg("upgrade-build-id-unknown");
     }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
index e26e2ff..c7edb7b 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
@@ -185,7 +185,8 @@
   private String getOldBuildString() {
     String oldVersion;
     try {
-      oldVersion = getApplication().getInstallation().getBuildId();
+      oldVersion = getApplication().getInstallation().
+              getBuildInformation().getBuildId();
     } catch (ApplicationException e) {
       LOG.log(Level.INFO, "error", e);
       oldVersion = getMsg("upgrade-build-id-unknown");
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/WelcomePanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/WelcomePanel.java
index 3a245ce..ea4151e 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/WelcomePanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/WelcomePanel.java
@@ -192,7 +192,7 @@
       String buildId = null;
       Installation installation = getApplication().getInstallation();
       try {
-        buildId = installation.getBuildId();
+        buildId = installation.getBuildInformation().getBuildId();
       } catch (Exception e) {
         buildId = getMsg("upgrade-build-id-unknown");
       }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/OperationOutput.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/OperationOutput.java
new file mode 100644
index 0000000..65c7d3e
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/OperationOutput.java
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.quicksetup.util;
+
+import java.util.List;
+
+/**
+ * Contains information about an operation invoked by this class.
+ */
+public class OperationOutput {
+
+  private Exception exception = null;
+
+  private List<String> errors = null;
+
+  /**
+   * Gets a list of string representing error messages obtained
+   * by invoking the operation.  Null if there were no errors.
+   * @return List of Strings representing errors
+   */
+  public List<String> getErrors() {
+    return errors;
+  }
+
+  /**
+   * Gets an exception that occurred by invoking the operation.  Null
+   * if there were no exceptions.
+   * @return Exception error
+   */
+  public Exception getException() {
+    return exception;
+  }
+
+  /**
+   * Sets the exception that occurred during execution.  Can be null to
+   * indicate no exception was encountered.
+   * @param exception Exception that occurred during invocation of the operation
+   */
+  void setException(Exception exception) {
+    this.exception = exception;
+  }
+
+  /**
+   * Sets the list of error messages that occurred during execution.
+   * Can be null to indicate no errors were encountered.
+   * @param errors List of Strings representing error messages
+   */
+  void setErrors(List<String> errors) {
+    this.errors = errors;
+  }
+}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java
index 0982969..3a19f43 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java
@@ -33,6 +33,7 @@
 import javax.naming.NamingException;
 import java.util.ArrayList;
 import java.util.Map;
+import java.util.List;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.io.IOException;
@@ -224,19 +225,26 @@
 
   /**
    * This methods starts the server.
+   * @return OperationOutput object containing output from the start server
+   * command invocation.
    * @throws org.opends.quicksetup.ApplicationException if something goes wrong.
    */
-  public void startServer() throws ApplicationException {
-    startServer(true);
+  public OperationOutput startServer() throws ApplicationException {
+    return startServer(true);
   }
 
   /**
    * This methods starts the server.
    * @param verify boolean indicating whether this method will attempt to
    * connect to the server after starting to verify that it is listening.
+   * @return OperationOutput object containing output from the start server
+   * command invocation.
    * @throws org.opends.quicksetup.ApplicationException if something goes wrong.
    */
-  private void startServer(boolean verify) throws ApplicationException {
+  private OperationOutput startServer(boolean verify)
+          throws ApplicationException
+  {
+    OperationOutput output = new OperationOutput();
     application.notifyListeners(
             application.getFormattedProgress(
                     application.getMsg("progress-starting")) +
@@ -275,7 +283,7 @@
       StartReader errReader = new StartReader(err, startedId, true);
       StartReader outputReader = new StartReader(out, startedId, false);
 
-      while (!errReader.isFinished() && !outputReader.isFinished())
+      while (!errReader.isFinished() || !outputReader.isFinished())
       {
         try
         {
@@ -284,6 +292,17 @@
         {
         }
       }
+
+      // Collect any errors found in the output
+      List<String> errors = errReader.getErrors();
+      if (outputReader.getErrors() != null) {
+        if (errors == null) {
+          errors = new ArrayList<String>();
+        }
+        errors.addAll(outputReader.getErrors());
+      }
+      output.setErrors(errors);
+
       // Check if something wrong occurred reading the starting of the server
       ApplicationException ex = errReader.getException();
       if (ex == null)
@@ -292,6 +311,11 @@
       }
       if (ex != null)
       {
+        // This is meaningless right now since we throw
+        // the exception below, but in case we change out
+        // minds later or add the ability to return exceptions
+        // in the output only instead of throwing...
+        output.setException(ex);
         throw ex;
 
       } else if (verify)
@@ -369,6 +393,7 @@
       throw new ApplicationException(ApplicationException.Type.START_ERROR,
           application.getThrowableMsg("error-starting-server", ioe), ioe);
     }
+    return output;
   }
 
   /**
@@ -481,6 +506,8 @@
   {
     private ApplicationException ex;
 
+    private List<String> errors;
+
     private boolean isFinished;
 
     private boolean isFirstLine;
@@ -530,6 +557,16 @@
               {
                 isFinished = true;
               }
+
+              // Collect lines that would seem to indicate all is
+              // not well with the server
+              if (line.indexOf("severity=SEVERE_ERROR") != -1) {
+                if (errors == null) {
+                  errors = new ArrayList<String>();
+                }
+                errors.add(line);
+              }
+
               line = reader.readLine();
             }
           } catch (IOException ioe)
@@ -563,6 +600,10 @@
       return ex;
     }
 
+    public List<String> getErrors() {
+      return errors;
+    }
+
     /**
      * Returns <CODE>true</CODE> if the server starting process finished
      * (successfully or not) and <CODE>false</CODE> otherwise.

--
Gitblit v1.10.0