Skip to content

Commit 245ff75

Browse files
brentwritescodeztzg
authored andcommitted
ZOOKEEPER-4050: Zookeeper Inspector reports "List of default node viewers is empty" when not specifically run from the zookeeper-contrib/zookeeper-contrib-zooinspector directory
ISSUE --- See https://issues.apache.org/jira/browse/ZOOKEEPER-4050 for details on the issue. This is a follow-on PR to issues identified in #1551. While that PR fixed some launch issues, currently ZooInspector still needs to be run from the root ZooInspector directory because it expects the `defaultConnectionSettings.cfg` and `defaultNodeViewers.cfg` to exist on the filesystem in a specific location. The previous PR ensured that these files are now bundled into the fat jar built by Maven, so this new PR makes the checks for these files fall back to checking the classpath (i.e. checking inside the jar) for these files if they can't be found on the filesystem first. This means that the `zooInspector.sh` and `zooInspector.cmd` scripts can now be run from anywhere once the project is built. TESTING --- I've tested cloning, building and running ZooInspector on Mac OS Catalina (10.15.7) on Java 8 with these fixes and invoking `zooInspector.sh` from different directories to ensure it runs properly and doesn't display the aforementioned error. I ran `mvn verify spotbugs:check checkstyle:check -Pfull-build -Dsurefire-forkcount=4` in the `zookeeper-contrib/zookeeper-contrib-zooinspector` directory (per https://cwiki.apache.org/confluence/display/ZOOKEEPER/HowToContribute#HowToContribute-FinalChecksonPullRequest) and got these results: ``` [INFO] You have 0 Checkstyle violations. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 15.037 s [INFO] Finished at: 2021-02-01T20:30:04-08:00 [INFO] ------------------------------------------------------------------------ ``` Since all of my proposed changes are in the `zookeeper-contrib` subtree (and specifically only in `zookeeper-contrib-zooinspector`, I did not run the wider unit tests for the Zookeeper project as a whole. Author: brentwritescode <brentwritescode@gmail.com> Author: Brent Nash <brent.nash@crowdstrike.com> Reviewers: Enrico Olivelli <eolivelli@apache.org>, Damien Diederen <ddiederen@apache.org> Closes #1589 from brentwritescode/ZOOKEEPER-4050
1 parent ae5443e commit 245ff75

1 file changed

Lines changed: 60 additions & 37 deletions

File tree

