blob: 04b42f0411b8596698822f155c23859c69ae7d5a (
plain) (
blame)
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
|
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.model;
import com.yahoo.cloud.config.LbServicesConfig;
import com.yahoo.config.model.api.ApplicationClusterEndpoint;
import com.yahoo.config.model.api.ApplicationClusterInfo;
import com.yahoo.config.model.api.ApplicationInfo;
import com.yahoo.config.model.api.HostInfo;
import com.yahoo.config.model.api.ServiceInfo;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.flags.FlagSource;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import static com.yahoo.config.model.api.container.ContainerServiceType.CONTAINER;
import static com.yahoo.config.model.api.container.ContainerServiceType.QRSERVER;
/**
* Produces lb-services cfg
*
* @author Vegard Havdal
*/
public class LbServicesProducer implements LbServicesConfig.Producer {
private final Map<TenantName, Set<ApplicationInfo>> models;
private final Zone zone;
public LbServicesProducer(Map<TenantName, Set<ApplicationInfo>> models, Zone zone, FlagSource flagSource) {
this.models = models;
this.zone = zone;
}
@Override
public void getConfig(LbServicesConfig.Builder builder) {
models.keySet().stream()
.sorted()
.forEach(tenant -> {
builder.tenants(tenant.value(), getTenantConfig(models.get(tenant)));
});
}
private LbServicesConfig.Tenants.Builder getTenantConfig(Set<ApplicationInfo> apps) {
LbServicesConfig.Tenants.Builder tb = new LbServicesConfig.Tenants.Builder();
apps.stream()
.sorted(Comparator.comparing(ApplicationInfo::getApplicationId))
.filter(applicationInfo -> generateRoutingConfig(applicationInfo.getApplicationId()))
.forEach(applicationInfo -> tb.applications(createLbAppIdKey(applicationInfo.getApplicationId()), getAppConfig(applicationInfo)));
return tb;
}
private boolean generateRoutingConfig(ApplicationId applicationId) {
return ( ! applicationId.instance().isTester());
}
private String createLbAppIdKey(ApplicationId applicationId) {
return applicationId.application().value() + ":" + zone.environment().value() + ":" + zone.region().value() + ":" + applicationId.instance().value();
}
private LbServicesConfig.Tenants.Applications.Builder getAppConfig(ApplicationInfo app) {
LbServicesConfig.Tenants.Applications.Builder ab = new LbServicesConfig.Tenants.Applications.Builder();
// TODO: read active rotation from ApplicationClusterInfo
ab.activeRotation(getActiveRotation(app));
Set<ApplicationClusterInfo> applicationClusterInfos = app.getModel().applicationClusterInfo();
List<LbServicesConfig.Tenants.Applications.Endpoints.Builder> endpointBuilder = applicationClusterInfos.stream()
.sorted(Comparator.comparing(ApplicationClusterInfo::name))
.map(ApplicationClusterInfo::endpoints)
.flatMap(endpoints -> getEndpointConfig(endpoints).stream())
.toList();
ab.endpoints(endpointBuilder);
return ab;
}
private List<LbServicesConfig.Tenants.Applications.Endpoints.Builder> getEndpointConfig(List<ApplicationClusterEndpoint> clusterEndpoints) {
return clusterEndpoints.stream()
.sorted(Comparator.comparing(ApplicationClusterEndpoint::dnsName))
.map(this::getEndpointConfig)
.toList();
}
private LbServicesConfig.Tenants.Applications.Endpoints.Builder getEndpointConfig(ApplicationClusterEndpoint clusterEndpoints) {
LbServicesConfig.Tenants.Applications.Endpoints.Builder builder = new LbServicesConfig.Tenants.Applications.Endpoints.Builder();
return builder.dnsName(clusterEndpoints.dnsName().value())
.scope(LbServicesConfig.Tenants.Applications.Endpoints.Scope.Enum.valueOf(clusterEndpoints.scope().name()))
.routingMethod(LbServicesConfig.Tenants.Applications.Endpoints.RoutingMethod.Enum.valueOf(clusterEndpoints.routingMethod().name()))
.weight(clusterEndpoints.weight())
.hosts(clusterEndpoints.hostNames())
.clusterId(clusterEndpoints.clusterId());
}
private boolean getActiveRotation(ApplicationInfo app) {
boolean activeRotation = false;
for (HostInfo hostInfo : app.getModel().getHosts()) {
Optional<ServiceInfo> container = hostInfo.getServices().stream().filter(
serviceInfo -> serviceInfo.getServiceType().equals(CONTAINER.serviceName) ||
serviceInfo.getServiceType().equals(QRSERVER.serviceName)).
findAny();
if (container.isPresent()) {
activeRotation |= Boolean.parseBoolean(container.get().getProperty("activeRotation").orElse("false"));
}
}
return activeRotation;
}
}
|