Mercurial > hg > thermostat-ng > agent
changeset 2439:cea7c676ac26
Don't HTML escape Byteman metric's data.
Reviewed-by: omajid
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-August/020720.html
author | Severin Gehwolf <sgehwolf@redhat.com> |
---|---|
date | Mon, 29 Aug 2016 17:30:33 +0200 |
parents | 2896940c9722 |
children | 4516a694428a |
files | vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapterTest.java |
diffstat | 3 files changed, 79 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java Thu Aug 25 19:08:52 2016 +0200 +++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java Mon Aug 29 17:30:33 2016 +0200 @@ -57,10 +57,16 @@ private static final Logger logger = LoggingUtils.getLogger(BytemanMetricsReceiver.class); private final VmBytemanDAO dao; private final VmSocketIdentifier socketId; + private final Gson gson; BytemanMetricsReceiver(VmBytemanDAO dao, VmSocketIdentifier socketId) { this.dao = dao; this.socketId = socketId; + this.gson = new GsonBuilder() + .registerTypeAdapterFactory(new BytemanMetricTypeAdapterFactory()) + .serializeNulls() + .disableHtmlEscaping() + .create(); } @Override @@ -76,10 +82,6 @@ } private List<BytemanMetric> convertFromJson(String data) { - Gson gson = new GsonBuilder() - .registerTypeAdapterFactory(new BytemanMetricTypeAdapterFactory()) - .serializeNulls() - .create(); BytemanMetric[] metrics = gson.fromJson(data, BytemanMetric[].class); List<BytemanMetric> listOfMetrics = new ArrayList<>(); for (BytemanMetric m: metrics) {
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java Thu Aug 25 19:08:52 2016 +0200 +++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java Mon Aug 29 17:30:33 2016 +0200 @@ -83,4 +83,42 @@ assertEquals("Expected 7 keys, including one with null value", 7, payloadAsMap.keySet().size()); } + /* + * There was an issue where the metric data json became HTML escaped: + * + * before JSON convert: 'count = foo' + * after JSON convert: 'count \u003d foo' + * + * This test is supposed to catch that data won't get HTML escaped. + */ + @Test + public void canSendDataToStorageUtf8() { + VmBytemanDAO dao = mock(VmBytemanDAO.class); + String jsonMetric = + "[ {\n" + + " \"marker\": \"marker\",\n" + + " \"timestamp\":\"30\",\n" + + " \"data\": {\n" + + " \"key\": \"value = foo\"\n" + + " }\n" + + "} ]"; + ByteBuffer data = Charset.forName("UTF-8").encode(jsonMetric); + IPCMessage message = mock(IPCMessage.class); + when(message.get()).thenReturn(data); + ArgumentCaptor<BytemanMetric> metricsCaptor = ArgumentCaptor.forClass(BytemanMetric.class); + + + BytemanMetricsReceiver receiver = new BytemanMetricsReceiver(dao, mock(VmSocketIdentifier.class)); + receiver.messageReceived(message); + + verify(dao, times(1)).addMetric(metricsCaptor.capture()); + + List<BytemanMetric> metrics = metricsCaptor.getAllValues(); + BytemanMetric metric = metrics.get(0); + // make sure HTML chars are not escaped + assertEquals("{\"key\":\"value = foo\"}", metric.getData()); + Map<String, Object> dataVals = metric.getDataAsMap(); + assertEquals("value = foo", dataVals.get("key")); + } + }
--- a/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapterTest.java Thu Aug 25 19:08:52 2016 +0200 +++ b/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapterTest.java Mon Aug 29 17:30:33 2016 +0200 @@ -43,6 +43,7 @@ import java.util.Map; +import org.junit.Before; import org.junit.Test; import com.google.gson.Gson; @@ -54,14 +55,21 @@ public class BytemanMetricTypeAdapterTest { private static final double DELTA = 0.001; + + private Gson gson; + + @Before + public void setup() { + gson = new GsonBuilder() + .registerTypeAdapterFactory(new BytemanMetricTypeAdapterFactory()) + .disableHtmlEscaping() + .serializeNulls() + .create(); + } @Test public void canDeserializeArrayOfMetrics() { String json = JsonHelper.buildJsonArray(10); - Gson gson = new GsonBuilder() - .registerTypeAdapterFactory(new BytemanMetricTypeAdapterFactory()) - .serializeNulls() - .create(); BytemanMetric[] metrics = gson.fromJson(json, BytemanMetric[].class); assertEquals(10, metrics.length); for (int i = 0; i < 10; i++) { @@ -87,5 +95,28 @@ assertEquals(10_000_000_001L, longVal); } } + + /* + * This is a test which makes sure that html characters don't get + * escaped. We were seeing instances where the following happened which this + * test is trying to catch: + * + * before JSON deserialization: {"key": "value = 'foo', 'bar', 'baz'"} + * after JSON deserialization: {"key"; "value \u003d \u0027foo\u0027, \u0027bar\u0027, \u0027baz\u0027"} + */ + @Test + public void canDeserializeMetricWithSpecialChar() { + String json = "{\n" + + " \"marker\": \"marker\",\n" + + " \"timestamp\":\"30\",\n" + + " \"data\": {\n" + + " \"key\": \"value = 'foo', 'bar', 'baz'\"\n" + + " }\n" + + "}"; + BytemanMetric metric = gson.fromJson(json, BytemanMetric.class); + assertEquals("{\"key\":\"value = 'foo', 'bar', 'baz'\"}", metric.getData()); + Map<String, Object> dataAsMap = metric.getDataAsMap(); + assertEquals("value = 'foo', 'bar', 'baz'", dataAsMap.get("key")); + } }