mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
12.49.2008 79257754116e73ab0bc852ae82259a8627c33a06
Fix for issue 3048 (Missing "Are you sure ?" confirmation question in setup --cli)

In interactive mode display a summary of the parameters provided by the user (as the one that we have in the GUI). If the user is not satisfied with the provided parameters we propose to revisit all of them again (the default values that we will propose are the ones the user provided).
5 files modified
430 ■■■■■ changed files
opendj-sdk/opends/src/messages/messages/quicksetup.properties 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/messages/messages/tools.properties 11 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java 15 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/InstallDS.java 398 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/messages/messages/quicksetup.properties
@@ -844,7 +844,8 @@
INFO_REVERT_CONFIRM_PROMPT=This installation will be reverted to version \
 %s using the files in %s.
INFO_REVIEW_CREATE_BASE_ENTRY_LABEL=Only Create Base Entry (%s)
INFO_REVIEW_CREATE_SUFFIX=Create New Base DN %s.Base DN Data: %s
INFO_REVIEW_CREATE_SUFFIX=Create New Base DN %s.  Base DN Data: %s
INFO_REVIEW_CREATE_SUFFIXES=Create New Base DNs:%n%s.%nBase DN Data: %s
INFO_REVIEW_IMPORT_AUTOMATICALLY_GENERATED=Import Automatically-Generated \
 Data (%s Entries)
INFO_REVIEW_IMPORT_LDIF=Import Data from LDIF File (%s)
opendj-sdk/opends/src/messages/messages/tools.properties
@@ -2333,3 +2333,14 @@
INFO_MULTICHOICE_TRUE_VALUE_1597=true
INFO_MULTICHOICE_FALSE_VALUE_1598=false
INFO_INSTALLDS_SERVER_JMXPORT_LABEL_1599=JMX Listener Port:
INFO_INSTALLDS_START_SERVER_1600=Start Server when the configuration is completed
INFO_INSTALLDS_DO_NOT_START_SERVER_1601=Do not start Server when the configuration \
 is completed
