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

lutoff
04.05.2007 2a10590dbf762f008cf32db42bbb36b0579cb633
This is another commit related to issue
https://opends.dev.java.net/issues/show_bug.cgi?id=1334

This commit implements error handling.
1 files added
7 files modified
644 ■■■■ changed files
opends/src/ads/org/opends/admin/ads/ADSContextException.java 50 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/DsServiceCliAds.java 15 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/DsServiceCliMain.java 68 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/DsServiceCliParser.java 27 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/DsServiceCliReturnCode.java 171 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/DsServiceCliServerGroup.java 81 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/DsServiceCliSubCommandGroup.java 7 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/AdminMessages.java 225 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ADSContextException.java
@@ -27,6 +27,9 @@
package org.opends.admin.ads;
import org.opends.admin.ads.DsServiceCliReturnCode.ReturnCode;
/**
 * This is the exception that is thrown in ADSContext.
 * @see ADSContext.
@@ -47,59 +50,78 @@
    /**
     * The host name is missing.
     */
    MISSING_HOSTNAME,
    MISSING_HOSTNAME(ReturnCode.MISSING_HOSTNAME),
    /**
     * The host name is not valid.
     */
    NOVALID_HOSTNAME,
    NOVALID_HOSTNAME(ReturnCode.NOVALID_HOSTNAME),
    /**
     * The installation path is missing.
     */
    MISSING_IPATH,
    MISSING_IPATH(ReturnCode.MISSING_IPATH),
    /**
     * The installation path is not valid.
     */
    NOVALID_IPATH,
    NOVALID_IPATH(ReturnCode.NOVALID_IPATH),
    /**
     * An access permission error.
     */
    ACCESS_PERMISSION,
    ACCESS_PERMISSION(ReturnCode.ACCESS_PERMISSION),
    /**
     * The entity is already registered.
     */
    ALREADY_REGISTERED,
    ALREADY_REGISTERED(ReturnCode.ALREADY_REGISTERED),
    /**
     * The installation is broken.
     */
    BROKEN_INSTALL,
    BROKEN_INSTALL(ReturnCode.BROKEN_INSTALL),
    /**
     * The entity is not yet registered.
     */
    NOT_YET_REGISTERED,
    NOT_YET_REGISTERED(ReturnCode.NOT_YET_REGISTERED),
    /**
     * The port is missing.
     */
    MISSING_PORT,
    MISSING_PORT(ReturnCode.MISSING_PORT),
    /**
     * The port is not valid.
     */
    NOVALID_PORT,
    NOVALID_PORT(ReturnCode.NOVALID_PORT),
    /**
     * The name is missing.
     */
    MISSING_NAME,
    MISSING_NAME(ReturnCode.MISSING_NAME),
    /**
     * The administration UID is missing.
     */
    MISSING_ADMIN_UID,
    MISSING_ADMIN_UID(ReturnCode.MISSING_ADMIN_UID),
    /**
     * The administratior password is missing.
     */
    MISSING_ADMIN_PASSWORD,
    MISSING_ADMIN_PASSWORD(ReturnCode.MISSING_ADMIN_PASSWORD),
    /**
     * Unexpected error (potential bug).
     */
    ERROR_UNEXPECTED
    ERROR_UNEXPECTED(ReturnCode.ERROR_UNEXPECTED);
    // The corresponding return code.
    private final ReturnCode returnCode;
    // Private constructor.
    private ErrorType(ReturnCode returnCode)
    {
      this.returnCode = returnCode;
    }
    /**
     * Get the corresponding return code.
     *
     * @return The corresponding return code.
     */
    public ReturnCode getReturnCode()
    {
      return returnCode;
    }
  };
  ErrorType error;
opends/src/ads/org/opends/admin/ads/DsServiceCliAds.java
@@ -33,6 +33,7 @@
import java.util.ArrayList;
import java.util.List;
import org.opends.admin.ads.DsServiceCliReturnCode.ReturnCode;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.SubCommand;
@@ -126,13 +127,13 @@
    // Create-ads subcommand
    createAdsSubCmd = new SubCommand(argParser, SubCommandNameEnum.CREATE_ADS
        .toString(), true, 1, 1, OPERAND_BACKEND,
        MSGID_DSSERVICE_SUBCMD_CREATE_ADS_DESCRIPTION);
        MSGID_ADMIN_SUBCMD_CREATE_ADS_DESCRIPTION);
    createAdsSubCmd.setHidden(true);
    // delete-ads
    deleteAdsSubCmd = new SubCommand(argParser,SubCommandNameEnum.DELETE_ADS
        .toString(), true, 1, 1, OPERAND_BACKEND,
        MSGID_DSSERVICE_SUBCMD_DELETE_ADS_DESCRIPTION);
        .toString(),  true, 1, 1, OPERAND_BACKEND,
        MSGID_ADMIN_SUBCMD_DELETE_ADS_DESCRIPTION);
    deleteAdsSubCmd.setHidden(true);
  }
