/* * JBoss, Home of Professional Open Source. * Copyright 2016, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ /** * */ package org.jboss.as.controller; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ATTRIBUTES; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.INCLUDE_RUNTIME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_RESOURCE_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESULT; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.as.controller.descriptions.NonResolvingResourceDescriptionResolver; import org.jboss.as.controller.operations.common.Util; import org.jboss.as.controller.operations.global.GlobalNotifications; import org.jboss.as.controller.operations.global.GlobalOperationHandlers; import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.as.controller.registry.Resource; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceContainer; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceTarget; import org.junit.After; import org.junit.Assert; import org.junit.Test; /** * Tests cases for attributes registration. * * Depending on the server environment (process type and running mode), resource attributes * may not be actually registered on the MMR. */ public class MetricsRegistrationTestCase { private static final PathElement ELEMENT = PathElement.pathElement("testing", "resource"); private static final PathAddress ADDRESS = PathAddress.pathAddress(ELEMENT); private static final String TEST_METRIC = "test-metric"; private static final String TEST_METRIC_2 = "test-metric-2"; private static final String TEST_RUNTIME_ATTRIBUTE = "test-runtime-attribute"; private static final String TEST_RUNTIME_ATTRIBUTE_2 = "test-runtime-attribute-2"; private static final Executor executor = Executors.newCachedThreadPool(); private ServiceContainer container; private ModelController controller; private ModelControllerClient client; private void checkMetricRegistration(ProcessType processType, boolean metricIsRegistered) throws Exception { setupController(processType, new TestResourceDefinition()); ModelNode description = getResult(client.execute(Util.getReadResourceDescriptionOperation(ADDRESS))); assertEquals(description.toJSONString(false), metricIsRegistered, description.hasDefined(ATTRIBUTES, TEST_METRIC)); if (metricIsRegistered) { checkAttribute(TEST_METRIC, 1000); } // metric that does not require runtime service is always registered assertTrue(description.hasDefined(ATTRIBUTES, TEST_METRIC_2)); checkAttribute(TEST_METRIC_2, 2000); } private void checkRuntimeAttributeRegistration(ProcessType processType, boolean attributeIsRegistered) throws Exception { setupController(processType, new TestResourceDefinition()); ModelNode rrd = Util.getReadResourceDescriptionOperation(ADDRESS); ModelNode description = getResult(client.execute(rrd)); assertEquals(description.toJSONString(false), attributeIsRegistered, description.hasDefined(ATTRIBUTES, TEST_RUNTIME_ATTRIBUTE)); if (attributeIsRegistered) { checkAttribute(TEST_RUNTIME_ATTRIBUTE, 3000); } // runtime attribute that does not required runtime service is always registered assertTrue(description.hasDefined(ATTRIBUTES, TEST_RUNTIME_ATTRIBUTE_2)); checkAttribute(TEST_RUNTIME_ATTRIBUTE_2, 4000); } @Test public void registerMetricOnEmbeddedServerRegistersIt() throws Exception { checkMetricRegistration(ProcessType.EMBEDDED_SERVER, true); } @Test public void registerMetricOnStandaloneServerRegistersIt() throws Exception { checkMetricRegistration(ProcessType.STANDALONE_SERVER, true); } @Test public void registerMetricOnDomainServerRegistersIt() throws Exception { checkMetricRegistration(ProcessType.DOMAIN_SERVER, true); } @Test public void registerMetricOnHostControllerDoesNotRegisterIt() throws Exception { checkMetricRegistration(ProcessType.HOST_CONTROLLER, false); } @Test public void registerMetricOnEmbeddedHostControllerDoesNotRegisterIt() throws Exception { checkMetricRegistration(ProcessType.EMBEDDED_HOST_CONTROLLER, false); } @Test public void registerRuntimeAttributeOnEmbeddedServerRegistersIt() throws Exception { checkRuntimeAttributeRegistration(ProcessType.EMBEDDED_SERVER, true); } @Test public void registerRuntimeAttributeOnStandaloneServerRegistersIt() throws Exception { checkRuntimeAttributeRegistration(ProcessType.STANDALONE_SERVER, true); } @Test public void registerRuntimeAttributeOnDomainServerRegistersIt() throws Exception { checkRuntimeAttributeRegistration(ProcessType.DOMAIN_SERVER, true); } @Test public void registerRuntimeAttributeOnHostControllerDoesNotRegisterIt() throws Exception { checkRuntimeAttributeRegistration(ProcessType.HOST_CONTROLLER, false); } @Test public void registerRuntimeAttributeOnEmbeddedHostControllerDoesNotRegisterIt() throws Exception { checkRuntimeAttributeRegistration(ProcessType.EMBEDDED_HOST_CONTROLLER, false); } private void checkAttribute(String attributeName, int expectedValue) throws Exception { ModelNode result = getResult(client.execute(Util.getReadAttributeOperation(ADDRESS, attributeName))); assertEquals(expectedValue, result.asInt()); ModelNode rr = Util.createEmptyOperation(READ_RESOURCE_OPERATION, ADDRESS); rr.get(INCLUDE_RUNTIME).set(true); result = getResult(client.execute(rr)); Assert.assertTrue(result.hasDefined(attributeName)); assertEquals(expectedValue, result.get(attributeName).asInt()); } private ModelNode getResult(ModelNode result) { assertEquals(SUCCESS, result.get(OUTCOME).asString()); return result.get(RESULT); } private void checkOperation(String operationName, int expectedValue) throws Exception { ModelNode op = Util.getEmptyOperation(operationName, ADDRESS.toModelNode()); ModelNode result = getResult(client.execute(op)); assertEquals(expectedValue, result.asInt()); } @After public void shutdownServiceContainer() { if (client != null) { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } if (container != null) { container.shutdown(); try { container.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } finally { container = null; } } } private ManagementResourceRegistration setupController(ProcessType processType, TestResourceDefinition resourceDefinition) throws InterruptedException { System.out.println("========= New Test \n"); container = ServiceContainer.Factory.create(TEST_METRIC); ServiceTarget target = container.subTarget(); ModelControllerService svc = new ModelControllerService(processType, resourceDefinition); ServiceBuilder<ModelController> builder = target.addService(ServiceName.of("ModelController"), svc); builder.install(); svc.awaitStartup(30, TimeUnit.SECONDS); controller = svc.getValue(); ModelNode setup = Util.getEmptyOperation("setup", new ModelNode()); controller.execute(setup, null, null, null); client = controller.createClient(executor); return svc.managementControllerResource; } private static class ModelControllerService extends TestModelControllerService { private final TestResourceDefinition resourceDefinition; public ManagementResourceRegistration managementControllerResource; public ModelControllerService(ProcessType processType, TestResourceDefinition resourceDefinition) { super(processType); this.resourceDefinition = resourceDefinition; } @Override protected void initModel(ManagementModel managementModel, Resource modelControllerResource) { ManagementResourceRegistration rootRegistration = managementModel.getRootResourceRegistration(); GlobalOperationHandlers.registerGlobalOperations(rootRegistration, processType); GlobalNotifications.registerGlobalNotifications(rootRegistration, processType); managementControllerResource = rootRegistration.registerSubModel(resourceDefinition); Resource rootResource = managementModel.getRootResource(); rootResource.registerChild(resourceDefinition.getPathElement(), Resource.Factory.create()); } } private static class TestResourceDefinition extends SimpleResourceDefinition { // metric is registered depending on the type of server for the MMR private static final SimpleAttributeDefinition METRIC = new SimpleAttributeDefinitionBuilder(TEST_METRIC, ModelType.INT) .setStorageRuntime() .setUndefinedMetricValue(new ModelNode(0)) .build(); // metric 2 does not require runtime service private static final SimpleAttributeDefinition METRIC_2 = new SimpleAttributeDefinitionBuilder(TEST_METRIC_2, ModelType.INT) .setRuntimeServiceNotRequired() .setUndefinedMetricValue(new ModelNode(0)) .build(); private static final SimpleAttributeDefinition RUNTIME_ATTRIBUTE = new SimpleAttributeDefinitionBuilder(TEST_RUNTIME_ATTRIBUTE, ModelType.INT) .setStorageRuntime() .build(); // runtime attribute 2 does not require runtime service private static final SimpleAttributeDefinition RUNTIME_ATTRIBUTE_2 = new SimpleAttributeDefinitionBuilder(TEST_RUNTIME_ATTRIBUTE_2, ModelType.INT) .setStorageRuntime() .setRuntimeServiceNotRequired() .build(); public TestResourceDefinition() { super(ELEMENT, new NonResolvingResourceDescriptionResolver(), new ModelOnlyAddStepHandler(), new ModelOnlyRemoveStepHandler()); } @Override public void registerAttributes(ManagementResourceRegistration resourceRegistration) { resourceRegistration.registerMetric(METRIC, (context, operation) -> context.getResult().set(1000)); resourceRegistration.registerMetric(METRIC_2, (context, operation) -> context.getResult().set(2000)); resourceRegistration.registerReadOnlyAttribute(RUNTIME_ATTRIBUTE, ((context, operation) -> context.getResult().set(3000))); resourceRegistration.registerReadOnlyAttribute(RUNTIME_ATTRIBUTE_2, ((context, operation) -> context.getResult().set(4000))); } } }