Skip to content

Commit

Permalink
WFLY-3639 default-web-module doesn't work for non default hosts & ser…
Browse files Browse the repository at this point in the history
…vers

- improve deployment message to include server on which it was deployed to
- add test to verify default-web-module works for all possible scenarios
- server addition doesn't require reload anymore
  • Loading branch information
ctomc committed Oct 16, 2016
1 parent 3bea0a2 commit 6958464
Show file tree
Hide file tree
Showing 21 changed files with 340 additions and 109 deletions.
Expand Up @@ -53,6 +53,7 @@
*/ */
@RunWith(Arquillian.class) @RunWith(Arquillian.class)
@RunAsClient @RunAsClient
//todo this test could probably be done in manual mode test with wildfly runner, also could be merged into VirtualHostTestCase
public class VirtualServerTestCase extends ContainerResourceMgmtTestBase { public class VirtualServerTestCase extends ContainerResourceMgmtTestBase {


@ArquillianResource @ArquillianResource
Expand Down Expand Up @@ -127,6 +128,7 @@ public void addRemoveVirtualServer(@ArquillianResource Deployer deployer) throws
private void addVirtualServer() throws IOException, MgmtOperationException { private void addVirtualServer() throws IOException, MgmtOperationException {
ModelNode addOp = createOpNode("subsystem=undertow/server=default-server/host=test", "add"); ModelNode addOp = createOpNode("subsystem=undertow/server=default-server/host=test", "add");
addOp.get("alias").add(virtualHost); addOp.get("alias").add(virtualHost);
addOp.get("default-web-module").set("some-test.war");


ModelNode rewrite = new ModelNode(); ModelNode rewrite = new ModelNode();
rewrite.get("condition").setEmptyList(); rewrite.get("condition").setEmptyList();
Expand Down
@@ -0,0 +1,160 @@
/*
* 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.wildfly.test.integration.web;

import static org.jboss.as.controller.client.helpers.ClientConstants.OUTCOME;
import static org.jboss.as.controller.client.helpers.ClientConstants.SUCCESS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ALLOW_RESOURCE_SERVICE_RESTART;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_HEADERS;
import static org.jboss.as.test.integration.management.util.ModelUtil.createOpNode;

import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.as.arquillian.api.ServerSetup;
import org.jboss.as.arquillian.api.ServerSetupTask;
import org.jboss.as.arquillian.container.ManagementClient;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.test.shared.TestSuiteEnvironment;
import org.jboss.dmr.ModelNode;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
* Test that default-web-module works as it should for scenarios:
* - default host on of single server
* - non-default host of single server
* - non default server
*
* @author Tomaz Cerar (c) 2015 Red Hat Inc.
*/

@RunWith(Arquillian.class)
@RunAsClient
@ServerSetup(VirtualHostTestCase.VirtualHostSetupTask.class)
//todo this test could probably be done in manual mode test with wildfly runner
public class VirtualHostTestCase {

public static class VirtualHostSetupTask implements ServerSetupTask {
@Override
public void setup(ManagementClient managementClient, String containerId) throws Exception {
ModelControllerClient client = managementClient.getControllerClient();
ModelNode addOp = createOpNode("subsystem=undertow/server=default-server/host=test", "add");
addOp.get("default-web-module").set("test.war");
addOp.get("alias").add(TestSuiteEnvironment.getServerAddress()); //either 127.0.0.1 or ::1
execute(client, addOp);

addOp = createOpNode("socket-binding-group=standard-sockets/socket-binding=myserver", "add");
addOp.get("port").set(8181);
execute(client, addOp);

addOp = createOpNode("subsystem=undertow/server=myserver", "add");
addOp.get("default-host").set("another");
execute(client, addOp);

addOp = createOpNode("subsystem=undertow/server=myserver/host=another", "add");
addOp.get("default-web-module").set("another-server.war");
execute(client, addOp);

addOp = createOpNode("subsystem=undertow/server=myserver/http-listener=myserver", "add");
addOp.get("socket-binding").set("myserver");
execute(client, addOp); //this one is runtime addable
}

private void execute(ModelControllerClient client, ModelNode op) throws IOException {
op.get(OPERATION_HEADERS, ALLOW_RESOURCE_SERVICE_RESTART).set(true);
ModelNode response = client.execute(op);
if (!SUCCESS.equals(response.get(OUTCOME).asString())) {
Assert.fail("Could not execute op: '" + op + "', result: " + response);
}
}

@Override
public void tearDown(ManagementClient managementClient, String containerId) throws Exception {
ModelControllerClient client = managementClient.getControllerClient();
execute(client, createOpNode("subsystem=undertow/server=default-server/host=test", "remove"));
execute(client, createOpNode("subsystem=undertow/server=myserver/host=another", "remove"));
execute(client, createOpNode("subsystem=undertow/server=myserver/http-listener=myserver", "remove"));
execute(client, createOpNode("subsystem=undertow/server=myserver", "remove"));
execute(client, createOpNode("socket-binding-group=standard-sockets/socket-binding=myserver", "remove"));
}
}

private static WebArchive createDeployment(String name) {
WebArchive war = ShrinkWrap.create(WebArchive.class, name + ".war");
war.addAsWebResource(new StringAsset(name), "index.html");
return war;
}

@Deployment(name = "ROOT")
public static Archive<?> getDefaultHostDeployment() {
return createDeployment("ROOT");
}

@Deployment(name = "test")
public static Archive<?> getAnotherHostDeployment() {
return createDeployment("test");
}

@Deployment(name = "another-server")
public static Archive<?> getAnotherServerDeployment() {
return createDeployment("another-server");
}

private void callAndTest(String uri, String expectedResult) throws IOException {
HttpClient client = HttpClients.createDefault();
HttpGet get = new HttpGet(uri);
HttpResponse response = client.execute(get);
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
String result = EntityUtils.toString(response.getEntity());
Assert.assertEquals("Got response from wrong deployment", expectedResult, result);
}

@Test
public void testDefaultHost() throws IOException {
callAndTest("http://localhost:8080/", "ROOT"); //this needs to be localhost, as it is by host mapping

This comment has been minimized.

Copy link
@jstourac

jstourac Nov 4, 2016

Contributor

Hi @ctomc - this test fails in our environment where we DO NOT execute tests on a localhost. Is it really neccessary to have it hardcoded here? If you need to have 'localhost' value here just to map to virtual host, I guess you could easily modify client request so you add it 'Host' header manually with required value (here localhost, some other value elsewhere). WDYT?

}

@Test
public void testNonDefaultHost() throws IOException {
callAndTest("http://" + TestSuiteEnvironment.getServerAddress() + ":8080/", "test"); //second host on first server has alias 127.0.0.1 or ::1
}

@Test
public void testAnotherServerHost() throws IOException {
callAndTest("http://" + TestSuiteEnvironment.getServerAddress() + ":8181/", "another-server");
}

}
Expand Up @@ -37,8 +37,9 @@


import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.OperationBuilder; import org.jboss.as.controller.client.OperationBuilder;
Expand All @@ -48,13 +49,12 @@
/** /**
* @author lbarreiro@redhat.com * @author lbarreiro@redhat.com
*/ */
public class RootContextUtil { public class RootContextUtil {


private static Logger log = Logger.getLogger(RootContextUtil.class); private static Logger log = Logger.getLogger(RootContextUtil.class);
private static String SERVER = "server"; private static String SERVER = "server";
private static String HOST = "host"; private static String HOST = "host";


private static String ENABLE_WELCOME_ROOT = "enable-welcome-root";
private static final String WEB_SUBSYSTEM_NAME = "undertow"; private static final String WEB_SUBSYSTEM_NAME = "undertow";


public static void createVirutalHost(ModelControllerClient client, String virtualHost) throws Exception { public static void createVirutalHost(ModelControllerClient client, String virtualHost) throws Exception {
Expand All @@ -65,6 +65,7 @@ public static void createVirutalHost(ModelControllerClient client, String virtua
op.get(OP_ADDR).add(SUBSYSTEM, WEB_SUBSYSTEM_NAME); op.get(OP_ADDR).add(SUBSYSTEM, WEB_SUBSYSTEM_NAME);
op.get(OP_ADDR).add(SERVER, "default-server"); op.get(OP_ADDR).add(SERVER, "default-server");
op.get(OP_ADDR).add(HOST, virtualHost); op.get(OP_ADDR).add(HOST, virtualHost);
op.get("default-web-module").set("somewar.war");


updates.add(op); updates.add(op);


Expand Down Expand Up @@ -115,7 +116,7 @@ public static void applyUpdates(final List<ModelNode> updates, final ModelContro
*/ */
public static String hitRootContext(Logger log, URL url, String serverName) throws Exception { public static String hitRootContext(Logger log, URL url, String serverName) throws Exception {
HttpGet httpget = new HttpGet(url.toURI()); HttpGet httpget = new HttpGet(url.toURI());
DefaultHttpClient httpclient = new DefaultHttpClient(); HttpClient httpclient = HttpClients.createDefault();
httpget.setHeader("Host", serverName); httpget.setHeader("Host", serverName);


log.info("executing request" + httpget.getRequestLine()); log.info("executing request" + httpget.getRequestLine());
Expand Down
Expand Up @@ -186,7 +186,7 @@ public void registerDeployment(final Deployment deployment, HttpHandler handler)
String path = getDeployedContextPath(deploymentInfo); String path = getDeployedContextPath(deploymentInfo);
registerHandler(path, handler); registerHandler(path, handler);
deployments.add(deployment); deployments.add(deployment);
UndertowLogger.ROOT_LOGGER.registerWebapp(path); UndertowLogger.ROOT_LOGGER.registerWebapp(path, getServer().getName());
undertowService.getValue().fireEvent(new EventInvoker() { undertowService.getValue().fireEvent(new EventInvoker() {
@Override @Override
public void invoke(UndertowEventListener listener) { public void invoke(UndertowEventListener listener) {
Expand All @@ -206,7 +206,7 @@ public void invoke(UndertowEventListener listener) {
}); });
unregisterHandler(path); unregisterHandler(path);
deployments.remove(deployment); deployments.remove(deployment);
UndertowLogger.ROOT_LOGGER.unregisterWebapp(path); UndertowLogger.ROOT_LOGGER.unregisterWebapp(path, getServer().getName());
} }


public void registerHandler(String path, HttpHandler handler) { public void registerHandler(String path, HttpHandler handler) {
Expand Down
Expand Up @@ -40,6 +40,7 @@
import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceController.Mode; import org.jboss.msc.service.ServiceController.Mode;
import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceName;
import org.wildfly.extension.undertow.deployment.DefaultDeploymentMappingProvider;


/** /**
* @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2013 Red Hat Inc. * @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2013 Red Hat Inc.
Expand All @@ -57,8 +58,8 @@ protected void performRuntime(OperationContext context, ModelNode operation, Mod
final PathAddress address = context.getCurrentAddress(); final PathAddress address = context.getCurrentAddress();
final PathAddress serverAddress = address.getParent(); final PathAddress serverAddress = address.getParent();
final PathAddress subsystemAddress = serverAddress.getParent(); final PathAddress subsystemAddress = serverAddress.getParent();
final ModelNode subsystemModel = Resource.Tools.readModel(context.readResourceFromRoot(subsystemAddress, false), 1); final ModelNode subsystemModel = Resource.Tools.readModel(context.readResourceFromRoot(subsystemAddress, false), 0);
final ModelNode serverModel = Resource.Tools.readModel(context.readResourceFromRoot(serverAddress, false), 1); final ModelNode serverModel = Resource.Tools.readModel(context.readResourceFromRoot(serverAddress, false), 0);


final String name = address.getLastElement().getValue(); final String name = address.getLastElement().getValue();
final List<String> aliases = HostDefinition.ALIAS.unwrap(context, model); final List<String> aliases = HostDefinition.ALIAS.unwrap(context, model);
Expand All @@ -69,6 +70,7 @@ protected void performRuntime(OperationContext context, ModelNode operation, Mod
final boolean isDefaultHost = defaultServerName.equals(serverName) && name.equals(defaultHostName); final boolean isDefaultHost = defaultServerName.equals(serverName) && name.equals(defaultHostName);
final int defaultResponseCode = HostDefinition.DEFAULT_RESPONSE_CODE.resolveModelAttribute(context, model).asInt(); final int defaultResponseCode = HostDefinition.DEFAULT_RESPONSE_CODE.resolveModelAttribute(context, model).asInt();
final boolean enableConsoleRedirect = !HostDefinition.DISABLE_CONSOLE_REDIRECT.resolveModelAttribute(context, model).asBoolean(); final boolean enableConsoleRedirect = !HostDefinition.DISABLE_CONSOLE_REDIRECT.resolveModelAttribute(context, model).asBoolean();
DefaultDeploymentMappingProvider.instance().addMapping(defaultWebModule, serverName, name);


final ServiceName virtualHostServiceName = UndertowService.virtualHostName(serverName, name); final ServiceName virtualHostServiceName = UndertowService.virtualHostName(serverName, name);


Expand Down
Expand Up @@ -26,12 +26,10 @@
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;


import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.AttributeMarshaller;
import org.jboss.as.controller.AttributeParser; import org.jboss.as.controller.AttributeParser;
import org.jboss.as.controller.DefaultAttributeMarshaller;
import org.jboss.as.controller.PersistentResourceDefinition; import org.jboss.as.controller.PersistentResourceDefinition;
import org.jboss.as.controller.SimpleAttributeDefinition; import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder; import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
Expand All @@ -53,21 +51,7 @@ class HostDefinition extends PersistentResourceDefinition {
.setElementValidator(new StringLengthValidator(1)) .setElementValidator(new StringLengthValidator(1))
.setAllowExpression(true) .setAllowExpression(true)
.setAttributeParser(AttributeParser.COMMA_DELIMITED_STRING_LIST) .setAttributeParser(AttributeParser.COMMA_DELIMITED_STRING_LIST)
.setAttributeMarshaller(new DefaultAttributeMarshaller() { .setAttributeMarshaller(AttributeMarshaller.COMMA_STRING_LIST)
@Override
public void marshallAsAttribute(AttributeDefinition attribute, ModelNode resourceModel, boolean marshallDefault, XMLStreamWriter writer) throws XMLStreamException {

StringBuilder builder = new StringBuilder();
if (resourceModel.hasDefined(attribute.getName())) {
for (ModelNode p : resourceModel.get(attribute.getName()).asList()) {
builder.append(p.asString()).append(", ");
}
}
if (builder.length() > 0) {
writer.writeAttribute(attribute.getXmlName(), builder.substring(0, builder.length() - 2));
}
}
})
.build(); .build();
static final SimpleAttributeDefinition DEFAULT_WEB_MODULE = new SimpleAttributeDefinitionBuilder(Constants.DEFAULT_WEB_MODULE, ModelType.STRING, true) static final SimpleAttributeDefinition DEFAULT_WEB_MODULE = new SimpleAttributeDefinitionBuilder(Constants.DEFAULT_WEB_MODULE, ModelType.STRING, true)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES) .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
Expand Down
Expand Up @@ -22,25 +22,24 @@


package org.wildfly.extension.undertow; package org.wildfly.extension.undertow;


import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;

import org.jboss.as.controller.AbstractRemoveStepHandler; import org.jboss.as.controller.AbstractRemoveStepHandler;
import org.jboss.as.controller.OperationContext; import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathAddress;
import org.jboss.as.web.host.WebHost; import org.jboss.as.web.host.WebHost;
import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelNode;
import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceName;
import org.wildfly.extension.undertow.deployment.DefaultDeploymentMappingProvider;


/** /**
* @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2013 Red Hat Inc. * @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2013 Red Hat Inc.
*/ */
class HostRemove extends AbstractRemoveStepHandler { class HostRemove extends AbstractRemoveStepHandler {


@Override @Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) { protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR)); final PathAddress address = context.getCurrentAddress();
final PathAddress parent = address.subAddress(0, address.size() - 1); final PathAddress parent = address.getParent();
final String name = address.getLastElement().getValue(); final String name = address.getLastElement().getValue();
final String serverName = parent.getLastElement().getValue(); final String serverName = parent.getLastElement().getValue();
final ServiceName virtualHostServiceName = UndertowService.virtualHostName(serverName, name); final ServiceName virtualHostServiceName = UndertowService.virtualHostName(serverName, name);
Expand All @@ -49,6 +48,8 @@ protected void performRuntime(OperationContext context, ModelNode operation, Mod
context.removeService(consoleRedirectName); context.removeService(consoleRedirectName);
final ServiceName commonHostName = WebHost.SERVICE_NAME.append(name); final ServiceName commonHostName = WebHost.SERVICE_NAME.append(name);
context.removeService(commonHostName); context.removeService(commonHostName);
final String defaultWebModule = HostDefinition.DEFAULT_WEB_MODULE.resolveModelAttribute(context, model).asString();
DefaultDeploymentMappingProvider.instance().removeMapping(defaultWebModule);
} }


protected void recoverServices(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException { protected void recoverServices(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
Expand Down
Expand Up @@ -22,7 +22,7 @@


package org.wildfly.extension.undertow; package org.wildfly.extension.undertow;


import org.jboss.as.controller.AbstractBoottimeAddStepHandler; import org.jboss.as.controller.AbstractAddStepHandler;
import org.jboss.as.controller.OperationContext; import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathAddress;
Expand All @@ -38,16 +38,16 @@
/** /**
* @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2013 Red Hat Inc. * @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2013 Red Hat Inc.
*/ */
class ServerAdd extends AbstractBoottimeAddStepHandler { class ServerAdd extends AbstractAddStepHandler {


ServerAdd() { ServerAdd() {
super(ServerDefinition.ATTRIBUTES); super(ServerDefinition.ATTRIBUTES);
} }


@Override @Override
protected void performBoottime(OperationContext context, ModelNode operation, Resource resource) throws OperationFailedException { protected void performRuntime(OperationContext context, ModelNode operation, Resource resource) throws OperationFailedException {
final PathAddress address = context.getCurrentAddress(); final PathAddress address = context.getCurrentAddress();
final PathAddress parentAddress = address.subAddress(0, address.size() - 1); final PathAddress parentAddress = address.getParent();
final ModelNode subsystemModel = Resource.Tools.readModel(context.readResourceFromRoot(parentAddress)); final ModelNode subsystemModel = Resource.Tools.readModel(context.readResourceFromRoot(parentAddress));


final String name = context.getCurrentAddressValue(); final String name = context.getCurrentAddressValue();
Expand Down

0 comments on commit 6958464

Please sign in to comment.