/*
Copyright 2016 Red Hat, Inc.
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.test.integration.management.extension.customcontext;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
import io.undertow.server.handlers.resource.ClassPathResourceManager;
import io.undertow.server.handlers.resource.ResourceManager;
import org.jboss.as.controller.AbstractAddStepHandler;
import org.jboss.as.controller.AbstractRemoveStepHandler;
import org.jboss.as.controller.Extension;
import org.jboss.as.controller.ExtensionContext;
import org.jboss.as.controller.ModelVersion;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.SubsystemRegistration;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.descriptions.NonResolvingResourceDescriptionResolver;
import org.jboss.as.controller.parsing.ExtensionParsingContext;
import org.jboss.as.controller.registry.Resource;
import org.jboss.as.server.mgmt.domain.ExtensibleHttpManagement;
import org.jboss.as.test.integration.management.extension.EmptySubsystemParser;
import org.jboss.dmr.ModelNode;
import org.jboss.logging.Logger;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;
/**
* Extension whose subsystem adds custom contexts to the http management interface.
*
* @author Brian Stansberry
*/
public class CustomContextExtension implements Extension {
private static final Logger log = Logger.getLogger(CustomContextExtension.class);
public static final String EXTENSION_NAME = "org.wildfly.extension.custom-context-test";
public static final String SUBSYSTEM_NAME = "custom-context-test";
private static final EmptySubsystemParser PARSER = new EmptySubsystemParser("urn:wildfly:extension:custom-context-test:1.0");
private static final String REQUIRED_CAP = "org.wildfly.management.http.extensible";
private static final RuntimeCapability<Void> CAP = RuntimeCapability.Builder.of(EXTENSION_NAME)
.addRequirements(REQUIRED_CAP)
.build();
@Override
public void initialize(ExtensionContext context) {
SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, ModelVersion.create(1));
subsystem.setHostCapable();
subsystem.registerSubsystemModel(new CustomContextSubsystemResourceDefinition());
subsystem.registerXMLElementWriter(PARSER);
}
@Override
public void initializeParsers(ExtensionParsingContext context) {
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, PARSER.getNamespace(), PARSER);
}
private static class CustomContextSubsystemResourceDefinition extends SimpleResourceDefinition {
private CustomContextSubsystemResourceDefinition() {
super(new Parameters(PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME), new NonResolvingResourceDescriptionResolver())
.setAddHandler(ADD_HANDLER)
.setRemoveHandler(REMOVE_HANDLER)
.setCapabilities(CAP)
);
}
}
private static AbstractAddStepHandler ADD_HANDLER = new AbstractAddStepHandler(){
@Override
protected void performRuntime(OperationContext context, ModelNode operation, Resource resource) throws OperationFailedException {
ServiceTarget target = context.getServiceTarget();
CustomContextService service = new CustomContextService(context.getProcessType().isServer());
target.addService(CustomContextService.SERVICE_NAME, service)
.addDependency(context.getCapabilityServiceName(REQUIRED_CAP, ExtensibleHttpManagement.class),
ExtensibleHttpManagement.class, service.getHttpManagementInjector())
.install();
}
};
private static AbstractRemoveStepHandler REMOVE_HANDLER = new AbstractRemoveStepHandler() {
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
context.removeService(CustomContextService.SERVICE_NAME);
}
};
private static class CustomContextService implements Service<Void> {
private static final ServiceName SERVICE_NAME = ServiceName.of("test", "customcontext");
private final boolean forServer;
private final InjectedValue<ExtensibleHttpManagement> httpManagementInjector = new InjectedValue<>();
private CustomContextService(boolean forServer) {
this.forServer = forServer;
}
@Override
public void start(StartContext context) throws StartException {
ExtensibleHttpManagement httpManagement = httpManagementInjector.getValue();
ResourceManager rm = new ClassPathResourceManager(getClass().getClassLoader(), getClass().getPackage());
httpManagement.addStaticContext("static", rm);
log.info("Added context 'static'");
ExtensibleHttpManagement.PathRemapper remapper = new ExtensibleHttpManagement.PathRemapper() {
@Override
public String remapPath(String originalPath) {
if ("/foo".equals(originalPath)) {
String prefix = forServer ? "" : "/host/master";
return prefix + "/extension/" + EXTENSION_NAME;
}
return null;
}
};
httpManagement.addManagementGetRemapContext("remap", remapper);
log.info("Added context 'remap'");
}
@Override
public void stop(StopContext context) {
ExtensibleHttpManagement httpManagement = httpManagementInjector.getValue();
httpManagement.removeContext("static");
log.info("Removed context 'static'");
httpManagement.removeContext("remap");
log.info("Removed context 'remap'");
}
@Override
public Void getValue() throws IllegalStateException, IllegalArgumentException {
return null;
}
InjectedValue<ExtensibleHttpManagement> getHttpManagementInjector() {
return httpManagementInjector;
}
}
}