aboutsummaryrefslogtreecommitdiffstats
path: root/messagebus/src/vespa/messagebus/routing/hop.h
blob: b26fcdf4ff7c900ee3f02670fdee664fe6d12214 (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "ihopdirective.h"
#include <vector>

namespace mbus {

/**
 * A hop is basically an instantiated {@link HopBlueprint}, but it can also be contructed using the factory method
 * {@link this#parse(String)}. It is a set of primitives, either a string primitive that is to be matched verbatim to a
 * service address, or a {@link RoutingPolicy} directive.
 */
class Hop {
private:
    std::vector<IHopDirective::SP> _selector;
    bool                           _ignoreResult;

public:
    /**
     * Convenience typedef for an auto-pointer to a hop.
     */
    using UP = std::unique_ptr<Hop>;

    /**
     * Constructs an empty hop.
     */
    Hop();

    /**
     * Constructs a new hop based on a selector string.
     *
     * @param selector The selector string for this hop.
     */
    Hop(const string &selector);

    /**
     * Constructs a fully populated hop.
     *
     * @param selector     The selector to copy.
     * @param ignoreResult Whether or not to ignore the result of this hop.
     */
    Hop(std::vector<IHopDirective::SP> selector, bool ignoreResult);

    Hop(const Hop &);
    Hop & operator = (const Hop &);
    Hop(Hop &&) noexcept = default;
    Hop & operator = (Hop &&) noexcept = default;

    ~Hop();

    /**
     * Adds a new directive to this hop.
     *
     * @param directive The directive to add.
     * @return This, to allow chaining.
     */
    Hop &addDirective(IHopDirective::SP dir);

    /**
     * Returns whether or not there are any directives contained in this hop.
     *
     * @return True if there is at least one directive.
     */
    bool hasDirectives() const { return !_selector.empty(); }

    /**
     * Returns the number of directives contained in this hop.
     *
     * @return The number of directives.
     */
    uint32_t getNumDirectives() const { return _selector.size(); }

    /**
     * Returns the directive at the given index.
     *
     * @param i The index of the directive to return.
     * @return The item.
     */
    const IHopDirective & getDirective(uint32_t i) const { return *_selector[i]; }
    IHopDirective::SP getDirectiveSP(uint32_t i) const { return _selector[i]; }

    /**
     * Sets the directive at a given index.
     *
     * @param i   The index at which to set the directive.
     * @param dir The directive to set.
     * @return This, to allow chaining.
     */
    Hop &setDirective(uint32_t i, IHopDirective::SP dir);

    /**
     * Returns the service name referenced by this hop. This is the concatenation of all selector primitives,
     * but with no ignore-result prefix.
     *
     * @return The service name.
     */
    string getServiceName() const { return toString(0, _selector.size()); }

    /**
     * Returns whether or not to ignore the result when routing through this hop.
     *
     * @return True to ignore the result.
     */
    bool getIgnoreResult() const { return _ignoreResult; }

    /**
     * Sets whether or not to ignore the result when routing through this hop.
     *
     * @param ignoreResult Whether or not to ignore the result.
     * @return This, to allow chaining.
     */
    Hop &setIgnoreResult(bool ignoreResult) {
        _ignoreResult = ignoreResult;
        return *this;
    }

    /**
     * Parses the given string as a single hop. The {@link this#toString()} method is compatible with this parser.
     *
     * @param hop The string to parse.
     * @return A hop that corresponds to the string.
     */
    static Hop parse(const string &hop);

    /**
     * Returns true whether this hop matches another. This respects policy directives matching any other.
     *
     * @param hop The hop to compare to.
     * @return True if this matches the argument, false otherwise.
     */
    bool matches(const Hop &hop) const;

    /**
     * Returns a string representation of this that can be debugged but not parsed.
     *
     * @return The debug string.
     */
    string toDebugString() const;

    /**
     * Returns a string representation of this that can be parsed.
     *
     * @return The parseable string.
     */
    string toString() const;

    /**
     * Returns a string concatenation of a subset of the selector primitives contained in this.
     *
     * @param fromIncluding  The index of the first primitive to include.
     * @param toNotIncluding The index after the last primitive to include.
     * @return The string concatenation.
     */
    string toString(uint32_t fromIncluding, uint32_t toNotIncluding) const;

    /**
     * Returns the prefix of this hop's selector to, but not including, the given index.
     *
     * @param toNotIncluding The index to which to generate prefix.
     * @return The prefix before the index.
     */
    string getPrefix(uint32_t toNotIncluding) const;

    /**
     * Returns the suffix of this hop's selector from, but not including, the given index.
     *
     * @param fromNotIncluding The index from which to generate suffix.
     * @return The suffix after the index.
     */
    string getSuffix(uint32_t fromNotIncluding) const;
};

} // namespace mbus