Skip to content

Commit 9f03425

Browse files
committed
SOLR-17450 Status Tool pure java
1 parent e2a0402 commit 9f03425

File tree

6 files changed

+445
-113
lines changed

6 files changed

+445
-113
lines changed

solr/bin/solr

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -496,55 +496,13 @@ function run_tool() {
496496

497497
# shellcheck disable=SC2086
498498
"$JAVA" $SOLR_SSL_OPTS $AUTHC_OPTS ${SOLR_ZK_CREDS_AND_ACLS:-} ${SOLR_TOOL_OPTS:-} -Dsolr.install.dir="$SOLR_TIP" \
499-
-Dlog4j.configurationFile="$DEFAULT_SERVER_DIR/resources/log4j2-console.xml" \
499+
-Dlog4j.configurationFile="$DEFAULT_SERVER_DIR/resources/log4j2-console.xml" -Dsolr.pid.dir="$SOLR_PID_DIR" \
500500
-classpath "$DEFAULT_SERVER_DIR/solr-webapp/webapp/WEB-INF/lib/*:$DEFAULT_SERVER_DIR/lib/ext/*:$DEFAULT_SERVER_DIR/lib/*" \
501501
org.apache.solr.cli.SolrCLI "$@"
502502

503503
return $?
504504
} # end run_tool function
505505

506-
# get status about any Solr nodes running on this host
507-
function get_status() {
508-
# first, see if Solr is running
509-
numSolrs=$(find "$SOLR_PID_DIR" -name "solr-*.pid" -type f | wc -l | tr -d ' ')
510-
if [ "$numSolrs" != "0" ]; then
511-
echo -e "\nFound $numSolrs Solr nodes: "
512-
while read PIDF
513-
do
514-
ID=$(cat "$PIDF")
515-
port=$(jetty_port "$ID")
516-
if [ "$port" != "" ]; then
517-
echo -e "\nSolr process $ID running on port $port"
518-
run_tool status --solr-url "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$port" "$@"
519-
echo ""
520-
else
521-
echo -e "\nSolr process $ID from $PIDF not found."
522-
fi
523-
done < <(find "$SOLR_PID_DIR" -name "solr-*.pid" -type f)
524-
else
525-
# no pid files but check using ps just to be sure
526-
numSolrs=$(ps auxww | grep start\.jar | grep solr\.solr\.home | grep -v grep | wc -l | sed -e 's/^[ \t]*//')
527-
if [ "$numSolrs" != "0" ]; then
528-
echo -e "\nFound $numSolrs Solr nodes: "
529-
PROCESSES=$(ps auxww | grep start\.jar | grep solr\.solr\.home | grep -v grep | awk '{print $2}' | sort -r)
530-
for ID in $PROCESSES
531-
do
532-
port=$(jetty_port "$ID")
533-
if [ "$port" != "" ]; then
534-
echo ""
535-
echo "Solr process $ID running on port $port"
536-
run_tool status --solr-url "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$port" "$@"
537-
echo ""
538-
fi
539-
done
540-
else
541-
echo -e "\nNo Solr nodes are running.\n"
542-
run_tool status "$@"
543-
fi
544-
fi
545-
546-
} # end get_status
547-
548506
# tries to gracefully stop Solr using the Jetty
549507
# stop command and if that fails, then uses kill -9
550508
# (will attempt to thread dump before killing)
@@ -635,20 +593,14 @@ else
635593
exit
636594
fi
637595

