Convert Wildfly tests to run in Docker (#53159)
Backport of #53126. Convert the Wildfly tests to run using Docker Compose. This drastically simplifies the build setup, and will hopefully make the tests more resilient.
This commit is contained in:
parent
c2a2fcb5a1
commit
17de77fd0f
|
@ -116,6 +116,7 @@ subprojects {
|
||||||
':distribution:tools:launchers',
|
':distribution:tools:launchers',
|
||||||
':distribution:tools:plugin-cli',
|
':distribution:tools:plugin-cli',
|
||||||
':qa:os',
|
':qa:os',
|
||||||
|
':qa:wildfly',
|
||||||
':x-pack:plugin:autoscaling',
|
':x-pack:plugin:autoscaling',
|
||||||
':x-pack:plugin:enrich',
|
':x-pack:plugin:enrich',
|
||||||
':x-pack:plugin:logstash'
|
':x-pack:plugin:logstash'
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
import org.elasticsearch.gradle.LoggedExec
|
|
||||||
import org.elasticsearch.gradle.VersionProperties
|
|
||||||
import org.apache.tools.ant.taskdefs.condition.Os
|
|
||||||
import org.elasticsearch.gradle.testclusters.DefaultTestClustersTask
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.util.stream.Stream
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Licensed to Elasticsearch under one or more contributor
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
* license agreements. See the NOTICE file distributed with
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
@ -26,33 +17,14 @@ import java.util.stream.Stream
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import org.elasticsearch.gradle.VersionProperties
|
||||||
|
|
||||||
apply plugin: 'war'
|
apply plugin: 'war'
|
||||||
apply plugin: 'elasticsearch.testclusters'
|
|
||||||
apply plugin: 'elasticsearch.build'
|
apply plugin: 'elasticsearch.build'
|
||||||
apply plugin: 'elasticsearch.rest-test'
|
apply plugin: 'elasticsearch.test.fixtures'
|
||||||
|
apply plugin: 'elasticsearch.distribution-download'
|
||||||
|
|
||||||
final String wildflyVersion = '11.0.0.Final'
|
testFixtures.useFixture()
|
||||||
final String wildflyDir = "${buildDir}/wildfly"
|
|
||||||
final String wildflyInstall = "${buildDir}/wildfly/wildfly-${wildflyVersion}"
|
|
||||||
int managementPort
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
// the Wildfly distribution is not available via a repository, so we fake an Ivy repository on top of the download site
|
|
||||||
ivy {
|
|
||||||
name "wildfly"
|
|
||||||
url "https://download.jboss.org"
|
|
||||||
metadataSources {
|
|
||||||
artifact()
|
|
||||||
}
|
|
||||||
patternLayout {
|
|
||||||
artifact 'wildfly/[revision]/[module]-[revision].[ext]'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations {
|
|
||||||
wildfly
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
providedCompile 'javax.enterprise:cdi-api:1.2'
|
providedCompile 'javax.enterprise:cdi-api:1.2'
|
||||||
|
@ -72,164 +44,42 @@ dependencies {
|
||||||
compile "com.fasterxml.jackson.module:jackson-module-jaxb-annotations:${versions.jackson}"
|
compile "com.fasterxml.jackson.module:jackson-module-jaxb-annotations:${versions.jackson}"
|
||||||
compile "org.apache.logging.log4j:log4j-api:${versions.log4j}"
|
compile "org.apache.logging.log4j:log4j-api:${versions.log4j}"
|
||||||
compile "org.apache.logging.log4j:log4j-core:${versions.log4j}"
|
compile "org.apache.logging.log4j:log4j-core:${versions.log4j}"
|
||||||
compile project(path: ':client:transport', configuration: 'runtime')
|
compile project(path: ':client:rest-high-level')
|
||||||
wildfly "org.jboss:wildfly:${wildflyVersion}@zip"
|
|
||||||
testCompile project(':test:framework')
|
testCompile project(':test:framework')
|
||||||
}
|
}
|
||||||
|
|
||||||
task unzipWildfly(type: Sync) {
|
war {
|
||||||
into wildflyDir
|
archiveName 'example-app.war'
|
||||||
from { zipTree(configurations.wildfly.singleFile) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task deploy(type: Copy) {
|
elasticsearch_distributions {
|
||||||
dependsOn unzipWildfly, war
|
docker {
|
||||||
from war
|
type = 'docker'
|
||||||
into "${wildflyInstall}/standalone/deployments"
|
flavor = System.getProperty('tests.distribution', 'default')
|
||||||
}
|
version = VersionProperties.getElasticsearch()
|
||||||
|
failIfUnavailable = false // This ensures we skip this testing if Docker is unavailable
|
||||||
task writeElasticsearchProperties(type: DefaultTestClustersTask) {
|
|
||||||
onlyIf { !Os.isFamily(Os.FAMILY_WINDOWS) }
|
|
||||||
useCluster testClusters.integTest
|
|
||||||
dependsOn deploy
|
|
||||||
doLast {
|
|
||||||
final File elasticsearchProperties = file("${wildflyInstall}/standalone/configuration/elasticsearch.properties")
|
|
||||||
elasticsearchProperties.write(
|
|
||||||
[
|
|
||||||
"transport.uri=${-> testClusters.integTest.getAllTransportPortURI().get(0)}",
|
|
||||||
"cluster.name=integTest"
|
|
||||||
].join("\n"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the default configuration ships with IPv6 disabled but our cluster could be bound to IPv6 if the host supports it
|
preProcessFixture {
|
||||||
task enableIPv6 {
|
dependsOn war, elasticsearch_distributions.docker
|
||||||
dependsOn unzipWildfly
|
|
||||||
doLast {
|
|
||||||
final File standaloneConf = file("${wildflyInstall}/bin/standalone.conf")
|
|
||||||
final List<String> lines =
|
|
||||||
Files.readAllLines(standaloneConf.toPath())
|
|
||||||
.collect { line -> line.replace("-Djava.net.preferIPv4Stack=true", "-Djava.net.preferIPv4Stack=false") }
|
|
||||||
standaloneConf.write(lines.join("\n"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task startWildfly {
|
dockerCompose {
|
||||||
dependsOn enableIPv6, writeElasticsearchProperties
|
if ('default'.equalsIgnoreCase(System.getProperty('tests.distribution', 'default'))) {
|
||||||
doLast {
|
useComposeFiles = ['docker-compose.yml']
|
||||||
// we skip these tests on Windows so we do no need to worry about compatibility here
|
|
||||||
final ProcessBuilder wildfly = new ProcessBuilder(
|
|
||||||
"${wildflyInstall}/bin/standalone.sh",
|
|
||||||
"-Djboss.http.port=0",
|
|
||||||
"-Djboss.https.port=0",
|
|
||||||
"-Djboss.management.http.port=0")
|
|
||||||
final Process process = wildfly.start()
|
|
||||||
new BufferedReader(new InputStreamReader(process.getInputStream())).withReader { br ->
|
|
||||||
String line
|
|
||||||
int httpPort = 0
|
|
||||||
while ((line = br.readLine()) != null) {
|
|
||||||
logger.info(line)
|
|
||||||
if (line.matches('.*Undertow HTTP listener default listening on .*:\\d+$')) {
|
|
||||||
assert httpPort == 0
|
|
||||||
final int index = line.lastIndexOf(":")
|
|
||||||
assert index >= 0
|
|
||||||
httpPort = Integer.parseInt(line.substring(index + 1))
|
|
||||||
// set this system property so the test runner knows the port Wildfly is listening for HTTP requests on
|
|
||||||
integTestRunner.systemProperty("tests.jboss.root", "http://localhost:$httpPort/wildfly-$version/transport")
|
|
||||||
} else if (line.matches('.*Http management interface listening on http://.*:\\d+/management$')) {
|
|
||||||
assert managementPort == 0
|
|
||||||
final int colonIndex = line.lastIndexOf(":")
|
|
||||||
assert colonIndex >= 0
|
|
||||||
final int slashIndex = line.lastIndexOf("/")
|
|
||||||
assert slashIndex >= 0
|
|
||||||
managementPort = Integer.parseInt(line.substring(colonIndex + 1, slashIndex))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* As soon as we know the management port, we fork a process that will ensure the Wildfly process is killed if we
|
|
||||||
* teardown abnormally. We skip these tests on Windows so we do not need to worry about CLI compatibility here.
|
|
||||||
*/
|
|
||||||
final File script = new File(project.buildDir, "wildfly/wildfly.killer.sh")
|
|
||||||
script.setText(
|
|
||||||
["function shutdown {",
|
|
||||||
" ${wildflyInstall}/bin/jboss-cli.sh --controller=localhost:${-> managementPort} --connect command=shutdown",
|
|
||||||
"}",
|
|
||||||
"trap shutdown EXIT",
|
|
||||||
// will wait indefinitely for input, but we never pass input, and the pipe is only closed when the build dies
|
|
||||||
"read line\n"].join('\n'), 'UTF-8')
|
|
||||||
final ProcessBuilder killer = new ProcessBuilder("bash", script.absolutePath)
|
|
||||||
killer.start()
|
|
||||||
|
|
||||||
} else if (line.matches(".*WildFly Full \\d+\\.\\d+\\.\\d+\\.Final \\(WildFly Core \\d+\\.\\d+\\.\\d+\\.Final\\) started.*")) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (httpPort == 0 || managementPort == 0) {
|
|
||||||
String portType = httpPort == 0 ? "http" : "management"
|
|
||||||
throw new GradleException("Failed to find ${portType} port in wildfly log")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task configureTransportClient(type: LoggedExec) {
|
|
||||||
dependsOn startWildfly
|
|
||||||
// we skip these tests on Windows so we do not need to worry about compatibility here
|
|
||||||
commandLine "${wildflyInstall}/bin/jboss-cli.sh",
|
|
||||||
"--controller=localhost:${-> managementPort}",
|
|
||||||
"--connect",
|
|
||||||
"--command=/system-property=elasticsearch.properties:add(value=\${jboss.server.config.dir}/elasticsearch.properties)"
|
|
||||||
}
|
|
||||||
|
|
||||||
task stopWildfly(type: LoggedExec) {
|
|
||||||
// we skip these tests on Windows so we do not need to worry about CLI compatibility here
|
|
||||||
commandLine "${wildflyInstall}/bin/jboss-cli.sh", "--controller=localhost:${-> managementPort}", "--connect", "command=shutdown"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
||||||
integTestRunner.dependsOn(configureTransportClient)
|
|
||||||
final TaskExecutionAdapter logDumpListener = new TaskExecutionAdapter() {
|
|
||||||
@Override
|
|
||||||
void afterExecute(final Task task, final TaskState state) {
|
|
||||||
if (task != startWildfly && task != integTestRunner) {
|
|
||||||
// we might have been called from a parallel, unrelated task
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (state.failure != null) {
|
|
||||||
final File logFile = new File(wildflyInstall, "standalone/log/server.log")
|
|
||||||
println("\nWildfly server log (from ${logFile}):")
|
|
||||||
println('-----------------------------------------')
|
|
||||||
final Stream<String> stream = Files.lines(logFile.toPath(), StandardCharsets.UTF_8)
|
|
||||||
try {
|
|
||||||
for (String line : stream) {
|
|
||||||
println(line)
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
stream.close()
|
|
||||||
}
|
|
||||||
println('=========================================')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startWildfly.doFirst {
|
|
||||||
project.gradle.addListener(logDumpListener)
|
|
||||||
}
|
|
||||||
integTestRunner.doFirst {
|
|
||||||
project.gradle.addListener(logDumpListener)
|
|
||||||
}
|
|
||||||
integTestRunner.doLast {
|
|
||||||
project.gradle.removeListener(logDumpListener)
|
|
||||||
}
|
|
||||||
startWildfly.doLast {
|
|
||||||
project.gradle.removeListener(logDumpListener)
|
|
||||||
}
|
|
||||||
integTestRunner.finalizedBy(stopWildfly)
|
|
||||||
} else {
|
} else {
|
||||||
integTest.enabled = false
|
useComposeFiles = ['docker-compose-oss.yml']
|
||||||
testingConventions.enabled = false
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check.dependsOn(integTest)
|
task integTest(type: Test) {
|
||||||
|
outputs.doNotCacheIf('Build cache is disabled for Docker tests') { true }
|
||||||
|
maxParallelForks = '1'
|
||||||
|
include '**/*IT.class'
|
||||||
|
}
|
||||||
|
|
||||||
|
check.dependsOn integTest
|
||||||
|
|
||||||
test.enabled = false
|
test.enabled = false
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
|
||||||
|
wildfly:
|
||||||
|
image: jboss/wildfly:18.0.1.Final
|
||||||
|
environment:
|
||||||
|
JAVA_OPTS: -Delasticsearch.uri=elasticsearch:9200 -Djboss.http.port=8080 -Djava.net.preferIPv4Stack=true
|
||||||
|
volumes:
|
||||||
|
- ./build/distributions/example-app.war:/opt/jboss/wildfly/standalone/deployments/example-app.war
|
||||||
|
ports:
|
||||||
|
- "8080"
|
||||||
|
healthcheck:
|
||||||
|
start_period: 5s
|
||||||
|
test: ["CMD", "grep", "Admin console listening on", "/opt/jboss/wildfly/standalone/log/server.log"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 1s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
elasticsearch:
|
||||||
|
image: elasticsearch-oss:test
|
||||||
|
environment:
|
||||||
|
discovery.type: single-node
|
||||||
|
ulimits:
|
||||||
|
memlock:
|
||||||
|
soft: -1
|
||||||
|
hard: -1
|
||||||
|
nofile:
|
||||||
|
soft: 65536
|
||||||
|
hard: 65536
|
||||||
|
healthcheck:
|
||||||
|
start_period: 15s
|
||||||
|
test: ["CMD", "curl", "-f", "-k", "http://localhost:9200"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 2s
|
||||||
|
retries: 5
|
|
@ -0,0 +1,35 @@
|
||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
|
||||||
|
wildfly:
|
||||||
|
image: jboss/wildfly:18.0.1.Final
|
||||||
|
environment:
|
||||||
|
JAVA_OPTS: -Delasticsearch.uri=elasticsearch:9200 -Djboss.http.port=8080 -Djava.net.preferIPv4Stack=true
|
||||||
|
volumes:
|
||||||
|
- ./build/distributions/example-app.war:/opt/jboss/wildfly/standalone/deployments/example-app.war
|
||||||
|
ports:
|
||||||
|
- "8080"
|
||||||
|
healthcheck:
|
||||||
|
start_period: 5s
|
||||||
|
test: ["CMD", "grep", "Admin console listening on", "/opt/jboss/wildfly/standalone/log/server.log"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 1s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
elasticsearch:
|
||||||
|
image: elasticsearch:test
|
||||||
|
environment:
|
||||||
|
discovery.type: single-node
|
||||||
|
ulimits:
|
||||||
|
memlock:
|
||||||
|
soft: -1
|
||||||
|
hard: -1
|
||||||
|
nofile:
|
||||||
|
soft: 65536
|
||||||
|
hard: 65536
|
||||||
|
healthcheck:
|
||||||
|
start_period: 15s
|
||||||
|
test: ["CMD", "curl", "-f", "-k", "http://localhost:9200"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 2s
|
||||||
|
retries: 5
|
|
@ -26,11 +26,11 @@ import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ApplicationPath("/transport")
|
@ApplicationPath("/transport")
|
||||||
public class TransportClientActivator extends Application {
|
public class RestHighLevelClientActivator extends Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Class<?>> getClasses() {
|
public Set<Class<?>> getClasses() {
|
||||||
return Collections.singleton(TransportClientEmployeeResource.class);
|
return Collections.singleton(RestHighLevelClientEmployeeResource.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,9 +19,12 @@
|
||||||
|
|
||||||
package org.elasticsearch.wildfly.transport;
|
package org.elasticsearch.wildfly.transport;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.get.GetRequest;
|
||||||
import org.elasticsearch.action.get.GetResponse;
|
import org.elasticsearch.action.get.GetResponse;
|
||||||
|
import org.elasticsearch.action.index.IndexRequest;
|
||||||
import org.elasticsearch.action.index.IndexResponse;
|
import org.elasticsearch.action.index.IndexResponse;
|
||||||
import org.elasticsearch.client.transport.TransportClient;
|
import org.elasticsearch.client.RequestOptions;
|
||||||
|
import org.elasticsearch.client.RestHighLevelClient;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.wildfly.model.Employee;
|
import org.elasticsearch.wildfly.model.Employee;
|
||||||
|
|
||||||
|
@ -33,7 +36,6 @@ import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
@ -44,17 +46,17 @@ import java.util.Objects;
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
|
|
||||||
@Path("/employees")
|
@Path("/employees")
|
||||||
public class TransportClientEmployeeResource {
|
public class RestHighLevelClientEmployeeResource {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TransportClient client;
|
private RestHighLevelClient client;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Response getEmployeeById(final @PathParam("id") Long id) {
|
public Response getEmployeeById(final @PathParam("id") Long id) throws IOException {
|
||||||
Objects.requireNonNull(id);
|
Objects.requireNonNull(id);
|
||||||
final GetResponse response = client.prepareGet("megacorp", "employee", Long.toString(id)).get();
|
final GetResponse response = client.get(new GetRequest("megacorp", Long.toString(id)), RequestOptions.DEFAULT);
|
||||||
if (response.isExists()) {
|
if (response.isExists()) {
|
||||||
final Map<String, Object> source = response.getSource();
|
final Map<String, Object> source = response.getSource();
|
||||||
final Employee employee = new Employee();
|
final Employee employee = new Employee();
|
||||||
|
@ -62,7 +64,8 @@ public class TransportClientEmployeeResource {
|
||||||
employee.setLastName((String) source.get("last_name"));
|
employee.setLastName((String) source.get("last_name"));
|
||||||
employee.setAge((Integer) source.get("age"));
|
employee.setAge((Integer) source.get("age"));
|
||||||
employee.setAbout((String) source.get("about"));
|
employee.setAbout((String) source.get("about"));
|
||||||
@SuppressWarnings("unchecked") final List<String> interests = (List<String>) source.get("interests");
|
@SuppressWarnings("unchecked")
|
||||||
|
final List<String> interests = (List<String>) source.get("interests");
|
||||||
employee.setInterests(interests);
|
employee.setInterests(interests);
|
||||||
return Response.ok(employee).build();
|
return Response.ok(employee).build();
|
||||||
} else {
|
} else {
|
||||||
|
@ -94,7 +97,10 @@ public class TransportClientEmployeeResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
final IndexResponse response = client.prepareIndex("megacorp", "employee", Long.toString(id)).setSource(builder).get();
|
final IndexRequest request = new IndexRequest("megacorp");
|
||||||
|
request.id(Long.toString(id));
|
||||||
|
request.source(builder);
|
||||||
|
final IndexResponse response = client.index(request, RequestOptions.DEFAULT);
|
||||||
if (response.status().getStatus() == 201) {
|
if (response.status().getStatus() == 201) {
|
||||||
return Response.created(new URI("/employees/" + id)).build();
|
return Response.created(new URI("/employees/" + id)).build();
|
||||||
} else {
|
} else {
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.wildfly.transport;
|
||||||
|
|
||||||
|
import org.apache.http.HttpHost;
|
||||||
|
import org.elasticsearch.client.RestClient;
|
||||||
|
import org.elasticsearch.client.RestHighLevelClient;
|
||||||
|
import org.elasticsearch.common.SuppressForbidden;
|
||||||
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
|
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class RestHighLevelClientProducer {
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
public RestHighLevelClient createRestHighLevelClient() {
|
||||||
|
String httpUri = System.getProperty("elasticsearch.uri");
|
||||||
|
|
||||||
|
return new RestHighLevelClient(RestClient.builder(HttpHost.create(httpUri)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressForbidden(reason = "get path not configured in environment")
|
||||||
|
private Path getPath(final String elasticsearchProperties) {
|
||||||
|
return PathUtils.get(elasticsearchProperties);
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,5 +24,6 @@ import org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider;
|
||||||
import javax.ws.rs.ext.Provider;
|
import javax.ws.rs.ext.Provider;
|
||||||
|
|
||||||
@Provider
|
@Provider
|
||||||
public class TransportJacksonJsonProvider extends ResteasyJackson2Provider {
|
public class RestHighLevelJacksonJsonProvider extends ResteasyJackson2Provider {
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.wildfly.transport;
|
|
||||||
|
|
||||||
import org.elasticsearch.client.transport.TransportClient;
|
|
||||||
import org.elasticsearch.common.SuppressForbidden;
|
|
||||||
import org.elasticsearch.common.io.PathUtils;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.transport.TransportAddress;
|
|
||||||
import org.elasticsearch.transport.client.PreBuiltTransportClient;
|
|
||||||
|
|
||||||
import javax.enterprise.inject.Produces;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public final class TransportClientProducer {
|
|
||||||
|
|
||||||
@Produces
|
|
||||||
public TransportClient createTransportClient() throws IOException {
|
|
||||||
final String elasticsearchProperties = System.getProperty("elasticsearch.properties");
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
|
|
||||||
final String transportUri;
|
|
||||||
final String clusterName;
|
|
||||||
try (InputStream is = Files.newInputStream(getPath(elasticsearchProperties))) {
|
|
||||||
properties.load(is);
|
|
||||||
transportUri = properties.getProperty("transport.uri");
|
|
||||||
clusterName = properties.getProperty("cluster.name");
|
|
||||||
}
|
|
||||||
|
|
||||||
final int lastColon = transportUri.lastIndexOf(':');
|
|
||||||
final String host = transportUri.substring(0, lastColon);
|
|
||||||
final int port = Integer.parseInt(transportUri.substring(lastColon + 1));
|
|
||||||
final Settings settings = Settings.builder().put("cluster.name", clusterName).build();
|
|
||||||
final TransportClient transportClient = new PreBuiltTransportClient(settings, Collections.emptyList());
|
|
||||||
transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName(host), port));
|
|
||||||
return transportClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressForbidden(reason = "get path not configured in environment")
|
|
||||||
private Path getPath(final String elasticsearchProperties) {
|
|
||||||
return PathUtils.get(elasticsearchProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -32,10 +32,8 @@ import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
import org.apache.lucene.util.TestRuleLimitSysouts;
|
import org.apache.lucene.util.TestRuleLimitSysouts;
|
||||||
import org.elasticsearch.cluster.ClusterModule;
|
import org.elasticsearch.cluster.ClusterModule;
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.xcontent.DeprecationHandler;
|
import org.elasticsearch.common.xcontent.DeprecationHandler;
|
||||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
|
|
||||||
|
@ -43,10 +41,8 @@ import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
@ -54,50 +50,62 @@ import static org.hamcrest.Matchers.instanceOf;
|
||||||
@TestRuleLimitSysouts.Limit(bytes = 14000)
|
@TestRuleLimitSysouts.Limit(bytes = 14000)
|
||||||
public class WildflyIT extends LuceneTestCase {
|
public class WildflyIT extends LuceneTestCase {
|
||||||
|
|
||||||
Logger logger = LogManager.getLogger(WildflyIT.class);
|
private Logger logger = LogManager.getLogger(WildflyIT.class);
|
||||||
|
|
||||||
public void testTransportClient() throws URISyntaxException, IOException {
|
private String buildBaseUrl() {
|
||||||
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
|
final String propertyName = "test.fixtures.wildfly.tcp.8080";
|
||||||
final String str = String.format(
|
final String port = System.getProperty(propertyName);
|
||||||
Locale.ROOT,
|
if (port == null) {
|
||||||
"%s/employees/1",
|
throw new IllegalStateException(
|
||||||
System.getProperty("tests.jboss.root")
|
"Could not find system property "
|
||||||
|
+ propertyName
|
||||||
|
+ ". This test expects to run with the elasticsearch.test.fixtures Gradle plugin"
|
||||||
);
|
);
|
||||||
logger.info("Connecting to uri: " + str);
|
|
||||||
final HttpPut put = new HttpPut(new URI(str));
|
|
||||||
final String body;
|
|
||||||
try (XContentBuilder builder = jsonBuilder()) {
|
|
||||||
builder.startObject();
|
|
||||||
{
|
|
||||||
builder.field("first_name", "John");
|
|
||||||
builder.field("last_name", "Smith");
|
|
||||||
builder.field("age", 25);
|
|
||||||
builder.field("about", "I love to go rock climbing");
|
|
||||||
builder.startArray("interests");
|
|
||||||
{
|
|
||||||
builder.value("sports");
|
|
||||||
builder.value("music");
|
|
||||||
}
|
}
|
||||||
builder.endArray();
|
return "http://localhost:" + port + "/example-app/transport";
|
||||||
}
|
|
||||||
builder.endObject();
|
|
||||||
body = Strings.toString(builder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRestClient() throws URISyntaxException, IOException {
|
||||||
|
final String baseUrl = buildBaseUrl();
|
||||||
|
|
||||||
|
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
|
||||||
|
final String endpoint = baseUrl + "/employees/1";
|
||||||
|
logger.info("Connecting to uri: " + baseUrl);
|
||||||
|
|
||||||
|
final HttpPut put = new HttpPut(new URI(endpoint));
|
||||||
|
|
||||||
|
final String body = "{"
|
||||||
|
+ " \"first_name\": \"John\","
|
||||||
|
+ " \"last_name\": \"Smith\","
|
||||||
|
+ " \"age\": 25,"
|
||||||
|
+ " \"about\": \"I love to go rock climbing\","
|
||||||
|
+ " \"interests\": ["
|
||||||
|
+ " \"sports\","
|
||||||
|
+ " \"music\""
|
||||||
|
+ " ]"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
put.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON));
|
put.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON));
|
||||||
try (CloseableHttpResponse response = client.execute(put)) {
|
try (CloseableHttpResponse response = client.execute(put)) {
|
||||||
int status = response.getStatusLine().getStatusCode();
|
int status = response.getStatusLine().getStatusCode();
|
||||||
assertThat("expected a 201 response but got: " + status + " - body: " + EntityUtils.toString(response.getEntity()),
|
assertThat(
|
||||||
status, equalTo(201));
|
"expected a 201 response but got: " + status + " - body: " + EntityUtils.toString(response.getEntity()),
|
||||||
|
status,
|
||||||
|
equalTo(201)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final HttpGet get = new HttpGet(new URI(str));
|
logger.info("Fetching resource at " + endpoint);
|
||||||
|
|
||||||
|
final HttpGet get = new HttpGet(new URI(endpoint));
|
||||||
try (
|
try (
|
||||||
CloseableHttpResponse response = client.execute(get);
|
CloseableHttpResponse response = client.execute(get);
|
||||||
XContentParser parser =
|
XContentParser parser = JsonXContent.jsonXContent.createParser(
|
||||||
JsonXContent.jsonXContent.createParser(
|
|
||||||
new NamedXContentRegistry(ClusterModule.getNamedXWriteables()),
|
new NamedXContentRegistry(ClusterModule.getNamedXWriteables()),
|
||||||
DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
|
DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
|
||||||
response.getEntity().getContent())) {
|
response.getEntity().getContent()
|
||||||
|
)
|
||||||
|
) {
|
||||||
final Map<String, Object> map = parser.map();
|
final Map<String, Object> map = parser.map();
|
||||||
assertThat(map.get("first_name"), equalTo("John"));
|
assertThat(map.get("first_name"), equalTo("John"));
|
||||||
assertThat(map.get("last_name"), equalTo("Smith"));
|
assertThat(map.get("last_name"), equalTo("Smith"));
|
||||||
|
@ -105,7 +113,8 @@ public class WildflyIT extends LuceneTestCase {
|
||||||
assertThat(map.get("about"), equalTo("I love to go rock climbing"));
|
assertThat(map.get("about"), equalTo("I love to go rock climbing"));
|
||||||
final Object interests = map.get("interests");
|
final Object interests = map.get("interests");
|
||||||
assertThat(interests, instanceOf(List.class));
|
assertThat(interests, instanceOf(List.class));
|
||||||
@SuppressWarnings("unchecked") final List<String> interestsAsList = (List<String>) interests;
|
@SuppressWarnings("unchecked")
|
||||||
|
final List<String> interestsAsList = (List<String>) interests;
|
||||||
assertThat(interestsAsList, containsInAnyOrder("sports", "music"));
|
assertThat(interestsAsList, containsInAnyOrder("sports", "music"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue