aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/vespa/model/PortsMeta.java
blob: 85cbdccb05e0961928dbe58aea6a7de379e088d6 (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * Track meta information about the ports of a service.
 *
 * @author Vidar Larsen
 */
public class PortsMeta implements Serializable {

    /** A list of all ports. The list elements are lists of strings. */
    private final List<LinkedList<String>> ports;

    /** Remember the rpc admin port offset. */
    private Integer rpcAdminOffset   = null;
    /** Remember the rpc status port offset. */
    private Integer rpcStatusOffset  = null;
    /** Remember the http admin port offset. */
    private Integer httpAdminOffset  = null;
    /** Remember the http status port offset. */
    private Integer httpStatusOffset = null;

    /** Keep track of the offset to register for, when chaining */
    private Integer currentOffset;

    /** Create a new PortsMeta object. */
    public PortsMeta() {
        ports = new ArrayList<>();
    }

    /**
     * Set up the port to tag, for chained usage.
     *
     * @param offset the relative port to tag
     * @return this portsmeta, to allow .tag calls
     */
    public PortsMeta on(int offset) {
        this.currentOffset = offset;
        return this;
    }

    /**
     * Tag a previously setup port (using 'on') with the specified tag.
     *
     * @param meta the tag to apply to the current port
     * @return this portsmeta, to allow further .tag calls
     */
    public PortsMeta tag(String meta) {
        if (currentOffset == null) {
            throw new NullPointerException("No current port offset to tag, use 'on#1'");
        }
        return register(currentOffset, meta);
    }

    /**
     * Register a given metainfo string to the port at offset.
     *
     * @param offset 0-based index to identify the port
     * @param meta a String to be added to the given ports meta set
     * @return this for convenient chaining
     */
    private PortsMeta register(int offset, String meta) {
        // Allocate new LinkedLists on each element up-to-and-including offset
        for (int i = ports.size(); i <= offset; i++) {
            ports.add(i, new LinkedList<>());
        }
        ports.get(offset).addFirst(meta);

        return this;
    }

    /**
     * Check if the port at a specific offset contains a particular meta attribute.
     *
     * @param offset the relative port offset
     * @param meta the meta info we want to check for
     * @return boolean true if the specific port has registered the meta
     */
    public boolean contains(int offset, String meta) {
        return offset < ports.size() && ports.get(offset).contains(meta);
    }

    /**
     * Get the number of ports with registered meta.
     *
     * @return the number of ports that have been registered
     */
    public int getNumPorts() {
        return ports.size();
    }

    /**
     * Get an iterator of the Strings registered at the specific point.
     *
     * @param offset the relative offset to inquire about tags
     * @return List of tags.
     */
    public List<String> getTagsAt(int offset) {
        try {
            return ports.get(offset);
        } catch (IndexOutOfBoundsException e) {
            throw new IllegalArgumentException("Trying to get ports meta with offset " + offset +
                                               ", which is outside the range 0 to " + ports.size(), e);
        }
    }

    /**
     * Get the offset to the rpc port used for admin.
     *
     * @return the offset, or null if none set
     */
    public Integer getRpcAdminOffset() {
        if (rpcAdminOffset == null) {
            for (int p = 0; p < getNumPorts(); p++) {
                if (contains(p, "rpc") && contains(p, "admin") && !contains(p, "nc")) {
                    rpcAdminOffset = p;
                    break;
                }
            }
        }
        return rpcAdminOffset;
    }

    /**
     * Get the offset to the rpc port used for status.
     * @return Integer the offset, or null if none set.
     */
    public Integer getRpcStatusOffset() {
        if (rpcStatusOffset == null) {
            for (int p = 0; p < getNumPorts(); p++) {
                if (contains(p, "rpc") && contains(p, "status") && !contains(p, "nc")) {
                    rpcStatusOffset = p;
                    break;
                }
            }
        }
        return rpcStatusOffset;
    }

    /**
     * Get the offset to the http port used for admin.
     * @return Integer the offset, or null if none set.
     */
    public Integer getHttpAdminOffset() {
        if (httpAdminOffset == null) {
            for (int p = 0; p < getNumPorts(); p++) {
                if (contains(p, "http") && contains(p, "admin")) {
                    httpAdminOffset = p;
                    break;
                }
            }
        }
        return httpAdminOffset;
    }

    /**
     * Get the offset to the http port used for status.
     * @return Integer the offset, or null if none set.
     */
    public Integer getHttpStatusOffset() {
        if (httpStatusOffset == null) {
            for (int p = 0; p < getNumPorts(); p++) {
                if (contains(p, "http") && contains(p, "status")) {
                    httpStatusOffset = p;
                    break;
                }
            }
        }
        return httpStatusOffset;
    }

}