summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2020-12-11 13:00:48 +0100
committerGitHub <noreply@github.com>2020-12-11 13:00:48 +0100
commit148a7456c7788c07e512df4a1f9c714d2c37be5f (patch)
tree7b2bf426eb606b9d2cdf3fd6c9a7593ff1678359
parentc330e6538addbe7f81e5728275e0d55207567ad1 (diff)
parent540ead4289358e47cc2c5244540b2b62e8c83e2d (diff)
Merge pull request #15791 from vespa-engine/mpolden/joining-servers
Make joining server an observer in initial config
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java20
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java41
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java19
-rw-r--r--configdefinitions/src/vespa/zookeeper-server.def2
-rw-r--r--zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java13
-rw-r--r--zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java114
6 files changed, 140 insertions, 69 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
index 2b8966ed541..f8ff7bcdc18 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
@@ -7,8 +7,11 @@ import com.yahoo.component.ComponentId;
import com.yahoo.component.ComponentSpecification;
import com.yahoo.config.FileReference;
import com.yahoo.config.application.api.ComponentInfo;
+import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.AbstractConfigProducer;
+import com.yahoo.config.provision.AllocatedHosts;
+import com.yahoo.config.provision.HostSpec;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.container.di.config.ApplicationBundlesConfig;
import com.yahoo.container.handler.metrics.MetricsProxyApiConfig;
@@ -74,6 +77,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
private final ConfigProducerGroup<Servlet> servletGroup;
private final ConfigProducerGroup<RestApi> restApiGroup;
+ private final Set<String> previousHosts;
private ContainerModelEvaluation modelEvaluation;
@@ -89,6 +93,12 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
this.tlsClientAuthority = deployState.tlsClientAuthority();
restApiGroup = new ConfigProducerGroup<>(this, "rest-api");
servletGroup = new ConfigProducerGroup<>(this, "servlet");
+ previousHosts = deployState.getPreviousModel().stream()
+ .map(Model::allocatedHosts)
+ .map(AllocatedHosts::getHosts)
+ .flatMap(Collection::stream)
+ .map(HostSpec::hostname)
+ .collect(Collectors.toUnmodifiableSet());
addSimpleComponent(DEFAULT_LINGUISTICS_PROVIDER);
addSimpleComponent("com.yahoo.container.jdisc.SecretStoreProvider");
@@ -261,10 +271,12 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
// Note: Default client and server ports are used, so not set here
for (Container container : getContainers()) {
ZookeeperServerConfig.Server.Builder serverBuilder = new ZookeeperServerConfig.Server.Builder();
- serverBuilder.hostname(container.getHostName());
- serverBuilder.id(container.index());
- builder.server(serverBuilder);
- builder.dynamicReconfiguration(true);
+ serverBuilder.hostname(container.getHostName())
+ .id(container.index())
+ .joining(!previousHosts.isEmpty() &&
+ !previousHosts.contains(container.getHostName()));
+ builder.server(serverBuilder)
+ .dynamicReconfiguration(true);
}
}
diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
index 96b2cfc3118..1abb72d73b5 100644
--- a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
+++ b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.model.provision;
+import com.yahoo.cloud.config.ZookeeperServerConfig;
import com.yahoo.cloud.config.log.LogdConfig;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.model.api.container.ContainerServiceType;
@@ -40,6 +41,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.function.Function;
import java.util.stream.Collectors;
import static com.yahoo.config.model.test.TestUtil.joinLines;
@@ -1871,6 +1873,45 @@ public class ModelProvisioningTest {
assertEquals(3, cluster.getContainers().stream().filter(c -> !c.isRetired()).count());
}
+ @Test
+ public void containerWithZooKeeperJoiningServers() {
+ Function<Integer, String> servicesXml = (nodeCount) -> {
+ return "<?xml version='1.0' encoding='utf-8' ?>" +
+ "<services>" +
+ " <container version='1.0' id='zk'>" +
+ " <zookeeper/>" +
+ " <nodes count='" + nodeCount + "'/>" +
+ " </container>" +
+ "</services>";
+ };
+ VespaModelTester tester = new VespaModelTester();
+ tester.addHosts(5);
+ VespaModel model = tester.createModel(servicesXml.apply(3), true);
+
+ {
+ ApplicationContainerCluster cluster = model.getContainerClusters().get("zk");
+ ZookeeperServerConfig.Builder config = new ZookeeperServerConfig.Builder();
+ cluster.getContainers().forEach(c -> c.getConfig(config));
+ cluster.getConfig(config);
+ assertTrue("Initial servers are not joining", config.build().server().stream().noneMatch(ZookeeperServerConfig.Server::joining));
+ }
+ {
+ VespaModel nextModel = tester.createModel(Zone.defaultZone(), servicesXml.apply(5), true, false, 0, Optional.of(model));
+ ApplicationContainerCluster cluster = nextModel.getContainerClusters().get("zk");
+ ZookeeperServerConfig.Builder config = new ZookeeperServerConfig.Builder();
+ cluster.getContainers().forEach(c -> c.getConfig(config));
+ cluster.getConfig(config);
+ assertEquals("New nodes are joining",
+ Map.of(0, false,
+ 1, false,
+ 2, false,
+ 3, true,
+ 4, true),
+ config.build().server().stream().collect(Collectors.toMap(ZookeeperServerConfig.Server::id,
+ ZookeeperServerConfig.Server::joining)));
+ }
+ }
+
private VespaModel createNonProvisionedMultitenantModel(String services) {
return createNonProvisionedModel(true, null, services);
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
index 813ca4ac0cb..7484095c5bc 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
@@ -104,22 +104,22 @@ public class VespaModelTester {
/** Creates a model which uses 0 as start index */
public VespaModel createModel(String services, boolean failOnOutOfCapacity, String ... retiredHostNames) {
- return createModel(Zone.defaultZone(), services, failOnOutOfCapacity, false, 0, retiredHostNames);
+ return createModel(Zone.defaultZone(), services, failOnOutOfCapacity, false, 0, Optional.empty(), retiredHostNames);
}
/** Creates a model which uses 0 as start index */
public VespaModel createModel(String services, boolean failOnOutOfCapacity, boolean useMaxResources, String ... retiredHostNames) {
- return createModel(Zone.defaultZone(), services, failOnOutOfCapacity, useMaxResources, 0, retiredHostNames);
+ return createModel(Zone.defaultZone(), services, failOnOutOfCapacity, useMaxResources, 0, Optional.empty(), retiredHostNames);
}
/** Creates a model which uses 0 as start index */
public VespaModel createModel(String services, boolean failOnOutOfCapacity, int startIndexForClusters, String ... retiredHostNames) {
- return createModel(Zone.defaultZone(), services, failOnOutOfCapacity, false, startIndexForClusters, retiredHostNames);
+ return createModel(Zone.defaultZone(), services, failOnOutOfCapacity, false, startIndexForClusters, Optional.empty(), retiredHostNames);
}
/** Creates a model which uses 0 as start index */
public VespaModel createModel(Zone zone, String services, boolean failOnOutOfCapacity, String ... retiredHostNames) {
- return createModel(zone, services, failOnOutOfCapacity, false, 0, retiredHostNames);
+ return createModel(zone, services, failOnOutOfCapacity, false, 0, Optional.empty(), retiredHostNames);
}
/**
@@ -132,7 +132,7 @@ public class VespaModelTester {
* @return the resulting model
*/
public VespaModel createModel(Zone zone, String services, boolean failOnOutOfCapacity, boolean useMaxResources,
- int startIndexForClusters, String ... retiredHostNames) {
+ int startIndexForClusters, Optional<VespaModel> previousModel, String ... retiredHostNames) {
VespaModelCreatorWithMockPkg modelCreatorWithMockPkg = new VespaModelCreatorWithMockPkg(null, services, ApplicationPackageUtils.generateSearchDefinition("type1"));
ApplicationPackage appPkg = modelCreatorWithMockPkg.appPkg;
@@ -148,12 +148,13 @@ public class VespaModelTester {
.setApplicationId(applicationId)
.setUseDedicatedNodeForLogserver(useDedicatedNodeForLogserver);
- DeployState deployState = new DeployState.Builder()
+ DeployState.Builder deployState = new DeployState.Builder()
.applicationPackage(appPkg)
.modelHostProvisioner(provisioner)
.properties(properties)
- .zone(zone)
- .build();
- return modelCreatorWithMockPkg.create(false, deployState, configModelRegistry);
+ .zone(zone);
+ previousModel.ifPresent(deployState::previousModel);
+ return modelCreatorWithMockPkg.create(false, deployState.build(), configModelRegistry);
}
+
}
diff --git a/configdefinitions/src/vespa/zookeeper-server.def b/configdefinitions/src/vespa/zookeeper-server.def
index 5aa0bb2ae9b..2e80f9b35e0 100644
--- a/configdefinitions/src/vespa/zookeeper-server.def
+++ b/configdefinitions/src/vespa/zookeeper-server.def
@@ -33,6 +33,8 @@ server[].id int
server[].hostname string
server[].quorumPort int default=2182
server[].electionPort int default=2183
+# Whether this server is joining an existing cluster
+server[].joining bool default=false
# Needed when upgrading from ZooKeeper 3.4 to 3.5, see https://issues.apache.org/jira/browse/ZOOKEEPER-3056,
# and in general where there is a zookeeper ensemble running that has had few transactions.
diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
index e535f627f00..5f8ebf29ccd 100644
--- a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
+++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
@@ -147,8 +147,17 @@ public class Configurator {
.append(":")
.append(server.quorumPort())
.append(":")
- .append(server.electionPort())
- .append(";")
+ .append(server.electionPort());
+ if (server.joining()) {
+ // Servers that are joining an existing cluster must be marked as observers. Note that this will NOT
+ // actually make the server an observer, but prevent it from forming an ensemble independently of the
+ // existing cluster.
+ //
+ // See https://zookeeper.apache.org/doc/r3.6.2/zookeeperReconfig.html#sc_reconfig_modifying
+ sb.append(":")
+ .append("observer");
+ }
+ sb.append(";")
.append(clientPort)
.append("\n");
}
diff --git a/zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java b/zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java
index 0cdbd68421c..0f43fb45d9d 100644
--- a/zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java
+++ b/zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java
@@ -2,11 +2,11 @@
package com.yahoo.vespa.zookeeper;
import com.yahoo.cloud.config.ZookeeperServerConfig;
-import com.yahoo.io.IOUtils;
import com.yahoo.security.KeyUtils;
import com.yahoo.security.X509CertificateBuilder;
import com.yahoo.security.X509CertificateUtils;
import com.yahoo.security.tls.TransportSecurityOptions;
+import com.yahoo.yolean.Exceptions;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -15,6 +15,7 @@ import org.junit.rules.TemporaryFolder;
import javax.security.auth.x500.X500Principal;
import java.io.File;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -22,14 +23,14 @@ import java.security.KeyPair;
import java.security.cert.X509Certificate;
import java.util.Optional;
-import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForQuorumCommunication;
import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForClientServerCommunication;
+import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForQuorumCommunication;
import static com.yahoo.security.KeyAlgorithm.EC;
import static com.yahoo.security.SignatureAlgorithm.SHA256_WITH_ECDSA;
+import static com.yahoo.vespa.defaults.Defaults.getDefaults;
import static com.yahoo.vespa.zookeeper.Configurator.ZOOKEEPER_JUTE_MAX_BUFFER;
import static java.time.Instant.EPOCH;
import static java.time.temporal.ChronoUnit.DAYS;
-import static com.yahoo.vespa.defaults.Defaults.getDefaults;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -53,7 +54,7 @@ public class ConfiguratorTest {
}
@Test
- public void config_is_written_correctly_when_one_server() throws IOException {
+ public void config_is_written_correctly_when_one_server() {
ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile);
new Configurator(builder.build()).writeConfigToDisk(Optional.empty());
validateConfigFileSingleHost(cfgFile);
@@ -61,12 +62,12 @@ public class ConfiguratorTest {
}
@Test
- public void config_is_written_correctly_when_multiple_servers() throws IOException {
+ public void config_is_written_correctly_when_multiple_servers() {
ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
builder.zooKeeperConfigFile(cfgFile.getAbsolutePath());
- builder.server(newServer(0, "foo", 123, 321));
- builder.server(newServer(1, "bar", 234, 432));
- builder.server(newServer(2, "baz", 345, 543));
+ builder.server(newServer(0, "foo", 123, 321, false));
+ builder.server(newServer(1, "bar", 234, 432, false));
+ builder.server(newServer(2, "baz", 345, 543, true));
builder.myidFile(idFile.getAbsolutePath());
builder.myid(1);
new Configurator(builder.build()).writeConfigToDisk(Optional.empty());
@@ -75,7 +76,7 @@ public class ConfiguratorTest {
}
@Test
- public void config_is_written_correctly_with_tls_for_quorum_communication_port_unification() throws IOException {
+ public void config_is_written_correctly_with_tls_for_quorum_communication_port_unification() {
ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile);
builder.tlsForQuorumCommunication(TlsForQuorumCommunication.PORT_UNIFICATION);
builder.tlsForClientServerCommunication(TlsForClientServerCommunication.PORT_UNIFICATION);
@@ -86,7 +87,7 @@ public class ConfiguratorTest {
}
@Test
- public void config_is_written_correctly_with_tls_for_quorum_communication_tls_with_port_unification() throws IOException {
+ public void config_is_written_correctly_with_tls_for_quorum_communication_tls_with_port_unification() {
ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile);
builder.tlsForQuorumCommunication(TlsForQuorumCommunication.TLS_WITH_PORT_UNIFICATION);
builder.tlsForClientServerCommunication(TlsForClientServerCommunication.TLS_WITH_PORT_UNIFICATION);
@@ -97,7 +98,7 @@ public class ConfiguratorTest {
}
@Test
- public void config_is_written_correctly_with_tls_for_quorum_communication_tls_only() throws IOException {
+ public void config_is_written_correctly_with_tls_for_quorum_communication_tls_only() {
ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile);
builder.tlsForQuorumCommunication(TlsForQuorumCommunication.TLS_ONLY);
builder.tlsForClientServerCommunication(TlsForClientServerCommunication.TLS_ONLY);
@@ -107,28 +108,18 @@ public class ConfiguratorTest {
validateThatJksKeyStoreFileExists(jksKeyStoreFile);
}
- private ZookeeperServerConfig.Builder createConfigBuilderForSingleHost(File cfgFile, File idFile, File jksKeyStoreFile) {
- ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
- builder.zooKeeperConfigFile(cfgFile.getAbsolutePath());
- builder.myidFile(idFile.getAbsolutePath());
- builder.server(newServer(0, "foo", 123, 321));
- builder.myid(0);
- builder.jksKeyStoreFile(jksKeyStoreFile.getAbsolutePath());
- return builder;
- }
-
@Test(expected = RuntimeException.class)
public void require_that_this_id_must_be_present_amongst_servers() {
ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
builder.zooKeeperConfigFile(cfgFile.getAbsolutePath());
- builder.server(newServer(1, "bar", 234, 432));
- builder.server(newServer(2, "baz", 345, 543));
+ builder.server(newServer(1, "bar", 234, 432, false));
+ builder.server(newServer(2, "baz", 345, 543, false));
builder.myid(0);
new Configurator(builder.build()).writeConfigToDisk(Optional.empty());
}
@Test
- public void juteMaxBufferCanBeSet() throws IOException {
+ public void jute_max_buffer_can_be_set() throws IOException {
ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
builder.myid(0);
File idFile = folder.newFile();
@@ -147,17 +138,28 @@ public class ConfiguratorTest {
assertEquals("" + max_buffer, System.getProperty(ZOOKEEPER_JUTE_MAX_BUFFER));
}
- private ZookeeperServerConfig.Server.Builder newServer(int id, String hostName, int electionPort, int quorumPort) {
+ private ZookeeperServerConfig.Builder createConfigBuilderForSingleHost(File cfgFile, File idFile, File jksKeyStoreFile) {
+ ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
+ builder.zooKeeperConfigFile(cfgFile.getAbsolutePath());
+ builder.myidFile(idFile.getAbsolutePath());
+ builder.server(newServer(0, "foo", 123, 321, false));
+ builder.myid(0);
+ builder.jksKeyStoreFile(jksKeyStoreFile.getAbsolutePath());
+ return builder;
+ }
+
+ private ZookeeperServerConfig.Server.Builder newServer(int id, String hostName, int electionPort, int quorumPort, boolean joining) {
ZookeeperServerConfig.Server.Builder builder = new ZookeeperServerConfig.Server.Builder();
builder.id(id);
builder.hostname(hostName);
builder.electionPort(electionPort);
builder.quorumPort(quorumPort);
+ builder.joining(joining);
return builder;
}
- private void validateIdFile(File idFile, String expected) throws IOException {
- String actual = IOUtils.readFile(idFile);
+ private void validateIdFile(File idFile, String expected) {
+ String actual = Exceptions.uncheck(() -> Files.readString(idFile.toPath()));
assertEquals(expected, actual);
}
@@ -201,7 +203,7 @@ public class ConfiguratorTest {
return sb.toString();
}
- private void validateConfigFileSingleHost(File cfgFile) throws IOException {
+ private void validateConfigFileSingleHost(File cfgFile) {
String expected =
commonConfig() +
"server.0=foo:321:123;2181\n" +
@@ -229,12 +231,12 @@ public class ConfiguratorTest {
"ssl.protocol=TLS\n";
}
- private void validateConfigFileMultipleHosts(File cfgFile) throws IOException {
+ private void validateConfigFileMultipleHosts(File cfgFile) {
String expected =
commonConfig() +
"server.0=foo:321:123;2181\n" +
"server.1=bar:432:234;2181\n" +
- "server.2=baz:543:345;2181\n" +
+ "server.2=baz:543:345:observer;2181\n" +
commonTlsQuorumConfig() +
"sslQuorum=false\n" +
"portUnification=false\n" +
@@ -243,7 +245,7 @@ public class ConfiguratorTest {
validateConfigFile(cfgFile, expected);
}
- private void validateConfigFilePortUnification(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) throws IOException {
+ private void validateConfigFilePortUnification(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) {
String expected =
commonConfig() +
"server.0=foo:321:123;2181\n" +
@@ -257,7 +259,7 @@ public class ConfiguratorTest {
validateConfigFile(cfgFile, expected);
}
- private void validateConfigFileTlsWithPortUnification(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) throws IOException {
+ private void validateConfigFileTlsWithPortUnification(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) {
String expected =
commonConfig() +
"server.0=foo:321:123;2181\n" +
@@ -271,7 +273,7 @@ public class ConfiguratorTest {
validateConfigFile(cfgFile, expected);
}
- private void validateConfigFileTlsOnly(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) throws IOException {
+ private void validateConfigFileTlsOnly(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) {
String expected =
commonConfig() +
"server.0=foo:321:123;2181\n" +
@@ -285,8 +287,8 @@ public class ConfiguratorTest {
validateConfigFile(cfgFile, expected);
}
- private void validateConfigFile(File cfgFile, String expected) throws IOException {
- String actual = IOUtils.readFile(cfgFile);
+ private void validateConfigFile(File cfgFile, String expected) {
+ String actual = Exceptions.uncheck(() -> Files.readString(cfgFile.toPath()));
assertEquals(expected, actual);
}
@@ -294,25 +296,29 @@ public class ConfiguratorTest {
assertTrue(cfgFile.exists() && cfgFile.canRead());
}
- private Optional<TransportSecurityOptions> createTransportSecurityOptions() throws IOException {
- KeyPair keyPair = KeyUtils.generateKeypair(EC);
- Path privateKeyFile = folder.newFile().toPath();
- Files.writeString(privateKeyFile, KeyUtils.toPem(keyPair.getPrivate()));
-
- X509Certificate certificate = X509CertificateBuilder
- .fromKeypair(keyPair, new X500Principal("CN=dummy"), EPOCH, EPOCH.plus(1, DAYS), SHA256_WITH_ECDSA, BigInteger.ONE)
- .build();
- Path certificateChainFile = folder.newFile().toPath();
- String certificatePem = X509CertificateUtils.toPem(certificate);
- Files.writeString(certificateChainFile, certificatePem);
-
- Path caCertificatesFile = folder.newFile().toPath();
- Files.writeString(caCertificatesFile, certificatePem);
-
- return Optional.of(new TransportSecurityOptions.Builder()
- .withCertificates(certificateChainFile, privateKeyFile)
- .withCaCertificates(caCertificatesFile)
- .build());
+ private Optional<TransportSecurityOptions> createTransportSecurityOptions() {
+ try {
+ KeyPair keyPair = KeyUtils.generateKeypair(EC);
+ Path privateKeyFile = folder.newFile().toPath();
+ Files.writeString(privateKeyFile, KeyUtils.toPem(keyPair.getPrivate()));
+
+ X509Certificate certificate = X509CertificateBuilder
+ .fromKeypair(keyPair, new X500Principal("CN=dummy"), EPOCH, EPOCH.plus(1, DAYS), SHA256_WITH_ECDSA, BigInteger.ONE)
+ .build();
+ Path certificateChainFile = folder.newFile().toPath();
+ String certificatePem = X509CertificateUtils.toPem(certificate);
+ Files.writeString(certificateChainFile, certificatePem);
+
+ Path caCertificatesFile = folder.newFile().toPath();
+ Files.writeString(caCertificatesFile, certificatePem);
+
+ return Optional.of(new TransportSecurityOptions.Builder()
+ .withCertificates(certificateChainFile, privateKeyFile)
+ .withCaCertificates(caCertificatesFile)
+ .build());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
}