Skip to content

Commit

Permalink
[WFARQ-120] Add the ability to override the protocol and socket bindi…
Browse files Browse the repository at this point in the history
…ngs for domain testing.

https://issues.redhat.com/browse/WFARQ-120
Signed-off-by: James R. Perkins <jperkins@redhat.com>
  • Loading branch information
jamezp committed Nov 3, 2022
1 parent 4dd66f3 commit 38b58d8
Show file tree
Hide file tree
Showing 12 changed files with 625 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public class CommonDomainContainerConfiguration implements ContainerConfiguratio
private String password;
private String authenticationConfig;

private String protocol = "http";
private String socketBindingName;

private Map<String, String> containerNameMap;

private Map<String, String> containerModeMap;
Expand Down Expand Up @@ -178,11 +181,58 @@ public void setAuthenticationConfig(final String authenticationConfig) {
this.authenticationConfig = authenticationConfig;
}

/**
* Returns the protocol to for HTTP connections. This currently only supports http and https with a default of http.
*
* @return the protocol
*/
public String getProtocol() {
return protocol;
}

/**
* Sets the protocol for HTTP connections. If {@code null} the default of http is used.
*
* @param protocol the protocol to use, this must be http or https
*/
public void setProtocol(final String protocol) {
this.protocol = protocol == null ? "http" : protocol;
if (!("http".equalsIgnoreCase(this.protocol) || "https".equalsIgnoreCase(this.protocol))) {
throw new ConfigurationException("Only http and https are allowed protocol settings, found " + protocol);
}
}

/**
* Returns the socket binding name to use.
*
* @return the socket binding name or {@code null} to discover one
*/
public String getSocketBindingName() {
return socketBindingName;
}

/**
* Sets the socket binding name to use for determining the host and port for HTTP connections. This can be used to
* override discovering the first binding name.
* <p>
* The socket binding name is configured in WildFly. If this is not set, one will be determined from the Undertow
* subsystem.
* </p>
*
* @param socketBindingName the socket binding name or {@code null} for one to be determined
*/
public void setSocketBindingName(final String socketBindingName) {
this.socketBindingName = socketBindingName;
}

@Override
public void validate() throws ConfigurationException {
if (username != null && password == null) {
throw new ConfigurationException("username has been set, but no password given");
}
if (protocol != null && !("http".equalsIgnoreCase(protocol) || "https".equalsIgnoreCase(protocol))) {
throw new ConfigurationException("Only http and https are allowed protocol settings, found " + protocol);
}
}