@@ -148,7 +149,7 @@
  /**
   * {@inheritDoc}
   */
  public int performSubCommand(ADSContext adsContext, SubCommand subCmd,
  public ReturnCode performSubCommand(ADSContext adsContext, SubCommand subCmd,
      OutputStream outStream, OutputStream errStream)
      throws ADSContextException
  {
@@ -161,7 +162,7 @@
      adsContext.createAdminData();
      helper.createAdministrationSuffix(adsContext.getDirContext(),
          backendName);
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    else if (subCmd.getName().equals(deleteAdsSubCmd.getName()))
    {
@@ -169,11 +170,11 @@
      ADSContextHelper helper = new ADSContextHelper();
      helper.removeAdministrationSuffix(adsContext.getDirContext(),
          backendName);
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    // Should never occurs: If we are here, it means that the code to
    // handle to subcommand is not yet written.
    return 1;
    return ReturnCode.ERROR_UNEXPECTED;
  }
}
opends/src/ads/org/opends/admin/ads/DsServiceCliMain.java
@@ -42,6 +42,7 @@
import static org.opends.server.messages.ToolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.admin.ads.DsServiceCliReturnCode.*;
/**
@@ -53,7 +54,7 @@
   * The fully-qualified name of this class.
   */
  private static final String CLASS_NAME =
      "org.opends.admin.ads.DsServiceCLI";
      "org.opends.admin.ads.DsServiceCliMain";
  // The print stream to use for standard error.
  private PrintStream err;
@@ -144,12 +145,27 @@
      err = new PrintStream(errStream);
    }
    DsServiceCliMain dsServiceCli = new DsServiceCliMain(out, err);
    return dsServiceCli.execute(args);
  }
  /**
   * Parses the provided command-line arguments and uses that information to
   * run the dsservice tool.
   *
   * @param  args              The command-line arguments provided to this
   *                           program.
   *
   * @return The error code.
   */
  public int execute(String[] args)
  {
    // Create the command-line argument parser for use with this
    // program.
    DsServiceCliParser argParser ;
    try
    {
      String toolDescription = getMessage(MSGID_DSSERVICE_TOOL_DESCRIPTION);
      String toolDescription = getMessage(MSGID_ADMIN_TOOL_DESCRIPTION);
      argParser = new DsServiceCliParser(CLASS_NAME,
          toolDescription, false);
      argParser.initializeParser(out);
@@ -160,7 +176,7 @@
      String message = getMessage(msgID, ae.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
      return ReturnCode.CANNOT_INITIALIZE_ARGS.getReturnCode();
    }
    // Parse the command-line arguments provided to this program.
@@ -175,13 +191,13 @@
      err.println(wrapText(message, MAX_LINE_WIDTH));
      err.println(argParser.getUsage());
      return 1;
      return ReturnCode.ERROR_PARSING_ARGS.getReturnCode();
    }
    // If we should just display usage information, then print it and exit.
    if (argParser.usageOrVersionDisplayed())
    {
      return 0;
      return ReturnCode.SUCCESSFUL.getReturnCode();
    }
    // Get connection parameters
@@ -189,17 +205,12 @@
    String port = argParser.getPort() ;
    String dn   = argParser.getBindDN() ;
    String pwd  = argParser.getBindPassword(dn,out,err) ;
    if (pwd == null)
    {
      // TODO Should we do something?
      return 1;
    }
    // Try to connect
    String ldapUrl = "ldap://"+host+":"+port;
   InitialLdapContext ctx = null;
   int returnCode = 0 ;
   ReturnCode returnCode = ReturnCode.SUCCESSFUL ;
    try
    {
      ctx = ConnectionUtils.createLdapContext(ldapUrl, dn, pwd,
@@ -207,25 +218,25 @@
    }
    catch (NamingException e)
    {
      int    msgID   = MSGID_DSSERVICE_CANNOT_CONNECT_TO_ADS;
      int    msgID   = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
      String message = getMessage(msgID, host);
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
      return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
    }
    ADSContext adsContext = new ADSContext(ctx);
    DirectoryServer.bootstrapClient();
    // perform the subCommand
    ADSContextException adsException = null ;
    try
    {
      returnCode = argParser.performSubCommand(adsContext, out, err);
    }
    catch (ADSContextException e)
    {
      // TODO Print a nice message
      e.printStackTrace();
      returnCode = e.error.ordinal();
      adsException = e;
      returnCode = e.error.getReturnCode();
    }
    // deconnection
@@ -237,6 +248,29 @@
    {
      // TODO Should we do something ?
    }
    return returnCode;
    int msgID = returnCode.getMessageId();
    String message = "" ;
    if ( (returnCode == ReturnCode.SUCCESSFUL)
         ||
         (returnCode == ReturnCode.SUCCESSFUL_NOP))
    {
      if (argParser.isVerbose())
      {
        out.println(wrapText(getMessage(msgID), MAX_LINE_WIDTH));
      }
    }
    else
    if (msgID != -1)
    {
      message = getMessage(MSGID_ADMIN_ERROR);
      message = message + getMessage(msgID);
      err.println(wrapText(message, MAX_LINE_WIDTH));
      if (argParser.isVerbose() && (adsException != null))
      {
        adsException.printStackTrace();
      }
    }
    return returnCode.getReturnCode();
  }
}
opends/src/ads/org/opends/admin/ads/DsServiceCliParser.java
@@ -37,6 +37,7 @@
import java.io.PrintStream;
import java.util.HashSet;
import org.opends.admin.ads.DsServiceCliReturnCode.ReturnCode;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.util.PasswordReader;
@@ -198,7 +199,6 @@
    addGlobalArgument(verboseArg);
  }
  /**
   * Get the host name which has to be used for the command.
   *
@@ -215,7 +215,6 @@
    {
      return hostNameArg.getDefaultValue();
    }
  }
  /**
@@ -234,7 +233,6 @@
    {
      return portArg.getDefaultValue();
    }
  }
  /**
@@ -312,8 +310,8 @@
   *           If there is a problem with when trying to perform the
   *           operation.
   */
  public int performSubCommand(ADSContext adsContext, OutputStream outStream,
      OutputStream errStream)
  public ReturnCode performSubCommand(ADSContext adsContext,
      OutputStream outStream, OutputStream errStream)
    throws ADSContextException
  {
    SubCommand subCmd = getSubCommand();
@@ -329,6 +327,23 @@
    // Should never occurs: If we are here, it means that the code to
    // handle to subcommand is not yet written.
    return 1;
    return ReturnCode.ERROR_UNEXPECTED;
  }
  /**
   * Indicate if the verbose mode is required.
   *
   * @return True if verbose mode is required
   */
  public boolean isVerbose()
  {
    if (verboseArg.isPresent())
    {
      return true;
    }
    else
    {
      return false ;
    }
  }
}
opends/src/ads/org/opends/admin/ads/DsServiceCliReturnCode.java
New file
@@ -0,0 +1,171 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.admin.ads;
import static org.opends.server.messages.AdminMessages.*;
/**
 * This class is handling server group CLI.
 */
