Skip to content

Commit

Permalink
WFLY-4780 Add migrate operation to the web subsystem to allow it to b…
Browse files Browse the repository at this point in the history
…e migrated to the Undertow subsystem
  • Loading branch information
stuartwdouglas committed Jul 27, 2015
1 parent 1fadb16 commit bb7928e
Show file tree
Hide file tree
Showing 18 changed files with 1,129 additions and 32 deletions.
5 changes: 5 additions & 0 deletions legacy/web/pom.xml
Expand Up @@ -52,6 +52,11 @@
<artifactId>wildfly-controller</artifactId> <artifactId>wildfly-controller</artifactId>
</dependency> </dependency>


<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-undertow</artifactId>
</dependency>

<dependency> <dependency>
<groupId>org.jboss.logging</groupId> <groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId> <artifactId>jboss-logging</artifactId>
Expand Down
6 changes: 6 additions & 0 deletions legacy/web/src/main/java/org/jboss/as/web/WebDefinition.java
Expand Up @@ -29,6 +29,7 @@
import org.jboss.as.controller.client.helpers.MeasurementUnit; import org.jboss.as.controller.client.helpers.MeasurementUnit;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants; import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.controller.registry.AttributeAccess; import org.jboss.as.controller.registry.AttributeAccess;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType; import org.jboss.dmr.ModelType;


Expand Down Expand Up @@ -71,5 +72,10 @@ private WebDefinition() {
setDeprecated(WebExtension.DEPRECATED_SINCE); setDeprecated(WebExtension.DEPRECATED_SINCE);
} }


@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);


WebMigrateOperation.registerOperations(resourceRegistration, getResourceDescriptionResolver());
}
} }
17 changes: 9 additions & 8 deletions legacy/web/src/main/java/org/jboss/as/web/WebExtension.java
Expand Up @@ -31,11 +31,10 @@
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.WRITE_ATTRIBUTE_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.WRITE_ATTRIBUTE_OPERATION;


import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;


import org.jboss.as.controller.Extension;
import org.jboss.as.controller.ExtensionContext; import org.jboss.as.controller.ExtensionContext;
import org.jboss.as.controller.ModelVersion; import org.jboss.as.controller.ModelVersion;
import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.OperationFailedException;
Expand All @@ -46,7 +45,8 @@
import org.jboss.as.controller.access.management.SensitiveTargetAccessConstraintDefinition; import org.jboss.as.controller.access.management.SensitiveTargetAccessConstraintDefinition;
import org.jboss.as.controller.descriptions.DeprecatedResourceDescriptionResolver; import org.jboss.as.controller.descriptions.DeprecatedResourceDescriptionResolver;
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver; import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
import org.jboss.as.controller.extension.AbstractLegacyExtension; import org.jboss.as.controller.extension.UnsupportedSubsystemDescribeHandler;
import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
import org.jboss.as.controller.parsing.ExtensionParsingContext; import org.jboss.as.controller.parsing.ExtensionParsingContext;
import org.jboss.as.controller.registry.AliasEntry; import org.jboss.as.controller.registry.AliasEntry;
import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.as.controller.registry.ManagementResourceRegistration;
Expand All @@ -67,7 +67,7 @@
* @author Emanuel Muckenhuber * @author Emanuel Muckenhuber
* @author Tomaz Cerar * @author Tomaz Cerar
*/ */
public class WebExtension extends AbstractLegacyExtension { public class WebExtension implements Extension {
public static final String SUBSYSTEM_NAME = "web"; public static final String SUBSYSTEM_NAME = "web";
public static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME); public static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
public static final PathElement VALVE_PATH = PathElement.pathElement(Constants.VALVE); public static final PathElement VALVE_PATH = PathElement.pathElement(Constants.VALVE);
Expand Down Expand Up @@ -99,7 +99,6 @@ public class WebExtension extends AbstractLegacyExtension {
new SensitivityClassification(SUBSYSTEM_NAME, "web-valve", false, false, false)); new SensitivityClassification(SUBSYSTEM_NAME, "web-valve", false, false, false));


