This is an automated email from the ASF dual-hosted git repository.
brandonwilliams pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new 26098da Add unit tests: tpstats, gossipinfo, en/disablebinary
26098da is described below
commit 26098da5d8fe39260b1b5e3a724f3b4e0b7719cb
Author: Bereng <[email protected]>
AuthorDate: Wed Oct 28 07:37:09 2020 +0100
Add unit tests: tpstats, gossipinfo, en/disablebinary
Patch by Berenguer Blasi, reviewed by brandonwilliams for
CASSANDRA-16230
---
.../tools/nodetool/stats/TpStatsHolder.java | 8 +-
.../test/NodeToolEnableDisableBinaryTest.java | 168 +++++++++++++++++
.../cassandra/tools/NodeToolGossipInfoTest.java | 130 +++++++++++++
.../cassandra/tools/NodeToolTPStatsTest.java | 210 +++++++++++++++++++++
4 files changed, 514 insertions(+), 2 deletions(-)
diff --git
a/src/java/org/apache/cassandra/tools/nodetool/stats/TpStatsHolder.java
b/src/java/org/apache/cassandra/tools/nodetool/stats/TpStatsHolder.java
index c641691..38011ba 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/stats/TpStatsHolder.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/stats/TpStatsHolder.java
@@ -18,6 +18,7 @@
package org.apache.cassandra.tools.nodetool.stats;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -38,7 +39,7 @@ public class TpStatsHolder implements StatsHolder
HashMap<String, Object> result = new HashMap<>();
HashMap<String, Map<String, Object>> threadPools = new HashMap<>();
HashMap<String, Object> droppedMessage = new HashMap<>();
- HashMap<String, Double[]> waitLatencies = new HashMap<>();
+ HashMap<String, String[]> waitLatencies = new HashMap<>();
for (Map.Entry<String, String> tp : probe.getThreadPools().entries())
{
@@ -57,7 +58,10 @@ public class TpStatsHolder implements StatsHolder
droppedMessage.put(entry.getKey(), entry.getValue());
try
{
- waitLatencies.put(entry.getKey(),
probe.metricPercentilesAsArray(probe.getMessagingQueueWaitMetrics(entry.getKey())));
+ String[] strValues = (String[])
Arrays.stream(probe.metricPercentilesAsArray(probe.getMessagingQueueWaitMetrics(entry.getKey())))
+ .map(D -> D.toString())
+ .toArray();
+ waitLatencies.put(entry.getKey(), strValues);
}
catch (RuntimeException e)
{
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/NodeToolEnableDisableBinaryTest.java
b/test/distributed/org/apache/cassandra/distributed/test/NodeToolEnableDisableBinaryTest.java
new file mode 100644
index 0000000..d690294
--- /dev/null
+++
b/test/distributed/org/apache/cassandra/distributed/test/NodeToolEnableDisableBinaryTest.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.distributed.test;
+
+import java.io.IOException;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.datastax.driver.core.Session;
+import org.apache.cassandra.distributed.api.ICluster;
+import org.apache.cassandra.tools.ToolRunner;
+import org.apache.cassandra.tools.ToolRunner.ToolResult;
+import org.assertj.core.api.Assertions;
+
+import static org.apache.cassandra.distributed.api.Feature.GOSSIP;
+import static org.apache.cassandra.distributed.api.Feature.NATIVE_PROTOCOL;
+import static org.apache.cassandra.distributed.api.Feature.NETWORK;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class NodeToolEnableDisableBinaryTest extends TestBaseImpl
+{
+ private static ICluster cluster;
+
+ @Before
+ public void setupEnv() throws IOException
+ {
+ if (cluster == null)
+ cluster = init(builder().withNodes(1)
+ .withConfig(config -> config.with(NETWORK,
GOSSIP, NATIVE_PROTOCOL))
+ .start());
+ }
+
+ @AfterClass
+ public static void teardownEnv() throws Exception
+ {
+ cluster.close();
+ }
+
+ @Test
+ public void testMaybeChangeDocs()
+ {
+ // If you added, modified options or help, please update docs if
necessary
+
+ ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1),
"help", "disablebinary");
+ String help = "NAME\n" +
+ " nodetool disablebinary - Disable native
transport (binary protocol)\n" +
+ "\n" +
+ "SYNOPSIS\n" +
+ " nodetool [(-h <host> | --host <host>)] [(-p
<port> | --port <port>)]\n" +
+ " [(-pp | --print-port)] [(-pw
<password> | --password <password>)]\n" +
+ " [(-pwf <passwordFilePath> |
--password-file <passwordFilePath>)]\n" +
+ " [(-u <username> | --username
<username>)] disablebinary\n" +
+ "\n" +
+ "OPTIONS\n" +
+ " -h <host>, --host <host>\n" +
+ " Node hostname or ip address\n" +
+ "\n" +
+ " -p <port>, --port <port>\n" +
+ " Remote jmx agent port number\n" +
+ "\n" +
+ " -pp, --print-port\n" +
+ " Operate in 4.0 mode with hosts
disambiguated by port number\n" +
+ "\n" +
+ " -pw <password>, --password <password>\n" +
+ " Remote jmx agent password\n" +
+ "\n" +
+ " -pwf <passwordFilePath>, --password-file
<passwordFilePath>\n" +
+ " Path to the JMX password file\n" +
+ "\n" +
+ " -u <username>, --username <username>\n" +
+ " Remote jmx agent username\n" +
+ "\n" +
+ "\n";
+ Assertions.assertThat(tool.getStdout()).isEqualTo(help);
+
+ tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), "help",
"enablebinary");
+ help = "NAME\n" +
+ " nodetool enablebinary - Reenable native transport
(binary protocol)\n" +
+ "\n" +
+ "SYNOPSIS\n" +
+ " nodetool [(-h <host> | --host <host>)] [(-p <port> |
--port <port>)]\n" +
+ " [(-pp | --print-port)] [(-pw <password> |
--password <password>)]\n" +
+ " [(-pwf <passwordFilePath> | --password-file
<passwordFilePath>)]\n" +
+ " [(-u <username> | --username <username>)]
enablebinary\n" +
+ "\n" +
+ "OPTIONS\n" +
+ " -h <host>, --host <host>\n" +
+ " Node hostname or ip address\n" +
+ "\n" +
+ " -p <port>, --port <port>\n" +
+ " Remote jmx agent port number\n" +
+ "\n" +
+ " -pp, --print-port\n" +
+ " Operate in 4.0 mode with hosts disambiguated by
port number\n" +
+ "\n" +
+ " -pw <password>, --password <password>\n" +
+ " Remote jmx agent password\n" +
+ "\n" +
+ " -pwf <passwordFilePath>, --password-file
<passwordFilePath>\n" +
+ " Path to the JMX password file\n" +
+ "\n" +
+ " -u <username>, --username <username>\n" +
+ " Remote jmx agent username\n" +
+ "\n" +
+ "\n";
+ Assertions.assertThat(tool.getStdout()).isEqualTo(help);
+ }
+
+ @Test
+ public void testEnableDisableBinary() throws Throwable
+ {
+ // We can connect
+ assertTrue(canConnect());
+
+ // We can't connect after disabling
+ ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1),
"disablebinary");
+ Assertions.assertThat(tool.getStdout()).containsIgnoringCase("Stop
listening for CQL clients");
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+ assertFalse(canConnect());
+
+ // We can connect after re-enabling
+ tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1),
"enablebinary");
+ Assertions.assertThat(tool.getStdout()).containsIgnoringCase("Starting
listening for CQL clients");
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+ assertTrue(canConnect());
+ }
+
+ private boolean canConnect()
+ {
+ boolean canConnect = false;
+ try(com.datastax.driver.core.Cluster c =
com.datastax.driver.core.Cluster.builder()
+
.addContactPoint("127.0.0.1")
+
.build();
+ Session s = c.connect("system_schema"))
+ {
+ s.execute("SELECT * FROM system_schema.aggregates");
+ canConnect = true;
+ }
+ catch(Exception e)
+ {
+ canConnect = false;
+ }
+
+ return canConnect;
+ }
+}
diff --git a/test/unit/org/apache/cassandra/tools/NodeToolGossipInfoTest.java
b/test/unit/org/apache/cassandra/tools/NodeToolGossipInfoTest.java
new file mode 100644
index 0000000..e69f860
--- /dev/null
+++ b/test/unit/org/apache/cassandra/tools/NodeToolGossipInfoTest.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.tools;
+
+import java.io.IOException;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.cassandra.OrderedJUnit4ClassRunner;
+import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.net.Message;
+import org.apache.cassandra.net.MessagingService;
+import org.apache.cassandra.net.NoPayload;
+import org.apache.cassandra.tools.ToolRunner.ToolResult;
+import org.apache.cassandra.utils.FBUtilities;
+import org.assertj.core.api.Assertions;
+
+import static org.apache.cassandra.net.Verb.ECHO_REQ;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(OrderedJUnit4ClassRunner.class)
+public class NodeToolGossipInfoTest extends CQLTester
+{
+ private static NodeProbe probe;
+
+ @BeforeClass
+ public static void setup() throws Exception
+ {
+ requireNetwork();
+ startJMXServer();
+ probe = new NodeProbe(jmxHost, jmxPort);
+ }
+
+ @AfterClass
+ public static void teardown() throws IOException
+ {
+ probe.close();
+ }
+
+ @Test
+ public void testMaybeChangeDocs()
+ {
+ // If you added, modified options or help, please update docs if
necessary
+ ToolResult tool = ToolRunner.invokeNodetool("help", "gossipinfo");
+ String help = "NAME\n" +
+ " nodetool gossipinfo - Shows the gossip
information for the cluster\n" +
+ "\n" +
+ "SYNOPSIS\n" +
+ " nodetool [(-h <host> | --host <host>)] [(-p
<port> | --port <port>)]\n" +
+ " [(-pp | --print-port)] [(-pw
<password> | --password <password>)]\n" +
+ " [(-pwf <passwordFilePath> |
--password-file <passwordFilePath>)]\n" +
+ " [(-u <username> | --username
<username>)] gossipinfo\n" +
+ "\n" +
+ "OPTIONS\n" +
+ " -h <host>, --host <host>\n" +
+ " Node hostname or ip address\n" +
+ "\n" +
+ " -p <port>, --port <port>\n" +
+ " Remote jmx agent port number\n" +
+ "\n" +
+ " -pp, --print-port\n" +
+ " Operate in 4.0 mode with hosts
disambiguated by port number\n" +
+ "\n" +
+ " -pw <password>, --password <password>\n" +
+ " Remote jmx agent password\n" +
+ "\n" +
+ " -pwf <passwordFilePath>, --password-file
<passwordFilePath>\n" +
+ " Path to the JMX password file\n" +
+ "\n" +
+ " -u <username>, --username <username>\n" +
+ " Remote jmx agent username\n" +
+ "\n" +
+ "\n";
+ Assertions.assertThat(tool.getStdout()).isEqualTo(help);
+ }
+
+ @Test
+ public void testTPStats() throws Throwable
+ {
+ ToolResult tool = ToolRunner.invokeNodetool("gossipinfo");
+ Assertions.assertThat(tool.getStdout()).contains("/127.0.0.1");
+
Assertions.assertThat(tool.getStdout()).containsPattern("heartbeat:[0-9]+");
+
Assertions.assertThat(tool.getStdout()).containsPattern("STATUS:[0-9]+:NORMAL,.+");
+ Assertions.assertThat(tool.getStdout()).containsPattern("SCHEMA:.+");
+
Assertions.assertThat(tool.getStdout()).containsPattern("DC:[0-9]+:datacenter1");
+
Assertions.assertThat(tool.getStdout()).containsPattern("RACK:[0-9]+:rack1");
+
Assertions.assertThat(tool.getStdout()).containsPattern("RELEASE_VERSION:.+");
+
Assertions.assertThat(tool.getStdout()).containsPattern("RPC_ADDRESS:[0-9]+:127.0.0.1");
+
Assertions.assertThat(tool.getStdout()).containsPattern("NET_VERSION:[0-9]+:.+");
+
Assertions.assertThat(tool.getStdout()).containsPattern("HOST_ID:[0-9]+:.+");
+
Assertions.assertThat(tool.getStdout()).containsPattern("NATIVE_ADDRESS_AND_PORT:[0-9]+:127.0.0.1:[0-9]+");
+
Assertions.assertThat(tool.getStdout()).containsPattern("STATUS_WITH_PORT:[0-9]+:NORMAL,.+");
+
Assertions.assertThat(tool.getStdout()).containsPattern("TOKENS:[0-9]+:<hidden>");
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+
+ // Make sure heartbeats are detected
+ Message<NoPayload> echoMessageOut = Message.out(ECHO_REQ,
NoPayload.noPayload);
+ MessagingService.instance().send(echoMessageOut,
FBUtilities.getBroadcastAddressAndPort());
+
+ String origHeartbeatCount =
StringUtils.substringBetween(tool.getStdout(), "heartbeat:", "\n");
+ tool = ToolRunner.invokeNodetool("gossipinfo");
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+ String newHeartbeatCount =
StringUtils.substringBetween(tool.getStdout(), "heartbeat:", "\n");
+ assertTrue(Integer.parseInt(origHeartbeatCount) <
Integer.parseInt(newHeartbeatCount));
+ }
+}
diff --git a/test/unit/org/apache/cassandra/tools/NodeToolTPStatsTest.java
b/test/unit/org/apache/cassandra/tools/NodeToolTPStatsTest.java
new file mode 100644
index 0000000..e437fc1
--- /dev/null
+++ b/test/unit/org/apache/cassandra/tools/NodeToolTPStatsTest.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.tools;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.cassandra.OrderedJUnit4ClassRunner;
+import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.net.Message;
+import org.apache.cassandra.net.MessagingService;
+import org.apache.cassandra.net.NoPayload;
+import org.apache.cassandra.tools.ToolRunner.ToolResult;
+import org.apache.cassandra.utils.FBUtilities;
+import org.assertj.core.api.Assertions;
+import org.yaml.snakeyaml.Yaml;
+
+import static org.apache.cassandra.net.Verb.ECHO_REQ;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(OrderedJUnit4ClassRunner.class)
+public class NodeToolTPStatsTest extends CQLTester
+{
+ private static NodeProbe probe;
+
+ @BeforeClass
+ public static void setup() throws Exception
+ {
+ requireNetwork();
+ startJMXServer();
+ probe = new NodeProbe(jmxHost, jmxPort);
+ }
+
+ @AfterClass
+ public static void teardown() throws IOException
+ {
+ probe.close();
+ }
+
+ @Test
+ public void testMaybeChangeDocs()
+ {
+ // If you added, modified options or help, please update docs if
necessary
+ ToolResult tool = ToolRunner.invokeNodetool("help", "tpstats");
+ String help = "NAME\n" +
+ " nodetool tpstats - Print usage statistics of
thread pools\n" +
+ "\n" +
+ "SYNOPSIS\n" +
+ " nodetool [(-h <host> | --host <host>)] [(-p
<port> | --port <port>)]\n" +
+ " [(-pp | --print-port)] [(-pw
<password> | --password <password>)]\n" +
+ " [(-pwf <passwordFilePath> |
--password-file <passwordFilePath>)]\n" +
+ " [(-u <username> | --username
<username>)] tpstats\n" +
+ " [(-F <format> | --format
<format>)]\n" +
+ "\n" +
+ "OPTIONS\n" +
+ " -F <format>, --format <format>\n" +
+ " Output format (json, yaml)\n" +
+ "\n" +
+ " -h <host>, --host <host>\n" +
+ " Node hostname or ip address\n" +
+ "\n" +
+ " -p <port>, --port <port>\n" +
+ " Remote jmx agent port number\n" +
+ "\n" +
+ " -pp, --print-port\n" +
+ " Operate in 4.0 mode with hosts
disambiguated by port number\n" +
+ "\n" +
+ " -pw <password>, --password <password>\n" +
+ " Remote jmx agent password\n" +
+ "\n" +
+ " -pwf <passwordFilePath>, --password-file
<passwordFilePath>\n" +
+ " Path to the JMX password file\n" +
+ "\n" +
+ " -u <username>, --username <username>\n" +
+ " Remote jmx agent username\n" +
+ "\n" +
+ "\n";
+ Assertions.assertThat(tool.getStdout()).isEqualTo(help);
+ }
+
+ @Test
+ public void testTPStats() throws Throwable
+ {
+ ToolResult tool = ToolRunner.invokeNodetool("tpstats");
+ Assertions.assertThat(tool.getStdout()).containsIgnoringCase("Pool
Name Active Pending Completed Blocked All time blocked");
+
Assertions.assertThat(tool.getStdout()).containsIgnoringCase("Latencies waiting
in queue (micros) per dropped message types");
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+
+ // Does inserting data alter tpstats?
+ String nonZeroedThreadsRegExp = "((?m)\\D.*[1-9].*)";
+ ArrayList<String> origStats =
getAllGroupMatches(nonZeroedThreadsRegExp, tool.getStdout());
+ Collections.sort(origStats);
+
+ createTable("CREATE TABLE %s (pk int, c int, PRIMARY KEY(pk))");
+ execute("INSERT INTO %s (pk, c) VALUES (?, ?)", 1, 1);
+ tool = ToolRunner.invokeNodetool("tpstats");
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+ ArrayList<String> newStats =
getAllGroupMatches(nonZeroedThreadsRegExp, tool.getStdout());
+ Collections.sort(newStats);
+
+ assertNotEquals(origStats, newStats);
+
+ // Does sending a message alter Gossip & ECHO stats?
+ String origGossip = getAllGroupMatches("((?m)GossipStage.*)",
tool.getStdout()).get(0);
+
Assertions.assertThat(tool.getStdout()).doesNotContainPattern("ECHO_REQ\\D.*[1-9].*");
+
Assertions.assertThat(tool.getStdout()).doesNotContainPattern("ECHO_RSP\\D.*[1-9].*");
+
+ Message<NoPayload> echoMessageOut = Message.out(ECHO_REQ,
NoPayload.noPayload);
+ MessagingService.instance().send(echoMessageOut,
FBUtilities.getBroadcastAddressAndPort());
+
+ tool = ToolRunner.invokeNodetool("tpstats");
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+ String newGossip = getAllGroupMatches("((?m)GossipStage.*)",
tool.getStdout()).get(0);
+
+ assertNotEquals(origGossip, newGossip);
+
Assertions.assertThat(tool.getStdout()).containsPattern("ECHO_REQ\\D.*[1-9].*");
+
Assertions.assertThat(tool.getStdout()).containsPattern("ECHO_RSP\\D.*[1-9].*");
+ }
+
+ @Test
+ public void testFromatArg() throws Throwable
+ {
+ Arrays.asList(Pair.of("-F", "json"), Pair.of("--format",
"json")).forEach(arg -> {
+ ToolResult tool = ToolRunner.invokeNodetool("tpstats",
arg.getLeft(), arg.getRight());
+ assertTrue(isJSONString(tool.getStdout()));
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+ });
+
+ Arrays.asList( Pair.of("-F", "yaml"), Pair.of("--format",
"yaml")).forEach(arg -> {
+ ToolResult tool = ToolRunner.invokeNodetool("tpstats",
arg.getLeft(), arg.getRight());
+ assertTrue(isYAMLString(tool.getStdout()));
+ assertTrue(tool.getCleanedStderr().isEmpty());
+ assertEquals(0, tool.getExitCode());
+ });
+ }
+
+ public static boolean isJSONString(String str)
+ {
+ try
+ {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.readTree(str);
+ return true;
+ }
+ catch(IOException e)
+ {
+ return false;
+ }
+ }
+
+ public static boolean isYAMLString(String str)
+ {
+ try
+ {
+ Yaml yaml = new Yaml();
+ yaml.load(str);
+ return true;
+ }
+ catch(Exception e)
+ {
+ return false;
+ }
+ }
+
+ private ArrayList<String> getAllGroupMatches(String regExp, String in)
+ {
+ Pattern pattern = Pattern.compile(regExp);
+ Matcher m = pattern.matcher(in);
+
+ ArrayList<String> matches = new ArrayList<>();
+ while (m.find())
+ matches.add(m.group(1));
+
+ return matches;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]