ServerController.java revision 358aa64445313154ce8f5e0acca0966f5a40fa0b
/*
* 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
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Portions Copyright 2007 Sun Microsystems, Inc.
*/
/**
* Class used to manipulate an OpenDS server.
*/
public class ServerController {
private Application application;
private Installation installation;
/**
* Creates a new instance that will operate on <code>application</code>'s
* installation.
* @param application to use for notifications
*/
}
/**
* Creates a new instance that will operate on <code>application</code>'s
* installation.
* @param installation representing the server instance to control
*/
this(null, installation);
}
/**
* Creates a new instance that will operate on <code>installation</code>
* and use <code>application</code> for notifications.
* @param application to use for notifications
* @param installation representing the server instance to control
*/
if (installation == null) {
throw new NullPointerException("installation cannot be null");
}
this.application = application;
this.installation = installation;
}
/**
* This methods stops the server.
*
* @throws org.opends.quicksetup.ApplicationException if something goes wrong.
*/
public void stopServer() throws ApplicationException {
if (application != null) {
}
/* Remove JAVA_BIN to be sure that we use the JVM running the uninstaller
* JVM to stop the server.
*/
try {
new BufferedReader(
new BufferedReader(
/* Create these objects to resend the stop process output to the details
* area.
*/
new StopReader(err, true);
new StopReader(out, false);
int clientSideError =
/*
* Sometimes the server keeps some locks on the files.
* TODO: remove this code once stop-ds returns properly when server
* is stopped.
*/
int nTries = 10;
boolean stopped = false;
if (!stopped) {
if (application != null) {
"progress-server-waiting-to-stop")) +
}
try {
}
}
}
}
if (!stopped) {
returnValue = -1;
}
}
}
if (returnValue == clientSideError) {
if (application != null) {
"progress-server-already-stopped")) +
}
} else if (returnValue != 0) {
/*
* The return code is not the one expected, assume the server could
* not be stopped.
*/
"error-stopping-server-code",
null);
} else {
if (application != null) {
}
}
} catch (Exception e) {
getThrowableMsg("error-stopping-server", e), e);
}
}
/**
* This methods starts the server.
* @return OperationOutput object containing output from the start server
* command invocation.
* @throws org.opends.quicksetup.ApplicationException if something goes wrong.
*/
return startServer(true);
}
/**
* This methods starts the server.
* @param verify boolean indicating whether this method will attempt to
* connect to the server after starting to verify that it is listening.
* @return OperationOutput object containing output from the start server
* command invocation.
* @throws org.opends.quicksetup.ApplicationException if something goes wrong.
*/
throws ApplicationException
{
if (application != null) {
}
/* Remove JAVA_BIN to be sure that we use the JVM running the installer
* JVM to start the server.
*/
// Upgrader's classpath contains jars located in the temporary
// directory that we don't want locked by the directory server
// when it starts. Since we're just calling the start-ds script
// it will figure out the correct classpath for the server.
try
{
{
try
{
} catch (InterruptedException ie)
{
}
}
// Collect any messages found in the output
}
}
// NOTE: this may not be the best place to drop these.
// However upon startup the server seems to log all messages,
// regardless of whether or not they signal an error condition,
// to its error log.
}
}
// Check if something wrong occurred reading the starting of the server
{
}
{
// This is meaningless right now since we throw
// the exception below, but in case we change out
// minds later or add the ability to return exceptions
// in the output only instead of throwing...
throw ex;
} else if (verify)
{
/*
* There are no exceptions from the readers and they are marked as
* finished. This means that the server has written in its output the
* message id informing that it started. So it seems that everything
* went fine.
*
* However we can have issues with the firewalls or do not have rights
* to connect. Just check if we can connect to the server.
* Try 5 times with an interval of 1 second between try.
*/
boolean connected = false;
// See if the application has prompted for credentials. If
// not we'll just try to connect anonymously.
if (application != null) {
}
}
{
try
{
connected = true;
}
catch (NamingException ne)
{
}
if (!connected)
{
try
{
}
catch (Throwable t)
{
}
}
}
if (!connected)
{
{
throw new ApplicationException(
getMsg("error-starting-server-in-windows",
null);
}
else
{
throw new ApplicationException(
getMsg("error-starting-server-in-unix",
null);
}
}
}
} catch (IOException ioe)
{
ioe);
}
return output;
}
/**
* Backs up all the databases to a specified directory.
* @param backupDir File representing the directory where the backups will
* be stored
* @return OperationOutput containing information about the operation
* @throws IOException if the process could not be started
* @throws InterruptedException if the process was prematurely interrupted
*/
throws IOException, InterruptedException {
new OutputReader(out) {
}
};
new OutputReader(err) {
}
};
return output;
}
/**
* This class is used to read the standard error and standard output of the
* Stop process.
* <p/>
* When a new log message is found notifies the
* UninstallProgressUpdateListeners of it. If an error occurs it also
* notifies the listeners.
*/
private class StopReader {
private boolean isFirstLine;
/**
* The protected constructor.
*
* @param reader the BufferedReader of the stop process.
* @param isError a boolean indicating whether the BufferedReader
* corresponds to the standard error or to the standard output.
*/
final boolean isError) {
isFirstLine = true;
public void run() {
try {
if (application != null) {
if (!isFirstLine) {
getLineBreak());
}
if (isError) {
} else {
}
isFirstLine = false;
}
}
} catch (Throwable t) {
if (application != null) {
}
}
}
});
t.start();
}
}
/**
* This class is used to read an input stream and process ouput.
*/
abstract private class OutputReader {
/**
* Called whenever new input is read from the reader.
* @param line String representing new input
*/
/**
* The protected constructor.
*
* @param reader the BufferedReader of the stop process.
*/
public void run() {
try {
}
} catch (Throwable t) {
}
}
});
t.start();
}
}
/**
* Returns the Message ID indicating that the server has started.
* @return the Message ID indicating that the server has started.
*/
private String getStartedId()
{
return helper.getStartedId();
}
/**
* This class is used to read the standard error and standard output of the
* Start process.
*
* When a new log message is found notifies the ProgressUpdateListeners
* of it. If an error occurs it also notifies the listeners.
*
*/
private class StartReader
{
private ApplicationException ex;
private boolean isFinished;
private boolean isFirstLine;
/**
* The protected constructor.
* @param reader the BufferedReader of the start process.
* @param startedId the message ID that this class can use to know whether
* the start is over or not.
* @param isError a boolean indicating whether the BufferedReader
* corresponds to the standard error or to the standard output.
*/
final boolean isError)
{
isFirstLine = true;
{
public void run()
{
try
{
{
if (application != null) {
if (!isFirstLine)
{
getLineBreak());
}
if (isError)
{
} else
{
}
isFirstLine = false;
}
{
isFinished = true;
}
}
} catch (Throwable t)
{
ex =
getThrowableMsg(errorTag, t), t);
}
isFinished = true;
}
});
t.start();
}
/**
* Returns the ApplicationException that occurred reading the Start error
* and output or <CODE>null</CODE> if no exception occurred.
* @return the exception that occurred reading or <CODE>null</CODE> if
* no exception occurred.
*/
public ApplicationException getException()
{
return ex;
}
return messages;
}
/**
* Returns <CODE>true</CODE> if the server starting process finished
* (successfully or not) and <CODE>false</CODE> otherwise.
* @return <CODE>true</CODE> if the server starting process finished
* (successfully or not) and <CODE>false</CODE> otherwise.
*/
public boolean isFinished()
{
return isFinished;
}
}
}
}
}
}