Skip to content

Commit 10cac0a

Browse files
committed
Implement unit tests. Minor refactoring. Migrate to JDK 21 to support Virtual Threads.
1 parent bd1f202 commit 10cac0a

File tree

11 files changed

+175
-91
lines changed

11 files changed

+175
-91
lines changed

java-components/domain-proxy/client/pom.xml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,6 @@
1414
<groupId>io.quarkus</groupId>
1515
<artifactId>quarkus-arc</artifactId>
1616
</dependency>
17-
<dependency>
18-
<groupId>io.quarkus</groupId>
19-
<artifactId>quarkus-junit5</artifactId>
20-
<scope>test</scope>
21-
</dependency>
22-
<dependency>
23-
<groupId>io.rest-assured</groupId>
24-
<artifactId>rest-assured</artifactId>
25-
<scope>test</scope>
26-
</dependency>
2717
<dependency>
2818
<groupId>io.github.redhat-appstudio.jvmbuild</groupId>
2919
<artifactId>domain-proxy-common</artifactId>
@@ -41,7 +31,6 @@
4131
<goals>
4232
<goal>build</goal>
4333
<goal>generate-code</goal>
44-
<goal>generate-code-tests</goal>
4534
</goals>
4635
</execution>
4736
</executions>

java-components/domain-proxy/client/src/main/java/com/redhat/hacbs/domainproxy/client/DomainProxyClient.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.redhat.hacbs.domainproxy.client;
22

3+
import static com.redhat.hacbs.domainproxy.common.CommonIOUtil.createChannelToSocketWriter;
4+
import static com.redhat.hacbs.domainproxy.common.CommonIOUtil.createSocketToChannelWriter;
5+
36
import java.io.IOException;
47
import java.net.ServerSocket;
58
import java.net.Socket;
@@ -12,8 +15,6 @@
1215

1316
import org.eclipse.microprofile.config.inject.ConfigProperty;
1417

