/*
* JBoss, Home of Professional Open Source
* Copyright 2016, Red Hat, Inc., and individual contributors as indicated
* by the @authors tag.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.as.server.controller.resources;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CAPABILITY_REGISTRY;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CORE_SERVICE;
import java.util.Set;
import org.jboss.as.controller.ObjectListAttributeDefinition;
import org.jboss.as.controller.ObjectTypeAttributeDefinition;
import org.jboss.as.controller.OperationDefinition;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleListAttributeDefinition;
import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.StringListAttributeDefinition;
import org.jboss.as.controller.capability.registry.CapabilityId;
import org.jboss.as.controller.capability.registry.CapabilityRegistration;
import org.jboss.as.controller.capability.registry.CapabilityScope;
import org.jboss.as.controller.capability.registry.ImmutableCapabilityRegistry;
import org.jboss.as.controller.capability.registry.RegistrationPoint;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.server.controller.descriptions.ServerDescriptions;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
/**
* @author Tomaz Cerar (c) 2015 Red Hat Inc.
*/
public class CapabilityRegistryResourceDefinition extends SimpleResourceDefinition {
private static final SimpleListAttributeDefinition DEPENDENT_ADDRESS = new SimpleListAttributeDefinition.
Builder("dependent-address", new SimpleAttributeDefinition("parameter", ModelType.PROPERTY, false)).build();
private static final SimpleAttributeDefinition NAME = SimpleAttributeDefinitionBuilder.create("name", ModelType.STRING)
.setAllowNull(false)
.build();
private static final StringListAttributeDefinition REGISTRATION_POINTS = new StringListAttributeDefinition.Builder("registration-points")
.build();
private static final SimpleAttributeDefinition DYNAMIC = SimpleAttributeDefinitionBuilder.create("dynamic", ModelType.BOOLEAN, false)
.build();
private static final SimpleAttributeDefinition SCOPE = SimpleAttributeDefinitionBuilder.create("scope", ModelType.STRING, true)
.build();
private static final ObjectTypeAttributeDefinition CAPABILITY = new ObjectTypeAttributeDefinition.Builder("capability", NAME, DYNAMIC, SCOPE, REGISTRATION_POINTS)
.build();
private static final ObjectListAttributeDefinition CAPABILITIES = new ObjectListAttributeDefinition.Builder("capabilities", CAPABILITY)
.build();
private static final ObjectTypeAttributeDefinition POSSIBLE_CAPABILITY = new ObjectTypeAttributeDefinition.Builder("possible-capability", NAME, DYNAMIC, REGISTRATION_POINTS)
.build();
private static final ObjectListAttributeDefinition POSSIBLE_CAPABILITIES = new ObjectListAttributeDefinition.Builder("possible-capabilities", POSSIBLE_CAPABILITY)
.build();
private static final OperationDefinition GET_PROVIDER_POINTS = new SimpleOperationDefinitionBuilder("get-provider-points", ServerDescriptions.getResourceDescriptionResolver("core", CAPABILITY_REGISTRY))
.addParameter(NAME)
.setReadOnly()
.setRuntimeOnly()
.setReplyType(ModelType.LIST)
.setReplyValueType(ModelType.STRING)
.build();
private static final OperationDefinition GET_CAPABILITY = new SimpleOperationDefinitionBuilder("get-capability", ServerDescriptions.getResourceDescriptionResolver("core", CAPABILITY_REGISTRY))
.addParameter(NAME)
.addParameter(SCOPE)
.setReadOnly()
.setRuntimeOnly()
.setReplyParameters(CAPABILITY)
.build();
private static final OperationDefinition SUGGEST_CAPABILITIES = new SimpleOperationDefinitionBuilder("suggest-capabilities", ServerDescriptions.getResourceDescriptionResolver("core", CAPABILITY_REGISTRY))
.addParameter(NAME)
.addParameter(DEPENDENT_ADDRESS)
.setReadOnly()
.setRuntimeOnly()
.setReplyType(ModelType.LIST)
.setReplyValueType(ModelType.STRING)
.build();
private final ImmutableCapabilityRegistry capabilityRegistry;
public CapabilityRegistryResourceDefinition(final ImmutableCapabilityRegistry capabilityRegistry) {
super(new Parameters(
PathElement.pathElement(CORE_SERVICE, CAPABILITY_REGISTRY),
ServerDescriptions.getResourceDescriptionResolver("core", CAPABILITY_REGISTRY))
.setRuntime()
);
assert capabilityRegistry != null;
this.capabilityRegistry = capabilityRegistry;
}
@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
resourceRegistration.registerReadOnlyAttribute(POSSIBLE_CAPABILITIES,
(context, operation) -> populateCapabilities(capabilityRegistry.getPossibleCapabilities(), context.getResult(), true));
resourceRegistration.registerReadOnlyAttribute(CAPABILITIES,
(context, operation) -> populateCapabilities(capabilityRegistry.getCapabilities(), context.getResult(), false));
}
private static void populateRegistrationPoints(ModelNode points, Set<RegistrationPoint> registrationPoints) {
for (RegistrationPoint point : registrationPoints) {
points.add(point.getAddress().toCLIStyleString());
}
}
private static void populateCapabilities(Set<CapabilityRegistration<?>> caps, ModelNode res, boolean possible) {
for (CapabilityRegistration cr : caps) {
ModelNode cap = res.add();
cap.get(NAME.getName()).set(cr.getCapabilityName());
cap.get(DYNAMIC.getName()).set(cr.getCapability().isDynamicallyNamed());
if (!possible) {
cap.get(SCOPE.getName()).set(cr.getCapabilityScope().getName());
}
populateRegistrationPoints(cap.get(REGISTRATION_POINTS.getName()), cr.getRegistrationPoints());
}
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(GET_PROVIDER_POINTS, (context, operation) -> {
final ModelNode model = new ModelNode();
NAME.validateAndSet(operation, model);
final String name = NAME.resolveModelAttribute(context, model).asString();
CapabilityId id = new CapabilityId(name, CapabilityScope.GLOBAL); //for possible capabilities it is always global
Set<PathAddress> providerPoints = capabilityRegistry.getPossibleProviderPoints(id);
for (PathAddress point : providerPoints) {
context.getResult().add(point.toCLIStyleString());
}
});
resourceRegistration.registerOperationHandler(GET_CAPABILITY, (context, operation) -> {
final ModelNode model = new ModelNode();
NAME.validateAndSet(operation, model);
SCOPE.validateAndSet(operation, model);
final String name = NAME.resolveModelAttribute(context, model).asString();
final CapabilityScope scope;
if (model.hasDefined(SCOPE.getName())) {
String scopeName = SCOPE.resolveModelAttribute(context, model).asString();
scope = CapabilityScope.Factory.forName(scopeName);
} else {
scope = CapabilityScope.GLOBAL;
}
CapabilityId id = new CapabilityId(name, scope);
CapabilityRegistration reg = capabilityRegistry.getCapability(id);
if (reg!=null) {
ModelNode result = context.getResult();
populateCapabilityRegistration(reg, result);
}
});
resourceRegistration.registerOperationHandler(SUGGEST_CAPABILITIES, (context, operation) -> {
final String name = NAME.resolveModelAttribute(context, operation).asString();
PathAddress address = PathAddress.pathAddress(DEPENDENT_ADDRESS.
resolveModelAttribute(context, operation));
CapabilityScope dependentScope = CapabilityScope.Factory.
create(context.getProcessType(),
address);
Set<String> capabilities = capabilityRegistry.getDynamicCapabilityNames(name, dependentScope);
for(String capability : capabilities) {
context.getResult().add(capability);
}
});
}
private void populateCapabilityRegistration(CapabilityRegistration reg, ModelNode capability) {
populateRegistrationPoints(capability.get(REGISTRATION_POINTS.getName()), reg.getRegistrationPoints());
}
}