‎zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/ZooInspectorManagerImpl.java‎

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
import java.io.BufferedReader;
2121
import java.io.BufferedWriter;
2222
import java.io.File;
23+
import java.io.FileNotFoundException;
2324
import java.io.FileReader;
2425
import java.io.FileWriter;
2526
import java.io.IOException;
27+
import java.io.InputStream;
28+
import java.io.InputStreamReader;
2629
import java.util.ArrayList;
2730
import java.util.Arrays;
2831
import java.util.Collection;
@@ -91,6 +94,12 @@ public class ZooInspectorManagerImpl implements ZooInspectorManager {
9194
*/
9295
public static final String AUTH_DATA_KEY = "authData";
9396

97+
private static final String DEFAULT_ENCRYPTION_MANAGER =
98+
BasicDataEncryptionManager.class.getName();
99+
private static final int DEFAULT_TIMEOUT = 5000;
100+
private static final String DEFAULT_HOSTS = "localhost:2181";
101+
private static final String DEFAULT_AUTH_SCHEME = "";
102+
private static final String DEFAULT_AUTH_VALUE = "";
94103

95104
private static final File defaultNodeViewersFile = new File(
96105
"./src/main/resources/defaultNodeViewers.cfg");
@@ -713,55 +722,47 @@ public void stop() {
713722
public List<String> loadNodeViewersFile(File selectedFile)
714723
throws IOException {
715724
List<String> result = new ArrayList<String>();
716-
if (defaultNodeViewersFile.exists()) {
717-
FileReader reader = new FileReader(selectedFile);
718-
try {
719-
BufferedReader buff = new BufferedReader(reader);
720-
try {
721-
while (buff.ready()) {
722-
String line = buff.readLine();
723-
if (line != null && line.length() > 0 && !line.startsWith("#")) {
724-
result.add(line);
725-
}
725+
726+
try(BufferedReader reader = getReaderForFile(selectedFile)) {
727+
if(reader == null) {
728+
return result;
729+
}
730+
731+
String line = "";
732+
while (line != null) {
733+
line = reader.readLine();
734+
if(line != null) {
735+
line = line.trim();
736+
if (!line.isEmpty() && !line.startsWith("#")) {
737+
result.add(line);
726738
}
727-
} finally {
728-
buff.close();
729739
}
730-
} finally {
731-
reader.close();
732740
}
733741
}
742+
734743
return result;
735744
}
736745

737746
private void loadDefaultConnectionFile() throws IOException {
738-
if (defaultConnectionFile.exists()) {
739-
Properties props = new Properties();
747+
Properties props = new Properties();
740748

741-
FileReader reader = new FileReader(defaultConnectionFile);
742-
try {
749+
try(BufferedReader reader = getReaderForFile(defaultConnectionFile)) {
750+
//If reader is null, it's OK. Default values will get set below.
751+
if(reader != null) {
743752
props.load(reader);
744-
} finally {
745-
reader.close();
746753
}
747-
defaultEncryptionManager = props
748-
.getProperty(DATA_ENCRYPTION_MANAGER) == null ? "org.apache.zookeeper.inspector.encryption.BasicDataEncryptionManager"
749-
: props.getProperty(DATA_ENCRYPTION_MANAGER);
750-
defaultTimeout = props.getProperty(SESSION_TIMEOUT) == null ? "5000"
751-
: props.getProperty(SESSION_TIMEOUT);
752-
defaultHosts = props.getProperty(CONNECT_STRING) == null ? "localhost:2181"
753-
: props.getProperty(CONNECT_STRING);
754-
defaultAuthScheme = props.getProperty(AUTH_SCHEME_KEY) == null ? ""
755-
: props.getProperty(AUTH_SCHEME_KEY);
756-
defaultAuthValue = props.getProperty(AUTH_DATA_KEY) == null ? ""
757-
: props.getProperty(AUTH_DATA_KEY);
758-
} else {
759-
defaultEncryptionManager = "org.apache.zookeeper.inspector.encryption.BasicDataEncryptionManager";
760-
defaultTimeout = "5000";
761-
defaultHosts = "localhost:2181";
762-
defaultAuthScheme = "";
763-
defaultAuthValue = "";
764754
}
755+
756+
defaultEncryptionManager = props.getProperty(DATA_ENCRYPTION_MANAGER) == null ?
757+
DEFAULT_ENCRYPTION_MANAGER : props.getProperty(DATA_ENCRYPTION_MANAGER);
758+
defaultTimeout = props.getProperty(SESSION_TIMEOUT) == null ?
759+
Integer.toString(DEFAULT_TIMEOUT) : props.getProperty(SESSION_TIMEOUT);
760+
defaultHosts = props.getProperty(CONNECT_STRING) == null ?
761+
DEFAULT_HOSTS : props.getProperty(CONNECT_STRING);
762+
defaultAuthScheme = props.getProperty(AUTH_SCHEME_KEY) == null ?
763+
DEFAULT_AUTH_SCHEME : props.getProperty(AUTH_SCHEME_KEY);
764+
defaultAuthValue = props.getProperty(AUTH_DATA_KEY) == null ?
765+
DEFAULT_AUTH_VALUE : props.getProperty(AUTH_DATA_KEY);
765766
}
766767

767768
/*
@@ -872,4 +873,26 @@ public Properties getLastConnectionProps() {
872873
public void setLastConnectionProps(Properties connectionProps) {
873874
this.lastConnectionProps = connectionProps;
874875
}
876+
877+
private static BufferedReader getReaderForFile(File file) {
878+
//check the filesystem first
879+
if (file.exists()) {
880+
try {
881+
return new BufferedReader(new FileReader(file));
882+
} catch (FileNotFoundException e) {
883+
return null;
884+
}
885+
}
886+
887+
//fall back to checking the CLASSPATH with only the filename
888+
//(for cases where the file exists in src/main/resources)
889+
InputStream classpathStream = ZooInspectorManagerImpl.class.getClassLoader()
890+
.getResourceAsStream(file.getName());
891+
if (classpathStream != null) {
892+
return new BufferedReader(new InputStreamReader(classpathStream));
893+
}
894+
895+
//couldn't find the file anywhere
896+
return null;
897+
}
875898
}

0 commit comments

Comments
 (0)