Installer.java revision 3ba4a8a412fa60c947ecb3cee9d90fb24e590d54
/*
* 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 legal-notices/CDDLv1_0.txt
* 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 legal-notices/CDDLv1_0.txt.
* 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
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS
*/
/**
* This is an abstract class that is in charge of actually performing the
* installation.
*
* It just takes a UserData object and based on that installs OpenDJ.
*
* When there is an update during the installation it will notify the
* ProgressUpdateListener objects that have been added to it. The
* notification will send a ProgressUpdateEvent.
*
* This class is supposed to be fully independent of the graphical layout.
*
* Note that we can use freely the class org.opends.server.util.SetupUtils as
* it is included in quicksetup.jar.
*/
public abstract class Installer extends GuiApplication
{
/** The minimum integer value that can be used for a port. */
public static final int MIN_PORT_VALUE = 1;
/** The maximum integer value that can be used for a port. */
public static final int MAX_PORT_VALUE = 65535;
/** The name of the backend created on setup. */
/** Constants used to do checks. */
private static final int MIN_DIRECTORY_MANAGER_PWD = 1;
private static final int MIN_NUMBER_ENTRIES = 1;
private static final int MAX_NUMBER_ENTRIES = 10000000;
/**
* If the user decides to import more than this number of entries, the import
* process of automatically generated data will be verbose.
*/
private static final int THRESHOLD_AUTOMATIC_DATA_VERBOSE = 20000;
/**
* If the user decides to import a number of entries higher than this
* threshold, the start process will be verbose.
*/
private static final int THRESHOLD_VERBOSE_START = 100000;
private TopologyCache lastLoadedCache;
/** Indicates that we've detected that there is something installed. */
boolean forceToDisplaySetup;
/** When true indicates that the user has canceled this operation. */
protected boolean canceled;
private boolean javaVersionCheckFailed;
/** Map containing information about what has been configured remotely. */
private final Map<ServerDescriptor, ConfiguredReplication> hmConfiguredRemoteReplication = new HashMap<>();
/** Set of progress steps that have been completed. */
{
}
private char[] selfSignedCertPw;
private boolean registeredNewServerOnRemote;
private boolean createdAdministrator;
private boolean createdRemoteAds;
private String lastImportProgress;
/** A static String that contains the class name of ConfigFileHandler. */
protected static final String DEFAULT_CONFIG_CLASS_NAME = "org.opends.server.extensions.ConfigFileHandler";
/** Aliases of self-signed certificates. */
/**
* The threshold in minutes used to know whether we must display a warning
* informing that there is a server clock difference between two servers whose
* contents are being replicated.
*/
public static final int THRESHOLD_CLOCK_DIFFERENCE_WARNING = 5;
/** Creates a default instance. */
public Installer()
{
try
{
if (!QuickSetupLog.isInitialized())
{
QuickSetupLog.initLogFileHandler(File.createTempFile(Constants.LOG_FILE_PREFIX, Constants.LOG_FILE_SUFFIX));
}
}
catch (IOException e)
{
}
}
public boolean isCancellable()
{
return true;
}
public UserData createUserData()
{
return ud;
}
{
{
{
{
try
{
}
catch (Throwable t)
{
}
}
break;
}
}
}
public void forceToDisplay()
{
forceToDisplaySetup = true;
}
{
}
{
}
{
}
{
}
{
if (step == CREATE_GLOBAL_ADMINISTRATOR)
{
return userData.mustCreateAdministrator();
}
else if (step == NEW_SUFFIX_OPTIONS)
{
return suf != null && suf.getType() != SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES;
}
else if (step == SUFFIXES_OPTIONS)
{
}
else if (step == REMOTE_REPLICATION_PORTS)
{
}
return true;
}
{
}
{
{
throw new IllegalStateException("Cannot click on finish when we are not in the Review window");
}
// Installer responsible for updating the user data and launching
return false;
}
{
{
throw new IllegalStateException("Cannot click on next from progress step");
}
{
throw new IllegalStateException("Cannot click on next from review step");
}
{
throw new IllegalStateException("Cannot click on next from finished step");
}
}
{
{
if (isFinished()
|| qs.displayConfirmation(INFO_CONFIRM_CLOSE_INSTALL_MSG.get(), INFO_CONFIRM_CLOSE_INSTALL_TITLE.get()))
{
}
}
{
}
else
{
throw new IllegalStateException("Close only can be clicked on PROGRESS step");
}
}
public boolean isFinished()
{
}
public void cancel()
{
this.canceled = true;
}
{
{
}
{
throw new IllegalStateException("Cannot click on quit from progress step");
}
else if (installStatus.isInstalled())
{
}
else if (javaVersionCheckFailed)
{
}
else if (qs.displayConfirmation(INFO_CONFIRM_QUIT_INSTALL_MSG.get(), INFO_CONFIRM_QUIT_INSTALL_TITLE.get()))
{
}
}
public ButtonName getInitialFocusButtonName()
{
{
return ButtonName.NEXT;
}
else if (installStatus.canOverwriteCurrentInstall())
{
return ButtonName.CONTINUE_INSTALL;
}
else
{
return ButtonName.QUIT;
}
}
{
JPanel p;
javaVersionCheckFailed = true;
try
{
javaVersionCheckFailed = false;
{
p = dlg.getInstalledPanel();
}
else
{
p = super.createFramePanel(dlg);
}
}
catch (IncompatibleVersionException ijv)
{
{
/**
* ButtonActionListener implementation. It assumes that we are called in
* the event thread.
*
* @param ev
* the ButtonEvent we receive.
*/
{
// Simulate a close button event
}
});
p = errPanel;
}
return p;
}
{
}
{
{
{
case WELCOME:
return new InstallWelcomePanel(this);
case LICENSE:
return new InstallLicensePanel(this);
case SERVER_SETTINGS:
return new ServerSettingsPanel(this);
case REPLICATION_OPTIONS:
return new DataReplicationPanel(this);
return new GlobalAdministratorPanel(this);
case SUFFIXES_OPTIONS:
return new SuffixesToReplicatePanel(this);
case REMOTE_REPLICATION_PORTS:
return new RemoteReplicationPortsPanel(this);
case NEW_SUFFIX_OPTIONS:
return new DataOptionsPanel(this);
case RUNTIME_OPTIONS:
return new RuntimeOptionsPanel(this);
case REVIEW:
return new InstallReviewPanel(this);
case PROGRESS:
return new ProgressPanel(this);
case FINISHED:
return new FinishedPanel(this);
}
}
return null;
}
{
{
// Simulate a close button event
}
{
// Simulate a close button event
}
else
{
// Simulate a quit button event
}
}
public LocalizableMessage getCloseButtonToolTip()
{
return INFO_CLOSE_BUTTON_INSTALL_TOOLTIP.get();
}
public LocalizableMessage getQuitButtonToolTip()
{
return INFO_QUIT_BUTTON_INSTALL_TOOLTIP.get();
}
public LocalizableMessage getFinishButtonToolTip()
{
return INFO_FINISH_BUTTON_INSTALL_TOOLTIP.get();
}
public int getExtraDialogHeight()
{
return UIFactory.EXTRA_DIALOG_HEIGHT;
}
{
{
throw new IllegalStateException("Cannot click on previous from progress step");
}
{
throw new IllegalStateException("Cannot click on previous from progress step");
}
{
throw new IllegalStateException("Cannot click on previous from finished step");
}
}
public LocalizableMessage getFrameTitle()
{
}
/** Indicates the current progress step. */
{
{
// Set the default button for the frame
{
}
{
}
{
}
else
{
}
}
}
public ProgressStep getCurrentProgressStep()
{
return currentProgressStep;
}
public WizardStep getFirstWizardStep()
{
return WELCOME;
}
{
{
}
return next;
}
{
{
if (getUserData().mustCreateAdministrator())
{
return Step.CREATE_GLOBAL_ADMINISTRATOR;
}
{
case FIRST_IN_TOPOLOGY:
case STANDALONE:
return Step.NEW_SUFFIX_OPTIONS;
default:
return Step.SUFFIXES_OPTIONS;
}
}
{
{
{
return Step.REMOTE_REPLICATION_PORTS;
}
return Step.RUNTIME_OPTIONS;
default:
return Step.NEW_SUFFIX_OPTIONS;
}
}
{
return Step.RUNTIME_OPTIONS;
}
else
{
{
}
}
return null;
}
{
return orderedSteps;
}
{
if (licenseExists)
{
}
}
{
// Try with the steps calculated in method getNextWizardStep.
{
if (i != -1 && i > 0)
{
}
}
return prev;
}
public WizardStep getFinishedStep()
{
}
/**
* Uninstalls installed services. This is to be used when the user has elected
* to cancel an installation.
*/
protected void uninstallServices()
{
{
try
{
new InstallerHelper().disableWindowsService();
}
catch (ApplicationException ae)
{
}
}
}
/**
* Creates the template files based in the contents of the UserData object.
* These templates files are used to generate automatically data. To generate
* the template file the code will basically take into account the value of
* the base dn and the number of entries to be generated.
*
* @return a list of file objects pointing to the create template files.
* @throws ApplicationException
* if an error occurs.
*/
{
try
{
}
catch (IOException ioe)
{
}
}
/**
* This methods configures the server based on the contents of the UserData
* object provided in the constructor.
*
* @throws ApplicationException
* if something goes wrong.
*/
protected void configureServer() throws ApplicationException
{
checkAbort();
// TODO: even if the user does not configure SSL maybe we should choose
// a secure port that is not being used and that we can actually use.
if (sec.getEnableSSL())
{
}
if (sec.getEnableStartTLS())
{
}
// For the moment do not enable JMX
{
}
if (backendType != null)
{
}
if (createNotReplicatedSuffix())
{
{
}
}
boolean nextPassword = false;
{
{
}
if (nextPassword)
{
}
else
{
}
}
setNotifyListeners(false);
{
public void run()
{
try
{
{
}
{
}
}
catch (ApplicationException aex)
{
}
catch (Throwable t)
{
ae = new ApplicationException(
}
finally
{
setNotifyListeners(true);
}
isOver = true;
}
public void abort()
{
// TODO: implement the abort
}
};
checkAbort();
}
{
try
{
{
}
switch (certType)
{
case NO_CERTIFICATE:
// Nothing to do
break;
case SELF_SIGNED_CERTIFICATE:
final CertificateManager certManager =
{
certManager.generateSelfSignedCertificate(keyType, alias, getSelfSignedCertificateSubjectDN(keyType),
}
break;
case JKS:
break;
case JCEKS:
break;
case PKCS12:
break;
case PKCS11:
configureKeyAndTrustStore(CertificateManager.KEY_STORE_PATH_PKCS11, CertificateManager.KEY_STORE_TYPE_PKCS11,
break;
default:
}
{
}
}
catch (Throwable t)
{
throw new ApplicationException(
}
}
{
CertificateManager certManager = new CertificateManager(keyStorePath, keyStoreType, keystorePassword);
{
}
}
private void configureTrustStore(final String type, final String keyStoreAlias, final String password)
throws Exception
{
f.delete();
}
{
switch (sec.getCertificateType())
{
case SELF_SIGNED_CERTIFICATE:
break;
case JKS:
"cn=JKS,cn=Trust Manager Providers,cn=config");
break;
case JCEKS:
addCertificateArguments(argList, sec, aliasInKeyStore, "cn=JCEKS,cn=Key Manager Providers,cn=config",
"cn=JCEKS,cn=Trust Manager Providers,cn=config");
break;
case PKCS12:
addCertificateArguments(argList, sec, aliasInKeyStore, "cn=PKCS12,cn=Key Manager Providers,cn=config",
"cn=JKS,cn=Trust Manager Providers,cn=config");
break;
case PKCS11:
addCertificateArguments(argList, null, aliasInKeyStore, "cn=PKCS11,cn=Key Manager Providers,cn=config",
"cn=JKS,cn=Trust Manager Providers,cn=config");
break;
case NO_CERTIFICATE:
// Nothing to do.
break;
default:
}
}
{
{
}
{
}
}
/**
* This methods creates the base entry for the suffix based on the contents of
* the UserData object provided in the constructor.
*
* @throws ApplicationException
* if something goes wrong.
*/
private void createBaseEntry() throws ApplicationException
{
{
}
else
{
}
{
}
checkAbort();
{
}
setNotifyListeners(false);
{
public void run()
{
try
{
if (result != 0)
{
}
}
catch (Throwable t)
{
ae =
}
finally
{
setNotifyListeners(true);
}
isOver = true;
}
public void abort()
{
// TODO: implement the abort
}
};
}
/**
* This methods imports the contents of an LDIF file based on the contents of
* the UserData object provided in the constructor.
*
* @throws ApplicationException
* if something goes wrong.
*/
private void importLDIF() throws ApplicationException
{
{
if (isVerbose())
{
}
else
{
mb.append(getFormattedProgress(INFO_PROGRESS_IMPORTING_LDIFS_NON_VERBOSE.get(joinAsString(", ", ldifPaths))));
}
}
else if (isVerbose())
{
}
else
{
mb.append(getFormattedProgress(INFO_PROGRESS_IMPORTING_LDIF_NON_VERBOSE.get(ldifPaths.getFirst())));
}
if (!isVerbose())
{
setNotifyListeners(false);
pointAdder.start();
}
{
}
if (rejectedFile != null)
{
}
if (skippedFile != null)
{
}
{
public void run()
{
try
{
if (result != 0)
{
}
}
catch (Throwable t)
{
ae = new ApplicationException(
}
finally
{
if (!isVerbose())
{
setNotifyListeners(true);
pointAdder.stop();
}
}
isOver = true;
}
public void abort()
{
// TODO: implement the abort
}
};
try
{
}
catch (ApplicationException ae)
{
{
}
throw ae;
}
if (!isVerbose())
{
if (lastImportProgress == null)
{
}
else
{
}
}
}
/**
* This methods imports automatically generated data based on the contents of
* the UserData object provided in the constructor.
*
* @throws ApplicationException
* if something goes wrong.
*/
private void importAutomaticallyGenerated() throws ApplicationException
{
{
}
else
{
mb.append(getFormattedProgress(INFO_PROGRESS_IMPORT_AUTOMATICALLY_GENERATED_NON_VERBOSE.get(nEntries)));
}
if (!isVerbose())
{
pointAdder.start();
}
if (!isVerbose())
{
setNotifyListeners(false);
}
{
public void run()
{
try
{
if (result != 0)
{
ae = new ApplicationException(
}
}
catch (Throwable t)
{
t.getLocalizedMessage()), t), t);
}
finally
{
if (!isVerbose())
{
setNotifyListeners(true);
{
pointAdder.stop();
}
}
}
isOver = true;
}
public void abort()
{
// TODO: implement the abort
}
};
if (!isVerbose())
{
pointAdder.stop();
}
}
/**
* This method undoes the modifications made in other servers in terms of
* replication. This method assumes that we are aborting the Installer and
* that is why it does not call checkAbort.
*/
private void unconfigureRemote()
{
{
// Try to connect
if (isVerbose())
{
notifyListeners(getFormattedWithPoints(INFO_PROGRESS_UNCONFIGURING_ADS_ON_REMOTE.get(getHostDisplay(auth))));
}
try
{
if (createdRemoteAds)
{
adsContext.removeAdminData(true);
}
else
{
{
try
{
}
catch (ADSContextException ace)
{
{
throw ace;
}
// Else, nothing to do: this may occur if the new server has been
// unregistered on another server and the modification has been
// already propagated by replication.
}
}
if (createdAdministrator)
{
}
}
if (isVerbose())
{
}
}
catch (Throwable t)
{
notifyListeners(getFormattedError(t, true));
}
finally
{
}
}
{
notifyListeners(getFormattedWithPoints(INFO_PROGRESS_UNCONFIGURING_REPLICATION_REMOTE.get(getHostPort(server))));
try
{
helper.unconfigureReplication(ctx, hmConfiguredRemoteReplication.get(server), ConnectionUtils.getHostPort(ctx));
}
catch (ApplicationException ae)
{
}
finally
{
}
}
}
/**
* This method configures the backends and suffixes that must be replicated.
* The setup uses the same backend names as in the remote servers. If userRoot
* is not one of the backends defined in the remote servers, it deletes it
* from the configuration. NOTE: this method assumes that the server is
* running.
*
* @throws ApplicationException
* if something goes wrong.
*/
protected void createReplicatedBackendsIfRequired() throws ApplicationException
{
{
return;
}
// The keys are the backend IDs and the values the list of base DNs.
checkAbort();
}
/**
* The criteria to choose the name of the backend is to try to have the
* configuration of the other server. The algorithm consists on putting the
* remote servers in a list and pick the backend as they appear on the list.
*/
private void populateBackendsToCreate(Map<String, Set<String>> hmBackendSuffix, Set<SuffixDescriptor> suffixes)
{
{
{
}
}
}
{
{
{
}
}
return serverList;
}
private ReplicaDescriptor retrieveReplicaForSuffix(Set<ServerDescriptor> serverList, SuffixDescriptor suffix)
{
{
{
{
return replica;
}
}
}
return null;
}
{
{
{
return storedBackend;
}
}
return backendName;
}
{
try
{
ctx = createLocalContext();
{
helper.createBackend(ctx, backendName, hmBackendSuffix.get(backendName), ConnectionUtils.getHostPort(ctx),
}
}
catch (NamingException ne)
{
}
finally
{
}
}
/**
* This method creates the replication configuration for the suffixes on the
* the local server (and eventually in the remote servers) to synchronize
* things. NOTE: this method assumes that the server is running.
*
* @throws ApplicationException
* if something goes wrong.
*/
protected void configureReplication() throws ApplicationException
{
if (lastLoadedCache != null)
{
{
{
}
}
{
if (v != null)
{
}
}
}
else
{
/* There is no ADS anywhere. Just use the SuffixDescriptors we found */
for (SuffixDescriptor suffix : getUserData().getSuffixesToReplicateOptions().getAvailableSuffixes())
{
{
if (v != null)
{
}
}
}
}
/*
* For each suffix specified by the user, create a map from the suffix DN to
* the set of replication servers. The initial instance in a topology is a
* degenerate case. Also, collect a set of all observed replication servers
* as the set of ADS suffix replicas (all instances hosting the replication
* server also replicate ADS).
*/
if (getUserData().getReplicationOptions().getType() == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY)
{
h.add(getLocalReplicationServer());
{
}
}
else
{
{
h.add(getLocalReplicationServer());
{
{
}
}
}
}
long localTime = -1;
long localTimeMeasureTime = -1;
try
{
ctx = createLocalContext();
}
catch (NamingException ne)
{
}
finally
{
}
checkAbort();
if (getUserData().getReplicationOptions().getType() == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY)
{
{
{
{
}
}
}
{
notifyListeners(getFormattedWithPoints(INFO_PROGRESS_CONFIGURING_REPLICATION_REMOTE.get(getHostPort(server))));
int replicationPort;
boolean enableSecureReplication;
if (v != null)
{
replicationPort = v;
enableSecureReplication = false;
}
else
{
{
}
else
{
enableSecureReplication = false;
}
}
{
}
{
{
// Do the comparison manually
{
{
break;
}
}
}
{
}
else
{
}
}
helper.configureReplication(ctx, remoteReplicationServers, replicationPort, enableSecureReplication,
if (localTime != -1
&& remoteTime != -1
{
}
checkAbort();
}
}
}
/**
* This methods enables this server as a Windows service.
*
* @throws ApplicationException
* if something goes wrong.
*/
protected void enableWindowsService() throws ApplicationException
{
}
/**
* Updates the contents of the provided map with the localized summary
* strings.
*
* @param hmSummary
* the Map to be updated.
* @param isCli
* a boolean to indicate if the install is using CLI or GUI
*/
{
if (!isCli)
{
}
Utils.addWordBreaks(formatter.getFormattedText(LocalizableMessage.raw(getPath(new File(getInstancePath()))))
LocalizableMessage.class);
hmSummary.put(FINISHED_CANCELED, getFormattedSuccess(INFO_SUMMARY_INSTALL_FINISHED_CANCELED.get()));
getFormattedError(INFO_SUMMARY_INSTALL_FINISHED_WITH_ERROR.get(INFO_GENERAL_SERVER_STOPPED.get(), cmd)));
}
private void put(Map<ProgressStep, LocalizableMessage> hmSummary, InstallProgressStep step, Arg0 msg)
{
}
/**
* Updates the messages in the summary with the state of the server.
*
* @param hmSummary
* the Map containing the messages.
* @param isCli
* a boolean to indicate if the install is using CLI or GUI
*/
protected void updateSummaryWithServerState(Map<ProgressStep, LocalizableMessage> hmSummary, Boolean isCli)
{
if (!isCli)
{
cmd = Utils.addWordBreaks(UIFactory.applyFontToHtml(cmd, UIFactory.INSTRUCTIONS_MONOSPACE_FONT), 60, 5);
}
{
}
else
{
}
Utils.addWordBreaks(formatter.getFormattedText(LocalizableMessage.raw(getPath(new File(getInstancePath()))))
hmSummary.put(InstallProgressStep.FINISHED_WITH_ERROR, getFormattedError(INFO_SUMMARY_INSTALL_FINISHED_WITH_ERROR
}
/**
* Checks the value of <code>canceled</code> field and throws an
* ApplicationException if true. This indicates that the user has canceled
* this operation and the process of aborting should begin as soon as
* possible.
*
* @throws ApplicationException
* thrown if <code>canceled</code>
*/
public void checkAbort() throws ApplicationException
{
if (canceled)
{
}
}
/**
* Writes the host name to a file that will be used by the server to generate
* a self-signed certificate.
*/
private void writeHostName()
{
try
{
}
catch (IOException ioe)
{
}
finally
{
}
}
/**
* Returns the file path where the host name is to be written.
*
* @return the file path where the host name is to be written.
*/
private String getHostNameFile()
{
return Utils.getPath(getInstallation().getRootDirectory().getAbsolutePath(), SetupUtils.HOST_NAME_FILE);
}
/**
* Writes the java home that we are using for the setup in a file. This way we
* can use this java home even if the user has not set OPENDJ_JAVA_HOME when
* running the different scripts.
*/
private void writeOpenDSJavaHome()
{
try
{
// This isn't likely to happen, and it's not a serious problem even if
// it does.
}
catch (Exception e)
{
}
}
/**
* These methods validate the data provided by the user in the panels and
* update the userData object according to that content.
*
* @param cStep
* the current step of the wizard
* @param qs
* QuickStart controller
* @throws UserDataException
* if the data provided by the user is not valid.
*/
{
if (cStep == SERVER_SETTINGS)
{
}
else if (cStep == REPLICATION_OPTIONS)
{
}
else if (cStep == CREATE_GLOBAL_ADMINISTRATOR)
{
}
else if (cStep == SUFFIXES_OPTIONS)
{
}
else if (cStep == REMOTE_REPLICATION_PORTS)
{
}
else if (cStep == NEW_SUFFIX_OPTIONS)
{
}
else if (cStep == RUNTIME_OPTIONS)
{
}
{
}
}
/**
* Sets the current progress step of the installation process.
*
* @param currentProgressStep
* the current progress step of the installation process.
*/
{
if (currentProgressStep != null)
{
}
}
/**
* This methods updates the data on the server based on the contents of the
* UserData object provided in the constructor.
*
* @throws ApplicationException
* if something goes wrong.
*/
protected void createData() throws ApplicationException
{
{
if (isVerbose())
{
}
{
case CREATE_BASE_ENTRY:
break;
case IMPORT_FROM_LDIF_FILE:
importLDIF();
break;
break;
default:
break;
}
}
}
/**
* This method initialize the contents of the synchronized servers with the
* contents of the first server we find.
*
* @throws ApplicationException
* if something goes wrong.
*/
protected void initializeSuffixes() throws ApplicationException
{
try
{
ctx = createLocalContext();
}
catch (Throwable t)
{
}
/* Initialize local ADS and schema contents using any replica. */
{
try
{
filter.setSearchMonitoringInformation(false);
{
{
}
{
}
}
}
catch (NamingException ne)
{
if (isCertificateException(ne))
{
msg = INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER.get(getHostPort(server), ne.toString(true));
}
else
{
}
}
finally
{
}
}
{
if (isADS)
{
if (isVerbose())
{
}
}
else if (isSchema)
{
if (isVerbose())
{
}
}
else
{
}
try
{
if (replicationId == -1)
{
// This occurs if the remote server had not replication configured.
try
{
filter.setSearchMonitoringInformation(false);
for (ReplicaDescriptor r : s.getReplicas())
{
{
replicationId = r.getReplicationId();
}
}
}
catch (NamingException ne)
{
if (isCertificateException(ne))
{
msg = INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER.get(getHostPort(server), ne.toString(true));
}
else
{
}
}
finally
{
}
}
if (replicationId == -1)
{
throw new ApplicationException(ReturnCode.APPLICATION_ERROR, ERR_COULD_NOT_FIND_REPLICATIONID.get(dn), null);
}
int nTries = 5;
boolean initDone = false;
while (!initDone)
{
try
{
initDone = true;
}
catch (PeerNotFoundException pnfe)
{
if (nTries == 1)
{
}
}
nTries--;
}
}
catch (ApplicationException ae)
{
throw ae;
}
{
}
checkAbort();
}
}
/**
* This method updates the ADS contents (and creates the according suffixes).
* If the user specified an existing topology, the new instance is registered
* with that ADS (the ADS might need to be created), and the local ADS will be
* populated when the local server is added to the remote server's ADS
* replication domain in a subsequent step. Otherwise, an ADS is created on
* the new instance and the server is registered with the new ADS. NOTE: this
* method assumes that the local server and any remote server are running.
*
* @throws ApplicationException
* if something goes wrong.
*/
protected void updateADS() throws ApplicationException
{
/*
* Outer try-catch-finally to convert occurrences of NamingException and
* ADSContextException to ApplicationException and clean up JNDI contexts.
*/
try
{
if (isRemoteServer)
{
/*
* Check the remote server for ADS. If it does not exist, create the
* initial ADS there and register the server with itself.
*/
if (!adsContext.hasAdminData())
{
if (isVerbose())
{
notifyListeners(getFormattedWithPoints(INFO_PROGRESS_CREATING_ADS_ON_REMOTE.get(getHostDisplay(auth))));
}
filter.setSearchMonitoringInformation(false);
filter.setSearchBaseDNInformation(false);
createdRemoteAds = true;
if (isVerbose())
{
}
checkAbort();
}
}
/* Act on local server depending on if using remote or local ADS */
if (isVerbose())
{
}
// if (isRemoteServer)
// {
// /* Create an empty ADS suffix on the local server. */
// ADSContext localAdsContext = new ADSContext(localCtx);
// localAdsContext.createAdministrationSuffix(null);
// }
if (!isRemoteServer)
{
/* Configure local server to have an ADS */
}
/* Register new server in ADS. */
filter.setSearchMonitoringInformation(false);
filter.setSearchBaseDNInformation(false);
{
if (isRemoteServer)
{
registeredNewServerOnRemote = true;
}
}
else
{
logger.warn(LocalizableMessage.raw("Server was already registered. Updating " + "server registration."));
}
if (isRemoteServer)
{
}
if (isVerbose())
{
}
checkAbort();
/* Add global administrator if the user specified one. */
if (getUserData().mustCreateAdministrator())
{
try
{
if (isVerbose())
{
}
if (isRemoteServer && !createdRemoteAds)
{
createdAdministrator = true;
}
if (isVerbose())
{
}
checkAbort();
}
catch (ADSContextException ade)
{
{
}
else
{
throw ade;
}
}
}
}
catch (NamingException ne)
{
if (isRemoteServer)
{
}
else
{
}
}
catch (ADSContextException ace)
{
throw new ApplicationException(ReturnCode.CONFIGURATION_ERROR, (isRemoteServer ? INFO_REMOTE_ADS_EXCEPTION.get(
}
finally
{
}
}
{
if (auth.useSecureConnection())
{
}
}
/**
* Tells whether we must create a suffix that we are not going to replicate
* with other servers or not.
*
* @return <CODE>true</CODE> if we must create a new suffix and
* <CODE>false</CODE> otherwise.
*/
protected boolean createNotReplicatedSuffix()
{
}
/**
* Returns <CODE>true</CODE> if we must configure replication and
* <CODE>false</CODE> otherwise.
*
* @return <CODE>true</CODE> if we must configure replication and
* <CODE>false</CODE> otherwise.
*/
protected boolean mustConfigureReplication()
{
}
/**
* Returns <CODE>true</CODE> if we must create the ADS and <CODE>false</CODE>
* otherwise.
*
* @return <CODE>true</CODE> if we must create the ADS and <CODE>false</CODE>
* otherwise.
*/
protected boolean mustCreateAds()
{
}
/**
* Returns <CODE>true</CODE> if we must start the server and
* <CODE>false</CODE> otherwise.
*
* @return <CODE>true</CODE> if we must start the server and
* <CODE>false</CODE> otherwise.
*/
protected boolean mustStart()
{
}
/**
* Returns <CODE>true</CODE> if the start server must be launched in verbose
* mode and <CODE>false</CODE> otherwise. The verbose flag is not enough
* because in the case where many entries have been imported, the startup
* phase can take long.
*
* @return <CODE>true</CODE> if the start server must be launched in verbose
* mode and <CODE>false</CODE> otherwise.
*/
protected boolean isStartVerbose()
{
if (isVerbose())
{
return true;
}
boolean manyEntriesToImport = false;
{
long mbTotalSize = 0;
{
mbTotalSize += f.length();
}
// Assume entries of 1kb
{
manyEntriesToImport = true;
}
}
{
if (nEntries > THRESHOLD_VERBOSE_START)
{
manyEntriesToImport = true;
}
}
return manyEntriesToImport;
}
/**
* Returns <CODE>true</CODE> if we must stop the server and <CODE>false</CODE>
* otherwise. The server might be stopped if the user asked not to start it at
* the end of the installation and it was started temporarily to update its
* configuration.
*
* @return <CODE>true</CODE> if we must stop the server and <CODE>false</CODE>
* otherwise.
*/
protected boolean mustStop()
{
}
/**
* Returns <CODE>true</CODE> if we must initialize suffixes and
* <CODE>false</CODE> otherwise.
*
* @return <CODE>true</CODE> if we must initialize suffixes and
* <CODE>false</CODE> otherwise.
*/
protected boolean mustInitializeSuffixes()
{
return getUserData().getReplicationOptions().getType() == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY;
}
/**
* Returns the list of preferred URLs to connect to remote servers. In fact it
* returns only the URL to the remote server specified by the user in the
* replication options panel. The method returns a list for convenience with
* other interfaces.
* <p>
* NOTE: this method assumes that the UserData object has
* already been updated with the host and port of the remote server.
*
* @return the list of preferred URLs to connect to remote servers.
*/
{
{
{
if (auth.useSecureConnection())
{
}
else
{
}
}
}
return cnx;
}
{
if (auth.useSecureConnection())
{
}
}
{
}
{
serverProperties.put(ADSContext.ServerProperty.LDAP_PORT, String.valueOf(userData.getServerPort()));
// TODO: even if the user does not configure SSL maybe we should choose
// a secure port that is not being used and that we can actually use.
if (sec.getEnableSSL())
{
}
else
{
}
if (sec.getEnableStartTLS())
{
}
else
{
}
String serverID = serverProperties.get(ADSContext.ServerProperty.HOST_NAME) + ":" + userData.getServerPort();
/* TODO: do we want to ask this specifically to the user? */
serverProperties.put(ADSContext.ServerProperty.HOST_OS, OperatingSystem.getOperatingSystem().toString());
return serverProperties;
}
{
adminProperties.put(ADSContext.AdministratorProperty.PASSWORD, userData.getGlobalAdministratorPassword());
return adminProperties;
}
/**
* Validate the data provided by the user in the server settings panel and
* update the userData object according to that content.
*
* @throws UserDataException
* if the data provided by the user is not valid.
*/
{
// Check the host is not empty.
// TODO: check that the host name is valid...
{
}
else
{
}
// Check the port
int port = -1;
try
{
{
}
else if (!canUseAsPort(port))
{
}
else
{
}
}
catch (NumberFormatException nfe)
{
}
// Check the admin connector port
int adminConnectorPort = -1;
try
{
{
}
else if (!canUseAsPort(adminConnectorPort))
{
}
else if (adminConnectorPort == port)
{
}
else
{
}
}
catch (NumberFormatException nfe)
{
}
// Check the secure port
if (sec.getEnableSSL())
{
{
}
else if (!canUseAsPort(securePort))
{
}
else if (port == securePort)
{
}
else if (adminConnectorPort == securePort)
{
}
else
{
}
}
else
{
}
// Check the Directory Manager DN
{
}
{
}
else if (isConfigurationDn(dmDn))
{
}
else
{
}
// Check the provided passwords
{
pwd1 = "";
}
boolean pwdValid = true;
{
pwdValid = false;
}
{
{
}
pwdValid = false;
}
if (pwdValid)
{
}
// For the moment do not enable JMX
if (defaultJMXPort != -1)
{
//getUserData().setServerJMXPort(defaultJMXPort);
}
{
}
if (confirmationMsg != null)
{
}
}
{
if (isPrivilegedPort(port))
{
}
}
/**
* Validate the data provided by the user in the data options panel and update
* the userData object according to that content.
*
* @throws UserDataException
* if the data provided by the user is not valid.
*/
{
boolean hasGlobalAdministrators = false;
int replicationPort = -1;
boolean secureReplication = false;
DataReplicationOptions.Type type = (DataReplicationOptions.Type) qs.getFieldValue(FieldName.REPLICATION_OPTIONS);
{
// Check replication port
}
switch (type)
{
case IN_EXISTING_TOPOLOGY:
{
{
// Try to connect
boolean[] globalAdmin = { hasGlobalAdministrators };
try
{
}
catch (UserDataConfirmationException e)
{
confirmEx = e;
}
}
break;
}
case STANDALONE:
{
break;
}
case FIRST_IN_TOPOLOGY:
{
break;
}
default:
}
{
{
}
auth.setUseSecureConnection(true);
getUserData().setReplicationOptions(createDataReplicationOptions(replicationPort, secureReplication, type, auth));
}
{
}
{
throw confirmEx;
}
}
private DataReplicationOptions createDataReplicationOptions(int replicationPort, boolean secureReplication,
{
switch (type)
{
case IN_EXISTING_TOPOLOGY:
case STANDALONE:
return DataReplicationOptions.createStandalone();
case FIRST_IN_TOPOLOGY:
default:
}
}
{
int replicationPort = -1;
try
{
{
}
else if (!canUseAsPort(replicationPort))
{
}
else
{
/* Check that we did not chose this port for another protocol */
if (replicationPort == getUserData().getServerPort() || replicationPort == getUserData().getServerJMXPort()
{
}
else
{
}
}
}
catch (NumberFormatException nfe)
{
}
return replicationPort;
}
private void checkRemoteHostPortDnAndPwd(String host, String sPort, String dn, String pwd, QuickSetup qs,
{
// Check host
{
}
else
{
}
// Check port
try
{
}
catch (Throwable t)
{
}
// Check dn
{
}
else
{
}
// Check password
{
}
else
{
}
}
throws UserDataException
{
try
{
try
{
}
catch (Throwable t)
{
if (!isCertificateException(t))
{
// Try using a global administrator
}
else
{
throw t;
}
}
if (adsContext.hasAdminData())
{
/* Check if there are already global administrators */
/* Check the exceptions and see if we throw them or not. */
for (TopologyCacheException e : exceptions)
{
switch (e.getType())
{
case NOT_GLOBAL_ADMINISTRATOR:
if (isCertificateException(e.getCause()))
{
if (e.getTrustManager() != null)
{
}
{
}
{
}
else
{
}
{
String h;
int p;
try
{
}
catch (Throwable t)
{
p = -1;
}
throw new UserDataCertificateException(Step.REPLICATION_OPTIONS, INFO_CERTIFICATE_EXCEPTION.get(h, p),
}
}
break;
default:
break;
}
}
if (!exceptionMsgs.isEmpty())
{
}
}
else
{
}
}
catch (UserDataException ude)
{
throw ude;
}
catch (Throwable t)
{
if (isCertificateException(t))
{
{
}
{
}
else
{
}
{
throw new UserDataCertificateException(Step.REPLICATION_OPTIONS, INFO_CERTIFICATE_EXCEPTION.get(host, port),
}
else
{
}
}
else if (t instanceof NamingException)
{
if (!(t instanceof NamingSecurityException))
{
}
}
else if (t instanceof ADSContextException)
{
}
else
{
}
}
finally
{
}
}
/**
* Validate the data provided by the user in the create global administrator
* panel and update the UserInstallData object according to that content.
*
* @throws UserDataException
* if the data provided by the user is not valid.
*/
{
// Check the Global Administrator UID
{
}
else
{
}
// Check the provided passwords
{
pwd1 = "";
}
boolean pwdValid = true;
{
pwdValid = false;
}
{
{
}
pwdValid = false;
}
if (pwdValid)
{
}
{
throw new UserDataException(Step.CREATE_GLOBAL_ADMINISTRATOR, getMessageFromCollection(errorMsgs, "\n"));
}
}
/**
* Validate the data provided by the user in the replicate suffixes options
* panel and update the UserInstallData object according to that content.
*
* @throws UserDataException
* if the data provided by the user is not valid.
*/
@SuppressWarnings("unchecked")
{
{
if (s.isEmpty())
{
}
else
{
for (Object o : s)
{
}
Set<SuffixDescriptor> available = getUserData().getSuffixesToReplicateOptions().getAvailableSuffixes();
SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES, available, chosen, suffixesBackendTypes);
}
}
else
{
Set<SuffixDescriptor> available = getUserData().getSuffixesToReplicateOptions().getAvailableSuffixes();
new SuffixesToReplicateOptions(SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY, available, chosen);
}
{
}
}
/**
* Validate the data provided by the user in the remote server replication
* port panel and update the userData object according to that content.
*
* @throws UserDataException
* if the data provided by the user is not valid.
*/
{
{
try
{
{
errorMsgs.add(INFO_INVALID_REMOTE_REPLICATION_PORT_VALUE_RANGE.get(getHostPort(server), MIN_PORT_VALUE,
}
{
int securePort = -1;
{
}
if (replicationPort == getUserData().getServerPort() || replicationPort == getUserData().getServerJMXPort()
|| replicationPort == securePort)
{
errorMsgs.add(INFO_REMOTE_REPLICATION_PORT_ALREADY_CHOSEN_FOR_OTHER_PROTOCOL.get(getHostPort(server)));
}
}
}
catch (NumberFormatException nfe)
{
errorMsgs.add(INFO_INVALID_REMOTE_REPLICATION_PORT_VALUE_RANGE.get(hostName, MIN_PORT_VALUE, MAX_PORT_VALUE));
}
}
{
throw new UserDataException(Step.REMOTE_REPLICATION_PORTS, getMessageFromCollection(errorMsgs, "\n"));
}
else
{
}
}
/**
* Validate the data provided by the user in the new suffix data options panel
* and update the UserInstallData object according to that content.
*
* @throws UserDataException
* if the data provided by the user is not valid.
*/
@SuppressWarnings("unchecked")
{
// Singleton list with the provided baseDN (if exists and valid)
if (dataOptions != null)
{
getUserData().setBackendType((ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg>)
}
{
}
}
private NewSuffixOptions checkImportData(final QuickSetup ui, final List<String> baseDn, final boolean validBaseDn,
{
{
}
final NewSuffixOptions.Type type = (NewSuffixOptions.Type) ui.getFieldValue(FieldName.DATA_OPTIONS);
switch (type)
{
case IMPORT_FROM_LDIF_FILE:
default:
if (validBaseDn)
{
}
}
return null;
}
{
boolean fieldIsValid = true;
{
fieldIsValid = false;
}
else
{
boolean nEntriesValid = false;
try
{
}
catch (NumberFormatException nfe)
{
/* do nothing */
}
if (!nEntriesValid)
{
fieldIsValid = false;
}
}
{
}
return null;
}
{
final boolean fieldIsValid = false;
{
}
else if (!fileExists(ldifPath))
{
}
else if (validBaseDn)
{
return NewSuffixOptions.createImportFromLDIF(baseDn, Collections.singletonList(ldifPath), null, null);
}
return null;
}
{
boolean validBaseDn = true;
{
// Do nothing, the user does not want to provide a base DN.
dn = "";
}
{
validBaseDn = false;
}
else if (isConfigurationDn(dn))
{
validBaseDn = false;
}
else
{
}
return validBaseDn;
}
/**
* Update the userData object according to the content of the runtime options
* panel.
*/
{
}
/** Update the userData object according to the content of the review panel. */
{
getUserData().setStartServer(b);
}
/**
* Returns the number of free disk space in bytes required to install Open DS
* For the moment we just return 20 Megabytes. TODO we might want to have
* something dynamic to calculate the required free disk space for the
* installation.
*
* @return the number of free disk space required to install Open DS.
*/
private long getRequiredInstallSpace()
{
return 20 * 1024 * 1024;
}
/** Update the UserInstallData with the contents we discover in the ADS. */
{
{
}
else
{
}
// We cannot use getPreferredConnections since the user data has not been
// updated yet.
{
}
getUserData().setSuffixesToReplicateOptions(new SuffixesToReplicateOptions(type, suffixes, moreSuffixes));
/*
* Analyze if we had any exception while loading servers. For the moment
* only throw the exception found if the user did not provide the
* Administrator DN and this caused a problem authenticating in one server
* or if there is a certificate problem.
*/
{
if (e != null)
{
exceptions.add(e);
}
}
return exceptions;
}
/**
* Update the UserInstallData object with the contents of the server to which
* we are connected with the provided InitialLdapContext.
*/
{
{
}
else
{
}
{
}
{
}
getUserData().setSuffixesToReplicateOptions(new SuffixesToReplicateOptions(type, suffixes, moreSuffixes));
}
/**
* Returns the keystore path to be used for generating a self-signed
* certificate.
*
* @return the keystore path to be used for generating a self-signed
* certificate.
*/
protected String getSelfSignedKeystorePath()
{
return getPath2("keystore");
}
/**
* Returns the trustmanager path to be used for generating a self-signed
* certificate.
*
* @return the trustmanager path to be used for generating a self-signed
* certificate.
*/
private String getTrustManagerPath()
{
return getPath2("truststore");
}
/**
* Returns the path of the self-signed that we export to be able to create a
* truststore.
*
* @return the path of the self-signed that is exported.
*/
private String getTemporaryCertificatePath()
{
return getPath2("server-cert.txt");
}
/**
* Returns the path to be used to store the password of the keystore.
*
* @return the path to be used to store the password of the keystore.
*/
private String getKeystorePinPath()
{
return getPath2("keystore.pin");
}
{
}
/**
* Returns the validity period to be used to generate the self-signed
* certificate.
*
* @return the validity period to be used to generate the self-signed
* certificate.
*/
private int getSelfSignedCertificateValidity()
{
return 20 * 365;
}
/**
* Returns the Subject DN to be used to generate the self-signed certificate.
*
* @return the Subject DN to be used to generate the self-signed certificate.
*/
{
return "cn=" + Rdn.escapeValue(getUserData().getHostName()) + ",O=OpenDJ " + keyType + " Self-Signed Certificate";
}
/**
* Returns the self-signed certificate password used for this session. This
* method calls <code>createSelfSignedCertificatePwd()</code> the first time
* this method is called.
*
* @return the self-signed certificate password used for this session.
*/
protected String getSelfSignedCertificatePwd()
{
if (selfSignedCertPw == null)
{
}
return new String(selfSignedCertPw);
}
{
{
{
{
authData.setUseSecureConnection(false);
}
}
}
return servers;
}
{
"ldaps://" + getHostNameForLdapUrl(getUserData().getHostName()) + ":" + getUserData().getAdminConnectorPort();
}
/**
* Gets an InitialLdapContext based on the information that appears on the
* provided ServerDescriptor.
*
* @param server
* the object describing the server.
* @param trustManager
* the trust manager to be used to establish the connection.
* @param cnx
* the list of preferred LDAP URLs to be used to connect to the
* server.
* @return the InitialLdapContext to the remote server.
* @throws ApplicationException
* if something goes wrong.
*/
private InitialLdapContext getRemoteConnection(ServerDescriptor server, ApplicationTrustManager trustManager,
{
if (!server.isRegistered())
{
/*
* Create adsProperties to be able to use the class ServerLoader to get
* the connection. Just update the connection parameters with what the
* user chose in the Topology Options panel (i.e. even if SSL is enabled
* on the remote server, use standard LDAP to connect to the server if the
* user specified the LDAP port: this avoids having an issue with the
* certificate if it has not been accepted previously by the user).
*/
adsProperties = new HashMap<>();
if (auth.useSecureConnection())
{
}
else
{
}
}
return getRemoteConnection(server, auth.getDn(), auth.getPwd(), trustManager, getConnectTimeout(), cnx);
}
/**
* Initializes a suffix with the contents of a replica that has a given
* replication id.
*
* @param ctx
* the connection to the server whose suffix we want to initialize.
* @param replicaId
* the replication ID of the replica we want to use to initialize the
* contents of the suffix.
* @param suffixDn
* the dn of the suffix.
* @param displayProgress
* whether we want to display progress or not.
* @param sourceServerDisplay
* the string to be used to represent the server that contains the
* data that will be used to initialize the suffix.
* @throws ApplicationException
* if an unexpected error occurs.
* @throws PeerNotFoundException
* if the replication mechanism cannot find a peer.
*/
public void initializeSuffix(InitialLdapContext ctx, int replicaId, String suffixDn, boolean displayProgress,
{
boolean taskCreated = false;
int i = 1;
boolean isOver = false;
while (!taskCreated)
{
checkAbort();
try
{
taskCreated = true;
}
catch (NameAlreadyBoundException x)
{
}
catch (NamingException ne)
{
}
i++;
}
// Wait until it is over
"ds-task-processed-entry-count", "ds-task-log-message", "ds-task-state" });
long lastTimeMsgDisplayed = -1;
long lastTimeMsgLogged = -1;
long totalEntries = 0;
while (!isOver)
{
if (canceled)
{
// TODO: we should try to cleanly abort the initialize. As we have
// aborted the install, the server will be stopped and the remote
// server will receive a connect error.
checkAbort();
}
if (canceled)
{
// TODO: we should try to cleanly abort the initialize. As we have
// aborted the install, the server will be stopped and the remote
// server will receive a connect error.
checkAbort();
}
try
{
try
{
{
}
}
finally
{
}
// Get the number of entries that have been handled and
// a percentage...
long processed = -1;
long unprocessed = -1;
if (sProcessed != null)
{
}
if (sUnprocessed != null)
{
}
{
{
}
else
{
//msg = INFO_NO_ENTRIES_TO_INITIALIZE.get();
}
}
else if (processed != -1)
{
}
else if (unprocessed != -1)
{
}
else
{
}
{
/* Refresh period: to avoid having too many lines in the log */
long minRefreshPeriod;
if (totalEntries < 100)
{
minRefreshPeriod = 0;
}
else if (totalEntries < 1000)
{
minRefreshPeriod = 1000;
}
else if (totalEntries < 10000)
{
minRefreshPeriod = 5000;
}
else
{
minRefreshPeriod = 10000;
}
{
}
if (displayProgress && currentTime - minRefreshPeriod > lastTimeMsgDisplayed && !msg.equals(lastDisplayedMsg))
{
}
}
{
lastLogMsg = logMsg;
}
{
isOver = true;
{
}
if (lastLogMsg != null)
{
errorMsg =
INFO_ERROR_DURING_INITIALIZATION_LOG.get(sourceServerDisplay, lastLogMsg, state, sourceServerDisplay);
}
else
{
errorMsg = INFO_ERROR_DURING_INITIALIZATION_NO_LOG.get(sourceServerDisplay, state, sourceServerDisplay);
}
{
if (displayProgress)
{
}
}
{
{
logger.warn(LocalizableMessage.raw("Throwing peer not found error. " + "Last Log Msg: " + lastLogMsg));
// Assume that this is a peer not found error.
throw new PeerNotFoundException(errorMsg);
}
else
{
throw ae;
}
}
else if (displayProgress)
{
}
}
}
catch (NameNotFoundException x)
{
isOver = true;
if (displayProgress)
{
}
}
catch (NamingException ne)
{
throw new ApplicationException(ReturnCode.APPLICATION_ERROR, getThrowableMsg(INFO_ERROR_POOLING_INITIALIZATION
}
}
}
/**
* Returns the configuration file path to be used when invoking the
* command-lines.
*
* @return the configuration file path to be used when invoking the
* command-lines.
*/
private String getConfigurationFile()
{
}
/**
* Returns the configuration class name to be used when invoking the
* command-lines.
*
* @return the configuration class name to be used when invoking the
* command-lines.
*/
private String getConfigurationClassName()
{
return DEFAULT_CONFIG_CLASS_NAME;
}
private String getLocalReplicationServer()
{
return getUserData().getHostName() + ":" + getUserData().getReplicationOptions().getReplicationPort();
}
private String getLocalHostPort()
{
}
throws ApplicationException
{
boolean taskCreated = false;
int i = 1;
boolean isOver = false;
while (!taskCreated)
{
checkAbort();
try
{
taskCreated = true;
}
catch (NameAlreadyBoundException x)
{
}
catch (NamingException ne)
{
}
i++;
}
// Wait until it is over
while (!isOver)
{
try
{
try
{
{
}
}
finally
{
}
{
lastLogMsg = logMsg;
}
{
isOver = true;
INFO_ERROR_DURING_INITIALIZATION_LOG.get(sourceServerDisplay, lastLogMsg, state, sourceServerDisplay)
{
}
{
}
}
}
catch (NameNotFoundException x)
{
isOver = true;
}
catch (NamingException ne)
{
}
}
}
/**
* Invokes a long operation in a separate thread and checks whether the user
* canceled the operation or not.
*
* @param thread
* the Thread that must be launched.
* @throws ApplicationException
* if there was an error executing the task or if the user canceled
* the installer.
*/
{
try
{
{
if (canceled)
{
// Try to abort the thread
try
{
}
catch (Throwable t)
{
}
}
{
throw thread.getException();
}
else
{
}
}
{
throw thread.getException();
}
if (canceled)
{
checkAbort();
}
}
catch (ApplicationException e)
{
throw e;
}
catch (Throwable t)
{
}
}
/**
* Returns the host port representation of the server to be used in progress
* and error messages. It takes into account the fact the host and port
* provided by the user in the replication options panel. NOTE: the code
* assumes that the user data with the contents of the replication options has
* already been updated.
*
* @param server
* the ServerDescriptor.
* @return the host port string representation of the provided server.
*/
{
{
{
}
{
}
}
{
}
return hostPort;
}
{
if (parsedMessage != null)
{
}
}
/**
* Returns the timeout to be used to connect in milliseconds.
*
* @return the timeout to be used to connect in milliseconds. Returns
* {@code 0} if there is no timeout.
*/
protected int getConnectTimeout()
{
return getUserData().getConnectTimeout();
}
/**
* Copies the template instance files into the instance directory.
*
* @throws ApplicationException
* If an IO error occurred.
*/
private void copyTemplateInstance() throws ApplicationException
{
fileManager.synchronize(getInstallation().getTemplateDirectory(), getInstallation().getInstanceDirectory());
}
}
/** Class used to be able to cancel long operations. */
{
protected boolean isOver;
protected ApplicationException ae;
/**
* Returns <CODE>true</CODE> if the thread is over and <CODE>false</CODE>
* otherwise.
*
* @return <CODE>true</CODE> if the thread is over and <CODE>false</CODE>
* otherwise.
*/
public boolean isOver()
{
return isOver;
}
/**
* Returns the exception that was encountered running the thread.
*
* @return the exception that was encountered running the thread.
*/
public ApplicationException getException()
{
return ae;
}
/** Runnable implementation. */
public abstract void run();
/** Abort this thread. */
public abstract void abort();
}