diff options
author | jonmv <venstad@gmail.com> | 2023-09-28 17:17:09 +0200 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2023-09-28 17:17:09 +0200 |
commit | 1b0cfae1d7c756c2caeef468d5d2725f81493fdc (patch) | |
tree | 7f5c9e89198ee71f8e3d2b4faa94659026d3ae2b /configserver | |
parent | a1bd65e6be24f8073c6a5cc826d291a3571ee676 (diff) |
Group fingerprints by token id
Diffstat (limited to 'configserver')
6 files changed, 38 insertions, 22 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java index 058606a789e..e675e00b642 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java @@ -41,6 +41,7 @@ import com.yahoo.slime.Slime; import com.yahoo.transaction.NestedTransaction; import com.yahoo.transaction.Transaction; import com.yahoo.vespa.applicationmodel.InfrastructureApplication; +import com.yahoo.vespa.config.server.application.ActiveTokenFingerprints.Token; import com.yahoo.vespa.config.server.application.ActiveTokenFingerprintsClient; import com.yahoo.vespa.config.server.application.Application; import com.yahoo.vespa.config.server.application.ApplicationCuratorDatabase; @@ -241,7 +242,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye private SecretStoreValidator secretStoreValidator = new SecretStoreValidator(new SecretStoreProvider().get()); private FlagSource flagSource = new InMemoryFlagSource(); private ConfigConvergenceChecker configConvergenceChecker = new ConfigConvergenceChecker(); - private Map<String, List<String>> activeTokens = Map.of(); + private Map<String, List<Token>> activeTokens = Map.of(); public Builder withTenantRepository(TenantRepository tenantRepository) { this.tenantRepository = tenantRepository; @@ -303,7 +304,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye return this; } - public Builder withActiveTokens(Map<String, List<String>> tokens) { + public Builder withActiveTokens(Map<String, List<Token>> tokens) { this.activeTokens = tokens; return this; } @@ -623,7 +624,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye return uncheck(() -> clusterReindexingStatusClient.getReindexingStatus(getApplication(applicationId))); } - public Map<String, List<String>> activeTokenFingerprints(ApplicationId applicationId) { + public Map<String, List<Token>> activeTokenFingerprints(ApplicationId applicationId) { return activeTokenFingerprints.get(getApplication(applicationId)); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprints.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprints.java index cf67d6e4abd..9cde5e38302 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprints.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprints.java @@ -10,7 +10,9 @@ import java.util.Map; */ public interface ActiveTokenFingerprints { - /** Lists all active token fingerprints for each token-enabled container host in the application, that is currently up. */ - Map<String, List<String>> get(ModelResult application); + /** Lists all active tokens and their fingerprints for each token-enabled container host in the application, that is currently up. */ + Map<String, List<Token>> get(ModelResult application); + + record Token(String id, List<String> fingerprints) { } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprintsClient.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprintsClient.java index d5beb263155..4e9eac7a9a6 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprintsClient.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprintsClient.java @@ -32,6 +32,7 @@ import static com.yahoo.config.model.api.container.ContainerServiceType.CONTAINE import static com.yahoo.config.model.api.container.ContainerServiceType.QRSERVER; import static com.yahoo.slime.SlimeUtils.entriesStream; import static com.yahoo.slime.SlimeUtils.jsonToSlime; +import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; /** @@ -46,7 +47,7 @@ public class ActiveTokenFingerprintsClient implements ActiveTokenFingerprints, A } @Override - public Map<String, List<String>> get(ModelResult application) { + public Map<String, List<Token>> get(ModelResult application) { Set<String> containersWithTokenFilter = application.getModel().applicationClusterInfo().stream() .flatMap(cluster -> cluster.endpoints().stream()) .filter(endpoint -> endpoint.authMethod() == AuthMethod.token) @@ -60,17 +61,17 @@ public class ActiveTokenFingerprintsClient implements ActiveTokenFingerprints, A .toList()); } - private Map<String, List<String>> getFingerprints(List<ServiceInfo> services) { - Map<String, List<String>> fingerprints = new ConcurrentHashMap<>(); + private Map<String, List<Token>> getFingerprints(List<ServiceInfo> services) { + Map<String, List<Token>> tokens = new ConcurrentHashMap<>(); Phaser phaser = new Phaser(services.size() + 1); - for (ServiceInfo service : services) getFingerprints(fingerprints, service, phaser); + for (ServiceInfo service : services) getFingerprints(tokens, service, phaser); phaser.arriveAndAwaitAdvance(); - return fingerprints; + return tokens; } // A container may be unable to provide its fingerprints for a number of reasons, which may be OK, so // we only track those containers which return an OK response, but we do require at least one such response. - private void getFingerprints(Map<String, List<String>> hostFingerprints, ServiceInfo service, Phaser phaser) { + private void getFingerprints(Map<String, List<Token>> hostTokens, ServiceInfo service, Phaser phaser) { URI uri = HttpURL.create(Scheme.http, DomainName.of(service.getHostName()), service.getPorts().stream().filter(port -> port.getTags().stream().anyMatch("http"::equals)).findAny().get().getPort(), @@ -78,7 +79,7 @@ public class ActiveTokenFingerprintsClient implements ActiveTokenFingerprints, A .asURI(); httpClient.execute(SimpleRequestBuilder.get(uri).build(), new FutureCallback<>() { @Override public void completed(SimpleHttpResponse result) { - if (result.getCode() == 200) hostFingerprints.put(service.getHostName(), parseFingerprints(result)); + if (result.getCode() == 200) hostTokens.put(service.getHostName(), parseTokens(result)); phaser.arrive(); } @Override public void failed(Exception ex) { phaser.arrive(); } @@ -86,8 +87,11 @@ public class ActiveTokenFingerprintsClient implements ActiveTokenFingerprints, A }); } - private static List<String> parseFingerprints(SimpleHttpResponse response) { - return entriesStream(jsonToSlime(response.getBodyBytes()).get().field("fingerprints")).map(Inspector::asString).toList(); + private static List<Token> parseTokens(SimpleHttpResponse response) { + return entriesStream(jsonToSlime(response.getBodyBytes()).get().field("tokens")) + .map(entry -> new Token(entry.field("id").asString(), + entriesStream(entry.field("fingerprints")).map(Inspector::asString).toList())) + .toList(); } private static CloseableHttpAsyncClient createHttpClient() { diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java index 69d0365f089..f39feceeeb1 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java @@ -191,10 +191,15 @@ public class ApplicationHandler extends HttpHandler { private HttpResponse activeTokenFingerprints(ApplicationId applicationId) { Slime slime = new Slime(); Cursor hostsArray = slime.setObject().setArray("hosts"); - applicationRepository.activeTokenFingerprints(applicationId).forEach((host, fingerprints) -> { + applicationRepository.activeTokenFingerprints(applicationId).forEach((host, tokens) -> { Cursor hostObject = hostsArray.addObject(); hostObject.setString("host", host); - fingerprints.forEach(hostObject.setArray("fingerprints")::addString); + Cursor tokensArray = hostObject.setArray("tokens"); + tokens.forEach(token -> { + Cursor tokenObject = tokensArray.addObject(); + tokenObject.setString("id", token.id()); + token.fingerprints().forEach(tokenObject.setArray("fingerprints")::addString); + }); }); return new SlimeJsonResponse(slime); } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprintsClientTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprintsClientTest.java index dea224d2e9b..03e379311cc 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprintsClientTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ActiveTokenFingerprintsClientTest.java @@ -17,6 +17,7 @@ import com.yahoo.config.model.api.ServiceInfo; import com.yahoo.config.provision.AllocatedHosts; import com.yahoo.vespa.config.ConfigKey; import com.yahoo.vespa.config.buildergen.ConfigDefinition; +import com.yahoo.vespa.config.server.application.ActiveTokenFingerprints.Token; import com.yahoo.vespa.config.server.modelfactory.ModelResult; import org.junit.Rule; import org.junit.Test; @@ -54,13 +55,14 @@ public class ActiveTokenFingerprintsClientTest { String uriPath = "/data-plane-tokens/v1"; server1.stubFor(get(urlEqualTo(uriPath)).willReturn(serverError())); server2.stubFor(get(urlEqualTo(uriPath)).willReturn(okJson(""" - { "fingerprints": [ "foo", "bar", "baz" ] } + { "tokens": [ {"id": "t1", "fingerprints": [ "foo", "bar", "baz" ] } ] } """))); server3.stubFor(get(urlEqualTo(uriPath)).willReturn(aResponse().withStatus(503))); server4.stubFor(get(urlEqualTo(uriPath)).willReturn(okJson(""" - { "fingerprints": [ "quu", "qux", "fez" ] } + { "tokens": [ {"id": "t2", "fingerprints": [ "quu" ] } ] } """))); - Map<String, List<String>> expected = Map.of("localhost", List.of("foo", "bar", "baz")); + Map<String, List<Token>> expected = Map.of("localhost", + List.of(new Token("t1", List.of("foo", "bar", "baz")))); assertEquals(expected, client.get(app)); } } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java index 5b2d5d491a1..6fb5db70b68 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java @@ -28,6 +28,7 @@ import com.yahoo.vespa.config.server.MockLogRetriever; import com.yahoo.vespa.config.server.MockProvisioner; import com.yahoo.vespa.config.server.MockSecretStoreValidator; import com.yahoo.vespa.config.server.MockTesterClient; +import com.yahoo.vespa.config.server.application.ActiveTokenFingerprints.Token; import com.yahoo.vespa.config.server.application.ApplicationCuratorDatabase; import com.yahoo.vespa.config.server.application.ApplicationReindexing; import com.yahoo.vespa.config.server.application.ClusterReindexing; @@ -117,7 +118,7 @@ public class ApplicationHandlerTest { private ManualClock clock; private List<Endpoint> expectedEndpoints; private Availability availability; - private Map<String, List<String>> activeTokenFingerprints; + private Map<String, List<Token>> activeTokenFingerprints; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -243,12 +244,13 @@ public class ApplicationHandlerTest { @Test public void testGetTokenFingerprints() throws IOException { applicationRepository.deploy(testApp, prepareParams(applicationId)); - activeTokenFingerprints.putAll(Map.of("host", List.of("fingers", "toes"), + activeTokenFingerprints.putAll(Map.of("host", List.of(new Token("t1", List.of("fingers", "toes")), + new Token("t2", List.of())), "toast", List.of())); HttpResponse response = createApplicationHandler().handleGET(createTestRequest(toUrlPath(applicationId, Zone.defaultZone(), true) + "/active-token-fingerprints", GET)); assertEquals(200, response.getStatus()); assertEquals(""" - {"hosts":[{"host":"host","fingerprints":["fingers","toes"]},{"host":"toast","fingerprints":[]}]}""", + {"hosts":[{"host":"host","tokens":[{"id":"t1","fingerprints":["fingers","toes"]},{"id":"t2","fingerprints":[]}]},{"host":"toast","tokens":[]}]}""", getRenderedString(response)); } |