15-
import com.redhat.hacbs.domainproxy.common.CommonIOUtil;
16-
1718
import io.quarkus.logging.Log;
1819
import io.quarkus.runtime.Quarkus;
1920
import io.quarkus.runtime.Startup;
@@ -43,10 +44,10 @@ public void start() {
4344
final Socket socket = serverSocket.accept();
4445
final UnixDomainSocketAddress address = UnixDomainSocketAddress.of(domainSocket);
4546
final SocketChannel channel = SocketChannel.open(address);
46-
// write from socket to channel
47-
CommonIOUtil.createSocketToChannelWriter(byteBufferSize, socket, channel).start();
48-
// write from channel to socket
49-
CommonIOUtil.createChannelToSocketWriter(byteBufferSize, channel, socket).start();
47+
// Write from socket to channel
48+
Thread.startVirtualThread(createSocketToChannelWriter(byteBufferSize, socket, channel));
49+
// Write from channel to socket
50+
Thread.startVirtualThread(createChannelToSocketWriter(byteBufferSize, channel, socket));
5051
}
5152
} catch (final IOException e) {
5253
Log.errorf(e, "Error initialising domain proxy client");

java-components/domain-proxy/common/src/main/java/com/redhat/hacbs/domainproxy/common/CommonIOUtil.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ public final class CommonIOUtil {
1313

1414
private static final Logger LOG = Logger.getLogger(CommonIOUtil.class);
1515

16-
public static Thread createSocketToChannelWriter(final int byteBufferSize, final Socket socket,
16+
public static Runnable createSocketToChannelWriter(final int byteBufferSize, final Socket socket,
1717
final SocketChannel channel) {
18-
// write from socket to channel
19-
return new Thread(() -> {
18+
// Write from socket to channel
19+
return () -> {
2020
int r;
2121
final byte[] buf = new byte[byteBufferSize];
2222
int bytesWritten = 0;
@@ -43,13 +43,13 @@ public static Thread createSocketToChannelWriter(final int byteBufferSize, final
4343
}
4444
}
4545
LOG.infof("Wrote %d bytes from socket to channel", bytesWritten);
46-
});
46+
};
4747
}
4848

49-
public static Thread createChannelToSocketWriter(final int byteBufferSize, final SocketChannel channel,
49+
public static Runnable createChannelToSocketWriter(final int byteBufferSize, final SocketChannel channel,
5050
final Socket socket) {
51-
// write from channel to socket
52-
return new Thread(() -> {
51+
// Write from channel to socket
52+
return () -> {
5353
int r;
5454
final ByteBuffer buf = ByteBuffer.allocate(byteBufferSize);
5555
buf.clear();
@@ -79,6 +79,6 @@ public static Thread createChannelToSocketWriter(final int byteBufferSize, final
7979
}
8080
}
8181
LOG.infof("Wrote %d bytes from channel to socket", bytesWritten);
82-
});
82+
};
8383
}
8484
}

java-components/domain-proxy/server/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
<artifactId>rest-assured</artifactId>
2929
<scope>test</scope>
3030
</dependency>
31+
<dependency>
32+
<groupId>org.wiremock</groupId>
33+
<artifactId>wiremock</artifactId>
34+
<scope>test</scope>
35+
</dependency>
3136
<dependency>
3237
<groupId>io.github.redhat-appstudio.jvmbuild</groupId>
3338
<artifactId>domain-proxy-common</artifactId>

java-components/domain-proxy/server/src/main/java/com/redhat/hacbs/domainproxy/DomainProxyServer.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.redhat.hacbs.domainproxy;
22

3+
import static com.redhat.hacbs.domainproxy.common.CommonIOUtil.createChannelToSocketWriter;
4+
import static com.redhat.hacbs.domainproxy.common.CommonIOUtil.createSocketToChannelWriter;
5+
36
import java.io.IOException;
47
import java.net.Socket;
58
import java.net.StandardProtocolFamily;
@@ -15,8 +18,6 @@
1518

1619
import org.eclipse.microprofile.config.inject.ConfigProperty;
1720

18-
import com.redhat.hacbs.domainproxy.common.CommonIOUtil;
19-
2021
import io.quarkus.logging.Log;
2122
import io.quarkus.runtime.Quarkus;
2223
import io.quarkus.runtime.Startup;
@@ -25,23 +26,22 @@
2526
@Singleton
2627
public class DomainProxyServer {
2728

28-
static final String HOST = "localhost";
29+
static final String LOCALHOST = "localhost";
2930

3031
@Inject
3132
@ConfigProperty(name = "server-domain-socket")
3233
String domainSocket;
3334

3435
@Inject
3536
@ConfigProperty(name = "server-http-port")
36-
int serverHttpPort;
37+
int httpServerPort;
3738

3839
@Inject
3940
@ConfigProperty(name = "byte-buffer-size")
4041
int byteBufferSize;
4142

4243
@PostConstruct
4344
public void start() {
44-
Log.info("Starting domain proxy server...");
4545
new Thread(() -> {
4646
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
4747
try {
@@ -55,11 +55,11 @@ public void start() {
5555
serverChannel.bind(address);
5656
while (true) {
5757
final SocketChannel channel = serverChannel.accept();
58-
final Socket socket = new Socket(HOST, serverHttpPort);
59-
// write from socket to channel
60-
CommonIOUtil.createSocketToChannelWriter(byteBufferSize, socket, channel).start();
61-
// write from channel to socket
62-
CommonIOUtil.createChannelToSocketWriter(byteBufferSize, channel, socket).start();
58+
final Socket socket = new Socket(LOCALHOST, httpServerPort);
59+
// Write from socket to channel
60+
Thread.startVirtualThread(createSocketToChannelWriter(byteBufferSize, socket, channel));
61+
// Write from channel to socket
62+
Thread.startVirtualThread(createChannelToSocketWriter(byteBufferSize, channel, socket));
6363
}
6464
} catch (final IOException e) {
6565
Log.errorf(e, "Error initialising domain proxy server");

java-components/domain-proxy/server/src/main/java/com/redhat/hacbs/domainproxy/ExternalProxyVerticle.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,35 @@ public class ExternalProxyVerticle extends AbstractVerticle {
2929

3030
@Inject
3131
@ConfigProperty(name = "server-http-port")
32-
int serverHttpPort;
32+
int httpServerPort;
3333

3434
@Inject
3535
@ConfigProperty(name = "proxy-target-whitelist")
3636
Set<String> proxyTargetWhitelist;
3737

3838
private final WebClient webClient;
3939
private final NetClient netClient;
40+
private final HttpServer httpServer;
4041

4142
public ExternalProxyVerticle(final Vertx vertx) {
4243
webClient = WebClient.create(vertx, new WebClientOptions());
4344
netClient = vertx.createNetClient(new NetClientOptions());
45+
httpServer = vertx.createHttpServer();
4446
}
4547

4648
@Override
4749
public void start() {
48-
final HttpServer server = vertx.createHttpServer();
49-
server.requestHandler(request -> {
50+
Log.info("Starting domain proxy server...");
51+
httpServer.requestHandler(request -> {
5052
if (request.method() == HttpMethod.GET) {
5153
handleGetRequest(request);
5254
} else if (request.method() == HttpMethod.CONNECT) {
5355
handleConnectRequest(request);
5456
}
5557
});
56-
server.listen(serverHttpPort, result -> {
58+
httpServer.listen(httpServerPort, result -> {
5759
if (result.succeeded()) {
58-
Log.infof("Server is now listening on port %d", serverHttpPort);
60+
Log.infof("Server is now listening on port %d", httpServerPort);
5961
} else {
6062
Log.errorf(result.cause(), "Failed to bind server");
6163
}

java-components/domain-proxy/server/src/test/java/com/redhat/hacbs/domainproxy/ExternalProxyEndpointTest.disabled

Lines changed: 0 additions & 50 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.redhat.hacbs.domainproxy;
2+
3+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
4+
import static com.github.tomakehurst.wiremock.client.WireMock.get;
5+
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
6+
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
7+
import static com.redhat.hacbs.domainproxy.DomainProxyServer.LOCALHOST;
8+
import static io.restassured.RestAssured.given;
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
10+
11+
import java.io.IOException;
12+
import java.nio.charset.StandardCharsets;
13+
import java.nio.file.Files;
14+
import java.nio.file.Path;
15+
16+
import jakarta.inject.Inject;
17+
18+
import org.apache.commons.codec.digest.DigestUtils;
19+
import org.eclipse.microprofile.config.inject.ConfigProperty;
20+
import org.junit.jupiter.api.AfterAll;
21+
import org.junit.jupiter.api.BeforeAll;
22+
import org.junit.jupiter.api.Test;
23+
24+
import com.github.tomakehurst.wiremock.WireMockServer;
25+
26+
import io.netty.handler.codec.http.HttpResponseStatus;
27+
import io.quarkus.test.junit.QuarkusTest;
28+
import io.quarkus.test.junit.TestProfile;
29+
import io.restassured.specification.RequestSpecification;
30+
31+
@QuarkusTest
32+
@TestProfile(ExternalProxyVerticleTestProfile.class)
33+
class ExternalProxyVerticleTest {
34+
35+
static final String MD5_HASH = "ea3ca57f8f99d1d210d1b438c9841440";
36+
37+
private static WireMockServer wireMockServer;
38+
39+
@Inject
40+
@ConfigProperty(name = "server-http-port")
41+
int httpServerPort;
42+
43+
@BeforeAll
44+
public static void before() throws IOException {
45+
wireMockServer = new WireMockServer(wireMockConfig().port(2002).httpsPort(2003));
46+
wireMockServer.start();
47+
wireMockServer.stubFor(
48+
get(urlEqualTo("/com/foo/bar/1.0/bar-1.0.pom"))
49+
.willReturn(aResponse()
50+
.withHeader("Content-Type", "text/xml")
51+
.withBody(
52+
Files.readString(Path.of("src/test/resources/bar-1.0.pom"), StandardCharsets.UTF_8))));
53+
}
54+
55+
@AfterAll
56+
public static void after() {
57+
if (wireMockServer != null) {
58+
wireMockServer.stop();
59+
}
60+
}
61+
62+
private RequestSpecification httpRequest() {
63+
return given().proxy(LOCALHOST, httpServerPort).port(wireMockServer.port());
64+
}
65+
66+
private RequestSpecification httpsRequest() {
67+
return given().proxy(LOCALHOST, httpServerPort).port(wireMockServer.httpsPort()).relaxedHTTPSValidation();
68+
}
69+
70+
@Test
71+
public void testDownloadDependencyHTTP() {
72+
final byte[] jar = httpRequest().get("http://" + LOCALHOST + "/com/foo/bar/1.0/bar-1.0.pom")
73+
.asByteArray();
74+
assertEquals(MD5_HASH, DigestUtils.md5Hex(jar));
75+
}
76+
77+
@Test
78+
public void testDownloadDependencyHTTPS() {
79+
final byte[] jar = httpsRequest().get("https://" + LOCALHOST + "/com/foo/bar/1.0/bar-1.0.pom")
80+
.asByteArray();
81+
assertEquals(MD5_HASH, DigestUtils.md5Hex(jar));
82+
}
83+
84+
@Test
85+
public void testMissingDependencyHTTP() {
86+
httpRequest().get("http://" + LOCALHOST + "/com/foo/bar/2.0/bar-2.0.pom")
87+
.then()
88+
.statusCode(HttpResponseStatus.NOT_FOUND.code());
89+
}
90+
91+
@Test
92+
public void testMissingDependencyHTTPS() {
93+
httpsRequest().get("https://" + LOCALHOST + "/com/foo/bar/2.0/bar-2.0.pom")
94+
.then()
95+
.statusCode(HttpResponseStatus.NOT_FOUND.code());
96+
}
97+
98+
@Test
99+
public void testNotWhitelistedHTTP() {
100+
httpRequest().get(
101+
"http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-jar-plugin/3.4.1/maven-jar-plugin-3.4.1.jar")
102+
.then()
103+
.statusCode(HttpResponseStatus.NOT_FOUND.code());
104+
}
105+
106+
@Test
107+
public void testNotWhitelistedHTTPS() {
108+
httpsRequest().get(
109+
"https://repo1.maven.org/maven2/org/apache/maven/plugins/maven-jar-plugin/3.4.1/maven-jar-plugin-3.4.1.jar")
110+
.then()
111+
.statusCode(HttpResponseStatus.NOT_FOUND.code());
112+
}
113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.redhat.hacbs.domainproxy;
2+
3+
import static com.redhat.hacbs.domainproxy.DomainProxyServer.LOCALHOST;
4+
5+
import java.util.Map;
6+
7+
import io.quarkus.test.junit.QuarkusTestProfile;
8+
9+
public class ExternalProxyVerticleTestProfile implements QuarkusTestProfile {
10+
11+
@Override
12+
public Map<String, String> getConfigOverrides() {
13+
return Map.of("server-http-port", "2001", "proxy-target-whitelist", LOCALHOST);
14+
}
15+
}

0 commit comments

Comments
 (0)