Search in sources :

Example 26 with Composite

use of org.jboss.hal.dmr.Composite in project console by hal.

the class DeploymentResources method readChildren.

public <T extends DeploymentResource> void readChildren(String subsystem, String resource, DeploymentResourceSupplier<T> supplier, Consumer<List<T>> callback) {
    // /deployment=*/subsystem=<subsystem>:read-children-resources(child-type=<resource>)
    // fails with "WFLYCTL0217: Child resource '\"deployment\" => \"*\"' not found"
    // That's why we use: /deployment=*/subsystem=<subsystem>/<resource>=*:read-resource()
    ResourceAddress deploymentAddress = DEPLOYMENT_TEMPLATE.append(SUBSYSTEM + "=" + subsystem).append(resource + "=*").resolve(statementContext);
    Operation deploymentJobOperation = new Operation.Builder(deploymentAddress, READ_RESOURCE_OPERATION).param(INCLUDE_RUNTIME, true).param(RECURSIVE, true).build();
    ResourceAddress subdeploymentAddress = SUBDEPLOYMENT_TEMPLATE.append(SUBSYSTEM + "=" + subsystem).append(resource + "=*").resolve(statementContext);
    Operation subdeploymentJobOperation = new Operation.Builder(subdeploymentAddress, READ_RESOURCE_OPERATION).param(INCLUDE_RUNTIME, true).param(RECURSIVE, true).build();
    dispatcher.execute(new Composite(deploymentJobOperation, subdeploymentJobOperation), (CompositeResult result) -> {
        List<T> nodes = new ArrayList<>();
        Consumer<ModelNode> nodeConsumer = node -> {
            ResourceAddress address = new ResourceAddress(node.get(ADDRESS));
            nodes.add(supplier.get(address, node.get(RESULT)));
        };
        result.step(0).get(RESULT).asList().forEach(nodeConsumer);
        result.step(1).get(RESULT).asList().forEach(nodeConsumer);
        callback.accept(nodes);
    }, (operation, failure) -> {
        logger.error("Unable to read {}/{} deployment resources: {}", subsystem, resource, failure);
        callback.accept(emptyList());
    });
}
Also used : ModelNode(org.jboss.hal.dmr.ModelNode) Logger(org.slf4j.Logger) CompositeResult(org.jboss.hal.dmr.CompositeResult) Operation(org.jboss.hal.dmr.Operation) StatementContext(org.jboss.hal.meta.StatementContext) Collections.emptyList(java.util.Collections.emptyList) LoggerFactory(org.slf4j.LoggerFactory) ResourceAddress(org.jboss.hal.dmr.ResourceAddress) ArrayList(java.util.ArrayList) Consumer(java.util.function.Consumer) Inject(javax.inject.Inject) Composite(org.jboss.hal.dmr.Composite) List(java.util.List) Dispatcher(org.jboss.hal.dmr.dispatch.Dispatcher) AddressTemplate(org.jboss.hal.meta.AddressTemplate) ModelDescriptionConstants(org.jboss.hal.dmr.ModelDescriptionConstants) Composite(org.jboss.hal.dmr.Composite) ResourceAddress(org.jboss.hal.dmr.ResourceAddress) CompositeResult(org.jboss.hal.dmr.CompositeResult) ArrayList(java.util.ArrayList) Operation(org.jboss.hal.dmr.Operation) ModelNode(org.jboss.hal.dmr.ModelNode)

Example 27 with Composite

use of org.jboss.hal.dmr.Composite in project console by hal.

the class CredentialReference method addCredentialReference.

