Permalink
Browse files

Subsystem remove example

  • Loading branch information...
1 parent 03f464a commit 70dff385695653396280b4eab50586bfe9a1e1a8 @kabir kabir committed Dec 25, 2011
@@ -4,6 +4,7 @@
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIBE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
import java.util.List;
@@ -59,6 +60,8 @@ public void initialize(ExtensionContext context) {
final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(SubsystemProviders.SUBSYSTEM);
//We always need to add an 'add' operation
registration.registerOperationHandler(ADD, SubsystemAdd.INSTANCE, SubsystemProviders.SUBSYSTEM_ADD, false);
+ //Every resource that is added, normally needs a remove operation
+ registration.registerOperationHandler(REMOVE, SubsystemRemove.INSTANCE, SubsystemProviders.SUBSYSTEM_REMOVE, false);
//We always need to add a 'describe' operation
registration.registerOperationHandler(DESCRIBE, SubsystemDescribeHandler.INSTANCE, SubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE);
@@ -5,6 +5,7 @@
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HEAD_COMMENT_ALLOWED;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAMESPACE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_NAME;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TAIL_COMMENT_ALLOWED;
import java.util.Locale;
@@ -52,4 +53,19 @@ public ModelNode getModelDescription(Locale locale) {
}
};
+ /**
+ * Used to create the description of the subsystem remove method
+ */
+ public static DescriptionProvider SUBSYSTEM_REMOVE = new DescriptionProvider() {
+ public ModelNode getModelDescription(Locale locale) {
+ //The locale is passed in so you can internationalize the strings used in the descriptions
+
+ final ModelNode subsystem = new ModelNode();
+ subsystem.get(OPERATION_NAME).set(REMOVE);
+ subsystem.get(DESCRIPTION).set("Removes my subsystem");
+
+ return subsystem;
+ }
+ };
+
}
@@ -0,0 +1,31 @@
+package com.mycompany.subsystem.extension;
+
+import org.jboss.as.controller.AbstractRemoveStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+import org.jboss.logging.Logger;
+import org.jboss.msc.service.ServiceName;
+
+/**
+ * Handler responsible for removing the subsystem resource from the model
+ *
+ * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
+ */
+class SubsystemRemove extends AbstractRemoveStepHandler {
+
+ static final SubsystemRemove INSTANCE = new SubsystemRemove();
+
+ private final Logger log = Logger.getLogger(SubsystemRemove.class);
+
+ private SubsystemRemove() {
+ }
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ //Remove any services installed by the corresponding add handler here
+ //context.removeService(ServiceName.of("some", "name"));
+ }
+
+
+}
@@ -119,6 +119,21 @@ public void testDescribeHandler() throws Exception {
//Make sure the models from the two controllers are identical
super.compare(modelA, modelB);
+ }
+
+ /**
+ * Tests that the subsystem can be removed
+ */
+ @Test
+ public void testSubsystemRemoval() throws Exception {
+ //Parse the subsystem xml and install into the first controller
+ String subsystemXml =
+ "<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\">" +
+ "</subsystem>";
+ KernelServices services = super.installInController(subsystemXml);
+ //Checks that the subsystem was removed from the model
+ super.assertRemoveSubsystemResources(services);
+ //TODO Chek that any services that were installed were removed here
}
}
@@ -25,6 +25,7 @@
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIBE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
import java.util.Collections;
@@ -85,6 +86,8 @@ public void initialize(ExtensionContext context) {
final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(SubsystemProviders.SUBSYSTEM);
//We always need to add an 'add' operation
registration.registerOperationHandler(ADD, SubsystemAdd.INSTANCE, SubsystemProviders.SUBSYSTEM_ADD, false);
+ //Every resource that is added, normally needs a remove operation
+ registration.registerOperationHandler(REMOVE, SubsystemRemove.INSTANCE, SubsystemProviders.SUBSYSTEM_REMOVE, false);
//We always need to add a 'describe' operation
registration.registerOperationHandler(DESCRIBE, SubsystemDescribeHandler.INSTANCE, SubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE);
@@ -11,6 +11,7 @@
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MODEL_DESCRIPTION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAMESPACE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_NAME;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REQUIRED;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TAIL_COMMENT_ALLOWED;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE;
@@ -69,6 +70,21 @@ public ModelNode getModelDescription(Locale locale) {
};
/**
+ * Used to create the description of the subsystem remove method
+ */
+ public static DescriptionProvider SUBSYSTEM_REMOVE = new DescriptionProvider() {
+ public ModelNode getModelDescription(Locale locale) {
+ //The locale is passed in so you can internationalize the strings used in the descriptions
+
+ final ModelNode subsystem = new ModelNode();
+ subsystem.get(OPERATION_NAME).set(REMOVE);
+ subsystem.get(DESCRIPTION).set("Removes the tracker subsystem");
+
+ return subsystem;
+ }
+ };
+
+ /**
* Used to create the description of the {@code type} child
*/
public static DescriptionProvider TYPE_CHILD = new DescriptionProvider() {
@@ -0,0 +1,19 @@
+package com.acme.corp.tracker.extension;
+
+import org.jboss.as.controller.AbstractRemoveStepHandler;
+import org.jboss.logging.Logger;
+
+/**
+ * Handler responsible for removing the subsystem resource from the model
+ *
+ * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
+ */
+class SubsystemRemove extends AbstractRemoveStepHandler {
+
+ static final SubsystemRemove INSTANCE = new SubsystemRemove();
+
+ private final Logger log = Logger.getLogger(SubsystemRemove.class);
+
+ private SubsystemRemove() {
+ }
+}
@@ -49,10 +49,10 @@ public void testParseSubsystem() throws Exception {
" </deployment-types>" +
"</subsystem>";
List<ModelNode> operations = super.parse(subsystemXml);
-
+
///Check that we have the expected number of operations
Assert.assertEquals(2, operations.size());
-
+
//Check that each operation has the correct content
//The add subsystem operation will happen first
ModelNode addSubsystem = operations.get(0);
@@ -62,7 +62,7 @@ public void testParseSubsystem() throws Exception {
PathElement element = addr.getElement(0);
Assert.assertEquals(SUBSYSTEM, element.getKey());
Assert.assertEquals(SubsystemExtension.SUBSYSTEM_NAME, element.getValue());
-
+
//Then we will get the add type operation
ModelNode addType = operations.get(1);
Assert.assertEquals(ADD, addType.get(OP).asString());
@@ -76,7 +76,7 @@ public void testParseSubsystem() throws Exception {
Assert.assertEquals("type", element.getKey());
Assert.assertEquals("tst", element.getValue());
}
-
+
/**
* Test that the model created from the xml looks as expected
*/
@@ -90,7 +90,7 @@ public void testInstallIntoController() throws Exception {
" </deployment-types>" +
"</subsystem>";
KernelServices services = super.installInController(subsystemXml);
-
+
//Read the whole model and make sure it looks as expected
ModelNode model = services.readWholeModel();
//Useful for debugging :-)
@@ -101,7 +101,7 @@ public void testInstallIntoController() throws Exception {
Assert.assertTrue(model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME, "type", "tst").hasDefined("tick"));
Assert.assertEquals(12345, model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME, "type", "tst", "tick").asLong());
}
-
+
/**
* Starts a controller with a given subsystem xml and then checks that a second
* controller started with the xml marshalled from the first one results in the same model
@@ -119,15 +119,15 @@ public void testParseAndMarshalModel() throws Exception {
//Get the model and the persisted xml from the first controller
ModelNode modelA = servicesA.readWholeModel();
String marshalled = servicesA.getPersistedSubsystemXml();
-
+
//Install the persisted xml from the first controller into a second controller
KernelServices servicesB = super.installInController(marshalled);
ModelNode modelB = servicesB.readWholeModel();
-
+
//Make sure the models from the two controllers are identical
super.compare(modelA, modelB);
}
-
+
/**
* Starts a controller with the given subsystem xml and then checks that a second
* controller started with the operations from its describe action results in the same model
@@ -144,20 +144,47 @@ public void testDescribeHandler() throws Exception {
ModelNode describeOp = new ModelNode();
describeOp.get(OP).set(DESCRIBE);
describeOp.get(OP_ADDR).set(
- PathAddress.pathAddress(
- PathElement.pathElement(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME)).toModelNode());
+ PathAddress.pathAddress(
+ PathElement.pathElement(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME)).toModelNode());
List<ModelNode> operations = super.checkResultAndGetContents(servicesA.executeOperation(describeOp)).asList();
-
-
+
//Install the describe options from the first controller into a second controller
KernelServices servicesB = super.installInController(operations);
ModelNode modelB = servicesB.readWholeModel();
-
+
//Make sure the models from the two controllers are identical
super.compare(modelA, modelB);
-
+
}
-
+
+ /**
+ * Tests that the subsystem can be removed
+ */
+ @Test
+ public void testSubsystemRemoval() throws Exception {
+ //Parse the subsystem xml and install into the first controller
+ String subsystemXml =
+ "<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\">" +
+ " <deployment-types>" +
+ " <deployment-type suffix=\"tst\" tick=\"12345\"/>" +
+ " </deployment-types>" +
+ "</subsystem>";
+ KernelServices services = super.installInController(subsystemXml);
+
+ //Sanity check to test the service for 'tst' was there
+ services.getContainer().getRequiredService(TrackerService.createServiceName("tst"));
+
+ //Checks that the subsystem was removed from the model
+ super.assertRemoveSubsystemResources(services);
+
+ //Check that any services that were installed were removed here
+ try {
+ services.getContainer().getRequiredService(TrackerService.createServiceName("tst"));
+ Assert.fail("Should have removed services");
+ } catch (Exception expected) {
+ }
+ }
+
@Test
public void testExecuteOperations() throws Exception {
String subsystemXml =
@@ -167,30 +194,30 @@ public void testExecuteOperations() throws Exception {
" </deployment-types>" +
"</subsystem>";
KernelServices services = super.installInController(subsystemXml);
-
+
//Add another type
PathAddress fooTypeAddr = PathAddress.pathAddress(
- PathElement.pathElement(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME),
- PathElement.pathElement("type", "foo"));
+ PathElement.pathElement(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME),
+ PathElement.pathElement("type", "foo"));
ModelNode addOp = new ModelNode();
addOp.get(OP).set(ADD);
addOp.get(OP_ADDR).set(fooTypeAddr.toModelNode());
addOp.get("tick").set(1000);
ModelNode result = services.executeOperation(addOp);
Assert.assertEquals(SUCCESS, result.get(OUTCOME).asString());
-
-
+
+
ModelNode model = services.readWholeModel();
Assert.assertTrue(model.get(SUBSYSTEM).hasDefined(SubsystemExtension.SUBSYSTEM_NAME));
Assert.assertTrue(model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME).hasDefined("type"));
Assert.assertTrue(model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME, "type").hasDefined("tst"));
Assert.assertTrue(model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME, "type", "tst").hasDefined("tick"));
Assert.assertEquals(12345, model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME, "type", "tst", "tick").asLong());
-
+
Assert.assertTrue(model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME, "type").hasDefined("foo"));
Assert.assertTrue(model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME, "type", "foo").hasDefined("tick"));
Assert.assertEquals(1000, model.get(SUBSYSTEM, SubsystemExtension.SUBSYSTEM_NAME, "type", "foo", "tick").asLong());
-
+
//Call write-attribute
ModelNode writeOp = new ModelNode();
writeOp.get(OP).set(WRITE_ATTRIBUTE_OPERATION);
@@ -199,15 +226,15 @@ public void testExecuteOperations() throws Exception {
writeOp.get(VALUE).set(3456);
result = services.executeOperation(writeOp);
Assert.assertEquals(SUCCESS, result.get(OUTCOME).asString());
-
+
//Check that write attribute took effect, this time by calling read-attribute instead of reading the whole model
ModelNode readOp = new ModelNode();
readOp.get(OP).set(READ_ATTRIBUTE_OPERATION);
readOp.get(OP_ADDR).set(fooTypeAddr.toModelNode());
readOp.get(NAME).set("tick");
result = services.executeOperation(readOp);
Assert.assertEquals(3456, checkResultAndGetContents(result).asLong());
-
+
TrackerService service = (TrackerService)services.getContainer().getService(TrackerService.createServiceName("foo")).getValue();
Assert.assertEquals(3456, service.getTick());
}

0 comments on commit 70dff38

Please sign in to comment.