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;
    }
  }
Exemple #3
0
    /** {@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();
  }