aboutsummaryrefslogtreecommitdiffstats
path: root/config/src/vespa/config/subscription/sourcespec.h
blob: 3dd735b30a7e8756acab566ec93018e621b4e436 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include <vespa/config/common/compressiontype.h>
#include <vespa/vespalib/stllike/string.h>
#include <vector>
#include <memory>

class FNET_Transport;

namespace config {

class ConfigInstance;
class SourceFactory;
struct TimingValues;

typedef vespalib::string SourceSpecKey;

/**
 * A source spec is a user provided specification of which sources to fetch
 * config from.
 */
class SourceSpec
{
public:
    using UP = std::unique_ptr<SourceSpec>; /// Convenience typedef

    /**
     * Creates a source factory from which to create config sources for new
     * subscriptions. The UpdateHandler should be
     * provided to the source for it to post any update given any config
     * request.
     *
     * @param handler A pointer to the update handler that will receive config
     *                updates from the source.
     * @param timingValues Timing values to be used for this source.
     * @return An std::unique_ptr<Source> that can be used to ask for config.
     */
    virtual std::unique_ptr<SourceFactory> createSourceFactory(const TimingValues & timingValues) const = 0;
    virtual ~SourceSpec() = default;
};


/**
 * A RawSpec gives the ability to specify config as a raw config string.
 */
class RawSpec : public SourceSpec
{
public:
    /**
     * Constructs a new RawSpec that can be sent with a subscribe call.
     *
     * @param config The config represented as a raw string.
     */
    RawSpec(const vespalib::string & config);

    std::unique_ptr<SourceFactory> createSourceFactory(const TimingValues & timingValues) const override;

    /**
     * Returns the string representation of this config.
     *
     * @return the config in a string.
     */
    const vespalib::string & toString() const { return _config; }
private:
    vespalib::string _config;
};

/**
 * A FileSpec gives the ability to serve config from a file. The filenames in
 * this spec must match the config definition name when subscribing.
 */
class FileSpec : public SourceSpec
{
public:
    /**
     * Creates a FileSpec to serve config from a file. Multiple files may be
     * added to the spec.
     *
     * @param fileName Path to the file to serve config from.
     */
    FileSpec(const vespalib::string & fileName);

    /**
     * Get the file name of this spec.
     *
     * @return the filename from which to serve config.
     */
    const vespalib::string & getFileName() const { return _fileName; }

    std::unique_ptr<SourceFactory> createSourceFactory(const TimingValues & timingValues) const override;
private:
    void verifyName(const vespalib::string & fileName);
    vespalib::string _fileName;
};

/**
 * A DirSpec gives the ability to serve config from a directory.
 */
class DirSpec : public SourceSpec
{
public:
    /**
     * Create a DirSpec to serve config from. The files within this directory
     * must have the names of the config definition ending with a .cfg suffix.
     *
     * @param dirName Directory to serve config from.
     */
    DirSpec(const vespalib::string & dirName);
    ~DirSpec() override;

    /**
     * Get directory handled by this spec.
     *
     * @return the directory from which to serve config.
     */
    const vespalib::string & getDirName() const { return _dirName; }

    std::unique_ptr<SourceFactory> createSourceFactory(const TimingValues & timingValues) const override;
private:
    vespalib::string _dirName;
};

/**
 * A server spec is a user provided specification of one or more config servers
 * that may provide config.
 */
class ServerSpec : public SourceSpec
{
public:
    /// A list of host specifications
    using HostSpecList = std::vector<vespalib::string>;

    /**
     * Construct a ServerSpec that fetches the host specs from the
     * VESPA_CONFIG_SOURCES environment variable.
     */
    ServerSpec();

    /**
     * Construct a ServerSpec with a list host specifications on the form
     * tcp/hostname:port
     *
     * @param list a list of host specifications.
     */
    ServerSpec(const HostSpecList & list);

    /**
     * Construct a ServerSpec with a host specification.
     *
     * @param hostSpec the host specification on the form "tcp/hostname:port"
     */
    ServerSpec(const vespalib::string & hostSpec);

    std::unique_ptr<SourceFactory> createSourceFactory(const TimingValues & timingValues) const override;

    /**
     * Inspect how many hosts this source refers to.
     *
     * @return the number of hosts referred.
     */
    size_t numHosts() const { return _hostList.size(); }

    /**
     * Retrieve host specification element i
     *
     * @param i the spec element to retrieve.
     */
    const vespalib::string & getHost(size_t i) const { return _hostList[i]; }

    /**
     * Get the protocol version as parsed by this source spec.
     */
    int protocolVersion() const { return _protocolVersion; }

    /**
     * Get the trace level as parsed by this source spec.
     */
    int traceLevel() const { return _traceLevel; }

    /**
     * Get the compression type as parsed by this source spec.
     */
    CompressionType compressionType() const { return _compressionType; }
private:
    void initialize(const vespalib::string & hostSpec);
    HostSpecList          _hostList;
    const int             _protocolVersion;
    const int             _traceLevel;
    const CompressionType _compressionType;
    const static int DEFAULT_PROXY_PORT = 19090;
};

/**
 * A ServerSpec that allows providing externally supplied transport
 */
class ConfigServerSpec : public config::ServerSpec {
public:
    ConfigServerSpec(FNET_Transport & transport);
    ~ConfigServerSpec() override;
    std::unique_ptr<SourceFactory> createSourceFactory(const TimingValues & timingValues) const override;
private:
    FNET_Transport & _transport;
};



/**
 * A ConfigSet gives the ability to serve config from a set of ConfigInstance
 * builders.
 */

class BuilderMap;

class ConfigSet : public SourceSpec
{
public:
    /// Constructs a new empty ConfigSet
    ConfigSet();

    using BuilderMapSP = std::shared_ptr<BuilderMap>;
    /**
     * Add a builder to serve config from. The builder must be of a
     * 'ConfigType'Builder, and the configId must be the id to which you want to
     * serve the config generated by this builder.
     *
     * @param configId The configId that should be used to get the config
     *                 produced by this builder.
     * @param builder A builder instance that you can use to change config later
     *                and then call reload on the ConfigContext object.
     */
    void addBuilder(const vespalib::string & configId, ConfigInstance * builder);

    std::unique_ptr<SourceFactory> createSourceFactory(const TimingValues & timingValues) const override;
private:
    BuilderMapSP _builderMap;
};

}