From 04ead8f1c81d759108686bbd4add4b9eee542c2e Mon Sep 17 00:00:00 2001
From: kenneth_suter <kenneth_suter@localhost>
Date: Wed, 11 Apr 2007 18:51:40 +0000
Subject: [PATCH] During schema and configuration upgrade, the server is started 'in process' without any connection handlers and the changes are made using an internal connection to the server. During configuration/schema updates:
---
opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java | 97 +++++
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties | 9
opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java | 44 --
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java | 5
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java | 69 ++++
opends/src/quicksetup/org/opends/quicksetup/Installation.java | 4
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java | 2
opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java | 110 ++++++
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java | 569 +++++++++++++++++++++++++---------
opends/src/quicksetup/org/opends/quicksetup/Application.java | 24 +
10 files changed, 706 insertions(+), 227 deletions(-)
diff --git a/opends/src/quicksetup/org/opends/quicksetup/Application.java b/opends/src/quicksetup/org/opends/quicksetup/Application.java
index 93fc59a..b0420e6 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/Application.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -33,6 +33,7 @@
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ProgressMessageFormatter;
+import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.ui.QuickSetupDialog;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.FramePanel;
@@ -110,6 +111,8 @@
private Installation installation;
+ private ServerController serverController;
+
/** Formats progress messages. */
protected ProgressMessageFormatter formatter;
@@ -190,6 +193,25 @@
}
/**
+ * Sets the application's installation.
+ * @param installation describing the application's OpenDS installation
+ */
+ protected void setInstallation(Installation installation) {
+ this.installation = installation;
+ }
+
+ /**
+ * Gets a server controller for use by this application.
+ * @return ServerController that can be used to start and stop the server.
+ */
+ public ServerController getServerController() {
+ if (serverController == null) {
+ serverController = new ServerController(this);
+ }
+ return serverController;
+ }
+
+ /**
* Returns the UserData object representing the parameters provided by
* the user to do the installation.
*
@@ -281,7 +303,7 @@
* @param args the arguments to be passed to generate the resulting value.
* @return the value associated to the key in the properties file.
*/
- public String getMsg(String key, String[] args)
+ public String getMsg(String key, String... args)
{
return getI18n().getMsg(key, args);
}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/Installation.java b/opends/src/quicksetup/org/opends/quicksetup/Installation.java
index 35f8a8b..f12c1cd 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/Installation.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/Installation.java
@@ -311,7 +311,7 @@
*/
public File getBaseSchemaFile() throws QuickSetupException {
return new File(getConfigurationUpgradeDirectory(),
- "config/upgrade/schema.ldif." + getSvnRev().toString());
+ "schema.ldif." + getSvnRev().toString());
}
/**
@@ -471,7 +471,7 @@
public File createHistoryBackupDirectory() throws IOException {
File backupDirectory =
new File(getHistoryDirectory(),
- "upgrade-" + System.currentTimeMillis());
+ Long.toString(System.currentTimeMillis()));
if (backupDirectory.exists()) {
backupDirectory.delete();
}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java b/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
index 74f6b0f..28672c7 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -115,6 +115,8 @@
getRatio(InstallProgressStep.CONFIGURING_SERVER));
notifyListeners(getTaskSeparator());
+ setInstallation(new Installation(getUserData().getServerLocation()));
+
status = InstallProgressStep.CONFIGURING_SERVER;
configureServer();
diff --git a/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties b/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
index 0f787e9..b0feaf7 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
+++ b/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -588,7 +588,7 @@
summary-upgrade-backing-up-files=Backing Up Files...
summary-upgrade-calculating-schema-customization=Calculating Schema \
Customizations...
-summary-upgrade-calculating-config-customization=Calculating Configuration\
+summary-upgrade-calculating-config-customization=Calculating Configuration \
Customizations...
summary-upgrade-upgrading-components=Upgrading Components...
summary-upgrade-applying-schema-customization=Applying Schema \
@@ -597,7 +597,8 @@
Customizations...
summary-upgrade-verifying=Verifying Upgrade...
summary-upgrade-history=Recording Upgrade History...
-summary-upgrade-cleanup=Cleanup...
+summary-upgrade-cleanup=Cleaning Up...
+summary-upgrade-abort=Aborting Upgrade Due to Error...
summary-upgrade-finished-successfully=Upgrade Finished Successfully
summary-upgrade-finished-with-errors=Upgrade Finished with Errors
@@ -701,3 +702,7 @@
server, install the new server, and manually migrate your data.
upgrade-hypothetical-versions-the-same=This operation is unnecessary. Both \
new current and proposed version numbers are the same: {0}
+upgrade-mod-no-schema=Processed server modifications \
+ (schema checking disabled): {0}
+upgrade-mod=Processed server modifications: {0}
+upgrade-mod-ignore=Attribute or value already exists: {0}
\ No newline at end of file
diff --git a/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java b/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java
index 7831319..3ea00eb 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java
@@ -77,9 +77,10 @@
*/
public boolean isSupported() {
boolean supported;
- if (newVersion == currentVersion) {
+ if (// newVersion.equals(currentVersion) || // support this for reinstall?
+ newVersion < 1565) {
supported = false;
- } else {
+ }else {
supported = true;
}
return supported;
diff --git a/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java b/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
index a6ce096..500ac5f 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -36,6 +36,12 @@
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.server.tools.BackUpDB;
import org.opends.server.tools.LDIFDiff;
+import org.opends.server.util.*;
+import org.opends.server.types.*;
+import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.ModifyOperation;
+import org.opends.server.core.DirectoryServer;
import java.awt.event.WindowEvent;
import java.util.*;
@@ -51,7 +57,9 @@
*/
public class Upgrader extends Application implements CliApplication {
- /** Steps in the Upgrade wizard. */
+ /**
+ * Steps in the Upgrade wizard.
+ */
enum UpgradeWizardStep implements WizardStep {
WELCOME("welcome-step"),
@@ -76,7 +84,9 @@
}
}
- /** Steps during the upgrade process. */
+ /**
+ * Steps during the upgrade process.
+ */
enum UpgradeProgressStep implements ProgressStep {
NOT_STARTED("summary-upgrade-not-started"),
@@ -85,16 +95,16 @@
STOPPING_SERVER("summary-stopping"),
- BACKING_UP_DATABASES("summary-upgrade-backing-up-db"),
-
- BACKING_UP_FILESYSTEM("summary-upgrade-backing-up-files"),
-
CALCULATING_SCHEMA_CUSTOMIZATIONS(
"summary-upgrade-calculating-schema-customization"),
CALCULATING_CONFIGURATION_CUSTOMIZATIONS(
"summary-upgrade-calculating-config-customization"),
+ BACKING_UP_DATABASES("summary-upgrade-backing-up-db"),
+
+ BACKING_UP_FILESYSTEM("summary-upgrade-backing-up-files"),
+
UPGRADING_COMPONENTS("summary-upgrade-upgrading-components"),
APPLYING_SCHEMA_CUSTOMIZATIONS(
@@ -109,6 +119,8 @@
CLEANUP("summary-upgrade-cleanup"),
+ ABORT("summary-upgrade-abort"),
+
FINISHED_WITH_ERRORS("summary-upgrade-finished-with-errors"),
FINISHED("summary-upgrade-finished-successfully");
@@ -121,6 +133,7 @@
/**
* Return a key for access a summary message.
+ *
* @return String representing key for access summary in resource bundle
*/
public String getSummaryMesssageKey() {
@@ -147,32 +160,47 @@
// Root files that will be ignored during backup
static private final String[] ROOT_FILES_TO_IGNORE_DURING_BACKUP = {
- CHANGELOG_PATH_RELATIVE, // changelogDb
- DATABASES_PATH_RELATIVE, // db
- LOGS_PATH_RELATIVE, // logs
- LOCKS_PATH_RELATIVE, // locks
- HISTORY_PATH_RELATIVE // history
+ CHANGELOG_PATH_RELATIVE, // changelogDb
+ DATABASES_PATH_RELATIVE, // db
+ LOGS_PATH_RELATIVE, // logs
+ LOCKS_PATH_RELATIVE, // locks
+ HISTORY_PATH_RELATIVE // history
};
private ProgressStep currentProgressStep = UpgradeProgressStep.NOT_STARTED;
- /** Assigned if an exception occurs during run(). */
+ /**
+ * Assigned if an exception occurs during run().
+ */
private ApplicationException runException = null;
- /** Helps with CLI specific tasks. */
+ /**
+ * Helps with CLI specific tasks.
+ */
private UpgraderCliHelper cliHelper = null;
- /** Directory where we keep files temporarily. */
+ /**
+ * Directory where we keep files temporarily.
+ */
private File stagingDirectory = null;
- /** Directory where backup is kept in case the upgrade needs reversion. */
+ /**
+ * Directory where backup is kept in case the upgrade needs reversion.
+ */
private File backupDirectory = null;
- /** ID that uniquely identifieds this invocation of the Upgrader in the
+ /**
+ * ID that uniquely identifieds this invocation of the Upgrader in the
* historical logs.
*/
private Long historicalOperationId;
+ /** SVN rev number of the current build. */
+ private Integer currentVersion = null;
+
+ /** SVN rev number of the build in the stage directory. */
+ private Integer stagedVersion = null;
+
/**
* {@inheritDoc}
*/
@@ -214,7 +242,7 @@
* {@inheritDoc}
*/
public Integer getRatio(ProgressStep step) {
- return 100 * ((UpgradeProgressStep)step).ordinal() /
+ return 100 * ((UpgradeProgressStep) step).ordinal() /
EnumSet.allOf(UpgradeWizardStep.class).size();
}
@@ -222,7 +250,7 @@
* {@inheritDoc}
*/
public String getSummary(ProgressStep step) {
- return getMsg(((UpgradeProgressStep)step).getSummaryMesssageKey());
+ return getMsg(((UpgradeProgressStep) step).getSummaryMesssageKey());
}
/**
@@ -278,8 +306,7 @@
* {@inheritDoc}
*/
protected void updateUserData(WizardStep cStep, QuickSetup qs)
- throws UserDataException
- {
+ throws UserDataException {
}
/**
@@ -319,17 +346,11 @@
// Reset exception just in case this application is rerun
// for some reason
runException = null;
- Integer fromVersion = null;
- Integer toVersion = null;
try {
try {
setCurrentProgressStep(UpgradeProgressStep.INITIALIZING);
initialize();
- fromVersion = getStagedInstallation().getSvnRev();
- toVersion = getInstallation().getSvnRev();
- this.historicalOperationId =
- writeInitialHistoricalRecord(fromVersion, toVersion);
} catch (ApplicationException e) {
LOG.log(Level.INFO, "error initializing upgrader", e);
throw e;
@@ -346,6 +367,25 @@
}
try {
+ setCurrentProgressStep(
+ UpgradeProgressStep.CALCULATING_SCHEMA_CUSTOMIZATIONS);
+ calculateSchemaCustomizations();
+ } catch (ApplicationException e) {
+ LOG.log(Level.INFO, "error calculating schema customizations", e);
+ throw e;
+ }
+
+ try {
+ setCurrentProgressStep(
+ UpgradeProgressStep.CALCULATING_CONFIGURATION_CUSTOMIZATIONS);
+ calculateConfigCustomizations();
+ } catch (ApplicationException e) {
+ LOG.log(Level.INFO,
+ "error calculating config customizations", e);
+ throw e;
+ }
+
+ try {
setCurrentProgressStep(UpgradeProgressStep.BACKING_UP_DATABASES);
backupDatabases();
} catch (ApplicationException e) {
@@ -361,28 +401,9 @@
throw e;
}
- try {
- setCurrentProgressStep(
- UpgradeProgressStep.CALCULATING_SCHEMA_CUSTOMIZATIONS);
- calculateSchemaCustomizations();
- } catch (ApplicationException e) {
- LOG.log(Level.INFO, "error calculating schema customizations", e);
- throw e;
- }
-
- try {
- setCurrentProgressStep(
- UpgradeProgressStep.CALCULATING_CONFIGURATION_CUSTOMIZATIONS);
- calculateConfigCustomizations();
- } catch (ApplicationException e) {
- LOG.log(Level.INFO,
- "error calculating config customizations", e);
- throw e;
- }
-
try {
setCurrentProgressStep(
- UpgradeProgressStep.UPGRADING_COMPONENTS);
+ UpgradeProgressStep.UPGRADING_COMPONENTS);
upgradeComponents();
} catch (ApplicationException e) {
LOG.log(Level.INFO,
@@ -390,16 +411,42 @@
throw e;
}
-// setCurrentProgressStep(
-// UpgradeProgressStep.APPLYING_SCHEMA_CUSTOMIZATIONS);
-// sleepFor1();
-// setCurrentProgressStep(
-// UpgradeProgressStep.APPLYING_CONFIGURATION_CUSTOMIZATIONS);
-// sleepFor1();
-// setCurrentProgressStep(UpgradeProgressStep.VERIFYING);
-// sleepFor1();
+ try {
+ setCurrentProgressStep(
+ UpgradeProgressStep.APPLYING_SCHEMA_CUSTOMIZATIONS);
+ applySchemaCustomizations();
+ } catch (ApplicationException e) {
+ LOG.log(Level.INFO,
+ "error applying schema customizations", e);
+ throw e;
+ }
+ try {
+ setCurrentProgressStep(
+ UpgradeProgressStep.APPLYING_CONFIGURATION_CUSTOMIZATIONS);
+ applyConfigurationCustomizations();
+ } catch (ApplicationException e) {
+ LOG.log(Level.INFO,
+ "error applying configuration customizations", e);
+ throw e;
+ }
+ if ("true".equals(
+ System.getProperty(
+ "org.opends.upgrader.Upgrader.CreateError.CreateError")))
+ {
+ throw new ApplicationException(
+ null, "ARTIFICIAL ERROR FOR TESTING ABORT PROCESS", null);
+ }
+
+ try {
+ setCurrentProgressStep(UpgradeProgressStep.VERIFYING);
+ verifyUpgrade();
+ } catch (ApplicationException e) {
+ LOG.log(Level.INFO,
+ "error verifying upgrade", e);
+ throw e;
+ }
} catch (ApplicationException ae) {
this.runException = ae;
@@ -410,11 +457,6 @@
t);
} finally {
try {
- setCurrentProgressStep(UpgradeProgressStep.CLEANUP);
- cleanup();
-
- // Write a record in the log file indicating success/failure
- setCurrentProgressStep(UpgradeProgressStep.RECORDING_HISTORY);
HistoricalRecord.Status status;
String note = null;
if (runException == null) {
@@ -422,16 +464,29 @@
} else {
status = HistoricalRecord.Status.FAILURE;
note = runException.getLocalizedMessage();
+
+ // Abort the upgrade and put things back like we found it
+ ProgressStep lastProgressStep = getCurrentProgressStep();
+ setCurrentProgressStep(UpgradeProgressStep.ABORT);
+ abort(lastProgressStep);
}
+
+ setCurrentProgressStep(UpgradeProgressStep.CLEANUP);
+ cleanup();
+
+ // Write a record in the log file indicating success/failure
+ setCurrentProgressStep(UpgradeProgressStep.RECORDING_HISTORY);
writeHistoricalRecord(historicalOperationId,
- fromVersion,
- toVersion,
+ getCurrentVersion(),
+ getStagedVersion(),
status,
note);
} catch (ApplicationException e) {
System.err.print("error cleaning up after upgrade: " +
e.getLocalizedMessage());
+ } finally {
+
}
}
@@ -440,19 +495,213 @@
setCurrentProgressStep(UpgradeProgressStep.FINISHED);
} else {
setCurrentProgressStep(UpgradeProgressStep.FINISHED_WITH_ERRORS);
+ notifyListeners(runException.getLocalizedMessage() +
+ formatter.getLineBreak());
}
}
+ /**
+ * 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 =
+ EnumSet.range(UpgradeProgressStep.INITIALIZING, lastUpgradeStep);
+
+ if (stepsStarted.contains(UpgradeProgressStep.BACKING_UP_FILESYSTEM)) {
+
+ // Files were copied from the stage directory to the current
+ // directory. Repair things by overwriting file in the
+ // root with those that were copied to the backup directory
+ // during backupFiles()
+
+ File root = getInstallation().getRootDirectory();
+ File backupDirectory;
+ try {
+ backupDirectory = getFilesBackupDirectory();
+ FileManager fm = new FileManager(this);
+ for (String fileName : backupDirectory.list()) {
+ File f = new File(backupDirectory, fileName);
+
+ // Do our best to restore the filesystem like
+ // we found it. Just report potential problems
+ // to the user.
+ try {
+ fm.move(f, root, null);
+ } catch (Throwable t) {
+ notifyListeners("The following could not be restored after the" +
+ "failed upgrade attempt. You should restore this " +
+ "file/directory manually: " + f + " to " + root);
+ }
+ }
+ fm.deleteRecursively(backupDirectory);
+ } catch (IOException e) {
+ LOG.log(Level.INFO, "error getting backup directory", e);
+ }
+ }
+
+
+ }
+
+ private void verifyUpgrade() throws ApplicationException {
+ try {
+ new ServerController(this).startServer();
+ } catch (QuickSetupException e) {
+ LOG.log(Level.INFO, "error starting server", e);
+ }
+ }
+
+ private void applyConfigurationCustomizations() throws ApplicationException {
+ try {
+ File configDiff = getCustomConfigDiffFile();
+ if (configDiff.exists()) {
+ applyCustomizationLdifFile(configDiff);
+ }
+ } catch (IOException e) {
+ LOG.log(Level.INFO, "error getting schema diff file", e);
+ throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
+ "error applying configuration customization", e);
+ } catch (LDIFException e) {
+ LOG.log(Level.INFO, "error reading change record", e);
+ throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
+ "error applying configuration customization", e);
+ }
+ }
+
+ private void applySchemaCustomizations() throws ApplicationException {
+ try {
+ File schemaDiff = getCustomSchemaDiffFile();
+ if (schemaDiff.exists()) {
+ applyCustomizationLdifFile(schemaDiff);
+ }
+ } catch (IOException e) {
+ LOG.log(Level.INFO, "error getting schema diff file", e);
+ throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
+ "error applying schema customization", e);
+ } catch (LDIFException e) {
+ LOG.log(Level.INFO, "error reading change record", e);
+ throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
+ "error applying schema customization", e);
+ }
+ }
+
+ private void startServerWithoutConnectionHandlers()
+ throws ApplicationException {
+ try {
+ ServerController control = new ServerController(this);
+ if (getInstallation().getStatus().isServerRunning()) {
+ control.stopServer();
+ }
+ control.startServerInProcess(true);
+ } catch (IOException e) {
+ LOG.log(Level.INFO, "could not determine server state", e);
+ throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
+ "error trying to determine server state", e);
+ } catch (InitializationException e) {
+ LOG.log(Level.INFO, "could not start server", e);
+ throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
+ "could not start server with handlers", e);
+ } catch (ConfigException e) {
+ LOG.log(Level.INFO, "configuration error starting server", e);
+ throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
+ "configuration error starting server", e);
+ }
+ }
+
+ private void applyCustomizationLdifFile(File ldifFile)
+ throws IOException, LDIFException, ApplicationException {
+ try {
+ startServerWithoutConnectionHandlers();
+ InternalClientConnection cc =
+ InternalClientConnection.getRootConnection();
+ LDIFImportConfig importCfg =
+ new LDIFImportConfig(Utils.getPath(ldifFile));
+ LDIFReader ldifReader = new LDIFReader(importCfg);
+ ChangeRecordEntry cre;
+ while (null != (cre = ldifReader.readChangeRecord(false))) {
+ if (cre instanceof ModifyChangeRecordEntry) {
+ ModifyChangeRecordEntry mcre = (ModifyChangeRecordEntry) cre;
+ ByteString dnByteString =
+ ByteStringFactory.create(mcre.getDN().toString());
+ ModifyOperation op =
+ cc.processModify(dnByteString, mcre.getModifications());
+ ResultCode rc = op.getResultCode();
+ if (rc.equals(ResultCode.OBJECTCLASS_VIOLATION)) {
+ // try again without schema checking
+ DirectoryServer.setCheckSchema(false);
+ op = cc.processModify(dnByteString, mcre.getModifications());
+ rc = op.getResultCode();
+ }
+ if (rc.equals(ResultCode.SUCCESS)) {
+ if (DirectoryServer.checkSchema()) {
+ notifyListeners(
+ getMsg("upgrade-mod",
+ modListToString(op.getModifications()))
+ + formatter.getLineBreak());
+ } else {
+ notifyListeners(
+ getMsg("upgrade-mod-no-schema",
+ modListToString(op.getModifications()))
+ + formatter.getLineBreak());
+ DirectoryServer.setCheckSchema(true);
+ }
+ } else if (rc.equals(ResultCode.ATTRIBUTE_OR_VALUE_EXISTS)) {
+ // ignore this error
+ notifyListeners(
+ getMsg("upgrade-mod-ignore",
+ modListToString(op.getModifications()))
+ + formatter.getLineBreak());
+ } else {
+ // report the error to the user
+ StringBuilder error = op.getErrorMessage();
+ if (error != null) {
+ throw new ApplicationException(
+ ApplicationException.Type.IMPORT_ERROR,
+ "error processing custom configuration "
+ + error.toString(),
+ null);
+ }
+ }
+ } else {
+ throw new ApplicationException(
+ ApplicationException.Type.IMPORT_ERROR,
+ "unexpected change record type " + cre.getClass(),
+ null);
+ }
+ }
+ } catch (Throwable t) {
+ // t.printStackTrace(System.out);
+ throw new ApplicationException(ApplicationException.Type.BUG,
+ t.getMessage(), t);
+ } finally {
+ getServerController().stopServerInProcess();
+ }
+ }
+
+ private String modListToString(List<Modification> modifications) {
+ StringBuilder modsMsg = new StringBuilder();
+ for(int i = 0; i < modifications.size(); i++) {
+ modsMsg.append(modifications.get(i).toString());
+ if (i < modifications.size() - 1) {
+ modsMsg.append(" ");
+ }
+ }
+ return modsMsg.toString();
+ }
+
private Long writeInitialHistoricalRecord(
Integer fromVersion,
Integer toVersion)
- throws ApplicationException
- {
+ throws ApplicationException {
Long id;
try {
HistoricalLog log =
- new HistoricalLog(getInstallation().getHistoryLogFile());
+ new HistoricalLog(getInstallation().getHistoryLogFile());
id = log.append(fromVersion, toVersion,
HistoricalRecord.Status.STARTED, null);
} catch (IOException e) {
@@ -471,15 +720,8 @@
throws ApplicationException {
try {
HistoricalLog log =
- new HistoricalLog(getInstallation().getHistoryLogFile());
+ new HistoricalLog(getInstallation().getHistoryLogFile());
log.append(id, from, to, status, note);
-
- // FOR TESTING
- List<HistoricalRecord> records = log.getRecords();
- for(HistoricalRecord record : records) {
- System.out.println(record);
- }
-
} catch (IOException e) {
throw ApplicationException.createFileSystemException(
"error logging operation", e);
@@ -493,7 +735,9 @@
FileManager fm = new FileManager(this);
for (String fileName : stageDir.list()) {
File f = new File(stageDir, fileName);
- fm.copyRecursively(f, root, new UpgradeFileFilter(stageDir));
+ fm.copyRecursively(f, root,
+ new UpgradeFileFilter(stageDir),
+ /*overwrite=*/true);
}
} catch (IOException e) {
throw ApplicationException.createFileSystemException(
@@ -503,47 +747,20 @@
private void calculateConfigCustomizations() throws ApplicationException {
try {
- if (getInstallation().getCurrentConfiguration().hasBeenModified()) {
-
- try {
- List<String> args = new ArrayList<String>();
-
- args.add("-s"); // source LDIF
- args.add(getInstallation().getCurrentConfigurationFile().
- getCanonicalPath());
-
- args.add("-t"); // target LDIF
- args.add(getInstallation().getBaseConfigurationFile().
- getCanonicalPath());
-
- args.add("-o"); // output LDIF
- args.add(getCustomConfigDiffFile().
- getCanonicalPath());
-
- // TODO i18n
- notifyListeners("Diff'ing configuration with base configuration...");
-
- int ret = LDIFDiff.mainDiff(args.toArray(new String[]{}), false);
- if (ret != 0) {
- StringBuffer msg = new StringBuffer()
- .append("'ldif-diff' tool returned error code ")
- .append(ret)
- .append(" when invoked with args :")
- .append(Utils.listToString(args, " "));
+ if (getInstallation().getCurrentConfiguration().hasBeenModified()) {
+ try {
+ ldifDiff(getInstallation().getBaseConfigurationFile(),
+ getInstallation().getCurrentConfigurationFile(),
+ getCustomConfigDiffFile());
+ } catch (Exception e) {
throw ApplicationException.createFileSystemException(
- msg.toString(), null);
- } else {
- notifyListeners(formatter.getFormattedDone());
+ "error determining configuration customizations", e);
}
- } catch (Exception e) {
- throw ApplicationException.createFileSystemException(
- "error determining configuration customizations", e);
+ } else {
+ // TODO i18n
+ notifyListeners("No configuration customizations to migrate" +
+ formatter.getLineBreak());
}
- } else {
- // TODO i18n
- notifyListeners("No configuration customizations to migrate" +
- formatter.getLineBreak());
- }
} catch (IOException e) {
// TODO i18n
throw ApplicationException.createFileSystemException(
@@ -551,44 +768,52 @@
}
}
+ private void ldifDiff(File source, File target, File output)
+ throws ApplicationException {
+ List<String> args = new ArrayList<String>();
+
+ args.add("-s"); // source LDIF
+ args.add(Utils.getPath(source));
+
+ args.add("-t"); // target LDIF
+ args.add(Utils.getPath(target));
+
+ args.add("-o"); // output LDIF
+ args.add(Utils.getPath(output));
+
+ args.add("-O"); // overwrite
+ args.add("-S"); // single-value changes
+
+ // TODO i18n
+ notifyListeners(formatter.getFormattedWithPoints("Diff'ing " +
+ Utils.getPath(source) + " with " +
+ Utils.getPath(target)));
+
+ int ret = LDIFDiff.mainDiff(args.toArray(new String[]{}), false);
+ if (ret != 0) {
+ StringBuffer sb = new StringBuffer()
+ .append("'ldif-diff' tool returned error code ")
+ .append(ret)
+ .append(" when invoked with args: ")
+ .append(Utils.listToString(args, " "));
+ notifyListeners(formatter.getLineBreak());
+ throw ApplicationException.createFileSystemException(sb.toString(),
+ null);
+ } else {
+ notifyListeners(formatter.getFormattedDone() + formatter.getLineBreak());
+ }
+ }
+
private void calculateSchemaCustomizations() throws ApplicationException {
if (getInstallation().getStatus().schemaHasBeenModified()) {
// TODO i18n
notifyListeners(
- "Schema contains customizations and needs to be migrated");
-
+ "Schema contains customizations and needs to be migrated\n");
try {
- List<String> args = new ArrayList<String>();
-
- args.add("-s"); // source LDIF
- args.add(getInstallation().getSchemaConcatFile().
- getCanonicalPath());
-
- args.add("-t"); // target LDIF
- args.add(getInstallation().getBaseSchemaFile().
- getCanonicalPath());
-
- args.add("-o"); // output LDIF
- args.add(getCustomSchemaDiffFile().
- getCanonicalPath());
-
- // TODO i18n
- notifyListeners("Diff'ing schema with base schema...");
-
- int ret = LDIFDiff.mainDiff(args.toArray(new String[]{}), false);
- if (ret != 0) {
- StringBuffer sb = new StringBuffer()
- .append("'ldif-diff' tool returned error code ")
- .append(ret)
- .append(" when invoked with args: ")
- .append(Utils.listToString(args, " "));
- throw ApplicationException.createFileSystemException(sb.toString(),
- null);
- } else {
- notifyListeners(formatter.getFormattedDone());
- }
-
+ ldifDiff(getInstallation().getBaseSchemaFile(),
+ getInstallation().getSchemaConcatFile(),
+ getCustomSchemaDiffFile());
} catch (Exception e) {
throw ApplicationException.createFileSystemException(
"error determining schema customizations", e);
@@ -596,7 +821,7 @@
} else {
// TODO i18n
notifyListeners("No schema customizations to migrate" +
- formatter.getLineBreak());
+ formatter.getLineBreak());
}
}
@@ -605,10 +830,11 @@
File filesBackupDirectory = getFilesBackupDirectory();
FileManager fm = new FileManager(this);
File root = getInstallation().getRootDirectory();
+ FileFilter filter = new UpgradeFileFilter(root);
for (String fileName : root.list()) {
File f = new File(root, fileName);
- fm.copyRecursively(f, filesBackupDirectory,
- new UpgradeFileFilter(root));
+ //fm.copyRecursively(f, filesBackupDirectory,
+ fm.move(f, filesBackupDirectory, filter);
}
} catch (Exception e) {
throw new ApplicationException(
@@ -657,12 +883,16 @@
try {
stagingDir = getStageDirectory();
FileManager fm = new FileManager(this);
+
+ // doing this seems to work betterh than just plain
+ // old delete
fm.deleteRecursively(stagingDir);
+
} catch (IOException e) {
// TODO i18n
throw ApplicationException.createFileSystemException(
"error attempting to clean up tmp directory " +
- stagingDir != null ? stagingDir.getName() : "null",
+ stagingDir != null ? stagingDir.getName() : "null",
e);
}
}
@@ -670,7 +900,14 @@
private void initialize() throws ApplicationException {
try {
expandZipFile();
+
+ Integer fromVersion = getStagedVersion();
+ Integer toVersion = getCurrentVersion();
+ this.historicalOperationId =
+ writeInitialHistoricalRecord(fromVersion, toVersion);
+
insureUpgradability();
+
} catch (Exception e) {
throw new ApplicationException(
ApplicationException.Type.FILE_SYSTEM_ERROR,
@@ -713,14 +950,12 @@
}
private Installation getStagedInstallation()
- throws IOException, ApplicationException
- {
+ throws IOException, ApplicationException {
return new Installation(getStageDirectory());
}
private void expandZipFile()
- throws ApplicationException, IOException, QuickSetupException
- {
+ throws ApplicationException, IOException, QuickSetupException {
File installPackage = getUpgradeUserData().getInstallPackage();
FileInputStream fis = new FileInputStream(installPackage);
ZipExtractor extractor = new ZipExtractor(fis,
@@ -746,8 +981,7 @@
* {@inheritDoc}
*/
public UserData createUserData(String[] args, CurrentInstallStatus cis)
- throws UserDataException
- {
+ throws UserDataException {
return getCliHelper().createUserData(args, cis);
}
@@ -776,8 +1010,7 @@
}
private File getStageDirectory()
- throws ApplicationException, IOException
- {
+ throws ApplicationException, IOException {
if (stagingDirectory == null) {
File tmpDir = getTempDirectory();
stagingDirectory =
@@ -793,7 +1026,7 @@
}
private UpgradeUserData getUpgradeUserData() {
- return (UpgradeUserData)getUserData();
+ return (UpgradeUserData) getUserData();
}
private File getFilesBackupDirectory() throws IOException {
@@ -821,6 +1054,30 @@
return new File(getUpgradeBackupDirectory(), "schema.custom.diff");
}
+ private Integer getCurrentVersion() {
+ if (this.currentVersion == null) {
+ try {
+ currentVersion = getInstallation().getSvnRev();
+ } catch (QuickSetupException e) {
+ LOG.log(Level.INFO, "error trying to determine current version", e);
+ }
+ }
+ return currentVersion;
+ }
+
+ private Integer getStagedVersion() {
+ if (stagedVersion == null) {
+ try {
+ stagedVersion = getStagedInstallation().getSvnRev();
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "error", e);
+ }
+ }
+ return stagedVersion;
+ }
+
+
+
/**
* Filter defining files we want to manage in the upgrade
* process.
diff --git a/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java b/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java
index a1d53bd..fa1d269 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java
@@ -50,6 +50,38 @@
}
/**
+ * Move a file.
+ * @param object File to move
+ * @param newParent File representing new parent directory
+ * @param filter that will be asked whether or not the operation should be
+ * performed
+ * @throws ApplicationException if something goes wrong
+ */
+ public void move(File object, File newParent, FileFilter filter)
+ throws ApplicationException
+ {
+ // TODO: application notification
+ if (filter == null || filter.accept(object)) {
+ new MoveOperation(object, newParent).apply();
+ }
+ }
+
+ /**
+ * Deletes a single file or directory.
+ * @param object File to delete
+ * @param filter that will be asked whether or not the operation should be
+ * performed
+ * @throws ApplicationException if something goes wrong
+ */
+ public void delete(File object, FileFilter filter)
+ throws ApplicationException
+ {
+ if (filter == null || filter.accept(object)) {
+ new DeleteOperation(object).apply();
+ }
+ }
+
+ /**
* Deletes everything below the specified file.
*
* @param file the path to be deleted.
@@ -252,16 +284,17 @@
String[] args = {objectFile.getAbsolutePath(),
destination.getAbsolutePath()};
- // If overwriting and the destination exists then kill it
- if (destination.exists() && overwrite) {
- deleteRecursively(destination);
- }
-
if (objectFile.isDirectory()) {
if (!destination.exists()) {
destination.mkdirs();
}
} else {
+
+ // If overwriting and the destination exists then kill it
+ if (destination.exists() && overwrite) {
+ deleteRecursively(destination);
+ }
+
if (!destination.exists()) {
if (insureParentsExist(destination)) {
application.notifyListeners(application.getFormattedWithPoints(
@@ -278,6 +311,18 @@
fis.close();
fos.close();
+ if (destination.exists()) {
+ // TODO: set the file's permissions. This is made easier in
+ // Java 1.6 but until then use the Utils methods
+ if (Utils.isUnix()) {
+ String permissions =
+ Utils.getFileSystemPermissions(objectFile);
+ Utils.setPermissionsUnix(
+ Utils.getPath(destination),
+ permissions);
+ }
+ }
+
application.notifyListeners(application.getFormattedDone() +
application.getLineBreak());
@@ -299,14 +344,6 @@
}
}
- private boolean insureParentsExist(File f) {
- File parent = f.getParentFile();
- boolean b = parent.exists();
- if (!b) {
- b = parent.mkdirs();
- }
- return b;
- }
}
/**
@@ -380,6 +417,53 @@
}
}
+ /**
+ * A delete operation.
+ */
+ private class MoveOperation extends FileOperation {
+
+ File destination = null;
+
+ /**
+ * Creates a delete operation.
+ * @param objectFile to delete
+ */
+ public MoveOperation(File objectFile, File newParent) {
+ super(objectFile);
+ this.destination = new File(newParent, objectFile.getName());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public FileOperation copyForChild(File child) {
+ return new MoveOperation(child, destination);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void apply() throws ApplicationException {
+ File objectFile = getObjectFile();
+ if (destination.exists()) {
+ deleteRecursively(destination);
+ }
+ if (!objectFile.renameTo(destination)) {
+ throw ApplicationException.createFileSystemException(
+ "failed to move " + objectFile + " to " + destination, null);
+ }
+ }
+ }
+
+ private boolean insureParentsExist(File f) {
+ File parent = f.getParentFile();
+ boolean b = parent.exists();
+ if (!b) {
+ b = parent.mkdirs();
+ }
+ return b;
+ }
+
private String getMsg(String key) {
return ResourceProvider.getInstance().getMsg(key);
}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java b/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java
index 0b917b5..7ebc621 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java
@@ -29,6 +29,9 @@
import org.opends.quicksetup.*;
import org.opends.server.protocols.ldap.LDAPResultCode;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.InitializationException;
+import org.opends.server.config.ConfigException;
import javax.naming.NamingException;
import java.util.ArrayList;
@@ -181,10 +184,54 @@
}
/**
+ * Starts the directory server within this process.
+ * @param disableConnectionHandlers boolean that when true starts the
+ * the server mode that is otherwise up and running but will not accept any
+ * connections from external clients (i.e., does not create or initialize the
+ * connection handlers). This could be useful, for example, in an upgrade mode
+ * where it might be helpful to start the server but don't want it to appear
+ * externally as if the server is online without connection handlers
+ * listening.
+ *
+ * @throws ConfigException If there is a problem with the Directory Server
+ * configuration that prevents a critical component
+ * from being instantiated.
+ *
+ * @throws InitializationException If some other problem occurs while
+ * attempting to initialize and start the
+ * Directory Server.
+ */
+ public void startServerInProcess(boolean disableConnectionHandlers)
+ throws InitializationException, ConfigException {
+ System.setProperty(
+ "org.opends.server.DisableConnectionHandlers",
+ disableConnectionHandlers ? "true" : null);
+ startServerInProcess();
+ }
+
+ /**
+ * Stops a server that had been running 'in process'.
+ */
+ public void stopServerInProcess() {
+ DirectoryServer.shutDown(ServerController.class.getName(),
+ "quicksetup requests shutdown");
+ }
+
+ /**
* This methods starts the server.
* @throws org.opends.quicksetup.QuickSetupException if something goes wrong.
*/
public void startServer() throws QuickSetupException {
+ 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.
+ * @throws org.opends.quicksetup.QuickSetupException if something goes wrong.
+ */
+ private void startServer(boolean verify) throws QuickSetupException {
application.notifyListeners(
application.getFormattedProgress(
application.getMsg("progress-starting")) +
@@ -235,7 +282,7 @@
{
throw ex;
- } else
+ } else if (verify)
{
/*
* There are no exceptions from the readers and they are marked as
@@ -248,17 +295,27 @@
* Try 5 times with an interval of 1 second between try.
*/
boolean connected = false;
+ Configuration config =
+ application.getInstallation().getCurrentConfiguration();
+ int port = config.getPort();
+ String ldapUrl = "ldap://localhost:" + port;
+
+ // See if the application has prompted for credentials. If
+ // not we'll just try to connect anonymously.
+ String userDn = application.getUserData().getDirectoryManagerDn();
+ String userPw = application.getUserData().getDirectoryManagerPwd();
+ if (userDn == null || userPw == null) {
+ userDn = null;
+ userPw = null;
+ }
+
for (int i=0; i<5 && !connected; i++)
{
- // TODO: get this information from the installation instead
- UserData userData = application.getUserData();
- String ldapUrl = "ldap://localhost:" + userData.getServerPort();
try
{
Utils.createLdapContext(
ldapUrl,
- userData.getDirectoryManagerDn(),
- userData.getDirectoryManagerPwd(), 3000, null);
+ userDn, userPw, 3000, null);
connected = true;
}
catch (NamingException ne)
@@ -277,8 +334,7 @@
}
if (!connected)
{
- String[] arg = {String.valueOf(application.getUserData().
- getServerPort())};
+ String[] arg = {String.valueOf(port)};
if (Utils.isWindows())
{
@@ -302,6 +358,31 @@
}
/**
+ * Starts the OpenDS server in this process.
+ *
+ * @throws ConfigException If there is a problem with the Directory Server
+ * configuration that prevents a critical component
+ * from being instantiated.
+ *
+ * @throws InitializationException If some other problem occurs while
+ * attempting to initialize and start the
+ * Directory Server.
+ */
+ public void startServerInProcess()
+ throws InitializationException, ConfigException
+ {
+ // Bootstrap and start the Directory Server.
+ DirectoryServer directoryServer = DirectoryServer.getInstance();
+
+ directoryServer.bootstrapServer();
+ String configClass = "org.opends.server.extensions.ConfigFileHandler";
+ String configPath = Utils.getPath(
+ application.getInstallation().getCurrentConfigurationFile());
+ directoryServer.initializeConfiguration(configClass, configPath);
+ directoryServer.startServer();
+ }
+
+ /**
* This class is used to read the standard error and standard output of the
* Stop process.
* <p/>
diff --git a/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java b/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
index 2ac5655..92583af 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -679,6 +679,27 @@
return p.waitFor();
}
+ /**
+ * Sets the permissions of the provided paths with the provided permission
+ * String.
+ * @param path to set permissions on.
+ * @param permissions the UNIX-mode file system permission representation
+ * (for example "644" or "755")
+ * @return the return code of the chmod command.
+ * @throws IOException if something goes wrong.
+ * @throws InterruptedException if the Runtime.exec method is interrupted.
+ */
+ public static int setPermissionsUnix(String path,
+ String permissions) throws IOException, InterruptedException
+ {
+ String[] args = new String[3];
+ args[0] = "chmod";
+ args[1] = permissions;
+ args[2] = path;
+ Process p = Runtime.getRuntime().exec(args);
+ return p.waitFor();
+ }
+
// Very limited for the moment: apply only permissions to the current user and
// does not work in non-English environments... to work in non English we
// should use xcalcs but it does not come in the windows default install...
@@ -1204,4 +1225,52 @@
return sb.toString();
}
+ /**
+ * Returns the file system permissions for a file.
+ * @param path the file for which we want the file permissions.
+ * @return the file system permissions for the file.
+ */
+ static public String getFileSystemPermissions(String path)
+ {
+ return getFileSystemPermissions(new File(path));
+ }
+
+ /**
+ * Returns the file system permissions for a file.
+ * @param file the file for which we want the file permissions.
+ * @return the file system permissions for the file.
+ */
+ static public String getFileSystemPermissions(File file)
+ {
+ String perm;
+ String name = file.getName();
+ if (file.getParent().endsWith(
+ File.separator + Installation.WINDOWS_BINARIES_PATH_RELATIVE) ||
+ file.getParent().endsWith(
+ File.separator + Installation.UNIX_BINARIES_PATH_RELATIVE))
+ {
+ if (name.endsWith(".bat"))
+ {
+ perm = "644";
+ }
+ else
+ {
+ perm = "755";
+ }
+ }
+ else if (name.endsWith(".sh"))
+ {
+ perm = "755";
+ } else if (name.endsWith(Installation.UNIX_SETUP_FILE_NAME) ||
+ name.endsWith(Installation.UNIX_UNINSTALL_FILE_NAME) ||
+ name.endsWith(Installation.UNIX_UPGRADE_FILE_NAME))
+ {
+ perm = "755";
+ } else
+ {
+ perm = "644";
+ }
+ return perm;
+ }
+
}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java b/opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java
index f0b8301..6219fff 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java
@@ -29,12 +29,10 @@
import org.opends.quicksetup.QuickSetupException;
import org.opends.quicksetup.Application;
-import org.opends.quicksetup.Installation;
import org.opends.quicksetup.i18n.ResourceProvider;
import java.io.InputStream;
import java.io.IOException;
-import java.io.File;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.ArrayList;
@@ -228,7 +226,7 @@
}
} else
{
- String perm = getFileSystemPermissions(path);
+ String perm = Utils.getFileSystemPermissions(path);
ArrayList<String> list = permissions.get(perm);
if (list == null)
{
@@ -255,44 +253,4 @@
return "755";
}
- /**
- * Returns the file system permissions for a file.
- * @param path the file for which we want the file permissions.
- * @return the file system permissions for the file.
- */
- private String getFileSystemPermissions(String path)
- {
- // TODO We should get this dynamically during build?
- String perm;
-
- File file = new File(path);
- if (file.getParent().endsWith(
- File.separator + Installation.WINDOWS_BINARIES_PATH_RELATIVE) ||
- file.getParent().endsWith(
- File.separator + Installation.UNIX_BINARIES_PATH_RELATIVE))
- {
- if (path.endsWith(".bat"))
- {
- perm = "644";
- }
- else
- {
- perm = "755";
- }
- }
- else if (path.endsWith(".sh"))
- {
- perm = "755";
- } else if (path.endsWith(Installation.UNIX_SETUP_FILE_NAME) ||
- path.endsWith(Installation.UNIX_UNINSTALL_FILE_NAME) ||
- path.endsWith(Installation.UNIX_UPGRADE_FILE_NAME))
- {
- perm = "755";
- } else
- {
- perm = "644";
- }
- return perm;
- }
-
}
--
Gitblit v1.10.0