638-
# status tool
639-
if [ "$SCRIPT_CMD" == "status" ]; then
640-
get_status
641-
exit $?
642-
fi
643-
644596
# configure authentication
645597
if [[ "$SCRIPT_CMD" == "auth" ]]; then
646598
: "${SOLR_SERVER_DIR:=$DEFAULT_SERVER_DIR}"
647599
if [ ! -e "$SOLR_SERVER_DIR" ]; then
648600
echo -e "\nSolr server directory $SOLR_SERVER_DIR not found!\n"
649601
exit 1
650602
fi
651-
603+
652604
if [ -z "${SOLR_HOME:-}" ]; then
653605
SOLR_HOME="$SOLR_SERVER_DIR/solr"
654606
elif [[ $SOLR_HOME != /* ]]; then
@@ -659,7 +611,7 @@ if [[ "$SCRIPT_CMD" == "auth" ]]; then
659611
SOLR_PID_DIR="$SOLR_HOME"
660612
fi
661613
fi
662-
614+
663615
if [ -z "${AUTH_PORT:-}" ]; then
664616
for ID in $(ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r)
665617
do
@@ -669,13 +621,13 @@ if [[ "$SCRIPT_CMD" == "auth" ]]; then
669621
break
670622
fi
671623
done
672-
fi
673-
624+
fi
625+
674626
run_tool auth $@ --solr-url "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:${AUTH_PORT:-8983}" --auth-conf-dir "$SOLR_HOME" "--solr-include-file" "$SOLR_INCLUDE"
675627
exit $?
676628
fi
677629

678-
# at this point all tools that have a custom run process, like "status" and "auth" have been run and exited.
630+
# at this point all tools that have a custom run process, like "status" and "auth" have been run and exited.
679631
# Unless a command is one of the ones in the if clause below, we will just run it with the default run_tool function and then exit.
680632
if [ "$SCRIPT_CMD" != "start" ] && [ "$SCRIPT_CMD" != "stop" ] && [ "$SCRIPT_CMD" != "restart" ]; then
681633
# hand off the command to the SolrCLI and let it handle the option parsing and validation

solr/bin/solr.cmd

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ IF "%1"=="-h" goto run_solrcli
253253
IF "%1"=="--help" goto run_solrcli
254254
IF "%1"=="-help" goto run_solrcli
255255
IF "%1"=="/?" goto run_solrcli
256-
IF "%1"=="status" goto get_status
256+
IF "%1"=="status" goto run_solrcli
257257
IF "%1"=="version" goto run_solrcli
258258
IF "%1"=="-v" goto run_solrcli
259259
IF "%1"=="-version" goto run_solrcli
@@ -1204,34 +1204,6 @@ REM Run the requested example
12041204
REM End of run_example
12051205
goto done
12061206

1207-
:get_status
1208-
REM Find all Java processes, correlate with those listening on a port
1209-
REM and then try to contact via that port using the status tool
1210-
for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
1211-
set SOME_SOLR_PORT=
1212-
For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
1213-
if NOT "!SOME_SOLR_PORT!"=="" (
1214-
for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
1215-
IF NOT "%%k"=="0" (
1216-
if "%%j"=="%SOLR_JETTY_HOST%:!SOME_SOLR_PORT!" (
1217-
@echo.
1218-
set has_info=1
1219-
echo Found Solr process %%k running on port !SOME_SOLR_PORT!
1220-
REM Passing in %2 (-h or --help) directly is captured by a custom help path for usage output
1221-
"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% %SOLR_TOOL_OPTS% -Dsolr.install.dir="%SOLR_TIP%" ^
1222-
-Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
1223-
-classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
1224-
org.apache.solr.cli.SolrCLI status --solr-url !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!SOME_SOLR_PORT! %2
1225-
@echo.
1226-
)
1227-
)
1228-
)
1229-
)
1230-
)
1231-
if NOT "!has_info!"=="1" echo No running Solr nodes found.
1232-
set has_info=
1233-
goto done
1234-
12351207
:run_solrcli
12361208
"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% %SOLR_TOOL_OPTS% -Dsolr.install.dir="%SOLR_TIP%" ^
12371209
-Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.cli;
18+
19+
import static org.apache.solr.servlet.SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIBUTE;
20+
21+
import java.io.IOException;
22+
import java.lang.invoke.MethodHandles;
23+
import java.nio.file.Files;
24+
import java.nio.file.Path;
25+
import java.nio.file.Paths;
26+
import java.util.ArrayList;
27+
import java.util.Arrays;
28+
import java.util.Collection;
29+
import java.util.List;
30+
import java.util.Map;
31+
import java.util.Optional;
32+
import java.util.regex.Pattern;
33+
import java.util.stream.Collectors;
34+
import java.util.stream.Stream;
35+
import org.apache.solr.common.util.EnvUtils;
36+
import org.slf4j.Logger;
37+
import org.slf4j.LoggerFactory;
38+
39+
/** Class to interact with Solr OS processes */
40+
public class SolrProcessMgr {
41+
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
42+
43+
private final Map<Long, SolrProcess> pidProcessMap;
44+
private final Map<Integer, SolrProcess> portProcessMap;
45+
private final Path pidDir;
46+
private static final Pattern pidFilePattern = Pattern.compile("^solr-([0-9]+)\\.(pid|port)$");
47+
// Set this to true during testing to allow the SolrProcessMgr to find only mock Solr processes
48+
public static boolean enableTestingMode = false;
49+
50+
public SolrProcessMgr() {
51+
pidProcessMap =
52+
ProcessHandle.allProcesses()
53+
.filter(p -> p.info().command().orElse("").contains("java"))
54+
.filter(p -> p.info().commandLine().orElse("").contains("-Djetty.port="))
55+
.filter(
56+
p ->
57+
!enableTestingMode
58+
|| p.info().commandLine().orElse("").contains("-DmockSolr=true"))
59+
.collect(
60+
Collectors.toUnmodifiableMap(
61+
ProcessHandle::pid,
62+
ph ->
63+
new SolrProcess(
64+
ph.pid(), parsePortFromProcess(ph).orElseThrow(), isProcessSsl(ph))));
65+
portProcessMap =
66+
pidProcessMap.values().stream().collect(Collectors.toUnmodifiableMap(p -> p.port, p -> p));
67+
pidDir =
68+
Paths.get(
69+
EnvUtils.getProperty(
70+
"solr.pid.dir", EnvUtils.getProperty(SOLR_INSTALL_DIR_ATTRIBUTE + "/bin", "/tmp")));
71+
}
72+
73+
public boolean isRunningWithPort(Integer port) {
74+
return portProcessMap.containsKey(port);
75+
}
76+
77+
public boolean isRunningWithPid(Long pid) {
78+
return pidProcessMap.containsKey(pid);
79+
}
80+
81+
public Optional<SolrProcess> processForPort(Integer port) {
82+
return portProcessMap.containsKey(port)
83+
? Optional.of(portProcessMap.get(port))
84+
: Optional.empty();
85+
}
86+
87+
/** Return the SolrProcess for a given PID, if it is running */
88+
public Optional<SolrProcess> getProcessForPid(Long pid) {
89+
return pidProcessMap.containsKey(pid) ? Optional.of(pidProcessMap.get(pid)) : Optional.empty();
90+
}
91+
92+
public Collection<SolrProcess> scanSolrPidFiles() throws IOException {
93+
List<SolrProcess> processes = new ArrayList<>();
94+
try (Stream<Path> pidFiles =
95+
Files.list(pidDir)
96+
.filter(p -> pidFilePattern.matcher(p.getFileName().toString()).matches())) {
97+
for (Path p : pidFiles.collect(Collectors.toList())) {
98+
Long pid = Long.valueOf(Files.readAllLines(p).get(0));
99+
Optional<SolrProcess> process = getProcessForPid(pid);
100+
if (process.isPresent()) {
101+
processes.add(process.get());
102+
} else {
103+
log.warn("PID file found for PID {}, but no process found. Deleting PID file", pid);
104+
Files.deleteIfExists(p);
105+
}
106+
}
107+
return processes;
108+
}
109+
}
110+
111+
public Collection<SolrProcess> getAllRunning() {
112+
return pidProcessMap.values();
113+
}
114+
115+
private Optional<Integer> parsePortFromProcess(ProcessHandle ph) {
116+
Optional<String> portStr =
117+
Arrays.stream(ph.info().arguments().orElse(new String[] {}))
118+
.filter(a -> a.contains("-Djetty.port="))
119+
.map(s -> s.split("=")[1])
120+
.findFirst();
121+
return portStr.isPresent() ? portStr.map(Integer::parseInt) : Optional.empty();
122+
}
123+
124+
private boolean isProcessSsl(ProcessHandle ph) {
125+
return Arrays.stream(ph.info().arguments().orElse(new String[] {}))
126+
.anyMatch(
127+
arg -> List.of("--module=https", "--module=ssl", "--module=ssl-reload").contains(arg));
128+
}
129+
130+
/** Represents a running Solr process */
131+
public static class SolrProcess {
132+
private final long pid;
133+
private final int port;
134+
private final boolean isHttps;
135+
136+
public SolrProcess(long pid, int port, boolean isHttps) {
137+
this.pid = pid;
138+
this.port = port;
139+
this.isHttps = isHttps;
140+
}
141+
142+
public long getPid() {
143+
return pid;
144+
}
145+
146+
public int getPort() {
147+
return port;
148+
}
149+
150+
public boolean isHttps() {
151+
return isHttps;
152+
}
153+
154+
public String getLocalUrl() {
155+
return String.format("%s://localhost:%s/solr", isHttps ? "https" : "http", port);
156+
}
157+
}
158+
}

0 commit comments

Comments
 (0)