INFO_INSTALLDS_SUMMARY_1602=Setup Summary%n=============
INFO_INSTALLDS_CONFIRM_INSTALL_PROMPT_1603=What would you like to do?
INFO_INSTALLDS_CONFIRM_INSTALL_1604=Setup the server with the parameters above
INFO_INSTALLDS_PROVIDE_DATA_AGAIN_1605=Provide the setup parameters again
INFO_INSTALLDS_CANCEL_1606=Cancel the setup
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -33,6 +33,7 @@
import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.SuffixDescriptor;
import org.opends.quicksetup.Constants;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.installer.AuthenticationData;
import org.opends.quicksetup.installer.DataReplicationOptions;
@@ -266,13 +267,12 @@
    getField(fieldName).setText(value);
  }
  /**
   * Returns the localized string describing the DataOptions chosen by the user.
   * @param userInstallData the DataOptions of the user.
   * @return the localized string describing the DataOptions chosen by the user.
   */
  private String getDataDisplayString(UserData userInstallData)
  public static String getDataDisplayString(UserData userInstallData)
  {
    Message msg;
@@ -320,8 +320,17 @@
        throw new IllegalArgumentException("Unknown type: "+options.getType());
      }
      msg = INFO_REVIEW_CREATE_SUFFIX.get(options.getBaseDns().getFirst(),
      if (options.getBaseDns().size() > 1)
      {
        msg = INFO_REVIEW_CREATE_SUFFIX.get(
            Utils.listToString(options.getBaseDns(), Constants.LINE_SEPARATOR),
            arg2);
      }
      else
      {
        msg = INFO_REVIEW_CREATE_SUFFIX.get(options.getBaseDns().getFirst(),
          arg2);
      }
    }
    else
    {
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
@@ -450,7 +450,8 @@
   * @return a localized String representation of the provided SecurityOptions
   * object.
   */
  protected String getSecurityOptionsString(SecurityOptions ops, boolean html)
  public static String getSecurityOptionsString(SecurityOptions ops,
      boolean html)
  {
    StringBuilder buf = new StringBuilder();
opendj-sdk/opends/src/server/org/opends/server/tools/InstallDS.java
@@ -55,6 +55,8 @@
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.installer.NewSuffixOptions;
import org.opends.quicksetup.installer.offline.OfflineInstaller;
import org.opends.quicksetup.installer.ui.InstallReviewPanel;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
import org.opends.quicksetup.util.Utils;
import org.opends.server.core.DirectoryServer;
@@ -71,6 +73,8 @@
import org.opends.server.util.cli.Menu;
import org.opends.server.util.cli.MenuBuilder;
import org.opends.server.util.cli.MenuResult;
import org.opends.server.util.table.TableBuilder;
import org.opends.server.util.table.TextTablePrinter;
/**
 * This class provides a very simple mechanism for installing the OpenDS
 * Directory Service.  It performs the following tasks:
@@ -130,7 +134,11 @@
    /**
     * The user failed providing password (for the keystore for instance).
     */
    ERROR_PASSWORD_LIMIT(5);
    ERROR_PASSWORD_LIMIT(5),
    /**
     * The user cancelled the setup.
     */
    ERROR_USER_CANCELLED(6);
    private int returnCode;
    private ErrorReturnCode(int returnCode)
@@ -149,8 +157,63 @@
    }
  };
  /**
   * Enumeration describing the different answer that the user can provide
   * when we ask to finalize the setup.  Note that the code associated
   * correspond to the order in the confirmation menu that is displayed at the
   * end of the setup in interactive mode.
   */
  private enum ConfirmCode
  {
    // Continue with the install
    CONTINUE(1),
    // Provide information again
    PROVIDE_INFORMATION_AGAIN(2),
    // Cancel the install
    CANCEL(3);
    private int returnCode;
    private ConfirmCode(int returnCode)
    {
      this.returnCode = returnCode;
    }
    /**
     * Get the corresponding return code value.
     *
     * @return The corresponding return code value.
     */
    public int getReturnCode()
    {
      return returnCode;
    }
  }
  private static final int LIMIT_KEYSTORE_PASSWORD_PROMPT = 7;
  // Different variables we use when the user decides to provide data again.
  private NewSuffixOptions.Type lastResetPopulateOption = null;
  private String lastResetImportFile = null;
  private String lastResetRejectedFile = null;
  private String lastResetSkippedFile = null;
  private Integer lastResetNumEntries = null;
  private Boolean lastResetEnableSSL = null;
  private Boolean lastResetEnableStartTLS = null;
  private SecurityOptions.CertificateType lastResetCertType = null;
  private String lastResetKeyStorePath = null;
  private Boolean lastResetEnableWindowsService = null;
  private Boolean lastResetStartServer = null;
  /**
   * The Logger.
   */
@@ -343,29 +406,60 @@
      }
    }
    UserData uData = new UserData();
    boolean userApproved = false;
    try
    UserData uData = new UserData();
    while (!userApproved)
    {
      try
      {
        if (isInteractive())
        {
          promptIfRequired(uData);
        }
        else
        {
          initializeUserDataWithParser(uData);
        }
      }
      catch (UserDataException ude)
      {
        println(ude.getMessageObject());
        if (isPasswordTriesError(ude.getMessageObject()))
        {
          return ErrorReturnCode.ERROR_PASSWORD_LIMIT.getReturnCode();
        }
        else
        {
          return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
        }
      }
      if (isInteractive())
      {
        promptIfRequired(uData);
        ConfirmCode confirm = askForConfirmation(uData);
        switch (confirm)
        {
        case CONTINUE:
          userApproved = true;
          break;
        case CANCEL:
          return ErrorReturnCode.ERROR_USER_CANCELLED.getReturnCode();
        default:
          // Reset the arguments
          try
          {
            resetArguments(uData);
          }
          catch (Throwable t)
          {
            LOG.log(Level.WARNING, "Error resetting arg parser: "+t, t);
          }
          userApproved = false;
        }
      }
      else
      {
        initializeUserDataWithParser(uData);
      }
    }
    catch (UserDataException ude)
    {
      println(ude.getMessageObject());
      if (isPasswordTriesError(ude.getMessageObject()))
      {
        return ErrorReturnCode.ERROR_PASSWORD_LIMIT.getReturnCode();
      }
      else
      {
        return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
        userApproved = true;
      }
    }
    System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