private void addCredentialReference(String baseId, Metadata crMetadata, String credentialReferenceName, String alternativeName, Supplier<ResourceAddress> address, Callback callback) {
    ResourceAddress fqAddress = address.get();
    if (fqAddress != null) {
        String id = Ids.build(baseId, credentialReferenceName, Ids.ADD);
        Form<ModelNode> form = new ModelNodeForm.Builder<>(id, crMetadata).addOnly().include(STORE, ALIAS, CLEAR_TEXT, TYPE).unsorted().build();
        form.addFormValidation(new CrFormValuesValidation(resources));
        new AddResourceDialog(resources.messages().addResourceTitle(Names.CREDENTIAL_REFERENCE), form, (name, model) -> {
            if (alternativeName != null) {
                Operation undefine = new Operation.Builder(fqAddress, UNDEFINE_ATTRIBUTE_OPERATION).param(NAME, alternativeName).build();
                Operation write = new Operation.Builder(fqAddress, WRITE_ATTRIBUTE_OPERATION).param(NAME, credentialReferenceName).param(VALUE, model).build();
                dispatcher.execute(new Composite(undefine, write), (CompositeResult result) -> {
                    MessageEvent.fire(eventBus, Message.success(resources.messages().addSingleResourceSuccess(Names.CREDENTIAL_REFERENCE)));
                    callback.execute();
                });
            } else {
                ca.add(credentialReferenceName, Names.CREDENTIAL_REFERENCE, fqAddress, model, callback);
            }
        }).show();
    } else {
        MessageEvent.fire(eventBus, Message.error(resources.messages().credentialReferenceAddressError()));
    }
}
Also used : AddResourceDialog(org.jboss.hal.core.mbui.dialog.AddResourceDialog) ModelNode(org.jboss.hal.dmr.ModelNode) Constraint(org.jboss.hal.meta.security.Constraint) MessageEvent(org.jboss.hal.spi.MessageEvent) SHORT_TIMEOUT(org.jboss.hal.resources.UIConstants.SHORT_TIMEOUT) AddResourceDialog(org.jboss.hal.core.mbui.dialog.AddResourceDialog) Supplier(java.util.function.Supplier) ResourceAddress(org.jboss.hal.dmr.ResourceAddress) Inject(javax.inject.Inject) ModelNodeForm(org.jboss.hal.core.mbui.form.ModelNodeForm) FormValidation(org.jboss.hal.ballroom.form.FormValidation) Strings(com.google.common.base.Strings) Message(org.jboss.hal.spi.Message) EmptyState(org.jboss.hal.ballroom.EmptyState) Metadata(org.jboss.hal.meta.Metadata) Names(org.jboss.hal.resources.Names) CompositeResult(org.jboss.hal.dmr.CompositeResult) Operation(org.jboss.hal.dmr.Operation) Ids(org.jboss.hal.resources.Ids) ComplexAttributeOperations(org.jboss.hal.core.ComplexAttributeOperations) EventBus(com.google.web.bindery.event.shared.EventBus) DialogFactory(org.jboss.hal.ballroom.dialog.DialogFactory) Composite(org.jboss.hal.dmr.Composite) LabelBuilder(org.jboss.hal.ballroom.LabelBuilder) Dispatcher(org.jboss.hal.dmr.dispatch.Dispatcher) FormItem(org.jboss.hal.ballroom.form.FormItem) Callback(org.jboss.hal.spi.Callback) Resources(org.jboss.hal.resources.Resources) ModelDescriptionConstants(org.jboss.hal.dmr.ModelDescriptionConstants) ValidationResult(org.jboss.hal.ballroom.form.ValidationResult) Form(org.jboss.hal.ballroom.form.Form) DomGlobal.setTimeout(elemental2.dom.DomGlobal.setTimeout) Composite(org.jboss.hal.dmr.Composite) ResourceAddress(org.jboss.hal.dmr.ResourceAddress) CompositeResult(org.jboss.hal.dmr.CompositeResult) LabelBuilder(org.jboss.hal.ballroom.LabelBuilder) Operation(org.jboss.hal.dmr.Operation) ModelNode(org.jboss.hal.dmr.ModelNode)

Example 28 with Composite

use of org.jboss.hal.dmr.Composite in project console by hal.

the class OperationFactory method fromChangeSet.

/**
 * Turns a change-set into a composite operation containing
 * {@linkplain org.jboss.hal.dmr.ModelDescriptionConstants#WRITE_ATTRIBUTE_OPERATION write-attribute} and
 * {@linkplain org.jboss.hal.dmr.ModelDescriptionConstants#UNDEFINE_ATTRIBUTE_OPERATION undefine-attribute} operations.
 * <p>
 * The composite operation will contain {@linkplain org.jboss.hal.dmr.ModelDescriptionConstants#UNDEFINE_ATTRIBUTE_OPERATION
 * undefine-attribute} operations which reflect the alternative attributes as defined in the specified metadata.
 *
 * @param address the fq address used for the operations
 * @param changeSet the changed values
 * @param metadata the metadata which should contain the attribute definitions of the change-set
 */
