• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nats-io / java-nats-server-runner / #5

pending completion
#5

push

github-actions

scottf
1.2.5 update cluster creation utils for JS support

8 of 8 new or added lines in 2 files covered. (100.0%)

380 of 454 relevant lines covered (83.7%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.79
/src/main/java/nats/io/NatsRunnerUtils.java
1
// Copyright 2020-2023 The NATS Authors
2
// Licensed under the Apache License, Version 2.0 (the "License");
3
// you may not use this file except in compliance with the License.
4
// You may obtain a copy of the License at:
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software
9
// distributed under the License is distributed on an "AS IS" BASIS,
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
// See the License for the specific language governing permissions and
12
// limitations under the License.
13

14
package nats.io;
15

16
import java.io.BufferedReader;
17
import java.io.File;
18
import java.io.IOException;
19
import java.io.InputStreamReader;
20
import java.net.ServerSocket;
21
import java.nio.file.Path;
22
import java.nio.file.Paths;
23
import java.util.ArrayList;
24
import java.util.List;
25

26
public abstract class NatsRunnerUtils {
27
    public static final String NATS_SERVER_PATH_ENV = "nats_server_path";
28
    public static final String DEFAULT_NATS_SERVER = "nats-server";
29

30
    public static final String CONFIG_FILE_OPTION_NAME = "--config";
31
    public static final String VERSION_OPTION = "--version";
32
    public static final String JETSTREAM_OPTION = "-js";
33

34
    public static final String CONF_FILE_PREFIX = "nats_java_test";
35
    public static final String CONF_FILE_EXT = ".conf";
36
    public static final String PORT_REGEX = "port: (\\d+)";
37
    public static final String PORT_PROPERTY = "port: ";
38
    public static final int DEFAULT_CLUSTER_COUNT = 3;
39
    public static final String DEFAULT_CLUSTER_NAME = "cluster";
40
    public static final String DEFAULT_SERVER_NAME_PREFIX = "server";
41

42
    public static String DEFAULT_HOST = "127.0.0.1";
1✔
43
    public static int DEFAULT_PORT_START = 4220;
1✔
44
    public static int DEFAULT_LISTEN_START = 4230;
1✔
45
    public static int DEFAULT_MONITOR_START = 4280;
1✔
46

47
    private NatsRunnerUtils() {}
48

49
    /**
50
     * Build a standard nats://localhost:port uri
51
     * @param port the port
52
     * @return the uri
53
     * @deprecated Use {@link #getNatsLocalhostUri(int)} instead.
54
     */
55
    @Deprecated
56
    public static String getURIForPort(int port) {
57
        return getLocalhostUri("nats", port);
1✔
58
    }
59

60
    /**
61
     * Build a nats://localhost:port uri
62
     * @param port the port
63
     * @return the uri
64
     */
65
    public static String getNatsLocalhostUri(int port) {
66
        return getLocalhostUri("nats", port);
1✔
67
    }
68

69
    /**
70
     * Build a schema://localhost:port uri
71
     * @param schema the schema
72
     * @param port the port
73
     * @return the uri
74
     */
75
    public static String getLocalhostUri(String schema, int port) {
76
        return schema + "://localhost:" + port;
1✔
77
    }
78

79
    /**
80
     * Set the path for the server. Will be used if {@value #NATS_SERVER_PATH_ENV} environment variable is not set.
81
     * @deprecated Use {@link NatsServerRunner#setPreferredServerPath} instead
82
     * @param serverPath the fully qualified path of the server
83
     */
84
    @Deprecated
85
    public static void setServerPath(String serverPath) {
86
        NatsServerRunner.setPreferredServerPath(serverPath);
1✔
87
    }
1✔
88

89
    /**
90
     * Clear the default path for the server.
91
     * @deprecated Use {@link NatsServerRunner#clearPreferredServerPath} instead
92
     */
93
    @Deprecated
94
    public static void clearServerPath() {
95
        NatsServerRunner.clearPreferredServerPath();
1✔
96
    }
1✔
97

98
    /**
99
     * Resolves the server executable path in this order:
100
     * <ol>
101
     * <li>Checking the {@value #NATS_SERVER_PATH_ENV} environment variable</li>
102
     * <li>Checking the value set via {@link NatsServerRunner#setPreferredServerPath} method</li>
103
     * <li>{@value #DEFAULT_NATS_SERVER}</li>
104
     * </ol>
105
     * @return the resolved path
106
     */
107
    public static String getResolvedServerPath() {
108
        String serverPath = NatsServerRunner.getPreferredServerPath();
1✔
109
        if (serverPath == null) {
1✔
110
            serverPath = System.getenv(NATS_SERVER_PATH_ENV);
1✔
111
            if (serverPath == null) {
1✔
112
                serverPath = DEFAULT_NATS_SERVER;
1✔
113
            }
114
        }
115
        return serverPath;
1✔
116
    }
117

118
    /**
119
     * Get a port number automatically allocated by the system, typically from an ephemeral port range.
120
     * @return the port number
121
     * @throws IOException if there is a problem getting a port
122
     */
123
    public static int nextPort() throws IOException {
124
        try (ServerSocket socket = new ServerSocket(0)) {
1✔
125
            while ( !socket.isBound() ) {
1✔
126
                //noinspection BusyWait
127
                Thread.sleep(50);
×
128
            }
129
            return socket.getLocalPort();
1✔
130
        } catch (InterruptedException e) {
×
131
            Thread.currentThread().interrupt();
×
132
            throw new IOException("Thread interrupted", e);
×
133
        }
134
    }
135

136
    /**
137
     * Get the version string from the nats server i.e. nats-server: v2.2.2
138
     * Using the server resolved by {@link #getResolvedServerPath}
139
     * @return the version string
140
     */
141
    public static String getNatsServerVersionString() {
142
        return getNatsServerVersionString(getResolvedServerPath());
1✔
143
    }
144

145

146
    /**
147
     * Get the version string from the nats server i.e. nats-server: v2.2.2
148
     * @param serverPath the specific server path to check
149
     * @return the version string
150
     */
151
    public static String getNatsServerVersionString(String serverPath) {
152
        ArrayList<String> cmd = new ArrayList<String>();
1✔
153

154
        // order of precedence is environment, value set statically, default
155

156
        cmd.add(serverPath);
1✔
157
        cmd.add(VERSION_OPTION);
1✔
158

159
        try {
160
            ProcessBuilder pb = new ProcessBuilder(cmd);
1✔
161
            Process process = pb.start();
1✔
162
            if (0 != process.waitFor()) {
1✔
163
                throw new IllegalStateException(String.format("Process %s failed", pb.command()));
×
164
            }
165
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
1✔
166
            ArrayList<String> lines = new ArrayList<>();
1✔
167
            String line = "";
1✔
168
            while ((line = reader.readLine())!= null) {
1✔
169
                lines.add(line);
1✔
170
            }
171

172
            if (lines.size() > 0) {
1✔
173
                return lines.get(0);
1✔
174
            }
175

176
            return null;
×
177
        }
178
        catch (Exception exp) {
×
179
            return null;
×
180
        }
181
    }
182

183
    public static List<ClusterInsert> createClusterInserts() throws IOException {
184
        return createClusterInserts(DEFAULT_CLUSTER_COUNT, DEFAULT_CLUSTER_NAME, DEFAULT_SERVER_NAME_PREFIX, false, null);
1✔
185
    }
186

187
    public static List<ClusterInsert> createClusterInserts(Path jsStoreDirBase) throws IOException {
188
        return createClusterInserts(DEFAULT_CLUSTER_COUNT, DEFAULT_CLUSTER_NAME, DEFAULT_SERVER_NAME_PREFIX, false, jsStoreDirBase);
×
189
    }
190

191
    public static List<ClusterInsert> createClusterInserts(int count) throws IOException {
192
        return createClusterInserts(count, DEFAULT_CLUSTER_NAME, DEFAULT_SERVER_NAME_PREFIX, false, null);
1✔
193
    }
194

195
    public static List<ClusterInsert> createClusterInserts(int count, Path jsStoreDirBase) throws IOException {
196
        return createClusterInserts(count, DEFAULT_CLUSTER_NAME, DEFAULT_SERVER_NAME_PREFIX, false, jsStoreDirBase);
×
197
    }
198

199
    public static List<ClusterInsert> createClusterInserts(int count, String clusterName, String serverNamePrefix) throws IOException {
200
        return createClusterInserts(createNodes(count, clusterName, serverNamePrefix, false, null));
×
201
    }
202

203
    public static List<ClusterInsert> createClusterInserts(int count, String clusterName, String serverNamePrefix, Path jsStoreDirBase) throws IOException {
204
        return createClusterInserts(createNodes(count, clusterName, serverNamePrefix, false, jsStoreDirBase));
×
205
    }
206

207
    public static List<ClusterInsert> createClusterInserts(int count, String clusterName, String serverNamePrefix, boolean monitor) throws IOException {
208
        return createClusterInserts(createNodes(count, clusterName, serverNamePrefix, monitor, null));
×
209
    }
210

211
    public static List<ClusterInsert> createClusterInserts(int count, String clusterName, String serverNamePrefix, boolean monitor, Path jsStoreDirBase) throws IOException {
212
        return createClusterInserts(createNodes(count, clusterName, serverNamePrefix, monitor, jsStoreDirBase));
1✔
213
    }
214

215
    public static void defaultHost(String defaultHost) {
216
        DEFAULT_HOST = defaultHost;
×
217
    }
×
218

219
    public static void defaultPortStart(int defaultPortStart) {
220
        DEFAULT_PORT_START = defaultPortStart;
×
221
    }
×
222

223
    public static void defaultListenStart(int defaultListenStart) {
224
        DEFAULT_LISTEN_START = defaultListenStart;
×
225
    }
×
226

227
    public static void defaultMonitorStart(int defaultMonitorStart) {
228
        DEFAULT_MONITOR_START = defaultMonitorStart;
×
229
    }
×
230

231
    public static List<ClusterNode> createNodes(int count, String clusterName, String serverNamePrefix, boolean monitor, Path jsStoreDirBase) {
232
        return createNodes(count, clusterName, serverNamePrefix, jsStoreDirBase,
1✔
233
            DEFAULT_HOST, DEFAULT_PORT_START, DEFAULT_LISTEN_START,
234
            monitor ? DEFAULT_MONITOR_START : null);
1✔
235
    }
236

237
    public static List<ClusterNode> createNodes(int count, String clusterName, String serverNamePrefix, Path jsStoreDirBase,
238
                                                String host, int portStart, int listenStart, Integer monitorStart) {
239
        List<ClusterNode> nodes = new ArrayList<>();
1✔
240
        for (int x = 0; x < count; x++) {
1✔
241
            int port = portStart + x;
1✔
242
            int listen = listenStart + x;
1✔
243
            Integer monitor = monitorStart == null ? null : monitorStart + x;
1✔
244
            Path jsStoreDir = jsStoreDirBase == null ? null : Paths.get(jsStoreDirBase.toString(), "" + port);
1✔
245
            nodes.add( new ClusterNode(clusterName, serverNamePrefix + x, host, port, listen, monitor, jsStoreDir));
1✔
246
        }
247
        return nodes;
1✔
248
    }
249

250
    public static List<ClusterInsert> createClusterInserts(List<ClusterNode> nodes) {
251
        List<ClusterInsert> inserts = new ArrayList<>();
1✔
252
        for (ClusterNode node : nodes) {
1✔
253
            List<String> lines = new ArrayList<>();
1✔
254
            lines.add("port:" + node.port);
1✔
255
            if (node.monitor != null) {
1✔
256
                lines.add("http:" + node.monitor);
×
257
            }
258
            if (node.jsStoreDir != null) {
1✔
259
                String dir = node.jsStoreDir.toString();
×
260
                if (File.separatorChar == '\\') {
×
261
                    dir = dir.replace("\\", "\\\\").replace("/", "\\\\");
×
262
                }
263
                else {
264
                    dir = dir.replace("\\", "/");
×
265
                }
266
                lines.add("jetstream {");
×
267
                lines.add("    store_dir=" + dir);
×
268
                lines.add("}");
×
269
            }
270
            lines.add("server_name=" + node.serverName);
1✔
271
            lines.add("cluster {");
1✔
272
            lines.add("  name: " + node.clusterName);
1✔
273
            lines.add("  listen: " + node.host + ":" + node.listen);
1✔
274
            lines.add("  routes: [");
1✔
275
            for (ClusterNode routeNode : nodes) {
1✔
276
                if (!routeNode.serverName.equals(node.serverName)) {
1✔
277
                    lines.add("    nats-route://" + node.host + ":" + routeNode.listen);
1✔
278
                }
279
            }
1✔
280
            lines.add("  ]");
1✔
281
            lines.add("}");
1✔
282
            inserts.add(new ClusterInsert(node, lines.toArray(new String[0])));
1✔
283
        }
1✔
284
        return inserts;
1✔
285

286
    }
287
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc