Skip to content

Commit 55dd805

Browse files
idodeclareVladimir Kotal
authored andcommitted
Use PortChecker to help settle on port
1 parent 9e27fc8 commit 55dd805

File tree

3 files changed

+94
-5
lines changed

3 files changed

+94
-5
lines changed

dev/checkstyle/suppressions.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ information: Portions Copyright [yyyy] [name of copyright owner]
1919
CDDL HEADER END
2020
2121
Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
22-
Portions Copyright (c) 2018-2019, Chris Fraire <[email protected]>.
22+
Portions Copyright (c) 2018-2020, Chris Fraire <[email protected]>.
2323
2424
-->
2525

@@ -33,7 +33,7 @@ Portions Copyright (c) 2018-2019, Chris Fraire <[email protected]>.
3333
|Summary\.java|OGKUnifiedHighlighter\.java|ResponseHeaderFilter\.java|BoundedBlockingObjectPool\.java|
3434
|ObjectPool\.java|ObjectValidator\.java|ObjectFactory\.java|AbstractObjectPool\.java|
3535
|BlockingObjectPool\.java|OGKTextVecField\.java|OGKTextField\.java|
36-
|LazilyInstantiate\.java" />
36+
|LazilyInstantiate\.java|PortChecker\.java" />
3737

3838
<suppress checks="ParameterNumber" files="CtagsReader\.java|Definitions\.java|
3939
|JFlexXrefUtils\.java|FileAnalyzerFactory\.java|SearchController\.java|
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.opengrok.indexer.util;
21+
22+
import java.io.IOException;
23+
import java.net.DatagramSocket;
24+
import java.net.ServerSocket;
25+
26+
/**
27+
* Represents a helper for checking a network port, borrowed from Apache
28+
* Usergrid's AvailablePortFinder.java.
29+
*/
30+
public class PortChecker {
31+
/** The minimum number of server port number. */
32+
public static final int MIN_PORT_NUMBER = 1;
33+
34+
/** The maximum number of server port number. */
35+
public static final int MAX_PORT_NUMBER = 65535;
36+
37+
/**
38+
* Checks to see if a specific port is available.
39+
*
40+
* @param port the port to check for availability
41+
*/
42+
public static boolean available(int port) {
43+
if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
44+
throw new IllegalArgumentException("Port out of valid range: " + port);
45+
}
46+
47+
ServerSocket ss = null;
48+
DatagramSocket ds = null;
49+
try {
50+
ss = new ServerSocket(port);
51+
ss.setReuseAddress(true);
52+
ds = new DatagramSocket(port);
53+
ds.setReuseAddress(true);
54+
return true;
55+
} catch (IOException e) {
56+
return false;
57+
} finally {
58+
if (ds != null) {
59+
ds.close();
60+
}
61+
62+
if (ss != null) {
63+
try {
64+
ss.close();
65+
} catch (IOException e) {
66+
/* should not be thrown */
67+
}
68+
}
69+
}
70+
}
71+
72+
/* private to enforce static */
73+
private PortChecker() {
74+
}
75+
}

opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/OGKJerseyTest.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.glassfish.jersey.test.JerseyTest;
2727
import org.glassfish.jersey.test.TestProperties;
2828
import org.junit.Before;
29+
import org.opengrok.indexer.util.PortChecker;
2930

3031
import java.util.Random;
3132

@@ -39,6 +40,8 @@ public abstract class OGKJerseyTest extends JerseyTest {
3940
/** Random.nextInt() will be at most one less than this -- but OK */
4041
private static final int DYNAMIC_OR_PRIVATE_PORT_RANGE = 16383;
4142

43+
private static final int MAX_PORT_TRIES = 20;
44+
4245
private final Random rand = new Random();
4346

4447
/**
@@ -47,9 +50,20 @@ public abstract class OGKJerseyTest extends JerseyTest {
4750
*/
4851
@Before
4952
public void setUp() throws Exception {
50-
int jerseyPort = BASE_DYNAMIC_OR_PRIVATE_PORT +
51-
rand.nextInt(DYNAMIC_OR_PRIVATE_PORT_RANGE);
52-
forceSet(TestProperties.CONTAINER_PORT, String.valueOf(jerseyPort));
53+
54+
int triesCount = 0;
55+
while (true) {
56+
int jerseyPort = BASE_DYNAMIC_OR_PRIVATE_PORT +
57+
rand.nextInt(DYNAMIC_OR_PRIVATE_PORT_RANGE);
58+
if (PortChecker.available(jerseyPort)) {
59+
forceSet(TestProperties.CONTAINER_PORT, String.valueOf(jerseyPort));
60+
break;
61+
}
62+
if (++triesCount > MAX_PORT_TRIES) {
63+
throw new RuntimeException("Could not find an available port after " +
64+
MAX_PORT_TRIES + " tries");
65+
}
66+
}
5367

5468
super.setUp();
5569
}

0 commit comments

Comments
 (0)