public Composite fromChangeSet(ResourceAddress address, Map<String, Object> changeSet, Metadata metadata) {
    // TODO Is it safe to always use ATTRIBUTES as path when calling ResourceDescription methods?
    Map<String, Operation> operations = new HashMap<>();
    HashMap<String, Object> localChanges = new HashMap<>(changeSet);
    ResourceDescription resourceDescription = metadata.getDescription();
    // look for alternatives
    Set<String> conflicts = new HashSet<>();
    Map<String, List<String>> allAlternatives = localChanges.keySet().stream().filter(name -> {
        Object value = changeSet.get(name);
        return !isNullOrEmpty(value);
    }).collect(toMap(identity(), name -> resourceDescription.findAlternatives(ATTRIBUTES, name)));
    allAlternatives.forEach((attribute, alternatives) -> {
        logger.debug("Alternatives resolution for {} -> [{}]", attribute, String.join(", ", alternatives));
        HashSet<String> intersection = new HashSet<>(alternatives);
        intersection.retainAll(changeSet.keySet());
        if (intersection.isEmpty()) {
            // the easy part: no conflicts
            alternatives.forEach(alternative -> {
                boolean alternativeDoesntExist = resourceDescription.findAttribute(ATTRIBUTES, alternative) == null;
                if (resourceDescription.isDeprecated(ATTRIBUTES, alternative) || alternativeDoesntExist) {
                    logger.debug("Skip undefine operations for deprecated or non-existent alternative {}", alternative);
                } else {
                    logger.debug("Add undefine operations for alternative {}", alternative);
                    operations.putIfAbsent(alternative, undefineAttribute(address, alternative));
                    List<String> requires = resourceDescription.findRequires(ATTRIBUTES, alternative);
                    if (!requires.isEmpty()) {
                        logger.debug("Add undefine operations for attributes which require {}: [{}]", alternative, String.join(", ", requires));
                        requires.forEach(r -> operations.putIfAbsent(r, undefineAttribute(address, r)));
                    }
                }
            });
        } else {
            // possible conflicts: one or more alternatives are also in the change-set
            // just collect for now and resolve later
            conflicts.add(attribute);
            conflicts.addAll(intersection);
            logger.debug("Record conflict {} <-> [{}]", attribute, String.join(", ", intersection));
        }
        alternatives.forEach(localChanges::remove);
    });
    if (!conflicts.isEmpty()) {
        // try to resolve conflicts: only one of the conflicting attributes must have a value other than
        // null, empty or default
        logger.debug("Try to resolve conflicts between alternatives [{}]", String.join(", ", conflicts));
        Map<Boolean, List<String>> resolution = conflicts.stream().collect(groupingBy(conflict -> {
            Object value = changeSet.get(conflict);
            return isNullOrEmpty(value) || resourceDescription.isDefaultValue(ATTRIBUTES, conflict, value);
        }));
        List<String> undefine = resolution.getOrDefault(true, Collections.emptyList());
        List<String> write = resolution.getOrDefault(false, Collections.emptyList());
        if (write.size() > 1) {
            logger.error("More than one conflicting alternative attribute which is not null, empty or default: [{}]. This should have been caught by a form validation. Adding the write operations anyway to get an appropriate error message from the server.", String.join(", ", write));
        }
        logger.debug("Add undefine operations for [{}], write operation for [{}]", String.join(", ", undefine), String.join(", ", write));
        undefine.forEach(u -> {
            operations.putIfAbsent(u, undefineAttribute(address, u));
            localChanges.remove(u);
            // process requires of the current undefine attribute
            List<String> requires = resourceDescription.findRequires(ATTRIBUTES, u);
            requires.forEach(ur -> {
                operations.putIfAbsent(ur, undefineAttribute(address, ur));
                localChanges.remove(ur);
            });
        });
        write.forEach(w -> {
            operations.putIfAbsent(w, writeAttribute(address, w, changeSet.get(w), resourceDescription, true));
            localChanges.remove(w);
            List<String> writeAlternatives = resourceDescription.findAlternatives(ATTRIBUTES, w);
            // process alternatives of the current write attribute
            writeAlternatives.forEach(wa -> {
                operations.putIfAbsent(wa, undefineAttribute(address, wa));
                localChanges.remove(wa);
            });
        });
    }
    // handle the remaining attributes
    logger.debug("Process remaining attributes [{}]", String.join(", ", localChanges.keySet()));
    localChanges.forEach((name, value) -> operations.putIfAbsent(name, writeAttribute(address, name, value, resourceDescription, false)));
    return new Composite(operations.values().stream().filter(Objects::nonNull).collect(toList()));
}
Also used : ModelNode(org.jboss.hal.dmr.ModelNode) DEFAULT(org.jboss.hal.dmr.ModelDescriptionConstants.DEFAULT) TYPE(org.jboss.hal.dmr.ModelDescriptionConstants.TYPE) VALUE_TYPE(org.jboss.hal.dmr.ModelDescriptionConstants.VALUE_TYPE) LoggerFactory(org.slf4j.LoggerFactory) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) HashMap(java.util.HashMap) Function(java.util.function.Function) ResourceAddress(org.jboss.hal.dmr.ResourceAddress) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) ModelType(org.jboss.hal.dmr.ModelType) HashSet(java.util.HashSet) BigDecimal(java.math.BigDecimal) Property(org.jboss.hal.dmr.Property) ResourceDescription(org.jboss.hal.meta.description.ResourceDescription) Strings(com.google.common.base.Strings) Collectors.toMap(java.util.stream.Collectors.toMap) VALUE(org.jboss.hal.dmr.ModelDescriptionConstants.VALUE) Map(java.util.Map) Expression(org.jboss.hal.core.expression.Expression) NAME(org.jboss.hal.dmr.ModelDescriptionConstants.NAME) UNDEFINE_ATTRIBUTE_OPERATION(org.jboss.hal.dmr.ModelDescriptionConstants.UNDEFINE_ATTRIBUTE_OPERATION) BigInteger(java.math.BigInteger) EXPRESSIONS_ALLOWED(org.jboss.hal.dmr.ModelDescriptionConstants.EXPRESSIONS_ALLOWED) Metadata(org.jboss.hal.meta.Metadata) Logger(org.slf4j.Logger) ACCESS_TYPE(org.jboss.hal.dmr.ModelDescriptionConstants.ACCESS_TYPE) READ_ONLY(org.jboss.hal.dmr.ModelDescriptionConstants.READ_ONLY) Operation(org.jboss.hal.dmr.Operation) ModelNodeHelper.failSafeList(org.jboss.hal.dmr.ModelNodeHelper.failSafeList) ALTERNATIVES(org.jboss.hal.dmr.ModelDescriptionConstants.ALTERNATIVES) Set(java.util.Set) WRITE_ATTRIBUTE_OPERATION(org.jboss.hal.dmr.ModelDescriptionConstants.WRITE_ATTRIBUTE_OPERATION) NILLABLE(org.jboss.hal.dmr.ModelDescriptionConstants.NILLABLE) Objects(java.util.Objects) Composite(org.jboss.hal.dmr.Composite) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) ATTRIBUTES(org.jboss.hal.dmr.ModelDescriptionConstants.ATTRIBUTES) Function.identity(java.util.function.Function.identity) Collections(java.util.Collections) REQUIRES(org.jboss.hal.dmr.ModelDescriptionConstants.REQUIRES) Composite(org.jboss.hal.dmr.Composite) HashMap(java.util.HashMap) Operation(org.jboss.hal.dmr.Operation) ResourceDescription(org.jboss.hal.meta.description.ResourceDescription) Objects(java.util.Objects) ArrayList(java.util.ArrayList) ModelNodeHelper.failSafeList(org.jboss.hal.dmr.ModelNodeHelper.failSafeList) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) HashSet(java.util.HashSet)

