Skip to content

Commit

Permalink
added documentation and only add ozark if a controller is present
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregor Tudan committed Sep 10, 2017
1 parent fdcb880 commit a654920
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 76 deletions.
57 changes: 54 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,59 @@
# Activation
[![Build Status](https://travis-ci.org/gtudan/wildfly-ozark.svg?branch=master)](https://travis-ci.org/gtudan/wildfly-ozark)

Activate using the cli:
# About this project

This module adds support for the MVC 1.0 spec to wildfly 10.x by installing the
reference implementation "Ozark".

# Installation

## Installing the Module

Unpack the distribution to the root of your wildfly installation. This will create
a new folder `ozark` in `modules/system/addons/`.

## Activating the subsystem

You can use the jboss-cli to activate the subsystem using these commands:

```
/extension=org.mvc-spec.ozark.wildfly:add(module=org.mvc-spec.ozark.wildfly)
/subsystem=mvc:add()
```
```

Or you can directly edit the config file (standalone.xml or domain.xml).

Add this inside the `extensions` tag at the top of the file:
```xml
<extension module="org.mvc-spec.ozark.wildfly"/>
```

Then add the subsystem the profile your using:

```xml
<subsystem xmlns="urn:org.mvc-spec.ozark:mvc:1.0"/>
```

Finally you need to restart the server.

# Using MVC 1.0 in your deployment

The subsystem will automatically add the necessary dependencies to your deployment
if it defects a `@Controller`-annotated class.

All you need is the MVC-API. If you are using Maven, you can add it like this:

```xml
<dependencies>
<!-- ... -->
<dependency>
<groupId>javax.mvc</groupId>
<artifactId>javax.mvc-api</artifactId>
<version>1.0-edr2</version>
<scope>provided</scope>
</dependency>
</dependencies>
```

The API-Package does not depend on the JAX-RS-API, so you will need to add this as well
if you are not using the full Java-EE 7 API package.
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
<module name="org.jboss.msc"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.vfs"/>
<module name="org.jboss.jandex"/>
</dependencies>
</module>
Original file line number Diff line number Diff line change
@@ -1,40 +1,54 @@
package org.mvcspec.ozwark.wildfly.deployment;

import org.jboss.as.server.AbstractDeploymentChainStep;
import org.jboss.as.server.deployment.*;
import org.jboss.as.server.deployment.annotation.CompositeIndex;
import org.jboss.as.server.deployment.module.ModuleDependency;
import org.jboss.as.server.deployment.module.ModuleSpecification;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;
import org.jboss.logging.Logger;
import org.jboss.modules.Module;
import org.jboss.modules.ModuleIdentifier;
import org.jboss.modules.ModuleLoader;

import java.util.List;


public class SubsystemDeploymentProcessor implements DeploymentUnitProcessor {

private static final ModuleIdentifier MVC_API = ModuleIdentifier.create("javax.mvc.api");
private static final ModuleIdentifier OZARK = ModuleIdentifier.create("org.mvc-spec.ozark.core");
private static final ModuleIdentifier OZARK_RESTEASY = ModuleIdentifier.create("org.mvc-spec.ozark.resteasy");
private static final DotName CONTROLLER = DotName.createSimple("javax.mvc.annotation.Controller");

private final Logger log = Logger.getLogger(SubsystemDeploymentProcessor.class);

/**
* See {@link Phase} for a description of the different phases
*/
public static final Phase PHASE = Phase.DEPENDENCIES;

public static final int PRIORITY = Phase.DEPENDENCIES_JAXRS;

@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
log.debugf("Initializing Ozark for deployment {0}", deploymentUnit.getName());

final ModuleSpecification moduleSpecification = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION);
final ModuleLoader moduleLoader = Module.getBootModuleLoader();

moduleSpecification.addLocalDependency(new ModuleDependency(moduleLoader, MVC_API, false, false, false, false));
moduleSpecification.addLocalDependency(new ModuleDependency(moduleLoader, OZARK, false, true, true, false));
moduleSpecification.addLocalDependency(new ModuleDependency(moduleLoader, OZARK_RESTEASY, false, true, true, false));
// all modules get the API dependency
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, MVC_API, false, false, false, false));

if (!isMVCDeployment(deploymentUnit)) {
return;
}

log.debugf("Initializing Ozark for deployment %s", deploymentUnit.getName());
moduleSpecification.addLocalDependency(new ModuleDependency(moduleLoader, OZARK, false, false, true, false));
moduleSpecification.addLocalDependency(new ModuleDependency(moduleLoader, OZARK_RESTEASY, false, false, true, false));
}

private boolean isMVCDeployment(DeploymentUnit deploymentUnit) {
final CompositeIndex index = deploymentUnit.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX);

final List<AnnotationInstance> annotations = index.getAnnotations(CONTROLLER);
return !annotations.isEmpty();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ class SubsystemAdd extends AbstractBoottimeAddStepHandler {
private SubsystemAdd() {
}


/**
* {@inheritDoc}
*/
@Override
public void performBoottime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {

//Add deployment processors here
//Remove this if you don't need to hook into the deployers, or you can add as many as you like
//see SubDeploymentProcessor for explanation of the phases
context.addStep(new AbstractDeploymentChainStep() {
public void execute(DeploymentProcessorTarget processorTarget) {
processorTarget.addDeploymentProcessor(SubsystemExtension.SUBSYSTEM_NAME,
Expand All @@ -39,6 +34,4 @@ public void execute(DeploymentProcessorTarget processorTarget) {
}, OperationContext.Stage.RUNTIME);

}


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,22 @@
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.registry.ManagementResourceRegistration;

/**
* @author <a href="mailto:[email protected]">Tomaz Cerar</a>
*/
public class SubsystemDefinition extends SimpleResourceDefinition {
public static final SubsystemDefinition INSTANCE = new SubsystemDefinition();
static final SubsystemDefinition INSTANCE = new SubsystemDefinition();

private SubsystemDefinition() {
super(SubsystemExtension.SUBSYSTEM_PATH,
SubsystemExtension.getResourceDescriptionResolver(null),
//We always need to add an 'add' operation
SubsystemAdd.INSTANCE,
//Every resource that is added, normally needs a remove operation
SubsystemRemove.INSTANCE);
}

@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
//you can register additional operations here
}

@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
//you can register attributes here
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,17 @@
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;


/**
* @author <a href="[email protected]">Kabir Khan</a>
*/
public class SubsystemExtension implements Extension {

/**
* The name space used for the {@code subsystem} element
*/
public static final String NAMESPACE = "urn:org.mvc-spec.ozark:mvc:1.0";
static final String NAMESPACE = "urn:org.mvc-spec.ozark:mvc:1.0";

/**
* The name of our subsystem within the model.
*/
public static final String SUBSYSTEM_NAME = "mvc";
static final String SUBSYSTEM_NAME = "mvc";

/**
* The parser used for parsing our subsystem
Expand Down Expand Up @@ -88,8 +84,7 @@ private static class SubsystemParser implements XMLStreamConstants, XMLElementRe
*/
@Override
public void writeContent(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
context.startSubsystemElement(SubsystemExtension.NAMESPACE, false);
writer.writeEndElement();
context.startSubsystemElement(SubsystemExtension.NAMESPACE, true);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,16 @@
import org.jboss.as.controller.OperationFailedException;
import org.jboss.dmr.ModelNode;

/**
* Handler responsible for removing the subsystem resource from the model
*
* @author <a href="[email protected]">Kabir Khan</a>
*/
class SubsystemRemove extends AbstractRemoveStepHandler {

static final SubsystemRemove INSTANCE = new SubsystemRemove();


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"));
// nothing to do here
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ public SubsystemBaseParsingTestCase() {
super(SubsystemExtension.SUBSYSTEM_NAME, new SubsystemExtension());
}


@Override
protected String getSubsystemXml() throws IOException {
return "<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\">" +
"</subsystem>";
return "<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\"/>";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@
import org.junit.Assert;
import org.junit.Test;


/**
* Tests all management expects for subsystem, parsing, marshaling, model definition and other
* Here is an example that allows you a fine grained controler over what is tested and how. So it can give you ideas what can be done and tested.
* If you have no need for advanced testing of subsystem you look at {@link SubsystemBaseParsingTestCase} that testes same stuff but most of the code
* is hidden inside of test harness
*
* @author <a href="[email protected]">Kabir Khan</a>
*/
public class SubsystemParsingTestCase extends AbstractSubsystemTest {

public SubsystemParsingTestCase() {
Expand All @@ -37,9 +28,7 @@ public SubsystemParsingTestCase() {
@Test
public void testParseSubsystem() throws Exception {
//Parse the subsystem xml into operations
String subsystemXml =
"<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\">" +
"</subsystem>";
String subsystemXml = "<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\"/>";
List<ModelNode> operations = super.parse(subsystemXml);

///Check that we have the expected number of operations
Expand All @@ -48,9 +37,9 @@ public void testParseSubsystem() throws Exception {
//Check that each operation has the correct content
ModelNode addSubsystem = operations.get(0);
Assert.assertEquals(ADD, addSubsystem.get(OP).asString());
PathAddress addr = PathAddress.pathAddress(addSubsystem.get(OP_ADDR));
Assert.assertEquals(1, addr.size());
PathElement element = addr.getElement(0);
PathAddress address = PathAddress.pathAddress(addSubsystem.get(OP_ADDR));
Assert.assertEquals(1, address.size());
PathElement element = address.getElement(0);
Assert.assertEquals(SUBSYSTEM, element.getKey());
Assert.assertEquals(SubsystemExtension.SUBSYSTEM_NAME, element.getValue());
}
Expand All @@ -61,9 +50,7 @@ public void testParseSubsystem() throws Exception {
@Test
public void testInstallIntoController() throws Exception {
//Parse the subsystem xml and install into the controller
String subsystemXml =
"<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\">" +
"</subsystem>";
String subsystemXml = "<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\"/>";
KernelServices services = super.createKernelServicesBuilder(null).setSubsystemXml(subsystemXml).build();

//Read the whole model and make sure it looks as expected
Expand All @@ -73,21 +60,19 @@ public void testInstallIntoController() throws Exception {

/**
* 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
* controller started with the xml marshaled from the first one results in the same model
*/
@Test
public void testParseAndMarshalModel() throws Exception {
//Parse the subsystem xml and install into the first controller
String subsystemXml =
"<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\">" +
"</subsystem>";
String subsystemXml = "<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\"/>";
KernelServices servicesA = super.createKernelServicesBuilder(null).setSubsystemXml(subsystemXml).build();
//Get the model and the persisted xml from the first controller
ModelNode modelA = servicesA.readWholeModel();
String marshalled = servicesA.getPersistedSubsystemXml();
String marshaled = servicesA.getPersistedSubsystemXml();

//Install the persisted xml from the first controller into a second controller
KernelServices servicesB = super.createKernelServicesBuilder(null).setSubsystemXml(marshalled).build();
KernelServices servicesB = super.createKernelServicesBuilder(null).setSubsystemXml(marshaled).build();
ModelNode modelB = servicesB.readWholeModel();

//Make sure the models from the two controllers are identical
Expand All @@ -100,13 +85,9 @@ public void testParseAndMarshalModel() throws Exception {
@Test
public void testSubsystemRemoval() throws Exception {
//Parse the subsystem xml and install into the first controller
String subsystemXml =
"<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\">" +
"</subsystem>";
String subsystemXml = "<subsystem xmlns=\"" + SubsystemExtension.NAMESPACE + "\"/>";
KernelServices services = super.createKernelServicesBuilder(null).setSubsystemXml(subsystemXml).build();
//Checks that the subsystem was removed from the model
super.assertRemoveSubsystemResources(services);

//TODO Chek that any services that were installed were removed here
}
}

0 comments on commit a654920

Please sign in to comment.