public WebExtension() { public WebExtension() {
super(extensionName, SUBSYSTEM_NAME);
} }


static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) { static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) {
Expand All @@ -108,7 +107,7 @@ static StandardResourceDescriptionResolver getResourceDescriptionResolver(final
} }


@Override @Override
protected Set<ManagementResourceRegistration> initializeLegacyModel(ExtensionContext context) { public void initialize(ExtensionContext context) {
final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, CURRENT_MODEL_VERSION); final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, CURRENT_MODEL_VERSION);


final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(WebDefinition.INSTANCE); final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(WebDefinition.INSTANCE);
Expand Down Expand Up @@ -164,11 +163,13 @@ protected Set<ManagementResourceRegistration> initializeLegacyModel(ExtensionCon
registerTransformers_2_x_0(subsystem, 0); registerTransformers_2_x_0(subsystem, 0);
registerTransformers_2_x_0(subsystem, 1); registerTransformers_2_x_0(subsystem, 1);
} }
return Collections.singleton(registration);
registration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION,
new UnsupportedSubsystemDescribeHandler(extensionName));
} }


@Override @Override
protected void initializeLegacyParsers(ExtensionParsingContext context) { public void initializeParsers(ExtensionParsingContext context) {
for (Namespace ns : Namespace.values()) { for (Namespace ns : Namespace.values()) {
if (ns.getUriString() != null) { if (ns.getUriString() != null) {
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, ns.getUriString(), WebSubsystemParser.getInstance()); context.setSubsystemXmlMapping(SUBSYSTEM_NAME, ns.getUriString(), WebSubsystemParser.getInstance());
Expand Down
717 changes: 717 additions & 0 deletions legacy/web/src/main/java/org/jboss/as/web/WebMigrateOperation.java

Large diffs are not rendered by default.

Expand Up @@ -6,6 +6,8 @@ web.instance-id=Set the identifier for this server instance.
web.native=Add the native initialization listener to the web container. web.native=Add the native initialization listener to the web container.
web.remove=Operation removing the web subsystem. web.remove=Operation removing the web subsystem.
web.deprecated=The Web subsystem is deprecated and may be removed or limited to managed domain legacy server use in future versions. web.deprecated=The Web subsystem is deprecated and may be removed or limited to managed domain legacy server use in future versions.
web.describe-migration=Describes the steps that will be taken to migrate this configuration to Undertow
web.migrate=Migrates this web subsystem config to Undertow


web.container=Common container configuration web.container=Common container configuration
web.container.add=Adds web container web.container.add=Adds web container
Expand Down
227 changes: 227 additions & 0 deletions legacy/web/src/test/java/org/jboss/as/web/test/WebMigrateTestCase.java
@@ -0,0 +1,227 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2015, Red Hat Middleware LLC, 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.web.test;

import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.RunningMode;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.access.management.DelegatingConfigurableAuthorizer;
import org.jboss.as.controller.capability.registry.RuntimeCapabilityRegistry;
import org.jboss.as.controller.descriptions.common.ControllerResolver;
import org.jboss.as.controller.extension.ExtensionRegistry;
import org.jboss.as.controller.extension.ExtensionRegistryType;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.registry.Resource;
import org.jboss.as.domain.management.CoreManagementResourceDefinition;
import org.jboss.as.domain.management.audit.EnvironmentNameReader;
import org.jboss.as.domain.management.security.KeystoreAttributes;
import org.jboss.as.subsystem.test.AbstractSubsystemTest;
import org.jboss.as.subsystem.test.AdditionalInitialization;
import org.jboss.as.subsystem.test.KernelServices;
import org.jboss.as.web.WebExtension;
import org.jboss.dmr.ModelNode;
import org.junit.Test;
import org.wildfly.extension.io.IOExtension;
import org.wildfly.extension.undertow.Constants;
import org.wildfly.extension.undertow.UndertowExtension;

import java.io.File;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.AUTHENTICATION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CORE_SERVICE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.EXTENSION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MANAGEMENT;
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.SECURITY_REALM;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TRUSTSTORE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
*
* @author Stuart Douglas
*/
public class WebMigrateTestCase extends AbstractSubsystemTest {

public static final String UNDERTOW_SUBSYSTEM_NAME = "undertow";

public WebMigrateTestCase() {
super(WebExtension.SUBSYSTEM_NAME, new WebExtension());
}

@Test
public void testMigrateOperation() throws Exception {
String subsystemXml = readResource("subsystem-migrate-2.2.0.xml");
NewSubsystemAdditionalInitialization additionalInitialization = new NewSubsystemAdditionalInitialization();
KernelServices services = createKernelServicesBuilder(additionalInitialization).setSubsystemXml(subsystemXml).build();

ModelNode model = services.readWholeModel();
assertFalse(additionalInitialization.extensionAdded);
assertTrue(model.get(SUBSYSTEM, WebExtension.SUBSYSTEM_NAME).isDefined());
assertFalse(model.get(SUBSYSTEM, UNDERTOW_SUBSYSTEM_NAME).isDefined());

ModelNode migrateOp = new ModelNode();
migrateOp.get(OP).set("migrate");
migrateOp.get(OP_ADDR).add(SUBSYSTEM, WebExtension.SUBSYSTEM_NAME);

checkOutcome(services.executeOperation(migrateOp));

model = services.readWholeModel();

assertTrue(additionalInitialization.extensionAdded);
assertFalse(model.get(SUBSYSTEM, WebExtension.SUBSYSTEM_NAME).isDefined());
assertTrue(model.get(SUBSYSTEM, UNDERTOW_SUBSYSTEM_NAME).isDefined());

//make sure we have an IO subsystem
ModelNode ioSubsystem = model.get(SUBSYSTEM, "io");
assertTrue(ioSubsystem.isDefined());
assertTrue(ioSubsystem.get("worker", "default").isDefined());
assertTrue(ioSubsystem.get("buffer-pool", "default").isDefined());

ModelNode newSubsystem = model.get(SUBSYSTEM, UNDERTOW_SUBSYSTEM_NAME);
ModelNode newServer = newSubsystem.get("server", "default");
assertNotNull(newServer);
assertTrue(newServer.isDefined());
assertEquals("default-host", newServer.get(Constants.DEFAULT_HOST).asString());


//servlet container
ModelNode servletContainer = newSubsystem.get(Constants.SERVLET_CONTAINER, "default");
assertNotNull(servletContainer);
assertTrue(servletContainer.isDefined());
assertEquals("${prop.default-session-timeout:30}", servletContainer.get(Constants.DEFAULT_SESSION_TIMEOUT).asString());
assertEquals("${prop.listings:true}", servletContainer.get(Constants.DIRECTORY_LISTING).asString());

//jsp settings
ModelNode jsp = servletContainer.get(Constants.SETTING, Constants.JSP);
assertNotNull(jsp);
assertEquals("${prop.recompile-on-fail:true}", jsp.get(Constants.RECOMPILE_ON_FAIL).asString());

//welcome file
ModelNode welcome = servletContainer.get(Constants.WELCOME_FILE, "toto");
assertTrue(welcome.isDefined());

//mime mapping
ModelNode mimeMapping = servletContainer.get(Constants.MIME_MAPPING, "ogx");
assertTrue(mimeMapping.isDefined());
assertEquals("application/ogg", mimeMapping.get(Constants.VALUE).asString());

//http connector
ModelNode connector = newServer.get(Constants.HTTP_LISTENER, "http");
assertTrue(connector.isDefined());
assertEquals("http", connector.get(Constants.SOCKET_BINDING).asString());
assertEquals("${prop.enabled:true}", connector.get(Constants.ENABLED).asString());
assertEquals("${prop.enable-lookups:false}", connector.get(Constants.RESOLVE_PEER_ADDRESS).asString());
assertEquals("${prop.max-post-size:2097153}", connector.get(Constants.MAX_POST_SIZE).asString());
assertEquals("https", connector.get(Constants.REDIRECT_SOCKET).asString());

//https connector
ModelNode httpsConnector = newServer.get(Constants.HTTPS_LISTENER, "https");
String realmName = httpsConnector.get(Constants.SECURITY_REALM).asString();
assertTrue(realmName, realmName.startsWith("jbossweb-migration-security-realm"));
assertEquals("${prop.session-cache-size:512}", httpsConnector.get(Constants.SSL_SESSION_CACHE_SIZE).asString());

//realm name is dynamic
ModelNode realm = model.get(CORE_SERVICE, MANAGEMENT).get(SECURITY_REALM, realmName);

//trust store
ModelNode trustStore = realm.get(AUTHENTICATION, TRUSTSTORE);
assertEquals("${file-base}/jsse.keystore", trustStore.get(KeystoreAttributes.KEYSTORE_PATH.getName()).asString());


//virtual host
ModelNode virtualHost = newServer.get(Constants.HOST, "default-host");
//welcome content
assertEquals("welcome-content", virtualHost.get("location", "/").get(Constants.HANDLER).asString());

assertEquals("localhost", virtualHost.get("alias").asList().get(0).asString());

ModelNode accessLog = virtualHost.get(Constants.SETTING, Constants.ACCESS_LOG);

assertEquals("prefix", accessLog.get(Constants.PREFIX).asString());
assertEquals("true", accessLog.get(Constants.ROTATE).asString());
assertEquals("extended", accessLog.get(Constants.PATTERN).asString());

//sso
ModelNode sso = virtualHost.get(Constants.SETTING, Constants.SINGLE_SIGN_ON);
assertEquals("${prop.domain:myDomain}", sso.get(Constants.DOMAIN).asString());
assertEquals("${prop.http-only:true}", sso.get(Constants.HTTP_ONLY).asString());


}

private static class NewSubsystemAdditionalInitialization extends AdditionalInitialization {

UndertowExtension undertow = new UndertowExtension();
IOExtension io = new IOExtension();

boolean extensionAdded = false;

@Override
protected void initializeExtraSubystemsAndModel(ExtensionRegistry extensionRegistry, Resource rootResource, ManagementResourceRegistration rootRegistration, RuntimeCapabilityRegistry capabilityRegistry) {
rootRegistration.registerSubModel(new SimpleResourceDefinition(PathElement.pathElement(EXTENSION),
ControllerResolver.getResolver(EXTENSION), new OperationStepHandler() {
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
if(!extensionAdded) {
extensionAdded = true;
undertow.initialize(extensionRegistry.getExtensionContext("org.wildfly.extension.undertow",
rootRegistration, ExtensionRegistryType.SERVER));
io.initialize(extensionRegistry.getExtensionContext("org.wildfly.extension.io",
rootRegistration, ExtensionRegistryType.SERVER));
}
}
}, null));
rootRegistration.registerSubModel(CoreManagementResourceDefinition.forStandaloneServer(new DelegatingConfigurableAuthorizer(), null, null, new EnvironmentNameReader() {
public boolean isServer() {
return true;
}

public String getServerName() {
return "Test";
}

public String getHostName() {
return null;
}

public String getProductName() {
return null;
}
}, null));
rootResource.registerChild(CoreManagementResourceDefinition.PATH_ELEMENT, Resource.Factory.create());
System.setProperty("file-base", new File(getClass().getClassLoader().getResource("server.keystore").getFile()).getParentFile().getAbsolutePath());
}

@Override
protected RunningMode getRunningMode() {
return RunningMode.ADMIN_ONLY;
}
}
}
Binary file added legacy/web/src/test/resources/jsse.keystore
Binary file not shown.

0 comments on commit bb7928e

Please sign in to comment.