Skip to content

Commit eda2c00

Browse files
authored
check webapp via API call (#4209)
fixes #4208
1 parent 88dfe91 commit eda2c00

File tree

4 files changed

+107
-39
lines changed

4 files changed

+107
-39
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/index/Indexer.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public final class Indexer {
149149
private static final String[] LUCENE_LOCKS = {ON, OFF, "simple", "native"};
150150
private static final String OPENGROK_JAR = "opengrok.jar";
151151

152-
private static final int WEBAPP_CONNECT_TIMEOUT = 1000; // in milliseconds
152+
private static final int WEBAPP_CONNECT_TIMEOUT = 3000; // in milliseconds
153153

154154
public static Indexer getInstance() {
155155
return indexer;
@@ -173,8 +173,9 @@ public static void main(String[] argv) {
173173
try {
174174
argv = parseOptions(argv);
175175

176-
if (webappURI != null && !HostUtil.isReachable(webappURI, WEBAPP_CONNECT_TIMEOUT)) {
177-
System.err.println(webappURI + " is not reachable.");
176+
if (webappURI != null && !HostUtil.isReachable(webappURI, WEBAPP_CONNECT_TIMEOUT,
177+
cfg.getIndexerAuthenticationToken())) {
178+
System.err.println(webappURI + " is not reachable and the -U option was specified, exiting.");
178179
System.exit(1);
179180
}
180181

opengrok-indexer/src/main/java/org/opengrok/indexer/index/IndexerUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ private IndexerUtil() {
4646
*/
4747
public static MultivaluedMap<String, Object> getWebAppHeaders() {
4848
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
49-
String token = null;
49+
String token;
5050
if ((token = RuntimeEnvironment.getInstance().getIndexerAuthenticationToken()) != null) {
5151
headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
5252
}

opengrok-indexer/src/main/java/org/opengrok/indexer/util/HostUtil.java

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,23 @@
1818
*/
1919

2020
/*
21-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
21+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
2222
*/
2323
package org.opengrok.indexer.util;
2424

25+
import jakarta.ws.rs.ProcessingException;
26+
import jakarta.ws.rs.client.Client;
27+
import jakarta.ws.rs.client.ClientBuilder;
28+
import jakarta.ws.rs.core.HttpHeaders;
29+
import jakarta.ws.rs.core.MultivaluedHashMap;
30+
import jakarta.ws.rs.core.MultivaluedMap;
31+
import jakarta.ws.rs.core.Response;
32+
import org.jetbrains.annotations.Nullable;
2533
import org.opengrok.indexer.logger.LoggerFactory;
2634

27-
import java.io.IOException;
28-
import java.net.InetAddress;
29-
import java.net.InetSocketAddress;
30-
import java.net.Socket;
3135
import java.net.URI;
3236
import java.net.URISyntaxException;
33-
import java.net.UnknownHostException;
37+
import java.util.concurrent.TimeUnit;
3438
import java.util.logging.Level;
3539
import java.util.logging.Logger;
3640

@@ -55,33 +59,49 @@ public static int urlToPort(String urlStr) throws URISyntaxException {
5559
return uri.getPort();
5660
}
5761

58-
/**
59-
* @param urlStr URI
60-
* @return hostname
61-
* @throws URISyntaxException on error
62-
*/
63-
public static String urlToHostname(String urlStr) throws URISyntaxException {
64-
URI uri = new URI(urlStr);
65-
return uri.getHost();
66-
}
62+
private static boolean isWebAppReachable(String webappURI, int timeOutMillis, @Nullable String token) {
63+
ClientBuilder clientBuilder = ClientBuilder.newBuilder();
64+
clientBuilder.connectTimeout(timeOutMillis, TimeUnit.MILLISECONDS);
65+
clientBuilder.readTimeout(timeOutMillis, TimeUnit.MILLISECONDS);
6766

68-
/**
69-
* @param addr IP address
70-
* @param port port number
71-
* @param timeOutMillis timeout in milliseconds
72-
* @return true if TCP connect works, false otherwise
73-
*/
74-
public static boolean isReachable(InetAddress addr, int port, int timeOutMillis) {
75-
try (Socket soc = new Socket()) {
76-
soc.connect(new InetSocketAddress(addr, port), timeOutMillis);
77-
} catch (IOException e) {
67+
// Here, IndexerUtil#getWebAppHeaders() is not used because at the point this method is called,
68+
// the RuntimeEnvironment configuration used by getWebAppHeaders() is not set yet.
69+
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
70+
if (token != null) {
71+
headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
72+
}
73+
74+
try (Client client = clientBuilder.build()) {
75+
Response response = client
76+
.target(webappURI)
77+
.path("api")
78+
.path("v1")
79+
.path("configuration")
80+
.request()
81+
.headers(headers)
82+
.get();
83+
84+
if (response.getStatusInfo().getFamily() != Response.Status.Family.SUCCESSFUL) {
85+
LOGGER.log(Level.SEVERE, "cannot reach OpenGrok web application on {0}: {1}",
86+
new Object[]{webappURI, response.getStatusInfo()});
87+
return false;
88+
}
89+
} catch (ProcessingException e) {
90+
LOGGER.log(Level.SEVERE, String.format("could not connect to %s", webappURI), e);
7891
return false;
7992
}
8093

8194
return true;
8295
}
8396

84-
public static boolean isReachable(String webappURI, int timeOutMillis) {
97+
/**
98+
*
99+
* @param webappURI URI of the web app
100+
* @param timeOutMillis connect/read timeout in milliseconds
101+
* @param token authentication token, can be {@code null}
102+
* @return whether web app is reachable within given timeout on given URI
103+
*/
104+
public static boolean isReachable(String webappURI, int timeOutMillis, @Nullable String token) {
85105
boolean connectWorks = false;
86106

87107
try {
@@ -91,15 +111,9 @@ public static boolean isReachable(String webappURI, int timeOutMillis) {
91111
return false;
92112
}
93113

94-
for (InetAddress addr : InetAddress.getAllByName(HostUtil.urlToHostname(webappURI))) {
95-
if (HostUtil.isReachable(addr, port, timeOutMillis)) {
96-
LOGGER.log(Level.FINE, "URI " + webappURI + " is reachable via " + addr.toString());
97-
connectWorks = true;
98-
break;
99-
}
100-
}
101-
} catch (URISyntaxException | UnknownHostException e) {
102-
LOGGER.log(Level.WARNING, String.format("URI not valid: %s", webappURI), e);
114+
return isWebAppReachable(webappURI, timeOutMillis, token);
115+
} catch (URISyntaxException e) {
116+
LOGGER.log(Level.SEVERE, String.format("URI not valid: %s", webappURI), e);
103117
}
104118

105119
return connectWorks;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* The contents of this file are subject to the terms of the
5+
* Common Development and Distribution License (the "License").
6+
* You may not use this file except in compliance with the License.
7+
*
8+
* See LICENSE.txt included in this distribution for the specific
9+
* language governing permissions and limitations under the License.
10+
*
11+
* When distributing Covered Code, include this CDDL HEADER in each
12+
* file and include the License file at LICENSE.txt.
13+
* If applicable, add the following below this CDDL HEADER, with the
14+
* fields enclosed by brackets "[]" replaced with your own identifying
15+
* information: Portions Copyright [yyyy] [name of copyright owner]
16+
*
17+
* CDDL HEADER END
18+
*/
19+
20+
/*
21+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
22+
*/
23+
package org.opengrok.indexer.util;
24+
25+
import org.junit.jupiter.api.Test;
26+
27+
import static org.junit.jupiter.api.Assertions.assertFalse;
28+
29+
/**
30+
* Basic tests for the {@link HostUtil} class. Ideally, these should use mocking to properly verify
31+
* the exceptions and code flow. Also, positive test is missing.
32+
*/
33+
public class HostUtilTest {
34+
@Test
35+
void testInvalidURI() {
36+
assertFalse(HostUtil.isReachable("htt://localhost:8080/source/", 1000, null));
37+
}
38+
39+
@Test
40+
void testInvalidHost() {
41+
assertFalse(HostUtil.isReachable("http://localhosta:8080/source/", 1000, null));
42+
}
43+
44+
@Test
45+
void testInvalidPort() {
46+
assertFalse(HostUtil.isReachable("http://localhost:zzzz/source/", 1000, null));
47+
}
48+
49+
@Test
50+
void testNotReachableWebApp() {
51+
assertFalse(HostUtil.isReachable("http://localhost:4444/source/", 1000, null));
52+
}
53+
}

0 commit comments

Comments
 (0)