From b83eb4c7cbaa8b736333db9a5e07dc8db810f6d5 Mon Sep 17 00:00:00 2001 From: Martin Polden Date: Wed, 10 Jun 2020 11:32:54 +0200 Subject: Extract LoadBalancerSpec --- .../hosted/provision/lb/LoadBalancerService.java | 10 ++---- .../provision/lb/LoadBalancerServiceMock.java | 11 +++--- .../hosted/provision/lb/LoadBalancerSpec.java | 42 ++++++++++++++++++++++ .../lb/PassthroughLoadBalancerService.java | 8 ++--- .../provision/lb/SharedLoadBalancerService.java | 4 +-- .../provision/maintenance/LoadBalancerExpirer.java | 3 +- .../provisioning/LoadBalancerProvisioner.java | 2 +- .../lb/PassthroughLoadBalancerServiceTest.java | 4 +-- .../lb/SharedLoadBalancerServiceTest.java | 4 +-- 9 files changed, 63 insertions(+), 25 deletions(-) create mode 100644 node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerSpec.java (limited to 'node-repository/src') diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerService.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerService.java index f6398c04e61..a38f115b0bf 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerService.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerService.java @@ -4,8 +4,6 @@ package com.yahoo.vespa.hosted.provision.lb; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterSpec; -import java.util.Set; - /** * A managed load balance service. * @@ -14,16 +12,14 @@ import java.util.Set; public interface LoadBalancerService { /** - * Create a load balancer for given application cluster. Implementations are expected to be idempotent + * Create a load balancer from the given specification. Implementations are expected to be idempotent * - * @param application Application owning the LB - * @param cluster Target cluster of the LB - * @param reals Reals that should be configured on the LB + * @param spec Load balancer specification * @param force Whether reconfiguration should be forced (e.g. allow configuring an empty set of reals on a * pre-existing load balancer). * @return The provisioned load balancer instance */ - LoadBalancerInstance create(ApplicationId application, ClusterSpec.Id cluster, Set reals, boolean force); + LoadBalancerInstance create(LoadBalancerSpec spec, boolean force); /** Permanently remove load balancer for given application cluster */ void remove(ApplicationId application, ClusterSpec.Id cluster); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java index 91f02a31f6b..f4d689056c3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerServiceMock.java @@ -10,7 +10,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.Set; /** * @author mpolden @@ -29,18 +28,18 @@ public class LoadBalancerServiceMock implements LoadBalancerService { } @Override - public LoadBalancerInstance create(ApplicationId application, ClusterSpec.Id cluster, Set reals, boolean force) { - var id = new LoadBalancerId(application, cluster); + public LoadBalancerInstance create(LoadBalancerSpec spec, boolean force) { + var id = new LoadBalancerId(spec.application(), spec.cluster()); var oldInstance = instances.get(id); - if (!force && oldInstance != null && !oldInstance.reals().isEmpty() && reals.isEmpty()) { + if (!force && oldInstance != null && !oldInstance.reals().isEmpty() && spec.reals().isEmpty()) { throw new IllegalArgumentException("Refusing to remove all reals from load balancer " + id); } var instance = new LoadBalancerInstance( - HostName.from("lb-" + application.toShortString() + "-" + cluster.value()), + HostName.from("lb-" + spec.application().toShortString() + "-" + spec.cluster().value()), Optional.of(new DnsZone("zone-id-1")), Collections.singleton(4443), ImmutableSet.of("10.2.3.0/24", "10.4.5.0/24"), - reals); + spec.reals()); instances.put(id, instance); return instance; } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerSpec.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerSpec.java new file mode 100644 index 00000000000..198f7f347ef --- /dev/null +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerSpec.java @@ -0,0 +1,42 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.provision.lb; + +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.ClusterSpec; + +import java.util.Objects; +import java.util.Set; + +/** + * A specification for a load balancer. + * + * @author mpolden + */ +public class LoadBalancerSpec { + + private final ApplicationId application; + private final ClusterSpec.Id cluster; + private final Set reals; + + public LoadBalancerSpec(ApplicationId application, ClusterSpec.Id cluster, Set reals) { + this.application = Objects.requireNonNull(application); + this.cluster = Objects.requireNonNull(cluster); + this.reals = Set.copyOf(Objects.requireNonNull(reals)); + } + + /** Owner of the load balancer */ + public ApplicationId application() { + return application; + } + + /** The target cluster of this load balancer */ + public ClusterSpec.Id cluster() { + return cluster; + } + + /** Real servers to attach to this load balancer */ + public Set reals() { + return reals; + } + +} diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerService.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerService.java index 891faceca7a..7667672e470 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerService.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerService.java @@ -17,10 +17,10 @@ import java.util.Set; public class PassthroughLoadBalancerService implements LoadBalancerService { @Override - public LoadBalancerInstance create(ApplicationId application, ClusterSpec.Id cluster, Set reals, boolean force) { - var real = reals.stream() - .min(Comparator.naturalOrder()) - .orElseThrow(() -> new IllegalArgumentException("No reals given")); + public LoadBalancerInstance create(LoadBalancerSpec spec, boolean force) { + var real = spec.reals().stream() + .min(Comparator.naturalOrder()) + .orElseThrow(() -> new IllegalArgumentException("No reals given")); return new LoadBalancerInstance(real.hostname(), Optional.empty(), Set.of(real.port()), Set.of(real.ipAddress() + "/32"), Set.of()); } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java index bfb1deacaf8..658d2313ab0 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java @@ -33,7 +33,7 @@ public class SharedLoadBalancerService implements LoadBalancerService { } @Override - public LoadBalancerInstance create(ApplicationId application, ClusterSpec.Id cluster, Set reals, boolean force) { + public LoadBalancerInstance create(LoadBalancerSpec spec, boolean force) { var proxyNodes = new ArrayList<>(nodeRepository.getNodes(NodeType.proxy)); proxyNodes.sort(hostnameComparator); @@ -52,7 +52,7 @@ public class SharedLoadBalancerService implements LoadBalancerService { Optional.empty(), Set.of(4080, 4443), networkNames, - reals + spec.reals() ); } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java index 163c34e024e..6edd57de1c1 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java @@ -7,6 +7,7 @@ import com.yahoo.vespa.hosted.provision.lb.LoadBalancer; import com.yahoo.vespa.hosted.provision.lb.LoadBalancer.State; import com.yahoo.vespa.hosted.provision.lb.LoadBalancerId; import com.yahoo.vespa.hosted.provision.lb.LoadBalancerService; +import com.yahoo.vespa.hosted.provision.lb.LoadBalancerSpec; import com.yahoo.vespa.hosted.provision.persistence.CuratorDatabaseClient; import java.time.Duration; @@ -99,7 +100,7 @@ public class LoadBalancerExpirer extends NodeRepositoryMaintainer { // Remove any real no longer allocated to this application reals.removeIf(real -> !allocatedNodes.contains(real.hostname().value())); try { - service.create(lb.id().application(), lb.id().cluster(), reals, true); + service.create(new LoadBalancerSpec(lb.id().application(), lb.id().cluster(), reals), true); db.writeLoadBalancer(lb.with(lb.instance().withReals(reals))); } catch (Exception e) { failed.add(lb.id()); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java index 00f394a7d0b..144959ca2f9 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java @@ -169,7 +169,7 @@ public class LoadBalancerProvisioner { log.log(Level.FINE, "Creating load balancer for " + cluster + " in " + application.toShortString() + ", targeting: " + reals); try { - return service.create(application, cluster, reals, force); + return service.create(new LoadBalancerSpec(application, cluster, reals), force); } catch (Exception e) { throw new LoadBalancerServiceException("Failed to (re)configure load balancer for " + cluster + " in " + application + ", targeting: " + reals + ". The operation will be " + diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerServiceTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerServiceTest.java index 402eaf37529..997aec8a156 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerServiceTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerServiceTest.java @@ -20,8 +20,8 @@ public class PassthroughLoadBalancerServiceTest { var lbService = new PassthroughLoadBalancerService(); var real = new Real(HostName.from("host1.example.com"), "192.0.2.10"); var reals = Set.of(real, new Real(HostName.from("host2.example.com"), "192.0.2.11")); - var instance = lbService.create(ApplicationId.from("tenant1", "app1", "default"), - ClusterSpec.Id.from("c1"), reals, false); + var instance = lbService.create(new LoadBalancerSpec(ApplicationId.from("tenant1", "app1", "default"), + ClusterSpec.Id.from("c1"), reals), false); assertEquals(real.hostname(), instance.hostname()); assertEquals(Set.of(real.port()), instance.ports()); assertEquals(Set.of(real.ipAddress() + "/32"), instance.networks()); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java index 1829a93c34f..06f18d94c5f 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java @@ -30,7 +30,7 @@ public class SharedLoadBalancerServiceTest { @Test public void test_create_lb() { tester.makeReadyNodes(2, "default", NodeType.proxy); - var lb = loadBalancerService.create(applicationId, clusterId, reals, false); + var lb = loadBalancerService.create(new LoadBalancerSpec(applicationId, clusterId, reals), false); assertEquals(HostName.from("host-1.yahoo.com"), lb.hostname()); assertEquals(Optional.empty(), lb.dnsZone()); @@ -40,7 +40,7 @@ public class SharedLoadBalancerServiceTest { @Test(expected = IllegalStateException.class) public void test_exception_on_missing_proxies() { - loadBalancerService.create(applicationId, clusterId, reals, false); + loadBalancerService.create(new LoadBalancerSpec(applicationId, clusterId, reals), false); } @Test -- cgit v1.2.3