8000 ssl resilience tests · arangodb/arangodb-java-driver@820c090 · GitHub
[go: up one dir, main page]

Skip to content

Commit 820c090

Browse files
committed
ssl resilience tests
1 parent b0017e3 commit 820c090

File tree

8 files changed

+345
-135
lines changed

8 files changed

+345
-135
lines changed

resilience-tests/src/test/java/resilience/protocol/ProtocolTest.java

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,12 @@
77
import io.netty.handler.codec.http2.Http2FrameLogger;
88
import io.netty.handler.logging.LoggingHandler;
99
import org.junit.jupiter.api.*;
10-
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
1110
import org.junit.jupiter.params.ParameterizedTest;
1211
import org.junit.jupiter.params.provider.Arguments;
1312
import org.junit.jupiter.params.provider.MethodSource;
1413
import resilience.TestUtils;
1514
import resilience.utils.MemoryAppender;
1615

17-
import javax.net.ssl.KeyManagerFactory;
18-
import javax.net.ssl.SSLContext;
19-
import javax.net.ssl.TrustManagerFactory;
20-
import java.security.KeyStore;
2116
import java.util.HashMap;
2217
import java.util.Map;
2318
import java.util.stream.Stream;
@@ -26,8 +21,6 @@
2621
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2722

2823
public class ProtocolTest extends TestUtils {
29-
private static final String SSL_TRUSTSTORE = "/example.truststore";
30-
private static final String SSL_TRUSTSTORE_PASSWORD = "12345678";
3124
private static final Map<Class<?>, Level> logLevels = new HashMap<>();
3225

3326
static {
@@ -74,39 +67,4 @@ void shouldUseConfiguredProtocol(Protocol p, String expectedLog) {
7467
adb.shutdown();
7568
}
7669

77-
@Tag("ssl")
78-
@EnabledIfSystemProperty(named = "SslTest", matches = "true")
79-
@ParameterizedTest
80-
@MethodSource("args")
81-
void shouldUseConfiguredProtocolWithTLS(Protocol p, String expectedLog) throws Exception {
82-
assumeTrue(!p.equals(Protocol.VST) || isLessThanVersion(3, 12));
83-
ArangoDB adb = new ArangoDB.Builder()
84-
.host("172.28.0.1", 8529)
85-
.password("test")
86-
.protocol(p)
87-
.useSsl(true)
88-
.sslContext(sslContext())
89-
.verifyHost(false)
90-
.build();
91-
adb.getVersion();
92-
assertThat(logs.getLogs()).anyMatch(it -> it.getLoggerName().contains(expectedLog));
93-
adb.shutdown();
94-
}
95-
96-
private SSLContext sslContext() throws Exception {
97-
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
98-
ks.load(this.getClass().getResourceAsStream(SSL_TRUSTSTORE), SSL_TRUSTSTORE_PASSWORD.toCharArray());
99-
100-
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
101-
kmf.init(ks, SSL_TRUSTSTORE_PASSWORD.toCharArray());
102-
103-
final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
104-
tmf.init(ks);
105-
106-
final SSLContext sc = SSLContext.getInstance("TLS");
107-
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
108-
109-
return sc;
110-
}
111-
11270
}

test-ssl/pom.xml

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,82 @@
1515

1616
<dependencies>
1717
<dependency>
18-
<groupId>com.arangodb</groupId>
19-
<artifactId>test-functional</artifactId>
20-
<version>${project.version}</version>
21-
<classifier>${test-package.classifier}</classifier>
22-
<type>test-jar</type>
18+
<groupId>ch.qos.logback</groupId>
19+
<artifactId>logback-classic</artifactId>
20+
<version>1.4.12</version>
2321
<scope>test</scope>
2422
</dependency>
2523
</dependencies>
2624

25+
<build>
26+
<testSourceDirectory>${testSourceDirectory}</testSourceDirectory>
27+
</build>
28+
29+
<profiles>
30+
<profile>
31+
<id>default</id>
32+
<activation>
33+
<property>
34+
<name>shaded</name>
35+
<value>!true</value>
36+
</property>
37+
</activation>
38+
<properties>
39+
<testSourceDirectory>src/test/java</testSourceDirectory>
40+
</properties>
41+
</profile>
42+
<profile>
43+
<id>shaded</id>
44+
<activation>
45+
<property>
46+
<name>shaded</name>
47+
<value>true</value>
48+
</property>
49+
</activation>
50+
<properties>
51+
<testSourceDirectory>${project.build.directory}/generated-test-sources/replacer
52+
</testSourceDirectory>
53+
</properties>
54+
<build>
55+
<plugins>
56+
<plugin>
57+
<groupId>com.google.code.maven-replacer-plugin</groupId>
58+
<artifactId>replacer</artifactId>
59+
<version>1.5.3</version>
60+
<executions>
61+
<execution>
62+
<phase>generate-test-sources</phase>
63+
<goals>
64+
<goal>replace</goal>
65+
</goals>
66+
</execution>
67+
</executions>
68+
<configuration>
69+
<basedir>${project.basedir}/src/test/java</basedir>
70+
<filesToInclude>**</filesToInclude>
71+
<outputBasedir>${project.build.directory}/generated-test-sources</outputBasedir>
72+
<outputDir>replacer</outputDir>
73+
<filesToExclude>
74+
</filesToExclude>
75+
<replacements>
76+
<replacement>
77+
<token>com.fasterxml</token>
78+
<value>com.arangodb.shaded.fasterxml</value>
79+
</replacement>
80+
<replacement>
81+
<token>io.vertx.core</token>
82+
<value>com.arangodb.shaded.vertx.core</value>
83+
</replacement>
84+
<replacement>
85+
<token>io.netty</token>
86+
<value>com.arangodb.shaded.netty</value>
87+
</replacement>
88+
</replacements>
89+
</configuration>
90+
</plugin>
91+
</plugins>
92+
</build>
93+
</profile>
94+
</profiles>
95+
2796
</project>

test-ssl/src/test/java/com/arangodb/ArangoSslTest.java

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@
2424
import org.junit.jupiter.params.ParameterizedTest;
2525
import org.junit.jupiter.params.provider.EnumSource;
2626

27-
import javax.net.ssl.KeyManagerFactory;
28-
import javax.net.ssl.SSLContext;
2927
import javax.net.ssl.SSLHandshakeException;
30-
import javax.net.ssl.TrustManagerFactory;
31-
import java.security.KeyStore;
3228
import java.util.List;
3329

3430
import static org.assertj.core.api.Assertions.assertThat;
@@ -40,43 +36,19 @@
4036
* @author Mark Vollmary
4137
* @author Michele Rastelli
4238
*/
43-
class ArangoSslTest {
44-
45-
/*
46-
* a SSL trust store
47-
*
48-
* create the trust store for the self signed certificate:
49-
* keytool -import -alias "my arangodb server cert" -file UnitTests/server.pem -keystore example.truststore
50-
*
51-
* Documentation:
52-
* https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLSocketFactory.html
53-
*/
54-
private static final String SSL_TRUSTSTORE = "/example.truststore";
55-
private static final String SSL_TRUSTSTORE_PASSWORD = "12345678";
39+
class ArangoSslTest extends BaseTest {
5640

5741
@ParameterizedTest
5842
@EnumSource(Protocol.class)
59-
void connect(Protocol protocol) throws Exception {
43+
void connect(Protocol protocol) {
6044
assumeTrue(protocol != Protocol.VST);
6145

62-
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
63-
ks.load(this.getClass().getResourceAsStream(SSL_TRUSTSTORE), SSL_TRUSTSTORE_PASSWORD.toCharArray());
64-
65-
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
66-
kmf.init(ks, SSL_TRUSTSTORE_PASSWORD.toCharArray());
67-
68-
final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
69-
tmf.init(ks);
70-
71-
final SSLContext sc = SSLContext.getInstance("TLS");
72-
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
73-
7446
final ArangoDB arangoDB = new ArangoDB.Builder()
7547
.protocol(protocol)
7648
.host("172.28.0.1", 8529)
7749
.password("test")
7850
.useSsl(true)
79-
.sslContext(sc)
51+
.sslContext(createSslContext())
8052
.verifyHost(false)
8153
.build();
8254
final ArangoDBVersion version = arangoDB.getVersion();
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.arangodb;
2+
3+
import com.arangodb.entity.ArangoDBVersion;
4+
import org.junit.jupiter.api.BeforeAll;
5+
6+
import javax.net.ssl.KeyManagerFactory;
7+
import javax.net.ssl.SSLContext;
8+
import javax.net.ssl.TrustManagerFactory;
9+
import java.security.KeyStore;
10+
11+
abstract class BaseTest {
12+
/*-
13+
* a SSL trust store
14+
*
15+
* create the trust store for the self signed certificate:
16+
* keytool -import -alias "my arangodb server cert" -file server.pem -keystore example.truststore
17+
*
18+
* Documentation:
19+
* https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLSocketFactory.html
20+
*/
21+
private static final String SSL_TRUSTSTORE = "/example.truststore";
22+
private static final String SSL_TRUSTSTORE_PASSWORD = "12345678";
23+
static ArangoDBVersion version;
24+
25+
@BeforeAll
26+
static void fetchVersion() {
27+
ArangoDB adb = new ArangoDB.Builder()
28+
.host("172.28.0.1", 8529)
29+
.password("test")
30+
.useSsl(true)
31+
.sslContext(createSslContext())
32+
.verifyHost(false)
33+
.build();
34+
version = adb.getVersion();
35+
adb.shutdown();
36+
}
37+
38+
static SSLContext createSslContext() {
39+
SSLContext sc;
40+
try {
41+
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
42+
ks.load(SslExampleTest.class.getResourceAsStream(SSL_TRUSTSTORE), SSL_TRUSTSTORE_PASSWORD.toCharArray());
43+
44+
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
45+
kmf.init(ks, SSL_TRUSTSTORE_PASSWORD.toCharArray());
46+
47+
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
48+
tmf.init(ks);
49+
50+
sc = SSLContext.getInstance("TLS");
51+
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
52+
} catch (Exception e) {
53+
throw new RuntimeException(e);
54+
}
55+
return sc;
56+
}
57+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.arangodb;
2+
3+
import ch.qos.logback.classic.Level;
4+
import ch.qos.logback.classic.Logger;
5+
import com.arangodb.vst.internal.VstConnection;
6+
import io.netty.handler.codec.http2.Http2FrameLogger;
7+
import io.netty.handler.logging.LoggingHandler;
8+
import org.junit.jupiter.api.AfterEach;
9+
import org.junit.jupiter.api.BeforeEach;
10+
import org.junit.jupiter.params.ParameterizedTest;
11+
import org.junit.jupiter.params.provider.Arguments;
12+
import org.junit.jupiter.params.provider.MethodSource;
13+
import org.slf4j.LoggerFactory;
14+
import utils.MemoryAppender;
15+
import utils.TestUtils;
16+
17+
import javax.net.ssl.KeyManagerFactory;
18+
import javax.net.ssl.SSLContext;
19+
import javax.net.ssl.TrustManagerFactory;
20+
import java.security.KeyStore;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
import java.util.stream.Stream;
24+
25+
import static org.assertj.core.api.Assertions.assertThat;
26+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
27+
28+
/**
29+
* SSL variant of <a href=test-resilience/src/test/java/resilience/protocol/ProtocolTest.java>ProtocolTest resilience test</a>
30+
*/
31+
public class ProtocolTest extends BaseTest {
32+
private static final String SSL_TRUSTSTORE = "/example.truststore";
33+
private static final String SSL_TRUSTSTORE_PASSWORD = "12345678";
34+
private static final Map<Class<?>, Level> logLevels = new HashMap<>();
35+
private final Map<Class<?>, Level> originalLogLevels = new HashMap<>();
36+
37+
static {
38+
logLevels.put(VstConnection.class, Level.DEBUG);
39+
logLevels.put(LoggingHandler.class, Level.DEBUG);
40+
logLevels.put(Http2FrameLogger.class, Level.DEBUG);
41+
}
42+
43+
private MemoryAppender logs;
44+
45+
@BeforeEach
46+
void setLogLevels() {
47+
logs = new MemoryAppender();
48+
logLevels.forEach((clazz, level) -> {
49+
Logger logger = (Logger) LoggerFactory.getLogger(clazz);
50+
originalLogLevels.put(clazz, logger.getLevel());
51+
logger.setLevel(level);
52+
});
53+
}
54+
55+
@AfterEach
56+
void resetLogLevels() {
57+
originalLogLevels.forEach((clazz, level) -> {
58+
Logger logger = (Logger) LoggerFactory.getLogger(clazz);
59+
logger.setLevel(level);
60+
});
61+
logs.stop();
62+
}
63+
64+
static Stream<Arguments> args() {
65+
return Stream.of(
66+
Arguments.of(Protocol.VST, "VstConnection"),
67+
Arguments.of(Protocol.HTTP_JSON, "LoggingHandler"),
68+
Arguments.of(Protocol.HTTP2_JSON, "Http2FrameLogger")
69+
);
70+
}
71+
72+
@ParameterizedTest
73+
@MethodSource("args")
74+
void shouldUseConfiguredProtocolWithTLS(Protocol p, String expectedLog) throws Exception {
75+
assumeTrue(!p.equals(Protocol.VST) || TestUtils.isLessThanVersion(version.getVersion(), 3, 12, 0));
76+
ArangoDB adb = new ArangoDB.Builder()
77+
.host("172.28.0.1", 8529)
78+
.password("test")
79+
.protocol(p)
80+
.useSsl(true)
81+
.sslContext(sslContext())
82+
.verifyHost(false)
83+
.build();
84+
adb.getVersion();
85+
assertThat(logs.getLogs()).anyMatch(it -> it.getLoggerName().contains(expectedLog));
86+
adb.shutdown();
87+
}
88+
89+
private SSLContext sslContext() throws Exception {
90+
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
91+
ks.load(this.getClass().getResourceAsStream(SSL_TRUSTSTORE), SSL_TRUSTSTORE_PASSWORD.toCharArray());
92+
93+
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
94+
kmf.init(ks, SSL_TRUSTSTORE_PASSWORD.toCharArray());
95+
96+
final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
97+
tmf.init(ks);
98+
99+
final SSLContext sc = SSLContext.getInstance("TLS");
100+
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
101+
102+
return sc;
103+
}
104+
105+
}

0 commit comments

Comments
 (0)
0