package org.jboss.as.subsystem.test; import java.io.Serializable; import java.util.List; import java.util.Map; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.ProcessType; import org.jboss.as.controller.RunningMode; import org.jboss.as.controller.capability.RuntimeCapability; import org.jboss.as.controller.capability.registry.CapabilityScope; import org.jboss.as.controller.capability.registry.RegistrationPoint; import org.jboss.as.controller.capability.registry.RuntimeCapabilityRegistration; import org.jboss.as.controller.capability.registry.RuntimeCapabilityRegistry; import org.jboss.as.controller.extension.ExtensionRegistry; import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.as.controller.registry.Resource; import org.jboss.as.model.test.ModelTestModelDescriptionValidator.AttributeOrParameterArbitraryDescriptorValidator; import org.jboss.as.subsystem.test.ModelDescriptionValidator.ValidationConfiguration; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import org.jboss.msc.service.ServiceTarget; /** * Allows you to additionally initialize the service container and the model controller * beyond the subsystem being tested. Override this class to add behaviour. * * @author <a href="kabir.khan@jboss.com">Kabir Khan</a> */ public class AdditionalInitialization extends AdditionalParsers { public static final AdditionalInitialization MANAGEMENT = new ManagementAdditionalInitialization(); public static final AdditionalInitialization ADMIN_ONLY_HC = new ManagementAdditionalInitialization() { @Override protected ProcessType getProcessType() { return ProcessType.HOST_CONTROLLER; } }; public static class HostControllerAdditionalInitialization extends AdditionalInitialization implements Serializable { private static final long serialVersionUID = -509444465514822866L; @Override protected ProcessType getProcessType() { return ProcessType.HOST_CONTROLLER; } @Override protected RunningMode getRunningMode() { return RunningMode.ADMIN_ONLY; } @Override protected boolean isValidateOperations() { return true; } } /** * An {@code AdditionalInitialization} whose {@link #getRunningMode() running mode} is * {@link org.jboss.as.controller.RunningMode#ADMIN_ONLY} */ public static class ManagementAdditionalInitialization extends AdditionalInitialization implements Serializable { private static final long serialVersionUID = -509444465514822866L; @Override protected RunningMode getRunningMode() { return RunningMode.ADMIN_ONLY; } } /** * Creates a {@link org.jboss.as.subsystem.test.AdditionalInitialization.ManagementAdditionalInitialization} with * the given {@link org.jboss.as.controller.capability.RuntimeCapability capabilities} registered, making it * possible for subsystems under test to require them. No runtime API will be available, but that should not * be needed for a {@link org.jboss.as.controller.RunningMode#ADMIN_ONLY} test. * * @param capabilities the capabilities * @return the additional initialization */ public static AdditionalInitialization withCapabilities(final String... capabilities) { return new ManagementAdditionalInitialization() { @Override protected void initializeExtraSubystemsAndModel(ExtensionRegistry extensionRegistry, Resource rootResource, ManagementResourceRegistration rootRegistration, RuntimeCapabilityRegistry capabilityRegistry) { super.initializeExtraSubystemsAndModel(extensionRegistry, rootResource, rootRegistration, capabilityRegistry); registerCapabilities(capabilityRegistry, capabilities); } }; } /** * Creates a {@link org.jboss.as.subsystem.test.AdditionalInitialization} with * the given {@link org.jboss.as.controller.capability.RuntimeCapability capabilities} registered, making it * possible for subsystems under test to require them. Any runtime API provided in the {@code capabilities} * parameter will be available. * * @param capabilities the capabilities; key is the name of the capability, value is its runtime API * @return the additional initialization */ public static AdditionalInitialization withCapabilities(final Map<String, Object> capabilities) { return new AdditionalInitialization() { @Override protected void initializeExtraSubystemsAndModel(ExtensionRegistry extensionRegistry, Resource rootResource, ManagementResourceRegistration rootRegistration, RuntimeCapabilityRegistry capabilityRegistry) { super.initializeExtraSubystemsAndModel(extensionRegistry, rootResource, rootRegistration, capabilityRegistry); registerCapabilities(capabilityRegistry, capabilities); } }; } public static final AttributeOrParameterArbitraryDescriptorValidator ARBITRARY_DESCRIPTOR_VALIDATOR = (ModelType currentType, ModelNode currentNode, String descriptor) -> null; /** * Creates a {@link org.jboss.as.subsystem.test.AdditionalInitialization} with arbitrary descriptors, making it * possible for subsystems under test to require them. * * @param address * @param operations list of operations the arbitrary descriptors will be used. * @param arbitraryDescriptors the arbitrary descriptors; key is the name of the descriptor, value is its value. * @return the additional initialization */ public static AdditionalInitialization withArbitraryDescriptors(final ModelNode address, final List<String> operations, final Map<String, String> arbitraryDescriptors) { return new AdditionalInitialization() { @Override protected ValidationConfiguration getModelValidationConfiguration() { ValidationConfiguration config = super.getModelValidationConfiguration(); arbitraryDescriptors.entrySet().stream().map((arbitraryDescriptor) -> { config.registerAttributeArbitraryDescriptor(address, arbitraryDescriptor.getKey(), arbitraryDescriptor.getValue(), ARBITRARY_DESCRIPTOR_VALIDATOR); return arbitraryDescriptor; }).forEach((arbitraryDescriptor) -> { operations.stream().forEach((operation) -> { config.registerArbitraryDescriptorForOperation(address, operation, arbitraryDescriptor.getValue(), ARBITRARY_DESCRIPTOR_VALIDATOR); }); }); return config; } }; } /** * Simple utility method to register a * {@link org.jboss.as.controller.capability.RuntimeCapability RuntimeCapability<Void>} for each of the given * capability names. They will be registered against * {@link CapabilityScope#GLOBAL} and with the root resource and no * specific attribute as their {@link org.jboss.as.controller.capability.registry.RegistrationPoint}. * * @param capabilityRegistry registry to use * @param capabilities names of the capabilities. */ public static void registerCapabilities(RuntimeCapabilityRegistry capabilityRegistry, String... capabilities) { for (final String capabilityName : capabilities) { RuntimeCapability<Void> capability = RuntimeCapability.Builder.of(capabilityName).build(); capabilityRegistry.registerCapability(new RuntimeCapabilityRegistration(capability, CapabilityScope.GLOBAL, new RegistrationPoint(PathAddress.EMPTY_ADDRESS, null))); } } /** * Simple utility method to register a * {@link org.jboss.as.controller.capability.RuntimeCapability RuntimeCapability<?>} for each of the given * capability. They will be registered against {@link CapabilityScope#GLOBAL} and with the root resource and no * specific attribute as their {@link org.jboss.as.controller.capability.registry.RegistrationPoint}. * * @param capabilityRegistry registry to use * @param capabilities the capabilities. */ public static void registerCapabilities(RuntimeCapabilityRegistry capabilityRegistry, RuntimeCapability<?>... capabilities) { for (final RuntimeCapability<?> capability : capabilities) { capabilityRegistry.registerCapability(new RuntimeCapabilityRegistration(capability, CapabilityScope.GLOBAL, new RegistrationPoint(PathAddress.EMPTY_ADDRESS, null))); } } /** * Simple utility method to register a {@link org.jboss.as.controller.capability.RuntimeCapability} with the * specified {@link org.jboss.as.controller.capability.RuntimeCapability#getRuntimeAPI() runtime API} * for each of the given capability names. They will be registered against {@link CapabilityScope#GLOBAL} * and with the root resource and no specific attribute as their {@link org.jboss.as.controller.capability.registry.RegistrationPoint}. * * @param capabilityRegistry registry to use * @param capabilities map of names of capabilities to their runtime API implementation. */ public static void registerCapabilities(RuntimeCapabilityRegistry capabilityRegistry, final Map<String, Object> capabilities) { for (Map.Entry<String, Object> entry : capabilities.entrySet()) { final String capabilityName = entry.getKey(); RuntimeCapability<?> capability = createCapability(capabilityName, entry.getValue()); capabilityRegistry.registerCapability(new RuntimeCapabilityRegistration(capability, CapabilityScope.GLOBAL, new RegistrationPoint(PathAddress.EMPTY_ADDRESS, null))); } } /** * Simple utility method to register a {@link org.jboss.as.controller.capability.RuntimeCapability} with the * specified service type for each of the given capability names. They will be registered against * {@link CapabilityScope#GLOBAL} * and with the root resource and no specific attribute as their {@link org.jboss.as.controller.capability.registry.RegistrationPoint}. * * @param capabilityRegistry registry to use * @param capabilities map of names of capabilities to the type exposed by the MSC service the capability installs */ public static void registerServiceCapabilities(RuntimeCapabilityRegistry capabilityRegistry, final Map<String, Class> capabilities) { for (Map.Entry<String, Class> entry : capabilities.entrySet()) { final String capabilityName = entry.getKey(); RuntimeCapability<?> capability = RuntimeCapability.Builder.of(capabilityName, entry.getValue()).build(); capabilityRegistry.registerCapability(new RuntimeCapabilityRegistration(capability, CapabilityScope.GLOBAL, new RegistrationPoint(PathAddress.EMPTY_ADDRESS, null))); } } /** * Simple utility method to register a single {@link org.jboss.as.controller.capability.RuntimeCapability} with the * specified service type for the given capability name. It will be registered against * {@link CapabilityScope#GLOBAL} * and with the root resource and no specific attribute as its {@link org.jboss.as.controller.capability.registry.RegistrationPoint}. * * @param capabilityRegistry registry to use * @param name the names of they capability * @param serviceType the type exposed by the MSC service the capability installs */ public static void registerServiceCapability(RuntimeCapabilityRegistry capabilityRegistry, String name, Class serviceType) { RuntimeCapability<?> capability = RuntimeCapability.Builder.of(name, serviceType).build(); capabilityRegistry.registerCapability(new RuntimeCapabilityRegistration(capability, CapabilityScope.GLOBAL, new RegistrationPoint(PathAddress.EMPTY_ADDRESS, null))); } private static <T> RuntimeCapability<T> createCapability(final String capabilityName, final T api) { return RuntimeCapability.Builder.of(capabilityName, api).build(); } /** * The process type to be used for the installed controller * * @return the process type */ protected ProcessType getProcessType() { return ProcessType.STANDALONE_SERVER; } /** * The running mode to be used for the installed controller when deciding whether to * execute the runtime parts of the operation handlers. e.g. if {@link RunningMode#ADMIN_ONLY} the * runtime parts of the operation handlers should not get called since that will make {@link org.jboss.as.controller.OperationContext#isNormalServer()} * server return {@code false} * * @return the running mode */ protected RunningMode getRunningMode() { return RunningMode.NORMAL; } /** * Whether or not the runtime resources should be registered. If {@link RunningMode#ADMIN_ONLY} the runtime resources will not * get registered since {@link org.jboss.as.controller.ExtensionContext#isRuntimeOnlyRegistrationValid()} will return false. * * @return the running mode */ protected RunningMode getExtensionRegistryRunningMode() { return RunningMode.NORMAL; } /** * Return {@code true} to validate operations against their description provider when executing in the controller. The default is * {@code false} * * @return Whether operations should be validated or not */ protected boolean isValidateOperations() { return true; } /** * Create a registry for extra configuration that should be taken into account when validating the description providers for the subsystem * in the controller. The default is an empty registry. * * @return An ArbitraryDescriptors instance containing the arbitrary descriptors, or {@code null} to not validate the description providers. */ protected ModelDescriptionValidator.ValidationConfiguration getModelValidationConfiguration() { return new ValidationConfiguration(); } /** * Creates the controller initializer. * Override this method to do custom initialization. * * @return the created controller initializer */ protected ControllerInitializer createControllerInitializer() { return new ControllerInitializer(); } /** * Allows easy initialization of commonly used parts of the model and invocation of associated boottime operations * * @param controllerInitializer the controller initializer */ protected void setupController(ControllerInitializer controllerInitializer) { } /** * Adds extra services to the service controller * * @param target the service controller target */ protected void addExtraServices(ServiceTarget target) { } /** * Allows extra initialization of the model and addition of extra subsystems * * @param extensionRegistry allows installation of extra subsystem extensions, call * {@link ExtensionRegistry#getExtensionContext(String, org.jboss.as.controller.registry.ManagementResourceRegistration, boolean)} * and then {@code Extension.initialize(extensionContext)} for each extra extension you have * @param rootResource the root model resource which allows you to for example add child elements to the model * @param rootRegistration the root resource registration which allows you to for example add additional operations to the model * @param capabilityRegistry registry for capabilities and requirements exposed by the extra subsystems */ @SuppressWarnings("deprecation") protected void initializeExtraSubystemsAndModel(ExtensionRegistry extensionRegistry, Resource rootResource, ManagementResourceRegistration rootRegistration, RuntimeCapabilityRegistry capabilityRegistry) { initializeExtraSubystemsAndModel(extensionRegistry, rootResource, rootRegistration); } /** * Allows extra initialization of the model and addition of extra subsystems * * @param extensionRegistry allows installation of extra subsystem extensions, call * {@link ExtensionRegistry#getExtensionContext(String, org.jboss.as.controller.registry.ManagementResourceRegistration, boolean)} * and then {@code Extension.initialize(extensionContext)} for each extra extension you have * @param rootResource the root model resource which allows you to for example add child elements to the model * @param rootRegistration the root resource registration which allows you to for example add additional operations to the model * * @deprecated override {@link #initializeExtraSubystemsAndModel(org.jboss.as.controller.extension.ExtensionRegistry, org.jboss.as.controller.registry.Resource, org.jboss.as.controller.registry.ManagementResourceRegistration, org.jboss.as.controller.capability.registry.RuntimeCapabilityRegistry)} */ @Deprecated protected void initializeExtraSubystemsAndModel(ExtensionRegistry extensionRegistry, Resource rootResource, ManagementResourceRegistration rootRegistration) { } }