opends/src/messages/messages/dsconfig.properties
@@ -101,7 +101,7 @@ retrieved because another client is currently making conflicting \ configuration changes SEVERE_ERR_DSCFG_ERROR_CREATE_MMPE_1032=The %s could not be created because \ the following mandatory properties must be defined: %s the following mandatory properties must be defined: SEVERE_ERR_DSCFG_ERROR_CREATE_MOAEE_1033=The %s could not be created because \ there is already an existing one with the same name SEVERE_ERR_DSCFG_ERROR_CREATE_AUTHZ_1034=The %s could not be created because \ @@ -424,3 +424,18 @@ INFO_EDITOR_PROMPT_SELECT_COMPONENTS_REMOVE_132=Select the %s you wish to remove: INFO_EDITOR_OPTION_CHANGE_TO_DEFAULT_COMPONENT_133=Change it to the default %s: %s INFO_EDITOR_OPTION_CHANGE_TO_COMPONENT_134=Change it to the %s: %s INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT_135=The referenced %s \ called "%s" must be enabled so that it can be used with this %s. Do \ you want to enabled it? SEVERE_ERR_SET_REFERENCED_COMPONENT_DISABLED_136=The modifications to \ the %s cannot be made because it contains a reference to a \ disabled %s SEVERE_ERR_CREATE_REFERENCED_COMPONENT_DISABLED_137=The %s cannot be created \ because it contains a reference to a disabled %s SEVERE_ERR_CREATE_HEADING_MMPE_SINGLE_138=The %s could not be created because the following mandatory property was not defined: SEVERE_ERR_CREATE_HEADING_MMPE_PLURAL_139=The %s could not be created because the following mandatory properties were not defined: SEVERE_ERR_MODIFY_HEADING_MMPE_SINGLE_140=The %s could not be modified because the following mandatory property was not defined: SEVERE_ERR_MODIFY_HEADING_MMPE_PLURAL_141=The %s could not be modified because the following mandatory properties were not defined: INFO_DSCFG_PROMPT_EDIT_142=Would you like to edit the properties of the %s in order to resolve this problem? SEVERE_ERR_GET_HEADING_MODE_SINGLE_143=The %s could not be decoded due to the following reason: SEVERE_ERR_GET_HEADING_MODE_PLURAL_144=The %s could not be decoded due to the following reasons: opends/src/server/org/opends/server/admin/client/MissingMandatoryPropertiesException.java
@@ -86,21 +86,37 @@ // The causes of this exception. private final Collection<PropertyIsMandatoryException> causes; // Indicates whether the exception occurred during managed object // creation. private final boolean isCreate; // The user friendly name of the component that caused this // exception. private final Message ufn; /** * Creates a new missing mandatory properties exception with the * provided causes. * * @param ufn * The user friendly name of the component that caused this * exception. * @param causes * The causes of this exception (must be non-<code>null</code> * and non-empty). * @param isCreate * Indicates whether the exception occurred during managed * object creation. */ public MissingMandatoryPropertiesException( Collection<PropertyIsMandatoryException> causes) { public MissingMandatoryPropertiesException(Message ufn, Collection<PropertyIsMandatoryException> causes, boolean isCreate) { super(createMessage(causes)); this.causes = new ArrayList<PropertyIsMandatoryException>(causes); this.ufn = ufn; this.isCreate = isCreate; } @@ -128,4 +144,30 @@ return Collections.unmodifiableCollection(causes); } /** * Gets the user friendly name of the component that caused this * exception. * * @return Returns the user friendly name of the component that * caused this exception. */ public Message getUserFriendlyName() { return ufn; } /** * Indicates whether or not this exception was thrown during managed * object creation or during modification. * * @return Returns <code>true</code> if this exception was thrown * during managed object creation. */ public boolean isCreate() { return isCreate; } } opends/src/server/org/opends/server/admin/client/OperationRejectedException.java
@@ -57,6 +57,26 @@ public class OperationRejectedException extends AdminClientException { /** * The type of operation that caused this exception. */ public enum OperationType { /** * A managed object could not be created. */ CREATE, /** * A managed object could not be deleted. */ DELETE, /** * A managed object could not be modified. */ MODIFY; } /** * Serialization ID. */ private static final long serialVersionUID = 8547688890613079044L; @@ -102,14 +122,27 @@ // The messages describing the constraint violations that occurred. private final Collection<Message> messages; // The type of operation that caused this exception. private final OperationType type; // The user friendly name of the component that caused this // exception. private final Message ufn; /** * Creates a new operation rejected exception with a default * message. * * @param type * The type of operation that caused this exception. * @param ufn * The user friendly name of the component that caused this * exception. */ public OperationRejectedException() { this(ERR_OPERATION_REJECTED_DEFAULT.get()); public OperationRejectedException(OperationType type, Message ufn) { this(type, ufn, ERR_OPERATION_REJECTED_DEFAULT.get()); } @@ -118,15 +151,23 @@ * Creates a new operation rejected exception with the provided * messages. * * @param type * The type of operation that caused this exception. * @param ufn * The user friendly name of the component that caused this * exception. * @param messages * The messages describing the constraint violations that * occurred (must be non-<code>null</code> and * non-empty). */ public OperationRejectedException(Collection<Message> messages) { public OperationRejectedException(OperationType type, Message ufn, Collection<Message> messages) { super(getDefaultMessage(messages)); this.messages = new ArrayList<Message>(messages); this.type = type; this.ufn = ufn; } @@ -135,12 +176,18 @@ * Creates a new operation rejected exception with the provided * message. * * @param type * The type of operation that caused this exception. * @param ufn * The user friendly name of the component that caused this * exception. * @param message * The message describing the constraint violation that * occurred. */ public OperationRejectedException(Message message) { this(Collections.singleton(message)); public OperationRejectedException(OperationType type, Message ufn, Message message) { this(type, ufn, Collections.singleton(message)); } @@ -169,4 +216,28 @@ return getSingleMessage(messages); } /** * Gets the type of operation that caused this exception. * * @return Returns the type of operation that caused this exception. */ public OperationType getOperationType() { return type; } /** * Gets the user friendly name of the component that caused this * exception. * * @return Returns the user friendly name of the component that * caused this exception. */ public Message getUserFriendlyName() { return ufn; } } opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
@@ -76,6 +76,7 @@ import org.opends.server.admin.client.ManagedObject; import org.opends.server.admin.client.ManagedObjectDecodingException; import org.opends.server.admin.client.OperationRejectedException; import org.opends.server.admin.client.OperationRejectedException.OperationType; import org.opends.server.admin.client.spi.Driver; import org.opends.server.admin.client.spi.PropertySet; import org.opends.server.admin.std.client.RootCfgClient; @@ -422,11 +423,15 @@ connection.deleteSubtree(dn); } catch (OperationNotSupportedException e) { // Unwilling to perform. AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition(); if (e.getMessage() == null) { throw new OperationRejectedException(); throw new OperationRejectedException(OperationType.DELETE, d .getUserFriendlyName()); } else { Message m = Message.raw("%s", e.getMessage()); throw new OperationRejectedException(m); throw new OperationRejectedException(OperationType.DELETE, d .getUserFriendlyName(), m); } } catch (NamingException e) { adaptNamingException(e); opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -60,6 +60,7 @@ import org.opends.server.admin.client.ConcurrentModificationException; import org.opends.server.admin.client.ManagedObject; import org.opends.server.admin.client.OperationRejectedException; import org.opends.server.admin.client.OperationRejectedException.OperationType; import org.opends.server.admin.client.spi.AbstractManagedObject; import org.opends.server.admin.client.spi.Driver; import org.opends.server.admin.client.spi.Property; @@ -160,6 +161,7 @@ CommunicationException, OperationRejectedException, ConcurrentModificationException, ManagedObjectAlreadyExistsException { // First make sure that the parent managed object still exists. ManagedObjectDefinition<?, ?> d = getManagedObjectDefinition(); ManagedObjectPath<?, ?> path = getManagedObjectPath(); ManagedObjectPath<?, ?> parent = path.parent(); @@ -181,8 +183,7 @@ // TODO: this implementation does not handle relations which // comprise of more than one RDN arc (this will probably never // be required anyway). LdapName dn = LDAPNameBuilder .create(parent, ir, driver.getLDAPProfile()); LdapName dn = LDAPNameBuilder.create(parent, ir, driver.getLDAPProfile()); if (!driver.entryExists(dn)) { // We need to create the entry. Attributes attributes = new BasicAttributes(); @@ -205,10 +206,12 @@ } catch (OperationNotSupportedException e) { // Unwilling to perform. if (e.getMessage() == null) { throw new OperationRejectedException(); throw new OperationRejectedException(OperationType.CREATE, d .getUserFriendlyName()); } else { Message m = Message.raw("%s", e.getMessage()); throw new OperationRejectedException(m); throw new OperationRejectedException(OperationType.CREATE, d .getUserFriendlyName(), m); } } catch (NamingException e) { driver.adaptNamingException(e); @@ -254,10 +257,12 @@ } catch (OperationNotSupportedException e) { // Unwilling to perform. if (e.getMessage() == null) { throw new OperationRejectedException(); throw new OperationRejectedException(OperationType.CREATE, d .getUserFriendlyName()); } else { Message m = Message.raw("%s", e.getMessage()); throw new OperationRejectedException(m); throw new OperationRejectedException(OperationType.CREATE, d .getUserFriendlyName(), m); } } catch (NamingException e) { driver.adaptNamingException(e); @@ -285,12 +290,11 @@ AuthorizationException, CommunicationException { // Build the list of modified attributes. Attributes mods = new BasicAttributes(); ManagedObjectDefinition<?, ?> definition = getManagedObjectDefinition(); for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) { ManagedObjectDefinition<?, ?> d = getManagedObjectDefinition(); for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { Property<?> p = getProperty(pd); if (p.isModified()) { String attrID = driver.getLDAPProfile().getAttributeName(definition, pd); String attrID = driver.getLDAPProfile().getAttributeName(d, pd); Attribute attribute = new BasicAttribute(attrID); encodeProperty(attribute, pd); mods.put(attribute); @@ -308,10 +312,12 @@ } catch (OperationNotSupportedException e) { // Unwilling to perform. if (e.getMessage() == null) { throw new OperationRejectedException(); throw new OperationRejectedException(OperationType.MODIFY, d .getUserFriendlyName()); } else { Message m = Message.raw("%s", e.getMessage()); throw new OperationRejectedException(m); throw new OperationRejectedException(OperationType.MODIFY, d .getUserFriendlyName(), m); } } catch (NamingException e) { // Just treat it as a communication problem. opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
@@ -68,6 +68,7 @@ import org.opends.server.admin.client.ManagementContext; import org.opends.server.admin.client.MissingMandatoryPropertiesException; import org.opends.server.admin.client.OperationRejectedException; import org.opends.server.admin.client.OperationRejectedException.OperationType; @@ -151,7 +152,8 @@ } if (!exceptions.isEmpty()) { throw new MissingMandatoryPropertiesException(exceptions); throw new MissingMandatoryPropertiesException(definition .getUserFriendlyName(), exceptions, !existsOnServer); } // Now enforce any constraints. @@ -175,7 +177,13 @@ } if (!isAcceptable) { throw new OperationRejectedException(messages); if (existsOnServer) { throw new OperationRejectedException(OperationType.MODIFY, definition .getUserFriendlyName(), messages); } else { throw new OperationRejectedException(OperationType.CREATE, definition .getUserFriendlyName(), messages); } } // Commit the managed object. opends/src/server/org/opends/server/admin/client/spi/Driver.java
@@ -69,6 +69,7 @@ import org.opends.server.admin.client.ManagedObjectDecodingException; import org.opends.server.admin.client.ManagementContext; import org.opends.server.admin.client.OperationRejectedException; import org.opends.server.admin.client.OperationRejectedException.OperationType; import org.opends.server.admin.std.client.RootCfgClient; @@ -783,7 +784,8 @@ } if (!isAcceptable) { throw new OperationRejectedException(messages); throw new OperationRejectedException(OperationType.DELETE, d .getUserFriendlyName(), messages); } deleteManagedObject(path); opends/src/server/org/opends/server/tools/dsconfig/ArgumentExceptionFactory.java
@@ -44,10 +44,15 @@ import org.opends.server.admin.PropertyIsSingleValuedException; import org.opends.server.admin.RelationDefinition; import org.opends.server.admin.client.IllegalManagedObjectNameException; import org.opends.server.admin.client.ManagedObjectDecodingException; import org.opends.server.admin.client.MissingMandatoryPropertiesException; import org.opends.server.admin.client.OperationRejectedException; import org.opends.server.util.args.Argument; import org.opends.server.util.args.ArgumentException; import org.opends.server.util.cli.CLIException; import org.opends.server.util.cli.ConsoleApplication; import org.opends.server.util.table.TableBuilder; import org.opends.server.util.table.TextTablePrinter; @@ -103,35 +108,6 @@ /** * Creates an argument exception from a missing mandatory properties * exception. * * @param e * The missing mandatory properties exception. * @param d * The managed object definition. * @return Returns an argument exception. */ public static ArgumentException adaptMissingMandatoryPropertiesException( MissingMandatoryPropertiesException e, AbstractManagedObjectDefinition<?, ?> d) { StringBuilder builder = new StringBuilder(); boolean isFirst = true; for (PropertyIsMandatoryException pe : e.getCauses()) { if (!isFirst) { builder.append(", "); } builder.append(pe.getPropertyDefinition().getName()); isFirst = false; } Message msg = ERR_DSCFG_ERROR_CREATE_MMPE.get( d.getUserFriendlyName(), builder.toString()); return new ArgumentException(msg); } /** * Creates an argument exception from a property exception. * * @param e @@ -172,6 +148,150 @@ /** * Displays a table listing reasons why a managed object could not * be decoded successfully. * * @param app * The console application. * @param e * The managed object decoding exception. */ public static void displayManagedObjectDecodingException( ConsoleApplication app, ManagedObjectDecodingException e) { AbstractManagedObjectDefinition<?, ?> d = e.getPartialManagedObject() .getManagedObjectDefinition(); Message ufn = d.getUserFriendlyName(); Message msg; if (e.getCauses().size() == 1) { msg = ERR_GET_HEADING_MODE_SINGLE.get(ufn); } else { msg = ERR_GET_HEADING_MODE_PLURAL.get(ufn); } app.println(msg); app.println(); TableBuilder builder = new TableBuilder(); for (PropertyException pe : e.getCauses()) { ArgumentException ae = adaptPropertyException(pe, d); builder.startRow(); builder.appendCell("*"); builder.appendCell(ae.getMessage()); } TextTablePrinter printer = new TextTablePrinter(app.getErrorStream()); printer.setDisplayHeadings(false); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); } /** * Displays a table listing missing mandatory properties. * * @param app * The console application. * @param e * The missing mandatory property exception. */ public static void displayMissingMandatoryPropertyException( ConsoleApplication app, MissingMandatoryPropertiesException e) { Message ufn = e.getUserFriendlyName(); Message msg; if (e.isCreate()) { if (e.getCauses().size() == 1) { msg = ERR_CREATE_HEADING_MMPE_SINGLE.get(ufn); } else { msg = ERR_CREATE_HEADING_MMPE_PLURAL.get(ufn); } } else { if (e.getCauses().size() == 1) { msg = ERR_MODIFY_HEADING_MMPE_SINGLE.get(ufn); } else { msg = ERR_MODIFY_HEADING_MMPE_PLURAL.get(ufn); } } app.println(msg); app.println(); TableBuilder builder = new TableBuilder(); builder.addSortKey(0); builder.appendHeading(INFO_DSCFG_HEADING_PROPERTY_NAME.get()); builder.appendHeading(INFO_DSCFG_HEADING_PROPERTY_SYNTAX.get()); PropertyDefinitionUsageBuilder b = new PropertyDefinitionUsageBuilder(true); for (PropertyIsMandatoryException pe : e.getCauses()) { PropertyDefinition<?> pd = pe.getPropertyDefinition(); builder.startRow(); builder.appendCell(pd.getName()); builder.appendCell(b.getUsage(pd)); } TextTablePrinter printer = new TextTablePrinter(app.getErrorStream()); printer.setDisplayHeadings(true); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); } /** * Displays a table listing the reasons why an operation was * rejected. * * @param app * The console application. * @param e * The operation rejected exception. */ public static void displayOperationRejectedException(ConsoleApplication app, OperationRejectedException e) { Message ufn = e.getUserFriendlyName(); Message msg; switch (e.getOperationType()) { case CREATE: if (e.getMessages().size() == 1) { msg = ERR_DSCFG_ERROR_CREATE_ORE_SINGLE.get(ufn); } else { msg = ERR_DSCFG_ERROR_CREATE_ORE_PLURAL.get(ufn); } break; case DELETE: if (e.getMessages().size() == 1) { msg = ERR_DSCFG_ERROR_DELETE_ORE_SINGLE.get(ufn); } else { msg = ERR_DSCFG_ERROR_DELETE_ORE_PLURAL.get(ufn); } break; default: if (e.getMessages().size() == 1) { msg = ERR_DSCFG_ERROR_MODIFY_ORE_SINGLE.get(ufn); } else { msg = ERR_DSCFG_ERROR_MODIFY_ORE_PLURAL.get(ufn); } break; } app.println(msg); app.println(); TableBuilder builder = new TableBuilder(); for (Message reason : e.getMessages()) { builder.startRow(); builder.appendCell("*"); builder.appendCell(reason); } TextTablePrinter printer = new TextTablePrinter(app.getErrorStream()); printer.setDisplayHeadings(false); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); } /** * Creates an argument exception which should be used when a * property modification argument is incompatible with a previous * modification argument. opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
@@ -29,6 +29,7 @@ import static org.opends.messages.DSConfigMessages.*; import static org.opends.server.tools.dsconfig.ArgumentExceptionFactory.*; import java.util.Collection; import java.util.Collections; @@ -44,6 +45,8 @@ import org.opends.messages.Message; import org.opends.server.admin.AbstractManagedObjectDefinition; import org.opends.server.admin.AggregationPropertyDefinition; import org.opends.server.admin.BooleanPropertyDefinition; import org.opends.server.admin.Configuration; import org.opends.server.admin.ConfigurationClient; import org.opends.server.admin.DefaultBehaviorException; @@ -355,6 +358,285 @@ return new CreateSubCommandHandler<C, S>(parser, p, r, null, p.child(r)); } /** * Create the provided managed object. * * @param app * The console application. * @param context * The management context. * @param mo * The managed object to be created. * @return Returns a MenuResult.success() if the managed object was * created successfully, or MenuResult.quit(), or * MenuResult.cancel(), if the managed object was edited * interactively and the user chose to quit or cancel. * @throws ClientException * If an unrecoverable client exception occurred whilst * interacting with the server. * @throws CLIException * If an error occurred whilst interacting with the * console. */ public static MenuResult<Void> createManagedObject(ConsoleApplication app, ManagementContext context, ManagedObject<?> mo) throws ClientException, CLIException { ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition(); Message ufn = d.getUserFriendlyName(); while (true) { // Interactively set properties if applicable. if (app.isInteractive()) { SortedSet<PropertyDefinition<?>> properties = new TreeSet<PropertyDefinition<?>>(); for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { if (pd.hasOption(PropertyOption.HIDDEN)) { continue; } if (!app.isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) { continue; } properties.add(pd); } PropertyValueEditor editor = new PropertyValueEditor(app, context); MenuResult<Void> result = editor.edit(mo, properties, false); // Interactively enable/edit referenced components. if (result.isSuccess()) { result = checkReferences(app, context, mo); if (result.isAgain()) { // Edit again. continue; } } if (result.isQuit()) { if (!app.isMenuDrivenMode()) { // User chose to cancel any changes. Message msg = INFO_DSCFG_CONFIRM_CREATE_FAIL.get(ufn); app.printVerboseMessage(msg); } return MenuResult.quit(); } else if (result.isCancel()) { return MenuResult.cancel(); } } try { // Create the managed object. mo.commit(); // Output success message. app.println(); Message msg = INFO_DSCFG_CONFIRM_CREATE_SUCCESS.get(ufn); app.printVerboseMessage(msg); return MenuResult.success(); } catch (MissingMandatoryPropertiesException e) { if (app.isInteractive()) { // If interactive, give the user the chance to fix the // problems. app.println(); displayMissingMandatoryPropertyException(app, e); app.println(); if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) { return MenuResult.cancel(); } } else { throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, e .getMessageObject(), e); } } catch (AuthorizationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn); throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg); } catch (ConcurrentModificationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn); throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg); } catch (OperationRejectedException e) { if (app.isInteractive()) { // If interactive, give the user the chance to fix the // problems. app.println(); displayOperationRejectedException(app, e); app.println(); if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) { return MenuResult.cancel(); } } else { throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, e .getMessageObject(), e); } } catch (CommunicationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e.getMessage()); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectAlreadyExistsException e) { Message msg = ERR_DSCFG_ERROR_CREATE_MOAEE.get(ufn); throw new ClientException(LDAPResultCode.ENTRY_ALREADY_EXISTS, msg); } } } // Check that any referenced components are enabled if // required. private static MenuResult<Void> checkReferences(ConsoleApplication app, ManagementContext context, ManagedObject<?> mo) throws ClientException, CLIException { ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition(); Message ufn = d.getUserFriendlyName(); for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { if (pd instanceof AggregationPropertyDefinition) { AggregationPropertyDefinition<?, ?> apd = (AggregationPropertyDefinition<?, ?>) pd; // Skip this aggregation if it doesn't have an enable // property. BooleanPropertyDefinition tpd = apd .getTargetEnabledPropertyDefinition(); if (tpd == null) { continue; } // Skip this aggregation if this managed object's enable // properties are not all true. boolean needsEnabling = true; for (BooleanPropertyDefinition bpd : apd .getSourceEnabledPropertyDefinitions()) { if (!mo.getPropertyValue(bpd)) { needsEnabling = false; break; } } if (!needsEnabling) { continue; } // The referenced component(s) must be enabled. for (String name : mo.getPropertyValues(apd)) { ManagedObjectPath<?, ?> path = apd.getChildPath(name); Message rufn = path.getManagedObjectDefinition() .getUserFriendlyName(); ManagedObject<?> ref; try { ref = context.getManagedObject(path); } catch (AuthorizationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn); throw new ClientException( LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg); } catch (DefinitionDecodingException e) { Message msg = ERR_DSCFG_ERROR_GET_CHILD_DDE.get(rufn, rufn, rufn); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectDecodingException e) { // FIXME: should not abort here. Instead, display the // errors (if verbose) and apply the changes to the // partial managed object. Message msg = ERR_DSCFG_ERROR_GET_CHILD_MODE.get(rufn); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg, e); } catch (CommunicationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e.getMessage()); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectNotFoundException e) { Message msg = ERR_DSCFG_ERROR_GET_CHILD_MONFE.get(rufn); throw new ClientException(LDAPResultCode.NO_SUCH_OBJECT, msg); } while (!ref.getPropertyValue(tpd)) { boolean isBadReference = true; app.println(); if (app.confirmAction( INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT.get(rufn, name, ufn), true)) { ref.setPropertyValue(tpd, true); try { ref.commit(); isBadReference = false; } catch (MissingMandatoryPropertiesException e) { // Give the user the chance to fix the problems. app.println(); displayMissingMandatoryPropertyException(app, e); app.println(); if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) { // FIXME: edit the properties of the referenced // object. MenuResult<Void> result = SetPropSubCommandHandler .modifyManagedObject(app, context, ref); if (result.isQuit()) { return result; } else if (result.isSuccess()) { // The referenced component was modified // successfully, but may still be disabled. isBadReference = false; } } } catch (AuthorizationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn); throw new ClientException( LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg); } catch (ConcurrentModificationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn); throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg); } catch (OperationRejectedException e) { // Give the user the chance to fix the problems. app.println(); displayOperationRejectedException(app, e); app.println(); if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) { MenuResult<Void> result = SetPropSubCommandHandler .modifyManagedObject(app, context, ref); if (result.isQuit()) { return result; } else if (result.isSuccess()) { // The referenced component was modified // successfully, but may still be disabled. isBadReference = false; } } } catch (CommunicationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_CE .get(ufn, e.getMessage()); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectAlreadyExistsException e) { // Should never happen. throw new IllegalStateException(e); } } // If the referenced component is still disabled because // the user refused to modify it, then give the used the // option of editing the referencing component. if (isBadReference) { app.println(); app.println(ERR_SET_REFERENCED_COMPONENT_DISABLED.get(ufn, rufn)); app.println(); if (app .confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) { return MenuResult.again(); } else { return MenuResult.cancel(); } } // If the referenced component is now enabled, then drop out. if (ref.getPropertyValue(tpd)) { break; } } } } } return MenuResult.success(); } // The sub-commands naming arguments. private final List<StringArgument> namingArgs; @@ -642,94 +924,16 @@ setProperty(child, provider, pd); } while (true) { // Interactively set properties if applicable. if (app.isInteractive()) { SortedSet<PropertyDefinition<?>> properties = new TreeSet<PropertyDefinition<?>>(); for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { if (pd.hasOption(PropertyOption.HIDDEN)) { continue; } if (!app.isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) { continue; } properties.add(pd); } PropertyValueEditor editor = new PropertyValueEditor(app, context); MenuResult<Void> result2 = editor.edit(child, properties, true); if (result2.isQuit()) { if (!app.isMenuDrivenMode()) { Message msg = INFO_DSCFG_CONFIRM_CREATE_FAIL.get(ufn); app.printVerboseMessage(msg); } return MenuResult.quit(); } else if (result2.isCancel()) { return MenuResult.cancel(); } } try { // Create the managed object. child.commit(); // Output success message. Message msg = INFO_DSCFG_CONFIRM_CREATE_SUCCESS.get(ufn); app.printVerboseMessage(msg); return MenuResult.success(0); } catch (MissingMandatoryPropertiesException e) { throw ArgumentExceptionFactory.adaptMissingMandatoryPropertiesException( e, d); } catch (AuthorizationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn); throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg); } catch (ManagedObjectAlreadyExistsException e) { Message msg = ERR_DSCFG_ERROR_CREATE_MOAEE.get(ufn); throw new ClientException(LDAPResultCode.ENTRY_ALREADY_EXISTS, msg); } catch (ConcurrentModificationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn); throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg); } catch (OperationRejectedException e) { Message msg; if (e.getMessages().size() == 1) { msg = ERR_DSCFG_ERROR_CREATE_ORE_SINGLE.get(ufn); } else { msg = ERR_DSCFG_ERROR_CREATE_ORE_PLURAL.get(ufn); } if (app.isInteractive()) { // If interactive, give the user the chance to fix the problems. app.println(); app.println(msg); app.println(); TableBuilder builder = new TableBuilder(); for (Message reason : e.getMessages()) { builder.startRow(); builder.appendCell("*"); builder.appendCell(reason); } TextTablePrinter printer = new TextTablePrinter(app.getErrorStream()); printer.setDisplayHeadings(false); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); app.println(); if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) { return MenuResult.cancel(); } } else { throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg, e); } } catch (CommunicationException e) { Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e.getMessage()); throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN, msg); } // Now the command line changes have been made, create the managed // object interacting with the user to fix any problems if // required. MenuResult<Void> result2 = createManagedObject(app, context, child); if (result2.isCancel()) { return MenuResult.cancel(); } else if (result2.isQuit()) { return MenuResult.quit(); } else { return MenuResult.success(0); } } opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
@@ -32,6 +32,7 @@ import static org.opends.messages.ToolMessages.*; import static org.opends.server.loggers.debug.DebugLogger.*; import static org.opends.server.tools.ToolConstants.*; import static org.opends.server.tools.dsconfig.ArgumentExceptionFactory.*; import static org.opends.server.util.StaticUtils.*; import java.io.InputStream; @@ -45,15 +46,14 @@ import java.util.TreeSet; import org.opends.messages.Message; import org.opends.server.admin.AbstractManagedObjectDefinition; import org.opends.server.admin.AttributeTypePropertyDefinition; import org.opends.server.admin.ClassLoaderProvider; import org.opends.server.admin.ClassPropertyDefinition; import org.opends.server.admin.InstantiableRelationDefinition; import org.opends.server.admin.PropertyException; import org.opends.server.admin.RelationDefinition; import org.opends.server.admin.Tag; import org.opends.server.admin.client.ManagedObjectDecodingException; import org.opends.server.admin.client.MissingMandatoryPropertiesException; import org.opends.server.admin.client.OperationRejectedException; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.tools.ClientException; @@ -72,8 +72,6 @@ import org.opends.server.util.cli.MenuCallback; import org.opends.server.util.cli.MenuResult; import org.opends.server.util.cli.OutputStreamConsoleApplication; import org.opends.server.util.table.TableBuilder; import org.opends.server.util.table.TextTablePrinter; @@ -826,50 +824,27 @@ println(e.getMessageObject()); return 1; } catch (ClientException e) { // If the client exception was caused by a decoding exception // then we should display the causes. println(e.getMessageObject()); Throwable cause = e.getCause(); if (cause instanceof ManagedObjectDecodingException) { ManagedObjectDecodingException de = (ManagedObjectDecodingException) cause; println(); TableBuilder builder = new TableBuilder(); for (PropertyException pe : de.getCauses()) { AbstractManagedObjectDefinition<?, ?> d = de .getPartialManagedObject().getManagedObjectDefinition(); ArgumentException ae = ArgumentExceptionFactory .adaptPropertyException(pe, d); builder.startRow(); builder.appendCell("*"); builder.appendCell(ae.getMessage()); } TextTablePrinter printer = new TextTablePrinter(getErrorStream()); printer.setDisplayHeadings(false); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); displayManagedObjectDecodingException(this, de); println(); } else if (cause instanceof MissingMandatoryPropertiesException) { MissingMandatoryPropertiesException mmpe = (MissingMandatoryPropertiesException) cause; println(); displayMissingMandatoryPropertyException(this, mmpe); println(); } else if (cause instanceof OperationRejectedException) { OperationRejectedException ore = (OperationRejectedException) cause; println(); TableBuilder builder = new TableBuilder(); for (Message reason : ore.getMessages()) { builder.startRow(); builder.appendCell("*"); builder.appendCell(reason); } TextTablePrinter printer = new TextTablePrinter(getErrorStream()); printer.setDisplayHeadings(false); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); displayOperationRejectedException(this, ore); println(); } else { // Just display the default message. println(e.getMessageObject()); } return 1; opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
@@ -29,6 +29,7 @@ import static org.opends.messages.DSConfigMessages.*; import static org.opends.server.tools.dsconfig.ArgumentExceptionFactory.*; import java.util.HashMap; import java.util.List; @@ -38,6 +39,8 @@ import java.util.TreeSet; import org.opends.messages.Message; import org.opends.server.admin.AggregationPropertyDefinition; import org.opends.server.admin.BooleanPropertyDefinition; import org.opends.server.admin.DefinitionDecodingException; import org.opends.server.admin.IllegalPropertyValueStringException; import org.opends.server.admin.InstantiableRelationDefinition; @@ -69,8 +72,6 @@ import org.opends.server.util.cli.CLIException; import org.opends.server.util.cli.ConsoleApplication; import org.opends.server.util.cli.MenuResult; import org.opends.server.util.table.TableBuilder; import org.opends.server.util.table.TextTablePrinter; @@ -83,7 +84,7 @@ final class SetPropSubCommandHandler extends SubCommandHandler { /** * Type of modication being performed. * Type of modification being performed. */ private static enum ModificationType { /** @@ -207,6 +208,285 @@ return new SetPropSubCommandHandler(parser, path.child(r), r); } /** * Configure the provided managed object. * * @param app * The console application. * @param context * The management context. * @param mo * The managed object to be configured. * @return Returns a MenuResult.success() if the managed object was * configured successfully, or MenuResult.quit(), or * MenuResult.cancel(), if the managed object was edited * interactively and the user chose to quit or cancel. * @throws ClientException * If an unrecoverable client exception occurred whilst * interacting with the server. * @throws CLIException * If an error occurred whilst interacting with the * console. */ public static MenuResult<Void> modifyManagedObject(ConsoleApplication app, ManagementContext context, ManagedObject<?> mo) throws ClientException, CLIException { ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition(); Message ufn = d.getUserFriendlyName(); while (true) { // Interactively set properties if applicable. if (app.isInteractive()) { SortedSet<PropertyDefinition<?>> properties = new TreeSet<PropertyDefinition<?>>(); for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { if (pd.hasOption(PropertyOption.HIDDEN)) { continue; } if (!app.isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) { continue; } properties.add(pd); } PropertyValueEditor editor = new PropertyValueEditor(app, context); MenuResult<Void> result = editor.edit(mo, properties, false); // Interactively enable/edit referenced components. if (result.isSuccess()) { result = checkReferences(app, context, mo); if (result.isAgain()) { // Edit again. continue; } } if (result.isQuit()) { if (!app.isMenuDrivenMode()) { // User chose to cancel any changes. Message msg = INFO_DSCFG_CONFIRM_MODIFY_FAIL.get(ufn); app.printVerboseMessage(msg); } return MenuResult.quit(); } else if (result.isCancel()) { return MenuResult.cancel(); } } try { // Commit the changes. mo.commit(); // Output success message. app.println(); Message msg = INFO_DSCFG_CONFIRM_MODIFY_SUCCESS.get(ufn); app.printVerboseMessage(msg); return MenuResult.success(); } catch (MissingMandatoryPropertiesException e) { if (app.isInteractive()) { // If interactive, give the user the chance to fix the // problems. app.println(); displayMissingMandatoryPropertyException(app, e); app.println(); if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) { return MenuResult.cancel(); } } else { throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, e .getMessageObject(), e); } } catch (AuthorizationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn); throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg); } catch (ConcurrentModificationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_CME.get(ufn); throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg); } catch (OperationRejectedException e) { if (app.isInteractive()) { // If interactive, give the user the chance to fix the // problems. app.println(); displayOperationRejectedException(app, e); app.println(); if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) { return MenuResult.cancel(); } } else { throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, e .getMessageObject(), e); } } catch (CommunicationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_CE.get(ufn, e.getMessage()); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectAlreadyExistsException e) { // Should never happen. throw new IllegalStateException(e); } } } // Check that any referenced components are enabled if // required. private static MenuResult<Void> checkReferences(ConsoleApplication app, ManagementContext context, ManagedObject<?> mo) throws ClientException, CLIException { ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition(); Message ufn = d.getUserFriendlyName(); for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { if (pd instanceof AggregationPropertyDefinition) { AggregationPropertyDefinition<?, ?> apd = (AggregationPropertyDefinition<?, ?>) pd; // Skip this aggregation if it doesn't have an enable // property. BooleanPropertyDefinition tpd = apd .getTargetEnabledPropertyDefinition(); if (tpd == null) { continue; } // Skip this aggregation if this managed object's enable // properties are not all true. boolean needsEnabling = true; for (BooleanPropertyDefinition bpd : apd .getSourceEnabledPropertyDefinitions()) { if (!mo.getPropertyValue(bpd)) { needsEnabling = false; break; } } if (!needsEnabling) { continue; } // The referenced component(s) must be enabled. for (String name : mo.getPropertyValues(apd)) { ManagedObjectPath<?, ?> path = apd.getChildPath(name); Message rufn = path.getManagedObjectDefinition() .getUserFriendlyName(); ManagedObject<?> ref; try { ref = context.getManagedObject(path); } catch (AuthorizationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn); throw new ClientException( LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg); } catch (DefinitionDecodingException e) { Message msg = ERR_DSCFG_ERROR_GET_CHILD_DDE.get(rufn, rufn, rufn); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectDecodingException e) { // FIXME: should not abort here. Instead, display the // errors (if verbose) and apply the changes to the // partial managed object. Message msg = ERR_DSCFG_ERROR_GET_CHILD_MODE.get(rufn); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg, e); } catch (CommunicationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_CE.get(ufn, e.getMessage()); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectNotFoundException e) { Message msg = ERR_DSCFG_ERROR_GET_CHILD_MONFE.get(rufn); throw new ClientException(LDAPResultCode.NO_SUCH_OBJECT, msg); } while (!ref.getPropertyValue(tpd)) { boolean isBadReference = true; app.println(); if (app.confirmAction( INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT.get(rufn, name, ufn), true)) { ref.setPropertyValue(tpd, true); try { ref.commit(); isBadReference = false; } catch (MissingMandatoryPropertiesException e) { // Give the user the chance to fix the problems. app.println(); displayMissingMandatoryPropertyException(app, e); app.println(); if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) { // FIXME: edit the properties of the referenced // object. MenuResult<Void> result = modifyManagedObject(app, context, ref); if (result.isQuit()) { return result; } else if (result.isSuccess()) { // The referenced component was modified // successfully, but may still be disabled. isBadReference = false; } } } catch (AuthorizationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn); throw new ClientException( LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg); } catch (ConcurrentModificationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_CME.get(ufn); throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg); } catch (OperationRejectedException e) { // Give the user the chance to fix the problems. app.println(); displayOperationRejectedException(app, e); app.println(); if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) { MenuResult<Void> result = modifyManagedObject(app, context, ref); if (result.isQuit()) { return result; } else if (result.isSuccess()) { // The referenced component was modified // successfully, but may still be disabled. isBadReference = false; } } } catch (CommunicationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_CE .get(ufn, e.getMessage()); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectAlreadyExistsException e) { // Should never happen. throw new IllegalStateException(e); } } // If the referenced component is still disabled because // the user refused to modify it, then give the used the // option of editing the referencing component. if (isBadReference) { app.println(); app.println(ERR_SET_REFERENCED_COMPONENT_DISABLED.get(ufn, rufn)); app.println(); if (app .confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) { return MenuResult.again(); } else { return MenuResult.cancel(); } } // If the referenced component is now enabled, then drop out. if (ref.getPropertyValue(tpd)) { break; } } } } } return MenuResult.success(); } // The sub-commands naming arguments. private final List<StringArgument> namingArgs; @@ -509,96 +789,15 @@ } } while (true) { // Interactively set properties if applicable. if (app.isInteractive()) { SortedSet<PropertyDefinition<?>> properties = new TreeSet<PropertyDefinition<?>>(); for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { if (pd.hasOption(PropertyOption.HIDDEN)) { continue; } if (!app.isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) { continue; } properties.add(pd); } PropertyValueEditor editor = new PropertyValueEditor(app, context); MenuResult<Void> result2 = editor.edit(child, properties, false); if (result2.isQuit()) { if (!app.isMenuDrivenMode()) { // User chose to cancel any changes. Message msg = INFO_DSCFG_CONFIRM_MODIFY_FAIL.get(ufn); app.printVerboseMessage(msg); } return MenuResult.quit(); } else if (result2.isCancel()) { return MenuResult.cancel(); } } try { // Commit the changes. child.commit(); // Output success message. Message msg = INFO_DSCFG_CONFIRM_MODIFY_SUCCESS.get(ufn); app.printVerboseMessage(msg); return MenuResult.success(0); } catch (MissingMandatoryPropertiesException e) { throw ArgumentExceptionFactory .adaptMissingMandatoryPropertiesException(e, d); } catch (AuthorizationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn); throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg); } catch (ConcurrentModificationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_CME.get(ufn); throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg); } catch (OperationRejectedException e) { Message msg; if (e.getMessages().size() == 1) { msg = ERR_DSCFG_ERROR_MODIFY_ORE_SINGLE.get(ufn); } else { msg = ERR_DSCFG_ERROR_MODIFY_ORE_PLURAL.get(ufn); } if (app.isInteractive()) { // If interactive, give the user the chance to fix the problems. app.println(); app.println(msg); app.println(); TableBuilder builder = new TableBuilder(); for (Message reason : e.getMessages()) { builder.startRow(); builder.appendCell("*"); builder.appendCell(reason); } TextTablePrinter printer = new TextTablePrinter(app.getErrorStream()); printer.setDisplayHeadings(false); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); app.println(); if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) { return MenuResult.cancel(); } } else { throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg, e); } } catch (CommunicationException e) { Message msg = ERR_DSCFG_ERROR_MODIFY_CE.get(ufn, e.getMessage()); throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg); } catch (ManagedObjectAlreadyExistsException e) { // Should never happen. throw new IllegalStateException(e); } // Now the command line changes have been made, apply the changes // interacting with the user to fix any problems if required. MenuResult<Void> result2 = modifyManagedObject(app, context, child); if (result2.isCancel()){ return MenuResult.cancel(); } else if (result2.isQuit()) { return MenuResult.quit(); } else { return MenuResult.success(0); } }