private Object getAttribute( final ResourceAndRegistration reg, final PathAddress address, final ObjectName name, final String attribute, final ResourceAccessControl accessControl) throws ReflectionException, AttributeNotFoundException, InstanceNotFoundException { final ImmutableManagementResourceRegistration registration = getMBeanRegistration(address, reg); final DescriptionProvider provider = registration.getModelDescription(PathAddress.EMPTY_ADDRESS); if (provider == null) { throw MESSAGES.descriptionProviderNotFound(address); } final ModelNode description = provider.getModelDescription(null); final String attributeName = findAttributeName(description.get(ATTRIBUTES), attribute); if (!accessControl.isReadableAttribute(attributeName)) { throw MESSAGES.notAuthorizedToReadAttribute(attributeName); } ModelNode op = new ModelNode(); op.get(OP).set(READ_ATTRIBUTE_OPERATION); op.get(OP_ADDR).set(address.toModelNode()); op.get(NAME).set(attributeName); ModelNode result = execute(op); String error = getFailureDescription(result); if (error != null) { throw new AttributeNotFoundException(error); } return converters.fromModelNode( description.require(ATTRIBUTES).require(attributeName), result.get(RESULT)); }
@Override AttributeAccess getAttributeAccess( final ListIterator<PathElement> iterator, final String attributeName) { if (iterator.hasNext()) { final PathElement next = iterator.next(); final NodeSubregistry subregistry = children.get(next.getKey()); if (subregistry == null) { return null; } return subregistry.getAttributeAccess(iterator, next.getValue(), attributeName); } else { final Map<String, AttributeAccess> snapshot = attributesUpdater.get(this); AttributeAccess access = snapshot.get(attributeName); if (access == null) { // If there is metadata for an attribute but no AttributeAccess, assume RO. Can't // be writable without a registered handler. This opens the possibility that out-of-date // metadata // for attribute "foo" can lead to a read of non-existent-in-model "foo" with // an unexpected undefined value returned. But it removes the possibility of a // dev forgetting to call registry.registerReadOnlyAttribute("foo", null) resulting // in the valid attribute "foo" not being readable final ModelNode desc = descriptionProvider.getModelDescription(null); if (desc.has(ATTRIBUTES) && desc.get(ATTRIBUTES).keys().contains(attributeName)) { access = new AttributeAccess(AccessType.READ_ONLY, Storage.CONFIGURATION, null, null, null); } } return access; } }
/** {@inheritDoc} */ public void execute(OperationContext context, ModelNode operation) { final ImmutableManagementResourceRegistration registry = context.getResourceRegistration(); final PathAddress address = PathAddress.pathAddress(operation.require(OP_ADDR)); final DescriptionProvider descriptionProvider = registry.getModelDescription(address); if (descriptionProvider == null) { context.getFailureDescription().set(new ModelNode()); } else { context.getResult().set(descriptionProvider.getModelDescription(null)); } context.stepCompleted(); }
private void setAttribute( final ResourceAndRegistration reg, final PathAddress address, final ObjectName name, final Attribute attribute, ResourceAccessControl accessControl) throws InvalidAttributeValueException, AttributeNotFoundException, InstanceNotFoundException { final ImmutableManagementResourceRegistration registration = getMBeanRegistration(address, reg); final DescriptionProvider provider = registration.getModelDescription(PathAddress.EMPTY_ADDRESS); if (provider == null) { throw MESSAGES.descriptionProviderNotFound(address); } final ModelNode description = provider.getModelDescription(null); final String attributeName = findAttributeName(description.get(ATTRIBUTES), attribute.getName()); if (!standalone) { throw MESSAGES.attributeNotWritable(attribute); } if (!accessControl.isWritableAttribute(attributeName)) { throw MESSAGES.notAuthorizedToWriteAttribute(attributeName); } ModelNode op = new ModelNode(); op.get(OP).set(WRITE_ATTRIBUTE_OPERATION); op.get(OP_ADDR).set(address.toModelNode()); op.get(NAME).set(attributeName); try { op.get(VALUE) .set( converters.toModelNode( description.require(ATTRIBUTES).require(attributeName), attribute.getValue())); } catch (ClassCastException e) { throw MESSAGES.invalidAttributeType(e, attribute.getName()); } ModelNode result = execute(op); String error = getFailureDescription(result); if (error != null) { // Since read-resource-description does not know the parameters of the operation, i.e. if a // vault expression is used or not, // check the error code // TODO add a separate authorize step where we check ourselves that the operation will pass // authorization? if (isVaultExpression(attribute.getValue()) && error.contains(AUTHORIZED_ERROR)) { throw MESSAGES.notAuthorizedToWriteAttribute(attributeName); } throw new InvalidAttributeValueException(error); } }
@Override public ModelNode getModelDescription(Locale locale) { ModelNode result = mainDescriptionProvider.getModelDescription(locale); ModelNode attrs = result.get(ModelDescriptionConstants.ATTRIBUTES); for (Map.Entry<String, ModelNode> entry : overrideDescriptionProvider.getAttributeOverrideDescriptions(locale).entrySet()) { attrs.get(entry.getKey()).set(entry.getValue()); } ModelNode children = result.get(ModelDescriptionConstants.CHILDREN); for (Map.Entry<String, ModelNode> entry : overrideDescriptionProvider.getChildTypeOverrideDescriptions(locale).entrySet()) { children.get(entry.getKey()).set(entry.getValue()); } return result; }
private MBeanInfoFactory( final ObjectName name, final TypeConverters converters, final ConfiguredDomains configuredDomains, final boolean standalone, final PathAddress address, final ImmutableManagementResourceRegistration resourceRegistration) { this.name = name; this.converters = converters; this.configuredDomains = configuredDomains; this.standalone = standalone; this.legacy = configuredDomains.isLegacyDomain(name); this.resourceRegistration = resourceRegistration; DescriptionProvider provider = resourceRegistration.getModelDescription(PathAddress.EMPTY_ADDRESS); providedDescription = provider != null ? provider.getModelDescription(null) : new ModelNode(); this.pathAddress = address; }
@Override void doExecute(OperationContext context, ModelNode operation) throws OperationFailedException { validator.validate(operation); final String opName = operation.require(OP).asString(); final ModelNode opAddr = operation.get(OP_ADDR); final PathAddress address = PathAddress.pathAddress(opAddr); final int recursiveDepth = operation.get(ModelDescriptionConstants.RECURSIVE_DEPTH).asInt(0); final boolean recursive = recursiveDepth > 0 ? true : operation.get(ModelDescriptionConstants.RECURSIVE).asBoolean(false); final boolean queryRuntime = operation.get(ModelDescriptionConstants.INCLUDE_RUNTIME).asBoolean(false); final boolean proxies = operation.get(ModelDescriptionConstants.PROXIES).asBoolean(false); final boolean aliases = operation.get(ModelDescriptionConstants.INCLUDE_ALIASES).asBoolean(false); final boolean defaults = operation.get(ModelDescriptionConstants.INCLUDE_DEFAULTS).asBoolean(true); final boolean attributesOnly = operation.get(ModelDescriptionConstants.ATTRIBUTES_ONLY).asBoolean(false); // Attributes read directly from the model with no special read handler step in the middle final Map<String, ModelNode> directAttributes = new HashMap<String, ModelNode>(); // Children names read directly from the model with no special read handler step in the middle final Map<String, ModelNode> directChildren = new HashMap<String, ModelNode>(); // Attributes of AccessType.METRIC final Map<String, ModelNode> metrics = queryRuntime ? new HashMap<String, ModelNode>() : Collections.<String, ModelNode>emptyMap(); // Non-AccessType.METRIC attributes with a special read handler registered final Map<String, ModelNode> otherAttributes = new HashMap<String, ModelNode>(); // Child resources recursively read final Map<PathElement, ModelNode> childResources = recursive ? new LinkedHashMap<PathElement, ModelNode>() : Collections.<PathElement, ModelNode>emptyMap(); // We're going to add a bunch of steps that should immediately follow this one. We are going to // add them // in reverse order of how they should execute, as that is the way adding a Stage.IMMEDIATE step // works // Last to execute is the handler that assembles the overall response from the pieces created by // all the other steps final ReadResourceAssemblyHandler assemblyHandler = new ReadResourceAssemblyHandler( directAttributes, metrics, otherAttributes, directChildren, childResources); context.addStep( assemblyHandler, queryRuntime ? OperationContext.Stage.VERIFY : OperationContext.Stage.MODEL, true); final ImmutableManagementResourceRegistration registry = context.getResourceRegistration(); // Get the model for this resource. final Resource resource = nullSafeReadResource(context, registry); final Map<String, Set<String>> childrenByType = registry != null ? GlobalOperationHandlers.getChildAddresses(context, address, registry, resource, null) : Collections.<String, Set<String>>emptyMap(); final ModelNode model = resource.getModel(); if (model.isDefined()) { // Store direct attributes first for (String key : model.keys()) { // In case someone put some garbage in it if (!childrenByType.containsKey(key)) { directAttributes.put(key, model.get(key)); } } } if (defaults) { // get the model description final DescriptionProvider descriptionProvider = registry.getModelDescription(PathAddress.EMPTY_ADDRESS); final Locale locale = GlobalOperationHandlers.getLocale(context, operation); final ModelNode nodeDescription = descriptionProvider.getModelDescription(locale); if (nodeDescription.isDefined() && nodeDescription.hasDefined(ATTRIBUTES)) { for (String key : nodeDescription.get(ATTRIBUTES).keys()) { if ((!childrenByType.containsKey(key)) && (!directAttributes.containsKey(key) || !directAttributes.get(key).isDefined()) && nodeDescription.get(ATTRIBUTES).hasDefined(key) && nodeDescription.get(ATTRIBUTES, key).hasDefined(DEFAULT)) { directAttributes.put(key, nodeDescription.get(ATTRIBUTES, key, DEFAULT)); } } } } if (!attributesOnly) { // Next, process child resources for (Map.Entry<String, Set<String>> entry : childrenByType.entrySet()) { String childType = entry.getKey(); Set<String> children = entry.getValue(); if (children.isEmpty()) { // Just treat it like an undefined attribute directAttributes.put(childType, new ModelNode()); } else { for (String child : children) { if (recursive) { PathElement childPE = PathElement.pathElement(childType, child); PathAddress relativeAddr = PathAddress.pathAddress(childPE); ImmutableManagementResourceRegistration childReg = registry.getSubModel(relativeAddr); if (childReg == null) { throw new OperationFailedException( new ModelNode().set(MESSAGES.noChildRegistry(childType, child))); } // Decide if we want to invoke on this child resource boolean proxy = childReg.isRemote(); boolean runtimeResource = childReg.isRuntimeOnly(); boolean getChild = !runtimeResource || (queryRuntime && !proxy) || (proxies && proxy); if (!aliases && childReg.isAlias()) { getChild = false; } if (getChild) { final int newDepth = recursiveDepth > 0 ? recursiveDepth - 1 : 0; // Add a step to read the child resource ModelNode rrOp = new ModelNode(); rrOp.get(OP).set(opName); rrOp.get(OP_ADDR).set(PathAddress.pathAddress(address, childPE).toModelNode()); rrOp.get(ModelDescriptionConstants.RECURSIVE) .set(operation.get(ModelDescriptionConstants.RECURSIVE)); rrOp.get(ModelDescriptionConstants.RECURSIVE_DEPTH).set(newDepth); rrOp.get(ModelDescriptionConstants.PROXIES).set(proxies); rrOp.get(ModelDescriptionConstants.INCLUDE_RUNTIME).set(queryRuntime); rrOp.get(ModelDescriptionConstants.INCLUDE_ALIASES).set(aliases); rrOp.get(ModelDescriptionConstants.INCLUDE_DEFAULTS).set(defaults); ModelNode rrRsp = new ModelNode(); childResources.put(childPE, rrRsp); OperationStepHandler rrHandler = childReg.getOperationHandler(PathAddress.EMPTY_ADDRESS, opName); context.addStep(rrRsp, rrOp, rrHandler, OperationContext.Stage.MODEL, true); } } else { ModelNode childMap = directChildren.get(childType); if (childMap == null) { childMap = new ModelNode(); childMap.setEmptyObject(); directChildren.put(childType, childMap); } // Add a "child" => undefined childMap.get(child); } } } } } // Last, handle attributes with read handlers registered final Set<String> attributeNames = registry != null ? registry.getAttributeNames(PathAddress.EMPTY_ADDRESS) : Collections.<String>emptySet(); for (final String attributeName : attributeNames) { final AttributeAccess access = registry.getAttributeAccess(PathAddress.EMPTY_ADDRESS, attributeName); if (access == null || access.getFlags().contains(AttributeAccess.Flag.ALIAS) && !aliases) { continue; } else { final AttributeAccess.Storage storage = access.getStorageType(); if (!queryRuntime && storage != AttributeAccess.Storage.CONFIGURATION) { continue; } final AttributeAccess.AccessType type = access.getAccessType(); final OperationStepHandler handler = access.getReadHandler(); if (handler != null) { // Discard any directAttribute map entry for this, as the read handler takes precedence directAttributes.remove(attributeName); // Create the attribute operation final ModelNode attributeOperation = new ModelNode(); attributeOperation.get(OP_ADDR).set(opAddr); attributeOperation.get(OP).set(READ_ATTRIBUTE_OPERATION); attributeOperation.get(GlobalOperationHandlers.NAME.getName()).set(attributeName); final ModelNode attrResponse = new ModelNode(); if (type == AttributeAccess.AccessType.METRIC) { metrics.put(attributeName, attrResponse); } else { otherAttributes.put(attributeName, attrResponse); } context.addStep( attrResponse, attributeOperation, handler, OperationContext.Stage.MODEL, true); } } } context.stepCompleted(); }