Example 29 with Composite

use of org.jboss.hal.dmr.Composite in project console by hal.

the class OperationFactory method resetResource.

/**
 * Creates a composite operation which resets the attributes of the specified resource. Only attributes which are nillable,
 * w/o alternatives and not read-only will be reset. The composite contains
 * {@linkplain org.jboss.hal.dmr.ModelDescriptionConstants#UNDEFINE_ATTRIBUTE_OPERATION undefine-attribute} operations for
 * each attribute of type {@code EXPRESSION, LIST, OBJECT, PROPERTY} or {@code STRING} and
 * {@linkplain org.jboss.hal.dmr.ModelDescriptionConstants#WRITE_ATTRIBUTE_OPERATION write-attribute} operations for
 * attributes of type {@code BIG_DECIMAL, BIG_INTEGER, BOOLEAN, BYTES, DOUBLE, INT} or {@code LONG} if they have a default
 * value.
 *
 * @param address the fq address used for the operations
 * @param attributes the attributes to reset
 * @param metadata the metadata which should contain the attribute definitions of the change-set
 * @return a composite to reset the attributes or an empty composite if no attributes could be reset.
 */
Composite resetResource(ResourceAddress address, Set<String> attributes, Metadata metadata) {
    List<Operation> operations = new ArrayList<>();
    ResourceDescription description = metadata.getDescription();
    // collect all attributes from the 'requires' list of this attribute
    // HashMultimap<String, String> requires = HashMultimap.create();
    TreeSet<String> requires = new TreeSet<>();
    ModelNode attributesDescription = description.get(ATTRIBUTES);
    attributes.forEach(attribute -> {
        ModelNode attributeDescription = attributesDescription.get(attribute);
        if (attributeDescription != null && attributeDescription.hasDefined(REQUIRES)) {
            failSafeList(attributeDescription, REQUIRES).forEach(node -> requires.add(node.asString()));
        /*
                 * .map(ModelNode::asString) .forEach(requiresName -> { requires.add(requiresName); });
                 */
        }
    });
    attributes.stream().map(attribute -> description.findAttribute(ATTRIBUTES, attribute)).filter(Objects::nonNull).forEach(property -> {
        ModelNode attributeDescription = property.getValue();
        boolean nillable = attributeDescription.hasDefined(NILLABLE) && attributeDescription.get(NILLABLE).asBoolean();
        boolean readOnly = attributeDescription.hasDefined(ACCESS_TYPE) && READ_ONLY.equals(attributeDescription.get(ACCESS_TYPE).asString());
        boolean alternatives = attributeDescription.hasDefined(ALTERNATIVES) && !attributeDescription.get(ALTERNATIVES).asList().isEmpty();
        boolean requiredBy = requires.contains(property.getName());
        if (nillable && !readOnly && !alternatives && !requiredBy) {
            boolean hasDefault = attributeDescription.hasDefined(DEFAULT);
            ModelType type = attributeDescription.get(TYPE).asType();
            switch(type) {
                case BIG_DECIMAL:
                case BIG_INTEGER:
                case BOOLEAN:
                case BYTES:
                case DOUBLE:
                case INT:
                case LONG:
                    if (hasDefault) {
                        operations.add(undefineAttribute(address, property.getName()));
                    }
                    break;
                case EXPRESSION:
                case LIST:
                case OBJECT:
                case PROPERTY:
                case STRING:
                    operations.add(undefineAttribute(address, property.getName()));
                    break;
                case TYPE:
                case UNDEFINED:
                    break;
                default:
                    break;
            }
        }
    });
    return new Composite(operations);
}
Also used : Composite(org.jboss.hal.dmr.Composite) ResourceDescription(org.jboss.hal.meta.description.ResourceDescription) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) ModelType(org.jboss.hal.dmr.ModelType) Operation(org.jboss.hal.dmr.Operation) ModelNode(org.jboss.hal.dmr.ModelNode)