private Map<String, String> convertToMap(String data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void setup(T config) {
// Register on setup so these can be injected into manual mode client tests
final DomainClient domainClient = DomainClient.Factory.create(new DelegatingModelControllerClient(DomainDelegateProvider.INSTANCE));
domainManager = new ContainerDomainManager(getContainerName(), isControllable(), domainClient);
managementClient = new ManagementClient(domainClient, domainManager);
managementClient = new ManagementClient(domainClient, config, domainManager);
managementClientInst.set(managementClient);

ArchiveDeployer archiveDeployer = new ArchiveDeployer(managementClient);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ public class ManagementClient {
private static final String SUBDEPLOYMENT = "subdeployment";
private static final String UNDERTOW = "undertow";

private static final String PROTOCOL_HTTP = "http";

private static final String NAME = "name";
private static final String SERVLET = "servlet";

Expand All @@ -79,6 +77,7 @@ public class ManagementClient {
private final DomainClient client;
private final DomainClient userClient;
private final Map<String, URI> subsystemURICache;
private final CommonDomainContainerConfiguration configuration;
private final DomainManager domainManager;

// cache static RootNode
Expand All @@ -89,12 +88,27 @@ public class ManagementClient {
*
* @param client the client to delegate management operations to
* @param domainManager the domain manager
*
* @deprecated use {@link ManagementClient#ManagementClient(ModelControllerClient, CommonDomainContainerConfiguration, DomainManager)}
*/
@Deprecated
protected ManagementClient(final ModelControllerClient client, final DomainManager domainManager) {
this(client, new CommonDomainContainerConfiguration(), domainManager);
}

/**
* Creates a new management client.
*
* @param client the client to delegate management operations to
* @param configuration the arquillian.xml configuration
* @param domainManager the domain manager
*/
protected ManagementClient(final ModelControllerClient client, final CommonDomainContainerConfiguration configuration, final DomainManager domainManager) {
if (client == null) {
throw new IllegalArgumentException("Client must be specified");
}
this.client = (client instanceof DomainClient ? ((DomainClient) client) : DomainClient.Factory.create(client));
this.configuration = configuration;
this.subsystemURICache = new HashMap<>();
userClient = DomainClient.Factory.create(new NonClosingDomainClient(client));
this.domainManager = domainManager;
Expand Down Expand Up @@ -170,8 +184,9 @@ public String getServerState(Domain.Server server) {

public HTTPContext getHTTPDeploymentMetaData(Server server, String uniqueDeploymentName) {

URI webURI = getProtocolURI(server, PROTOCOL_HTTP);
HTTPContext context = new HTTPContext(webURI.getHost(), webURI.getPort());
final String protocol = configuration.getProtocol();
final URI webURI = getProtocolURI(server, protocol);
HTTPContext context = new SecureHttpContext(webURI.getHost(), webURI.getPort(), "https".equalsIgnoreCase(protocol));
try {
ModelNode deploymentNode = readResource(createHostServerDeploymentAddress(
server.getHost(), server.getName(), uniqueDeploymentName));
Expand Down Expand Up @@ -283,10 +298,12 @@ private URI getProtocolURI(Server server, String subsystem) {

private URI extractProtocolURI(Server server, String protocol) {
try {
final String socketBindingGroup = getSocketBindingGroup(server.getGroup());
ModelNode node = readResource(createHostServerSocketBindingsAddress(server.getHost(), server.getName(),
getSocketBindingGroup(server.getGroup())));
socketBindingGroup));

ModelNode socketBinding = node.get(SOCKET_BINDING).get(protocol);
final String socketBindingName = configuration.getSocketBindingName();
ModelNode socketBinding = node.get(SOCKET_BINDING).get(socketBindingName == null ? "http" : socketBindingName);
return URI.create(protocol + "://" + socketBinding.get("bound-address").asString() + ":"
+ socketBinding.get("bound-port"));

Expand Down Expand Up @@ -443,4 +460,70 @@ public void close() throws IOException {
}
}

private static class SecureHttpContext extends HTTPContext {
private final boolean secure;

public SecureHttpContext(final String host, final int port, final boolean secure) {
super(host, port);
this.secure = secure;
}

@Override
public HTTPContext add(final Servlet servlet) {
return super.add(SchemeServlet.of(servlet, this, secure ? "https" : "http"));
}
}

private static class SchemeServlet extends Servlet {
private final String scheme;
private final String host;
private final int port;

private SchemeServlet(final String name, final String contextRoot, final String scheme, final String host, final int port) {
super(name, contextRoot);
this.scheme = scheme;
this.host = host;
this.port = port;
}

static SchemeServlet of(final Servlet servlet, final HTTPContext context, final String scheme) {
return new SchemeServlet(servlet.getName(), servlet.getContextRoot(), scheme, context.getHost(), context.getPort());
}

@Override
public URI getBaseURI() {
return URI.create(getBaseURIAsString(getContextRoot()));
}

@Override
public URI getFullURI() {
return URI.create(getBaseURIAsString(getContextRoot(), getName()));
}

private String getBaseURIAsString(final String... paths) {
final StringBuilder result = new StringBuilder()
.append(scheme)
.append("://")
.append(host)
.append(':')
.append(port);
for (String path : paths) {
if (path.isEmpty() || path.charAt(0) != '/') {
result.append('/').append(path);
} else {
result.append(path);
}
}
if (result.charAt(result.length() - 1) != '/') {
result.append('/');
}
return result.toString();
}

@Override
public String toString() {
return "SchemeServlet [name=" + getName() + ", contextRoot=" + getContextRoot() + ", scheme=" + scheme + "]";
}
}

}
135 changes: 135 additions & 0 deletions integration-tests/domain/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2022 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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.wildfly.arquillian</groupId>
<artifactId>integration-tests</artifactId>
<version>5.0.0.Alpha6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>domain</artifactId>
<name>WildFly: Arquillian Domain Integration Tests</name>

<dependencies>
<!-- Test Dependencies -->
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit5</groupId>
<artifactId>arquillian-junit5-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet-jakarta</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.ejb</groupId>
<artifactId>jakarta.ejb-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
<!-- Required by okhttp, but also transitive to it causing a dependency convergence -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wildfly.arquillian</groupId>
<artifactId>wildfly-arquillian-container-domain-managed</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.jboss.galleon</groupId>
<artifactId>galleon-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<jboss.home>${jboss.home}</jboss.home>
</systemPropertyVariables>
<environmentVariables>
<JBOSS_HOME>${jboss.home}</JBOSS_HOME>
</environmentVariables>
</configuration>
<executions>
<execution>
<id>default-test</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<groups>!OverrideWebUri</groups>
</configuration>
</execution>
<execution>
<id>override-web-uri</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<groups>OverrideWebUri</groups>
<systemPropertyVariables>
<arquillian.xml>override-web-uri-arquillian.xml</arquillian.xml>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Loading

0 comments on commit 38b58d8

Please sign in to comment.