@@ -1124,7 +1218,7 @@
        try
        {
          String path = readInput(INFO_INSTALLDS_PROMPT_IMPORT_FILE.get(),
              null);
              lastResetImportFile);
          if (!Utils.fileExists(path))
          {
            println();
@@ -1151,7 +1245,8 @@
          try
          {
            rejectedFile =
              readInput(INFO_INSTALLDS_PROMPT_REJECTED_FILE.get(), null);
              readInput(INFO_INSTALLDS_PROMPT_REJECTED_FILE.get(),
                  lastResetRejectedFile);
          }
          catch (CLIException ce)
          {
@@ -1170,7 +1265,8 @@
          try
          {
            skippedFile =
              readInput(INFO_INSTALLDS_PROMPT_SKIPPED_FILE.get(), null);
              readInput(INFO_INSTALLDS_PROMPT_SKIPPED_FILE.get(),
                  lastResetSkippedFile);
          }
          catch (CLIException ce)
          {
@@ -1209,6 +1305,7 @@
      final int POPULATE_TYPE_LEAVE_EMPTY = 2;
      final int POPULATE_TYPE_IMPORT_FROM_LDIF = 3;
      final int POPULATE_TYPE_GENERATE_SAMPLE_DATA = 4;
      int[] indexes = {POPULATE_TYPE_BASE_ONLY, POPULATE_TYPE_LEAVE_EMPTY,
          POPULATE_TYPE_IMPORT_FROM_LDIF, POPULATE_TYPE_GENERATE_SAMPLE_DATA};
      Message[] msgs = new Message[] {
@@ -1226,9 +1323,37 @@
        builder.addNumberedOption(msgs[i], MenuResult.success(indexes[i]));
      }
      builder.setDefault(Message.raw(
      if (lastResetPopulateOption == null)
      {
        builder.setDefault(Message.raw(
              String.valueOf(POPULATE_TYPE_BASE_ONLY)),
              MenuResult.success(POPULATE_TYPE_BASE_ONLY));
      }
      else
      {
        switch (lastResetPopulateOption)
        {
          case LEAVE_DATABASE_EMPTY:
            builder.setDefault(Message.raw(
              String.valueOf(POPULATE_TYPE_LEAVE_EMPTY)),
              MenuResult.success(POPULATE_TYPE_LEAVE_EMPTY));
            break;
          case IMPORT_FROM_LDIF_FILE:
            builder.setDefault(Message.raw(
                String.valueOf(POPULATE_TYPE_IMPORT_FROM_LDIF)),
                MenuResult.success(POPULATE_TYPE_IMPORT_FROM_LDIF));
            break;
          case IMPORT_AUTOMATICALLY_GENERATED_DATA:
            builder.setDefault(Message.raw(
                String.valueOf(POPULATE_TYPE_GENERATE_SAMPLE_DATA)),
                MenuResult.success(POPULATE_TYPE_GENERATE_SAMPLE_DATA));
            break;
          default:
            builder.setDefault(Message.raw(
                String.valueOf(POPULATE_TYPE_BASE_ONLY)),
                MenuResult.success(POPULATE_TYPE_BASE_ONLY));
        }
      }
      Menu<Integer> menu = builder.toMenu();
      int populateType;
@@ -1322,7 +1447,17 @@
      else if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
      {
        Message message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
        int numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
        int defaultValue;
        if (lastResetNumEntries == null)
        {
          defaultValue = 2000;
        }
        else
        {
          defaultValue = lastResetNumEntries;
        }
        int numUsers = promptForInteger(message, defaultValue, 0,
            Integer.MAX_VALUE);
        dataOptions = NewSuffixOptions.createAutomaticallyGenerated(baseDNs,
            numUsers);
@@ -1376,8 +1511,10 @@
      println();
      try
      {
        boolean defaultValue = lastResetEnableSSL != null ? lastResetEnableSSL :
          false;
        enableSSL = confirmAction(INFO_INSTALLDS_PROMPT_ENABLE_SSL.get(),
            false);
            defaultValue);
        if (enableSSL)
        {
          ldapsPort = promptIfRequiredForPortData(argParser.ldapsPortArg,
@@ -1402,8 +1539,10 @@
      println();
      try
      {
        boolean defaultValue = lastResetEnableStartTLS != null ?
            lastResetEnableStartTLS : false;
        enableStartTLS = confirmAction(INFO_INSTALLDS_ENABLE_STARTTLS.get(),
            argParser.enableStartTLSArg.isPresent());
            defaultValue);
      }
      catch (CLIException ce)
      {
@@ -1470,8 +1609,32 @@
          builder.addNumberedOption(msgs[i], MenuResult.success(indexes[i]));
        }
        builder.setDefault(Message.raw(String.valueOf(SELF_SIGNED)),
        if (lastResetCertType == null)
        {
          builder.setDefault(Message.raw(String.valueOf(SELF_SIGNED)),
            MenuResult.success(SELF_SIGNED));
        }
        else
        {
          switch (lastResetCertType)
          {
          case JKS:
            builder.setDefault(Message.raw(String.valueOf(JKS)),
                MenuResult.success(JKS));
            break;
          case PKCS11:
            builder.setDefault(Message.raw(String.valueOf(PKCS11)),
                MenuResult.success(PKCS11));
            break;
          case PKCS12:
            builder.setDefault(Message.raw(String.valueOf(PKCS12)),
                MenuResult.success(PKCS12));
            break;
          default:
            builder.setDefault(Message.raw(String.valueOf(SELF_SIGNED)),
                MenuResult.success(SELF_SIGNED));
          }
        }
        Menu<Integer> menu = builder.toMenu();
        int certType;
@@ -1550,7 +1713,9 @@
        Message message = INFO_INSTALLDS_PROMPT_ENABLE_SERVICE.get();
        try
        {
          enableService = confirmAction(message, false);
          boolean defaultValue = (lastResetEnableWindowsService == null) ?
              false : lastResetEnableWindowsService;
          enableService = confirmAction(message, defaultValue);
        }
        catch (CLIException ce)
        {
@@ -1577,7 +1742,9 @@
      Message message = INFO_INSTALLDS_PROMPT_START_SERVER.get();
      try
      {
        startServer = confirmAction(message, true);
        boolean defaultValue = (lastResetStartServer == null) ?
            false : lastResetStartServer;
        startServer = confirmAction(message, defaultValue);
      }
      catch (CLIException ce)
      {
@@ -1773,6 +1940,10 @@
      path = argParser.useJavaKeyStoreArg.getValue();
      pathPrompt = INFO_INSTALLDS_PROMPT_JKS_PATH.get();
      defaultPathValue = argParser.useJavaKeyStoreArg.getValue();
      if (defaultPathValue == null)
      {
        defaultPathValue = lastResetKeyStorePath;
      }
      break;
    case PKCS11:
      path = null;
@@ -1782,6 +1953,10 @@
    case PKCS12:
      path = argParser.usePkcs12Arg.getValue();
      defaultPathValue = argParser.usePkcs12Arg.getValue();
      if (defaultPathValue == null)
      {
        defaultPathValue = lastResetKeyStorePath;
      }
      pathPrompt = INFO_INSTALLDS_PROMPT_PKCS12_PATH.get();
      break;
    default:
@@ -2096,4 +2271,173 @@
    }
    return nickname;
  }
  /**
   * This method asks the user to confirm to continue the setup.  It basically
   * displays the information provided by the user and at the end proposes a
   * menu with the different options to choose from.
   * @param uData the UserData that the user provided.
   * @return the answer provided by the user: cancel setup, continue setup or
   * provide information again.
   */
  private ConfirmCode askForConfirmation(UserData uData)
  {
    ConfirmCode returnValue;
    println();
    println();
    println(INFO_INSTALLDS_SUMMARY.get());
    Message[] labels =
    {
        INFO_SERVER_PORT_LABEL.get(),
        INFO_INSTALLDS_SERVER_JMXPORT_LABEL.get(),
        INFO_SERVER_SECURITY_LABEL.get(),
        INFO_SERVER_DIRECTORY_MANAGER_DN_LABEL.get(),
        INFO_DIRECTORY_DATA_LABEL.get()
    };
    int jmxPort = uData.getServerJMXPort();
    Message[] values =
    {
        Message.raw(String.valueOf(uData.getServerPort())),
        Message.raw(jmxPort != -1 ? String.valueOf(jmxPort) : null),
        Message.raw(
            QuickSetupStepPanel.getSecurityOptionsString(
                uData.getSecurityOptions(), false)),
        Message.raw(uData.getDirectoryManagerDn()),
        Message.raw(InstallReviewPanel.getDataDisplayString(uData)),
    };
    TableBuilder table = new TableBuilder();
    for (int i=0; i<labels.length; i++)
    {
      if (values[i] != null)
      {
        table.startRow();
        table.appendCell(labels[i]);
        table.appendCell(values[i]);
      }
    }
    TextTablePrinter printer = new TextTablePrinter(getOutputStream());
    printer.setDisplayHeadings(false);
    printer.setColumnSeparator("");
    table.print(printer);
    println();
    if (uData.getStartServer())
    {
      println(INFO_INSTALLDS_START_SERVER.get());
    }
    else
    {
      println(INFO_INSTALLDS_DO_NOT_START_SERVER.get());
    }
    println();
    println();
    Message[] msgs = new Message[] {
        INFO_INSTALLDS_CONFIRM_INSTALL.get(),
        INFO_INSTALLDS_PROVIDE_DATA_AGAIN.get(),
        INFO_INSTALLDS_CANCEL.get()
      };
    MenuBuilder<ConfirmCode> builder = new MenuBuilder<ConfirmCode>(this);
    builder.setPrompt(INFO_INSTALLDS_CONFIRM_INSTALL_PROMPT.get());
    int i=0;
    for (ConfirmCode code : ConfirmCode.values())
    {
      builder.addNumberedOption(msgs[i], MenuResult.success(code));
      i++;
    }
    builder.setDefault(Message.raw(
            String.valueOf(ConfirmCode.CONTINUE.getReturnCode())),
            MenuResult.success(ConfirmCode.CONTINUE));
    Menu<ConfirmCode> menu = builder.toMenu();
    try
    {
      MenuResult<ConfirmCode> m = menu.run();
      if (m.isSuccess())
      {
        returnValue = m.getValue();
      }
      else
      {
        // Should never happen.
        throw new RuntimeException();
      }
    }
    catch (CLIException ce)
    {
      returnValue = ConfirmCode.CANCEL;
      LOG.log(Level.WARNING, "Error reading input: "+ce, ce);
    }
    return returnValue;
  }
  private void resetArguments(UserData uData)
  {
    argParser = new InstallDSArgumentParser(InstallDS.class.getName());
    try
    {
      argParser.initializeArguments();
      argParser.directoryManagerDNArg.setDefaultValue(
          uData.getDirectoryManagerDn());
      argParser.ldapPortArg.setDefaultValue(
          String.valueOf(uData.getServerPort()));
      int jmxPort = uData.getServerJMXPort();
      if (jmxPort != -1)
      {
        argParser.jmxPortArg.setDefaultValue(String.valueOf(jmxPort));
      }
      LinkedList<String> baseDNs = uData.getNewSuffixOptions().getBaseDns();
      if (!baseDNs.isEmpty())
      {
        argParser.baseDNArg.setDefaultValue(baseDNs.getFirst());
      }
      NewSuffixOptions suffixOptions = uData.getNewSuffixOptions();
      lastResetPopulateOption = suffixOptions.getType();
      if (lastResetPopulateOption ==
        NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA)
      {
        lastResetNumEntries = suffixOptions.getNumberEntries();
      }
      else if (lastResetPopulateOption ==
        NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE)
      {
        lastResetImportFile = suffixOptions.getLDIFPaths().getFirst();
        lastResetRejectedFile = suffixOptions.getRejectedFile();
        lastResetSkippedFile = suffixOptions.getSkippedFile();
      }
      SecurityOptions sec = uData.getSecurityOptions();
      if (sec.getEnableSSL())
      {
        argParser.ldapsPortArg.setDefaultValue(
            String.valueOf(sec.getSslPort()));
      }
      lastResetEnableSSL = sec.getEnableSSL();
      lastResetEnableStartTLS = sec.getEnableStartTLS();
      lastResetCertType = sec.getCertificateType();
      if (lastResetCertType == SecurityOptions.CertificateType.JKS ||
          lastResetCertType == SecurityOptions.CertificateType.PKCS11)
      {
        lastResetKeyStorePath = sec.getKeystorePath();
      }
      else
      {
        lastResetKeyStorePath = null;
      }
      lastResetEnableWindowsService = uData.getEnableWindowsService();
      lastResetStartServer = uData.getStartServer();
    }
    catch (Throwable t)
    {
      LOG.log(Level.WARNING, "Error resetting arguments: "+t, t);
    }
  }
}