diff --git a/cli/src/main/java/org/jboss/as/cli/impl/aesh/cmd/security/model/ElytronUtil.java b/cli/src/main/java/org/jboss/as/cli/impl/aesh/cmd/security/model/ElytronUtil.java index 8c51b590ad7..5121e2b1a05 100644 --- a/cli/src/main/java/org/jboss/as/cli/impl/aesh/cmd/security/model/ElytronUtil.java +++ b/cli/src/main/java/org/jboss/as/cli/impl/aesh/cmd/security/model/ElytronUtil.java @@ -745,9 +745,7 @@ private static ModelNode buildUsersResource(PropertiesRealmConfiguration config) mn.get(Util.RELATIVE_TO).set(config.getRelativeTo()); } mn.get(Util.DIGEST_REALM_NAME).set(config.getExposedRealmName()); - if (config.getPlainText()) { - mn.get(Util.PLAIN_TEXT).set(config.getPlainText()); - } + mn.get(Util.PLAIN_TEXT).set(config.getPlainText()); return mn; } diff --git a/controller/src/main/java/org/jboss/as/controller/ValidateModelStepHandler.java b/controller/src/main/java/org/jboss/as/controller/ValidateModelStepHandler.java index ef8a70c2b0c..57c209ce6d5 100644 --- a/controller/src/main/java/org/jboss/as/controller/ValidateModelStepHandler.java +++ b/controller/src/main/java/org/jboss/as/controller/ValidateModelStepHandler.java @@ -223,11 +223,12 @@ private void validateNestedAttributes(final ModelNode subModel, final ObjectType return; } - final Set keys = subModel.keys(); - final Set definedKeys = new HashSet<>(keys.size()); - for (String key : keys) { - if (subModel.hasDefined(key)) { - definedKeys.add(key); + // only top-level model contains all keys, we have to retrieve keys from the description + final AttributeDefinition[] keys = attr.getValueTypes(); + final Set definedKeys = new HashSet<>(keys.length); + for (AttributeDefinition key : keys) { + if (subModel.hasDefined(key.getName()) || key.getDefaultValue() != null) { + definedKeys.add(key.getName()); } } AttributeDefinition[] subAttrs = attr.getValueTypes(); diff --git a/controller/src/main/java/org/jboss/as/controller/operations/common/Util.java b/controller/src/main/java/org/jboss/as/controller/operations/common/Util.java index f191da994e1..72d82ef5d79 100644 --- a/controller/src/main/java/org/jboss/as/controller/operations/common/Util.java +++ b/controller/src/main/java/org/jboss/as/controller/operations/common/Util.java @@ -9,6 +9,7 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.COMPOSITE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FAILED; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FAILURE_DESCRIPTION; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.INCLUDE_DEFAULTS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR; @@ -161,6 +162,12 @@ public static ModelNode getReadAttributeOperation(final PathAddress address, Str return createAttributeOperation(READ_ATTRIBUTE_OPERATION, address, attributeName); } + public static ModelNode getReadAttributeOperation(final PathAddress address, String attributeName, boolean includeDefaults) { + ModelNode op = getReadAttributeOperation(address, attributeName); + op.get(INCLUDE_DEFAULTS).set(includeDefaults); + return op; + } + public static ModelNode getReadResourceDescriptionOperation(final PathAddress address) { ModelNode op = createEmptyOperation(READ_RESOURCE_DESCRIPTION_OPERATION, address); return op; diff --git a/controller/src/main/java/org/jboss/as/controller/operations/global/AbstractCollectionHandler.java b/controller/src/main/java/org/jboss/as/controller/operations/global/AbstractCollectionHandler.java index 80c3189327e..266b26cbeff 100644 --- a/controller/src/main/java/org/jboss/as/controller/operations/global/AbstractCollectionHandler.java +++ b/controller/src/main/java/org/jboss/as/controller/operations/global/AbstractCollectionHandler.java @@ -99,7 +99,7 @@ public void execute(OperationContext context, ModelNode operation) throws Operat }, OperationContext.Stage.MODEL, true); // 1. read current attribute value - ModelNode readAttributeOperation = Util.getReadAttributeOperation(address, useEnhancedSyntax ? attributeExpression : attributeName); + ModelNode readAttributeOperation = Util.getReadAttributeOperation(address, useEnhancedSyntax ? attributeExpression : attributeName, false); context.addStep(readResponse, readAttributeOperation, ReadAttributeHandler.INSTANCE, OperationContext.Stage.MODEL, true); } else { assert attributeAccess.getStorageType() == AttributeAccess.Storage.RUNTIME; diff --git a/controller/src/main/java/org/jboss/as/controller/operations/global/ReadAttributeHandler.java b/controller/src/main/java/org/jboss/as/controller/operations/global/ReadAttributeHandler.java index 0e0f5addc07..51be88929c5 100644 --- a/controller/src/main/java/org/jboss/as/controller/operations/global/ReadAttributeHandler.java +++ b/controller/src/main/java/org/jboss/as/controller/operations/global/ReadAttributeHandler.java @@ -15,6 +15,9 @@ import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.ExpressionResolver; +import org.jboss.as.controller.ObjectListAttributeDefinition; +import org.jboss.as.controller.ObjectMapAttributeDefinition; +import org.jboss.as.controller.ObjectTypeAttributeDefinition; import org.jboss.as.controller.OperationContext; import org.jboss.as.controller.OperationDefinition; import org.jboss.as.controller.OperationFailedException; @@ -276,6 +279,9 @@ static void resolveAttribute(OperationContext context, AttributeDefinition attri } else if (subModel.hasDefined(attribute.getName())) { final ModelNode result = subModel.get(attribute.getName()); context.getResult().set(result); + if (defaults) { + handleObjectAttributes(context.getResult(), attribute); + } } else if (defaults && attribute.getDefaultValue() != null) { // No defined value in the model. See if we should reply with a default from the metadata, // reply with undefined, or fail because it's a non-existent attribute name @@ -287,6 +293,36 @@ static void resolveAttribute(OperationContext context, AttributeDefinition attri } } + private static void handleObjectAttributes(ModelNode model, AttributeDefinition attribute) { + if (attribute instanceof ObjectTypeAttributeDefinition) { + readNestedDefaults(model, (ObjectTypeAttributeDefinition) attribute); + } else if (attribute instanceof ObjectListAttributeDefinition) { + ObjectTypeAttributeDefinition valueType = ((ObjectListAttributeDefinition) attribute).getValueType(); + for (int i = 0; i < model.asInt(); i++) { + readNestedDefaults(model.get(i), valueType); + } + } else if (attribute instanceof ObjectMapAttributeDefinition) { + ObjectTypeAttributeDefinition valueType = ((ObjectMapAttributeDefinition) attribute).getValueType(); + for (String key : model.keys()) { + readNestedDefaults(model.get(key), valueType); + } + } + } + + private static void readNestedDefaults(ModelNode model, ObjectTypeAttributeDefinition attribute) { + for (AttributeDefinition subAttribute : attribute.getValueTypes()) { + ModelNode defaultValue = subAttribute.getDefaultValue(); + String subAttrName = subAttribute.getName(); + if (defaultValue != null && !model.hasDefined(subAttrName)) { + model.get(subAttrName).set(defaultValue); + } + + if (model.hasDefined(subAttrName)) { + handleObjectAttributes(model.get(subAttrName), subAttribute); + } + } + } + private static class Validator extends ParametersValidator { private static final Validator RESOLVABLE = new Validator(true);