BROOKLYN-475: fix machine-details parsing
(cherry picked from commit d292e3dbe37dfd7e32c081f755026b230758ca3b)
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineDetails.java b/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineDetails.java
index b0a9bcd..93374c4 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineDetails.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineDetails.java
@@ -22,8 +22,10 @@
import java.io.BufferedReader;
import java.io.IOException;
+import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
@@ -47,6 +49,7 @@
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
+import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
@@ -146,10 +149,20 @@
LOG.debug("Found following details at {}: {}", location, stdout);
}
- Map<String,String> details = Maps.newHashMap(Splitter.on(CharMatcher.anyOf("\r\n"))
+ // See https://issues.apache.org/jira/browse/BROOKLYN-475:
+ // If using splitter.withKeyValueSeparator, it fails with "Chunk ... is not a valid entry"
+ // if a line contains more than one ":"; therefore filter those out ourselves.
+ Iterable<String> lines = Splitter.on(CharMatcher.anyOf("\r\n"))
.omitEmptyStrings()
- .withKeyValueSeparator(":")
- .split(stdout));
+ .split(stdout);
+
+ Map<String, String> details = Maps.newHashMap();
+ for (String line : lines) {
+ Optional<Entry<String, String>> detail = splitLine(line, ":");
+ if (detail.isPresent()) {
+ details.put(detail.get().getKey(), detail.get().getValue());
+ }
+ }
String name = details.remove("name");
String version = details.remove("version");
@@ -177,6 +190,17 @@
return null;
}
}
+
+ private Optional<Map.Entry<String, String>> splitLine(String sequence, String separator) {
+ int index = sequence.indexOf(separator);
+ if (index < 0) {
+ return Optional.absent(); // ignore
+ } else {
+ String key = sequence.substring(0, index).trim();
+ String value = sequence.substring(index+1).trim();
+ return Optional.<Map.Entry<String, String>>of(new AbstractMap.SimpleEntry<>(key, value));
+ }
+ }
};
}
diff --git a/core/src/test/java/org/apache/brooklyn/core/location/MachineDetailsIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/core/location/MachineDetailsIntegrationTest.java
index e54cb08..c2994f8 100644
--- a/core/src/test/java/org/apache/brooklyn/core/location/MachineDetailsIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/location/MachineDetailsIntegrationTest.java
@@ -41,6 +41,8 @@
public class MachineDetailsIntegrationTest {
+ // See SshMachineLocationTest.testGetMachineDetails for an equivalent unit test
+
private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsIntegrationTest.class);
TestApplication app;
diff --git a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
index 844df4a..c770527 100644
--- a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationIntegrationTest.java
@@ -127,6 +127,13 @@
}
}
+ // Overrides and disables super, because real machine won't give extra stdout
+ @Test(enabled=false)
+ @Override
+ public void testGetMachineDetailsWithExtraStdout() throws Exception {
+ throw new UnsupportedOperationException("Test disabled because real machine does not have extra stdout");
+ }
+
@Test(groups = "Integration")
public void testCopyFileTo() throws Exception {
File dest = Os.newTempFile(getClass(), ".dest.tmp");
diff --git a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
index bac6018..d2f8645 100644
--- a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
@@ -150,6 +150,41 @@
}
@Test
+ public void testGetMachineDetailsWithExtraStdout() throws Exception {
+ String response = Joiner.on("\n").join(
+ "Last login: Fri Apr 14 08:01:37 2017 from 35.156.73.145",
+ "Line with no colons",
+ ": colon first",
+ "colon last:",
+ "name:MyCentOS",
+ "version:6.7",
+ "architecture:x86_64",
+ "ram:15948",
+ "cpus:4");
+ RecordingSshTool.setCustomResponse(".*uname.*", new CustomResponse(0, response, ""));
+
+ BasicExecutionManager execManager = new BasicExecutionManager("mycontextid");
+ BasicExecutionContext execContext = new BasicExecutionContext(execManager);
+ try {
+ MachineDetails details = execContext.submit(new Callable<MachineDetails>() {
+ @Override
+ public MachineDetails call() {
+ return host.getMachineDetails();
+ }}).get();
+ LOG.info("machineDetails="+details);
+ assertNotNull(details);
+
+ assertEquals(details.getOsDetails().getName(), "MyCentOS", "details="+details);
+ assertEquals(details.getOsDetails().getVersion(), "6.7", "details="+details);
+ assertEquals(details.getOsDetails().getArch(), "x86_64", "details="+details);
+ assertEquals(details.getHardwareDetails().getCpuCount(), Integer.valueOf(4), "details="+details);
+ assertEquals(details.getHardwareDetails().getRam(), Integer.valueOf(15948), "details="+details);
+ } finally {
+ execManager.shutdownNow();
+ }
+ }
+
+ @Test
public void testSupplyingMachineDetails() throws Exception {
MachineDetails machineDetails = new BasicMachineDetails(new BasicHardwareDetails(1, 1024), new BasicOsDetails("myname", "myarch", "myversion"));
SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)