aboutsummaryrefslogtreecommitdiffstats
path: root/config/src/main/java/com/yahoo/config/subscription/ConfigSourceSet.java
blob: 65737d116c5cbb98f53b49f75fb2a873687b87ea (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.subscription;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import static java.util.logging.Level.INFO;

/**
 * An immutable set of connection endpoints, where each endpoint points to either a
 * remote config server or a config proxy.
 *
 * Two sets are said to be equal if they contain the same sources, independent of order,
 * upper/lower-casing and whitespaces.
 *
 * @author gjoranv
 */
public class ConfigSourceSet implements ConfigSource {

    private static final Logger log = Logger.getLogger(ConfigSourceSet.class.getName());
    private final Set<String> sources = new LinkedHashSet<>();

    /**
     * Creates an empty ConfigSourceSet, mostly used for unit testing.
     */
    public ConfigSourceSet() {
    }

    /**
     * Creates a ConfigSourceSet containing all the unique given input addresses.
     * Each address is trimmed and lower-cased before adding.
     *
     * @param addresses  Connection endpoints on the format "tcp/host:port".
     */
    public ConfigSourceSet(List<String> addresses) {
        for (String a : addresses) {
           sources.add(a.trim().toLowerCase());
        }
    }

    /**
     * Creates a ConfigSourceSet containing all the unique given input addresses.
     * Each address is trimmed and lower-cased before adding.
     *
     * @param addresses  Connection endpoints on the format "tcp/host:port".
     */
    public ConfigSourceSet(String[] addresses) {
        this(Arrays.asList(addresses));
    }

    /**
     * Convenience constructor to create a ConfigSourceSet with only one input address.
     *
     * @param address  Connection endpoint on the format "tcp/host:port".
     */
    public ConfigSourceSet(String address) {
        this(new String[] { address });
    }

    /**
     * Returns an unmodifiable set containing all sources in this ConfigSourceSet. Iteration order is
     * guaranteed to be the same as that of the list or array that was given when this set was created.
     *
     * @return All sources in this ConfigSourceSet.
     */
    public Set<String> getSources() {
        return Collections.unmodifiableSet(sources);
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (! (o instanceof ConfigSourceSet)) {
            return false;
        }
        ConfigSourceSet css = (ConfigSourceSet)o;
        return sources.equals(css.sources);
    }

    public int hashCode() {
        return sources.hashCode();
    }

    public String toString() {
        return sources.toString();
    }

    /**
     * Create a new source set using the environment variables or system properties
     * @return a new source set if available, null if not.
     */
    public static ConfigSourceSet createDefault() {
        String configSources = System.getenv("VESPA_CONFIG_SOURCES");
        if (configSources != null) {
            log.log(INFO, "Using config sources from VESPA_CONFIG_SOURCES: " + configSources);
            return new ConfigSourceSet(checkSourcesSyntax(configSources));
        } else {
            String[] def = {"tcp/localhost:" + System.getProperty("vespa.config.port", "19090")};
            String[] sourceSet = checkSourcesSyntax(System.getProperty("configsources"));
            return new ConfigSourceSet(sourceSet == null ? def : sourceSet);
        }
    }

    /**
     * Check sources syntax and convert it to a proper source set by checking if
     * sources start with the required "tcp/" prefix and add that prefix if not.
     *
     * @param sources a source set as a comma-separated string
     * @return a String array with sources, or null if the input source set was null
     */
    private static String[] checkSourcesSyntax(String sources) {
        String[] sourceSet = null;
        if (sources != null) {
            sourceSet = sources.split(",");
            int i = 0;
            for (String s : sourceSet) {
                if (!s.startsWith("tcp/")) {
                    sourceSet[i] = "tcp/" + sourceSet[i];
                }
                i++;
            }
        }
        return sourceSet;
    }

}