public class DsServiceCliReturnCode
{
  /**
   *
   * The enumeration which defines the return code.
   *
   */
  public enum ReturnCode
  {
    /**
     * successful.
     */
    SUCCESSFUL(0, MSGID_ADMIN_SUCCESSFUL),
    /**
     * successful but no operation was performed.
     */
    SUCCESSFUL_NOP(SUCCESSFUL.getReturnCode(), MSGID_ADMIN_SUCCESSFUL_NOP),
    /**
     * Unable to initialze arguments.
     */
    CANNOT_INITIALIZE_ARGS(1, -1),
    /**
     * Cannot parse argument.
     */
    ERROR_PARSING_ARGS(2, -1),
    /**
     * Return code: Cannot get the connection to the ADS.
     */
    CANNOT_CONNECT_TO_ADS(3, -1),
    /**
     * The host name is missing.
     */
    MISSING_HOSTNAME(4, MSGID_ADMIN_MISSING_HOSTNAME),
    /**
     * The host name is not valid.
     */
    NOVALID_HOSTNAME(5, MSGID_ADMIN_NOVALID_HOSTNAME),
    /**
     * The installation path is missing.
     */
    MISSING_IPATH(6, MSGID_ADMIN_MISSING_IPATH),
    /**
     * The installation path is not valid.
     */
    NOVALID_IPATH(7, MSGID_ADMIN_NOVALID_IPATH),
    /**
     * An access permission error.
     */
    ACCESS_PERMISSION(8, MSGID_ADMIN_ACCESS_PERMISSION),
    /**
     * The entity is already registered.
     */
    ALREADY_REGISTERED(9, MSGID_ADMIN_ALREADY_REGISTERED),
    /**
     * The installation is broken.
     */
    BROKEN_INSTALL(10, MSGID_ADMIN_BROKEN_INSTALL),
    /**
     * The entity is not yet registered.
     */
    NOT_YET_REGISTERED(11, MSGID_ADMIN_NOT_YET_REGISTERED),
    /**
     * The port is missing.
     */
    MISSING_PORT(12, MSGID_ADMIN_MISSING_PORT),
    /**
     * The port is not valid.
     */
    NOVALID_PORT(13, MSGID_ADMIN_NOVALID_PORT),
    /**
     * The name is missing.
     */
    MISSING_NAME(14, MSGID_ADMIN_MISSING_NAME),
    /**
     * The administration UID is missing.
     */
    MISSING_ADMIN_UID(15, MSGID_ADMIN_MISSING_ADMIN_UID),
    /**
     * The administratior password is missing.
     */
    MISSING_ADMIN_PASSWORD(16, MSGID_ADMIN_MISSING_ADMIN_PASSWORD),
    /**
     * Unexpected error (potential bug).
     */
    ERROR_UNEXPECTED(17, MSGID_ADMIN_ERROR_UNEXPECTED);
    // The retunCodevalue of the value.
    private final int returnCode;
    // The message id to be used of the value.
    private final int messageId;
    // Private constructor.
    private ReturnCode(int returnCode, int messageId)
    {
      this.returnCode = returnCode;
      this.messageId = messageId;
    }
    /**
     * Get the corresponding message Id.
     *
     * @return The corresponding message Id.
     */
    public int getMessageId()
    {
      return messageId;
    }
    /**
     * Get the corresponding return code value.
     *
     * @return The corresponding return code value.
     */
    public int getReturnCode()
    {
      return returnCode;
    }
  };
}
opends/src/ads/org/opends/admin/ads/DsServiceCliServerGroup.java
@@ -38,8 +38,11 @@
import java.util.Map;
import java.util.Set;
import javax.naming.ldap.Rdn;
import org.opends.admin.ads.ADSContext.ServerGroupProperty;
import org.opends.admin.ads.DsServiceCliReturnCode.ReturnCode;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.StringArgument;
@@ -224,65 +227,65 @@
    // Create-group subcommand
    createGoupSubCmd = new SubCommand(argParser, SubCommandNameEnum.CREATE_GROUP
        .toString(), true, 1, 1, OPERAND_GROUPID,
        MSGID_DSSERVICE_SUBCMD_CREATE_GROUP_DESCRIPTION);
        MSGID_ADMIN_SUBCMD_CREATE_GROUP_DESCRIPTION);
    createGoupDescriptionArg = new StringArgument("description",
        OPTION_SHORT_DESCRIPTION, OPTION_LONG_DESCRIPTION, false, false,
        true, OPTION_VALUE_DESCRIPTION, "", null,
        MSGID_DSSERVICE_ARG_DESCRIPTION_DESCRIPTION);
        MSGID_ADMIN_ARG_DESCRIPTION_DESCRIPTION);
    createGoupSubCmd.addArgument(createGoupDescriptionArg);
    // modify-group
    modifyGroupSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.MODIFY_GROUP.toString(), true, 1, 1,
        OPERAND_GROUPID, MSGID_DSSERVICE_SUBCMD_MODIFY_GROUP_DESCRIPTION);
        OPERAND_GROUPID, MSGID_ADMIN_SUBCMD_MODIFY_GROUP_DESCRIPTION);
    modifyGroupDescriptionArg = new StringArgument("new-description",
        OPTION_SHORT_DESCRIPTION, OPTION_LONG_DESCRIPTION, false, false,
        true, OPTION_VALUE_DESCRIPTION, "", null,
        MSGID_DSSERVICE_ARG_NEW_DESCRIPTION_DESCRIPTION);
        MSGID_ADMIN_ARG_NEW_DESCRIPTION_DESCRIPTION);
    modifyGroupSubCmd.addArgument(modifyGroupDescriptionArg);
    modifyGroupGroupIdArg = new StringArgument("new-groupID",
        OPTION_SHORT_GROUPID, OPTION_LONG_GROUPID, false, false, true,
        OPTION_VALUE_GROUPID, "", null,
        MSGID_DSSERVICE_ARG_NEW_GROUPID_DESCRIPTION);
        MSGID_ADMIN_ARG_NEW_GROUPID_DESCRIPTION);
    modifyGroupSubCmd.addArgument(modifyGroupGroupIdArg);
    // delete-group
    deleteGroupSubCmd = new SubCommand(argParser,SubCommandNameEnum.DELETE_GROUP
        .toString(), true, 1, 1, OPERAND_GROUPID,
        MSGID_DSSERVICE_SUBCMD_DELETE_GROUP_DESCRIPTION);
        MSGID_ADMIN_SUBCMD_DELETE_GROUP_DESCRIPTION);
    // list-groups
    listGroupSubCmd = new SubCommand(argParser, "list-groups",
        MSGID_DSSERVICE_SUBCMD_LIST_GROUPS_DESCRIPTION);
        MSGID_ADMIN_SUBCMD_LIST_GROUPS_DESCRIPTION);
    // add-to-group
    addToGroupSubCmd = new SubCommand(argParser, SubCommandNameEnum.ADD_TO_GROUP
        .toString(), true, 1, 1, OPERAND_GROUPID,
        MSGID_DSSERVICE_SUBCMD_ADD_TO_GROUP_DESCRIPTION);
        MSGID_ADMIN_SUBCMD_ADD_TO_GROUP_DESCRIPTION);
    addToGoupMemberIdArg = new StringArgument("memberID", OPTION_SHORT_MEMBERID,
        OPTION_LONG_MEMBERID, false, false, true, OPTION_VALUE_MEMBERID, "",
        null, MSGID_DSSERVICE_ARG_ADD_MEMBERID_DESCRIPTION);
        null, MSGID_ADMIN_ARG_ADD_MEMBERID_DESCRIPTION);
    addToGroupSubCmd.addArgument(addToGoupMemberIdArg);
    // remove-from-group
    removeFromGroupSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.REMOVE_FROM_GROUP.toString(), true, 1, 1,
        OPERAND_GROUPID, MSGID_DSSERVICE_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION);
        OPERAND_GROUPID, MSGID_ADMIN_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION);
    removeFromGoupMemberIdArg = new StringArgument("memberID",
        OPTION_SHORT_MEMBERID, OPTION_LONG_MEMBERID, false, false, true,
        OPTION_VALUE_MEMBERID, "", null,
        MSGID_DSSERVICE_ARG_REMOVE_MEMBERID_DESCRIPTION);
        MSGID_ADMIN_ARG_REMOVE_MEMBERID_DESCRIPTION);
    removeFromGroupSubCmd.addArgument(removeFromGoupMemberIdArg);
    // list-members
    listMembersSubCmd = new SubCommand(argParser,SubCommandNameEnum.LIST_MEMBERS
        .toString(), true, 1, 1, OPERAND_GROUPID,
        MSGID_DSSERVICE_SUBCMD_LIST_MEMBERS_DESCRIPTION);
        MSGID_ADMIN_SUBCMD_LIST_MEMBERS_DESCRIPTION);
    // list-membership
    listMembershipSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.LIST_MEMBERSHIP.toString(), true, 1, 1,
        OPERAND_MEMBERID, MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION);
        OPERAND_MEMBERID, MSGID_ADMIN_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION);
  }
  /**
@@ -297,7 +300,7 @@
  /**
   * {@inheritDoc}
   */
  public int performSubCommand(ADSContext adsContext, SubCommand subCmd,
  public ReturnCode performSubCommand(ADSContext adsContext, SubCommand subCmd,
      OutputStream outStream, OutputStream errStream)
      throws ADSContextException
  {
@@ -322,7 +325,7 @@
      // Create the group
      adsContext.createServerGroup(serverGroupProperties);
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // delete-group subcommand
@@ -338,7 +341,7 @@
      // Delete the group
      adsContext.deleteServerGroup(serverGroupProperties);
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // list-group subcommand
@@ -391,7 +394,7 @@
      catch (IOException e)
      {
      }
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // modify-group subcommand
@@ -410,7 +413,9 @@
      if (modifyGroupGroupIdArg.isPresent())
      {
        // rename the entry !
        serverGroupProperties.put(ServerGroupProperty.UID, groupId);
        serverGroupProperties.put(ServerGroupProperty.UID,
            modifyGroupGroupIdArg.getValue());
        updateRequired = true;
      }
      else
      {
@@ -447,7 +452,14 @@
            serverGroupPropertiesToRemove);
      }
      return 0;
      if (updateRequired || removeRequired)
      {
        return ReturnCode.SUCCESSFUL;
      }
      else
      {
       return ReturnCode.SUCCESSFUL_NOP;
      }
    }
    // -----------------------
    // add-to-group subcommand
