diff options
author | gjoranv <gv@verizonmedia.com> | 2021-09-23 16:59:45 +0200 |
---|---|---|
committer | gjoranv <gv@verizonmedia.com> | 2021-09-23 16:59:45 +0200 |
commit | bc736edc5b7ee54f4beb6a53ab11a8fe9d75673f (patch) | |
tree | 62105a593006c0e895b30ee49bc3720ad992f2c7 /config-proxy | |
parent | 5f1f8f36cd26e5d8a5502d165e3760ab636f8979 (diff) |
Move ConfigVerification to config-proxy
.. to allow decoupling config-bundle from http-utils.
Diffstat (limited to 'config-proxy')
-rw-r--r-- | config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigVerification.java | 97 | ||||
-rw-r--r-- | config-proxy/src/main/sh/vespa-config-verification.sh | 2 |
2 files changed, 98 insertions, 1 deletions
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigVerification.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigVerification.java new file mode 100644 index 00000000000..56824c85413 --- /dev/null +++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigVerification.java @@ -0,0 +1,97 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.config.proxy; + +import ai.vespa.util.http.hc5.VespaHttpClientBuilder; +import com.yahoo.slime.ArrayTraverser; +import com.yahoo.slime.Slime; +import com.yahoo.slime.SlimeUtils; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +/** + * Tool to verify that configs across multiple config servers are the same. + * + * @author Ulf Lilleengen + */ +public class ConfigVerification { + + private final static int port = 19071; + private final static String prefix = "http://"; + + public static void main(String [] args) throws IOException { + List<String> configservers = new ArrayList<>(); + String tenant = "default"; + String appName = "default"; + String environment = "prod"; + String region = "default"; + String instance= "default"; + for (String arg : args) { + configservers.add(prefix + arg + ":" + port + "/config/v2/tenant/" + tenant + "/application/" + appName + "/environment/" + environment + "/region/" + region + "/instance/" + instance + "/?recursive=true"); + } + try (CloseableHttpClient httpClient = VespaHttpClientBuilder.create(BasicHttpClientConnectionManager::new).build()) { + System.exit(compareConfigs(listConfigs(configservers, httpClient), httpClient)); + } + } + + private static Map<String, Stack<String>> listConfigs(List<String> urls, CloseableHttpClient httpClient) throws IOException { + Map<String, String> outputs = performRequests(urls, httpClient); + + Map<String, Stack<String>> recurseMappings = new LinkedHashMap<>(); + for (Map.Entry<String, String> entry : outputs.entrySet()) { + Slime slime = SlimeUtils.jsonToSlime(entry.getValue()); + final List<String> list = new ArrayList<>(); + slime.get().field("configs").traverse((ArrayTraverser) (idx, inspector) -> list.add(inspector.asString())); + Stack<String> stack = new Stack<>(); + Collections.sort(list); + stack.addAll(list); + recurseMappings.put(entry.getKey(), stack); + } + return recurseMappings; + } + + private static Map<String, String> performRequests(List<String> urls, CloseableHttpClient httpClient) throws IOException { + Map<String, String> outputs = new LinkedHashMap<>(); + for (String url : urls) { + outputs.put(url, performRequest(url, httpClient)); + } + return outputs; + } + + private static int compareConfigs(Map<String, Stack<String>> mappings, CloseableHttpClient httpClient) throws IOException { + for (int n = 0; n < mappings.values().iterator().next().size(); n++) { + List<String> recurseUrls = new ArrayList<>(); + for (Map.Entry<String, Stack<String>> entry : mappings.entrySet()) { + recurseUrls.add(entry.getValue().pop()); + } + if ( ! equalOutputs(performRequests(recurseUrls, httpClient))) + return -1; + } + return 0; + } + + private static boolean equalOutputs(Map<String, String> outputs) { + Map.Entry<String, String> firstEntry = outputs.entrySet().iterator().next(); + for (Map.Entry<String, String> entry : outputs.entrySet()) { + if (!entry.getValue().equals(firstEntry.getValue())) { + System.out.println("output from '" + entry.getKey() + "': '" + entry.getValue() + + "' did not equal output from '" + firstEntry.getKey() + "': '" + firstEntry.getValue() + "'"); + return false; + } + } + return true; + } + + private static String performRequest(String url, CloseableHttpClient httpClient) throws IOException { + return httpClient.execute(new HttpGet(url), new BasicHttpClientResponseHandler()); + } +} diff --git a/config-proxy/src/main/sh/vespa-config-verification.sh b/config-proxy/src/main/sh/vespa-config-verification.sh index 308d7f733a4..97201d772eb 100644 --- a/config-proxy/src/main/sh/vespa-config-verification.sh +++ b/config-proxy/src/main/sh/vespa-config-verification.sh @@ -79,4 +79,4 @@ export ROOT echo "# Using CLASSPATH=$CLASSPATH, args=$@" -java -cp $CLASSPATH:$ROOT/lib/jars/config-proxy-jar-with-dependencies.jar com.yahoo.vespa.config.ConfigVerification "$@" +java -cp $CLASSPATH:$ROOT/lib/jars/config-proxy-jar-with-dependencies.jar com.yahoo.vespa.config.proxy.ConfigVerification "$@" |