Example 30 with Composite

use of org.jboss.hal.dmr.Composite in project console by hal.

the class ComplexAttributeOperations method reset.

/**
 * Undefines all non required attributes in the specified form. After the attributes in the complex attribute have been
 * undefined a standard success message is fired and the specified callback is executed.
 * <p>
 * If the form contains only required attributes, a warning message is fired and the specified callback is executed.
 *
 * @param complexAttribute the name of the complex attribute
 * @param type the human readable name of the complex attribute
 * @param address the fq address for the operation
 * @param form the form which should be reset
 * @param callback the callback executed after the resource has been saved
 */
@JsIgnore
public <T> void reset(String complexAttribute, String type, ResourceAddress address, Metadata metadata, Form<T> form, Callback callback) {
    Set<String> attributes = stream(form.getBoundFormItems().spliterator(), false).map(FormItem::getName).collect(toSet());
    Composite composite = operationFactory(complexAttribute).resetResource(address, attributes, metadata);
    reset(type, composite, callback);
}
Also used : Composite(org.jboss.hal.dmr.Composite) JsIgnore(jsinterop.annotations.JsIgnore)

Aggregations

Composite (org.jboss.hal.dmr.Composite)81 Operation (org.jboss.hal.dmr.Operation)53 CompositeResult (org.jboss.hal.dmr.CompositeResult)50 ResourceAddress (org.jboss.hal.dmr.ResourceAddress)43 ModelNode (org.jboss.hal.dmr.ModelNode)39 ArrayList (java.util.ArrayList)25 List (java.util.List)24 Dispatcher (org.jboss.hal.dmr.dispatch.Dispatcher)22 AddressTemplate (org.jboss.hal.meta.AddressTemplate)22 ModelDescriptionConstants (org.jboss.hal.dmr.ModelDescriptionConstants)21 StatementContext (org.jboss.hal.meta.StatementContext)20 Inject (javax.inject.Inject)19 EventBus (com.google.web.bindery.event.shared.EventBus)18 Metadata (org.jboss.hal.meta.Metadata)18 Ids (org.jboss.hal.resources.Ids)17 Resources (org.jboss.hal.resources.Resources)17 Message (org.jboss.hal.spi.Message)17 MessageEvent (org.jboss.hal.spi.MessageEvent)17 Collectors.toList (java.util.stream.Collectors.toList)16 Provider (javax.inject.Provider)16