@@ -464,13 +476,19 @@
      {
        memberList = new HashSet<String>();
      }
      memberList.add("cn=" + addToGoupMemberIdArg.getValue());
      String newMember = "cn="
          + Rdn.escapeValue(addToGoupMemberIdArg.getValue());
      if (memberList.contains(newMember))
      {
        return ReturnCode.ALREADY_REGISTERED;
      }
      memberList.add(newMember);
      serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
      // Update the server group
      adsContext.updateServerGroup(groupId, serverGroupProperties);
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // remove-from-group subcommand
@@ -485,14 +503,13 @@
      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
      if (memberList == null)
      {
        // TODO Error message
        return 1;
        return ReturnCode.NOT_YET_REGISTERED;
      }
      String memberToRemove = "cn=" + removeFromGoupMemberIdArg.getValue();
      if (! memberList.contains(memberToRemove))
      String memberToRemove = "cn="
          + Rdn.escapeValue(removeFromGoupMemberIdArg.getValue());
      if (!memberList.contains(memberToRemove))
      {
        // TODO Error message
        return 1;
        return ReturnCode.NOT_YET_REGISTERED;
      }
      memberList.remove(memberToRemove);
@@ -501,7 +518,7 @@
      // Update the server group
      adsContext.updateServerGroup(groupId, serverGroupProperties);
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // list-members subcommand
@@ -514,7 +531,7 @@
      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
      if (memberList == null)
      {
        return 0;
        return ReturnCode.SUCCESSFUL;
      }
      StringBuffer buffer = new StringBuffer();
      for (String member : memberList)
