forked from open-telemetry/opentelemetry-java-contrib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTestAppContainer.java
152 lines (129 loc) · 5.07 KB
/
TestAppContainer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.contrib.jmxscraper;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.shaded.com.google.errorprone.annotations.CanIgnoreReturnValue;
import org.testcontainers.utility.MountableFile;
/** Test container that allows to execute {@link TestApp} in an isolated container */
public class TestAppContainer extends GenericContainer<TestAppContainer> {
private final Map<String, String> properties;
private String login;
private String pwd;
public TestAppContainer() {
super("openjdk:8u272-jre-slim");
this.properties = new HashMap<>();
String appJar = System.getProperty("app.jar.path");
assertThat(Paths.get(appJar)).isNotEmptyFile().isReadable();
this.withCopyFileToContainer(MountableFile.forHostPath(appJar), "/app.jar")
.waitingFor(
Wait.forLogMessage(TestApp.APP_STARTED_MSG + "\\n", 1)
.withStartupTimeout(Duration.ofSeconds(5)))
.withCommand("java", "-jar", "/app.jar");
}
/**
* Configures app container for container-to-container access
*
* @param port mapped port to use
* @return this
*/
@CanIgnoreReturnValue
public TestAppContainer withJmxPort(int port) {
properties.put("com.sun.management.jmxremote.port", Integer.toString(port));
return this;
}
@CanIgnoreReturnValue
public TestAppContainer withUserAuth(String login, String pwd) {
this.login = login;
this.pwd = pwd;
return this;
}
/**
* Configures app container for host-to-container access, port will be used as-is from host to
* work-around JMX in docker. This is optional on Linux as there is a network route and the
* container is accessible, but not on Mac where the container runs in an isolated VM.
*
* @param port port to use, must be available on host.
* @return this
*/
@CanIgnoreReturnValue
public TestAppContainer withHostAccessFixedJmxPort(int port) {
// To get host->container JMX connection working docker must expose JMX/RMI port under the same
// port number. Because of this testcontainers' standard exposed port randomization approach
// can't be used.
// Explanation:
// https://forums.docker.com/t/exposing-mapped-jmx-ports-from-multiple-containers/5287/6
properties.put("com.sun.management.jmxremote.port", Integer.toString(port));
properties.put("com.sun.management.jmxremote.rmi.port", Integer.toString(port));
properties.put("java.rmi.server.hostname", getHost());
addFixedExposedPort(port, port);
return this;
}
@Override
public void start() {
// properties.put("com.sun.management.jmxremote.local.only", "false");
// properties.put("java.rmi.server.logCalls", "true");
//
// TODO: add support for ssl
properties.put("com.sun.management.jmxremote.ssl", "false");
if (pwd == null) {
properties.put("com.sun.management.jmxremote.authenticate", "false");
} else {
properties.put("com.sun.management.jmxremote.authenticate", "true");
Path pwdFile = createPwdFile(login, pwd);
this.withCopyFileToContainer(MountableFile.forHostPath(pwdFile), "/jmx.password");
properties.put("com.sun.management.jmxremote.password.file", "/jmx.password");
Path accessFile = createAccessFile(login);
this.withCopyFileToContainer(MountableFile.forHostPath(accessFile), "/jmx.access");
properties.put("com.sun.management.jmxremote.access.file", "/jmx.access");
}
String confArgs =
properties.entrySet().stream()
.map(
e -> {
String s = "-D" + e.getKey();
if (!e.getValue().isEmpty()) {
s += "=" + e.getValue();
}
return s;
})
.collect(Collectors.joining(" "));
this.withEnv("JAVA_TOOL_OPTIONS", confArgs);
logger().info("Test application JAVA_TOOL_OPTIONS = {}", confArgs);
super.start();
}
private static Path createPwdFile(String login, String pwd) {
try {
Path path = Files.createTempFile("test", ".pwd");
writeLine(path, String.format("%s %s", login, pwd));
return path;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static Path createAccessFile(String login) {
try {
Path path = Files.createTempFile("test", ".pwd");
writeLine(path, String.format("%s %s", login, "readwrite"));
return path;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void writeLine(Path path, String line) throws IOException {
line = line + "\n";
Files.write(path, line.getBytes(StandardCharsets.UTF_8));
}
}