@@ -530,7 +547,7 @@
      {
      }
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // list-membership subcommand
@@ -577,11 +594,11 @@
      catch (IOException e)
      {
      }
      return 0;
      return ReturnCode.SUCCESSFUL;
    }
    // Should never occurs: If we are here, it means that the code to
    // handle to subcommand is not yet written.
    return 1;
    return ReturnCode.ERROR_UNEXPECTED;
  }
}
opends/src/ads/org/opends/admin/ads/DsServiceCliSubCommandGroup.java
@@ -28,6 +28,7 @@
import java.io.OutputStream;
import org.opends.admin.ads.DsServiceCliReturnCode.ReturnCode;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.SubCommand;
@@ -50,7 +51,7 @@
   *           If there is a problem with any of the parameters used
   *           to create this argument.
   */
  public abstract void initializeCliGroup(SubCommandArgumentParser argParser,
  public void initializeCliGroup(SubCommandArgumentParser argParser,
      BooleanArgument verboseArg) throws ArgumentException;
  /**
@@ -60,7 +61,7 @@
   *          The actual subcommand with input parameter.
   * @return True if the provided suncommand is part of this group.
   */
  public abstract boolean isSubCommand(SubCommand subCmd);
  public boolean isSubCommand(SubCommand subCmd);
  /**
   * Handle the subcommand.
@@ -78,7 +79,7 @@
   *           If there is a problem with when trying to perform the
   *           operation.
   */
  public abstract int performSubCommand(ADSContext adsContext,
  public ReturnCode performSubCommand(ADSContext adsContext,
      SubCommand subCmd, OutputStream outStream, OutputStream errStream)
      throws ADSContextException;
opends/src/server/org/opends/server/messages/AdminMessages.java
@@ -202,7 +202,7 @@
   * The message ID for the message that will be used as the description for the
   * dsservice tool.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_TOOL_DESCRIPTION =
  public static final int MSGID_ADMIN_TOOL_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 18;
  /**
@@ -210,7 +210,7 @@
   * create-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_CREATE_GROUP_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_CREATE_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 19;
@@ -218,7 +218,7 @@
   * The message ID for the message that will be used as the description of the
   * "description" argument.  This does take one argument.
   */
  public static final int MSGID_DSSERVICE_ARG_DESCRIPTION_DESCRIPTION =
  public static final int MSGID_ADMIN_ARG_DESCRIPTION_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 20;
  /**
@@ -226,14 +226,14 @@
   * modify-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_MODIFY_GROUP_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_MODIFY_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 21;
  /**
   * The message ID for the message that will be used as the description of the
   * new "description" argument.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_ARG_NEW_DESCRIPTION_DESCRIPTION =
  public static final int MSGID_ADMIN_ARG_NEW_DESCRIPTION_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 22;
@@ -241,7 +241,7 @@
   * The message ID for the message that will be used as the description of the
   * new "groupid" argument.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_ARG_NEW_GROUPID_DESCRIPTION =
  public static final int MSGID_ADMIN_ARG_NEW_GROUPID_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 23;
  /**
@@ -249,7 +249,7 @@
   * delete-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_DELETE_GROUP_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_DELETE_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 24;
  /**
@@ -257,7 +257,7 @@
   * list-groups subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_LIST_GROUPS_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_LIST_GROUPS_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 25;
  /**
@@ -265,14 +265,14 @@
   * add-to-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_ADD_TO_GROUP_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_ADD_TO_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 26;
  /**
   * The message ID for the message that will be used as the description of the
   * added "member-id" argument.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_ARG_ADD_MEMBERID_DESCRIPTION =
  public static final int MSGID_ADMIN_ARG_ADD_MEMBERID_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 27;
  /**
@@ -280,14 +280,14 @@
   * remove-from-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 28;
  /**
   * The message ID for the message that will be used as the description of the
   * removed "member-id" argument.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_ARG_REMOVE_MEMBERID_DESCRIPTION =
  public static final int MSGID_ADMIN_ARG_REMOVE_MEMBERID_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 29;
  /**
@@ -295,7 +295,7 @@
   * list-members subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_LIST_MEMBERS_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_LIST_MEMBERS_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 30;
  /**
@@ -303,22 +303,22 @@
   * list-members subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 31;
  /**
   * The message ID for the message that will be used if the
   * client CLI cannot contact the ADS. This does one take argument.
   */
  public static final int MSGID_DSSERVICE_CANNOT_CONNECT_TO_ADS =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_SEVERE_ERROR | 32;
  public static final int MSGID_ADMIN_CANNOT_CONNECT_TO_ADS =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 32;
  /**
   * The message ID for the message that will be used as the description for the
   * create-ads subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_CREATE_ADS_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_CREATE_ADS_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 33;
  /**
@@ -326,9 +326,129 @@
   * delete-ads subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_DELETE_ADS_DESCRIPTION =
  public static final int MSGID_ADMIN_SUBCMD_DELETE_ADS_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 34;
  /**
   * The message ID for the message that will be used if the hostname of
   * the ADS is missing.
   */
  public static final int MSGID_ADMIN_MISSING_HOSTNAME=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 35;
  /**
   * The message ID for the message that will be used if the hostname of
   * the ADS is not valid.
   */
  public static final int MSGID_ADMIN_NOVALID_HOSTNAME=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 36;
  /**
   * The message ID for the message that will be used if the ipath of
   * the ADS is missing.
   */
  public static final int MSGID_ADMIN_MISSING_IPATH=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 37;
  /**
   * The message ID for the message that will be used if the ipath of
   * the ADS is not valid.
   */
  public static final int MSGID_ADMIN_NOVALID_IPATH=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 38;
  /**
   * The message ID for the message that will be used if we have an
   * access permission error.
   */
  public static final int MSGID_ADMIN_ACCESS_PERMISSION=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 39;
  /**
   * The message ID for the message that will be used if the element is
   * already registered in the ADS.
   */
  public static final int MSGID_ADMIN_ALREADY_REGISTERED=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 40;
  /**
   * The message ID for the message that will be used if the ADS is
   * bot valid.
   */
  public static final int MSGID_ADMIN_BROKEN_INSTALL=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 41;
  /**
   * The message ID for the message that will be used if ADS is not
   * defined in the instance and if we try to perform an admin operation.
   */
  public static final int MSGID_ADMIN_NOT_YET_REGISTERED=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 42;
  /**
   * The message ID for the message that will be used if the port of
   * the ADS is missing.
   */
  public static final int MSGID_ADMIN_MISSING_PORT=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 43;
  /**
   * The message ID for the message that will be used if the port of
   * the ADS is not valid.
   */
  public static final int MSGID_ADMIN_NOVALID_PORT=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 44;
  /**
   * The message ID for the message that will be used if the name of
   * an element is missing.
   */
  public static final int MSGID_ADMIN_MISSING_NAME=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 45;
  /**
   * The message ID for the message that will be used if the admin uid name
   * is missing.
   */
  public static final int MSGID_ADMIN_MISSING_ADMIN_UID=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 46;
  /**
   * The message ID for the message that will be used if the admin password
   * is missing.
   */
  public static final int MSGID_ADMIN_MISSING_ADMIN_PASSWORD=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 47;
  /**
   * The message ID for the message that will be used if an unexpected error
   * occurs.
   */
  public static final int MSGID_ADMIN_ERROR_UNEXPECTED=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_FATAL_ERROR | 48;
  /**
   * The message ID for the message that will be used to indicate that the
   * message is an error message.
   */
  public static final int MSGID_ADMIN_ERROR=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 49;
  /**
   * The message ID for the message that will be used to indicate that the
   * operation is successful.
   */
  public static final int MSGID_ADMIN_SUCCESSFUL=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 50;
  /**
   * The message ID for the message that will be used to indicate that the
   * operation is successful, but nothing was performed.
   */
  public static final int MSGID_ADMIN_SUCCESSFUL_NOP=
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 51;
  // Prevent instantiation.
  private AdminMessages() {
    // Do nothing.
@@ -420,42 +540,77 @@
        "extension %s cannot be loaded because an unexpected error " +
        "occurred while trying to read it:  %s");
    registerMessage(MSGID_DSSERVICE_TOOL_DESCRIPTION,
    registerMessage(MSGID_ADMIN_TOOL_DESCRIPTION,
        "This utility may be used to perform " +
        "operations in the Directory Server administration framework");
    registerMessage(MSGID_DSSERVICE_SUBCMD_CREATE_GROUP_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_CREATE_GROUP_DESCRIPTION,
        "Create a new group of servers");
    registerMessage(MSGID_DSSERVICE_ARG_DESCRIPTION_DESCRIPTION,
    registerMessage(MSGID_ADMIN_ARG_DESCRIPTION_DESCRIPTION,
        "The group description. If not specified, " +
        "the description will be empty");
    registerMessage(MSGID_DSSERVICE_SUBCMD_MODIFY_GROUP_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_MODIFY_GROUP_DESCRIPTION,
        "Modify a group's properties");
    registerMessage(MSGID_DSSERVICE_ARG_NEW_DESCRIPTION_DESCRIPTION,
    registerMessage(MSGID_ADMIN_ARG_NEW_DESCRIPTION_DESCRIPTION,
        "If specified, the new description");
    registerMessage(MSGID_DSSERVICE_ARG_NEW_GROUPID_DESCRIPTION,
    registerMessage(MSGID_ADMIN_ARG_NEW_GROUPID_DESCRIPTION,
        "If specified, the new group's identifier");
    registerMessage(MSGID_DSSERVICE_SUBCMD_DELETE_GROUP_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_DELETE_GROUP_DESCRIPTION,
        "Delete an existing group of servers" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_LIST_GROUPS_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_LIST_GROUPS_DESCRIPTION,
        "List groups that have been defined" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_ADD_TO_GROUP_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_ADD_TO_GROUP_DESCRIPTION,
        "Add a member to a group" );
    registerMessage(MSGID_DSSERVICE_ARG_ADD_MEMBERID_DESCRIPTION,
    registerMessage(MSGID_ADMIN_ARG_ADD_MEMBERID_DESCRIPTION,
        "The member to add" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION,
        "Remove a member from a group" );
    registerMessage(MSGID_DSSERVICE_ARG_REMOVE_MEMBERID_DESCRIPTION,
    registerMessage(MSGID_ADMIN_ARG_REMOVE_MEMBERID_DESCRIPTION,
        "The member to remove" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_LIST_MEMBERS_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_LIST_MEMBERS_DESCRIPTION,
        "List members of the specified group" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION,
        "List groups in which the specified server is a member" );
    registerMessage(MSGID_DSSERVICE_CANNOT_CONNECT_TO_ADS,
    registerMessage(MSGID_ADMIN_CANNOT_CONNECT_TO_ADS,
        "Could not connect to %s. Check that the "+
        "server is running and that the provided credentials are valid");
    registerMessage(MSGID_DSSERVICE_SUBCMD_CREATE_ADS_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_CREATE_ADS_DESCRIPTION,
        "Create a new ADS DN");
    registerMessage(MSGID_DSSERVICE_SUBCMD_DELETE_ADS_DESCRIPTION,
    registerMessage(MSGID_ADMIN_SUBCMD_DELETE_ADS_DESCRIPTION,
         "Delete an existing ADS DN");
    registerMessage(MSGID_ADMIN_MISSING_HOSTNAME,
        "The host name is missing");
    registerMessage(MSGID_ADMIN_NOVALID_HOSTNAME,
        "The host name is not valid");
    registerMessage(MSGID_ADMIN_MISSING_IPATH,
        "The installation path is missing");
    registerMessage(MSGID_ADMIN_NOVALID_IPATH,
        "The installation path is not valid");
    registerMessage(MSGID_ADMIN_ACCESS_PERMISSION,
        "An access permission error occurs");
    registerMessage(MSGID_ADMIN_ALREADY_REGISTERED,
        "The entity is already registered");
    registerMessage(MSGID_ADMIN_BROKEN_INSTALL,
        "The administrative repository is broken");
    registerMessage(MSGID_ADMIN_NOT_YET_REGISTERED,
        "The entity is not yet registered");
    registerMessage(MSGID_ADMIN_MISSING_PORT,
        "The port is missing");
    registerMessage(MSGID_ADMIN_NOVALID_PORT,
        "The port is not vaklid");
    registerMessage(MSGID_ADMIN_MISSING_NAME,
        "The name is missing");
    registerMessage(MSGID_ADMIN_MISSING_ADMIN_UID,
        "The administration UID is missing");
    registerMessage(MSGID_ADMIN_MISSING_ADMIN_PASSWORD,
        "The administratior password is missing");
    registerMessage(MSGID_ADMIN_ERROR_UNEXPECTED,
        "An unexpected error occurs");
    registerMessage(MSGID_ADMIN_ERROR,
        "[error] ");
    registerMessage(MSGID_ADMIN_SUCCESSFUL,
        "The operation has been successfully completed");
    registerMessage(MSGID_ADMIN_SUCCESSFUL_NOP,
       "The operation has been successfully completed, "+
       "but no action was required");
  }
}