changeset 2780:0633f63d464d

Remove typeadapters and use JSONService This patch removes most of the type adapters from the agent, and replaces them with the JSONService from thermostat-common. The version of thermostat-common is updated to 0.1.2, which supports the current JSON expected by the web-gateway Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-October/025522.html
author Simon Tooke <stooke@redhat.com>
date Wed, 25 Oct 2017 12:53:20 -0400
parents 25179f6b60ae
children cd8047394d27
files common/plugin/pom.xml common/plugin/src/main/java/com/redhat/thermostat/common/plugin/PluginDAOBase.java plugins/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatDAOImpl.java plugins/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/model/CpuStat.java plugins/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/model/CpuStatTypeAdapter.java plugins/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatDAOTest.java plugins/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/model/CpuStatTypeAdapterTest.java plugins/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatDAOImpl.java plugins/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/model/MemoryStat.java plugins/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/model/MemoryStatTypeAdapter.java plugins/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatDAOTest.java plugins/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/model/MemoryStatTypeAdapterTest.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOImpl.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoList.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoListTypeAdapter.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfo.java plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTypeAdapter.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOTest.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInfoListTypeAdapterTest.java plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTypeAdapterTest.java plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/internal/models/HostInfoDAOImpl.java plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/model/HostInfo.java plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/model/HostInfoTypeAdapter.java plugins/host-overview/agent/src/test/java/com/redhat/thermostat/host/overview/internal/models/HostInfoDAOImplTest.java plugins/host-overview/agent/src/test/java/com/redhat/thermostat/host/overview/model/HostInfoTypeAdapterTest.java plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoDAOImpl.java plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoTypeAdapter.java plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/VmInfo.java plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/VmRef.java plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoDAOImplTest.java plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoTypeAdapterTest.java plugins/jvm-overview/pom.xml.orig plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/BytemanMetric.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanStatus.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanDAOImpl.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanMetricsStore.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanStatusStore.java plugins/vm-classstat/agent/src/main/java/com/redhat/thermostat/vm/classstat/agent/internal/VmClassStatDAOImpl.java plugins/vm-classstat/agent/src/main/java/com/redhat/thermostat/vm/classstat/model/VmClassStat.java plugins/vm-classstat/agent/src/main/java/com/redhat/thermostat/vm/classstat/model/VmClassStatTypeAdapter.java plugins/vm-classstat/agent/src/test/java/com/redhat/thermostat/vm/classstat/agent/internal/VmClassStatDAOTest.java plugins/vm-classstat/agent/src/test/java/com/redhat/thermostat/vm/classstat/model/VmClassStatTypeAdapterTest.java plugins/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatDaoImpl.java plugins/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/model/VmCompilerStat.java plugins/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/model/VmCompilerStatTypeAdapter.java plugins/vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatDaoImplTest.java plugins/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatDAOImpl.java plugins/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/model/VmCpuStat.java plugins/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/model/VmCpuStatTypeAdapter.java plugins/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatBuilderTest.java plugins/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatDAOImplTest.java plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatDAOImpl.java plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatTypeAdapter.java plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/model/VmGcStat.java plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatDAOImplTest.java plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatTypeAdapterTest.java plugins/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatDAOImpl.java plugins/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/model/VmIoStat.java plugins/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/model/VmIoStatTypeAdapter.java plugins/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatDAOImplTest.java plugins/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/model/VmIoStatTypeAdapterTest.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListener.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAO.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAOImpl.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatTypeAdapter.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAO.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAOImpl.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatTypeAdapter.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/model/VmMemoryStat.java plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/model/VmTlabStat.java plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListenerTest.java plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAOImplTest.java plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatTypeAdapterTest.java plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAOTest.java plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatTypeAdapterTest.java pom.xml storage/core/src/main/java/com/redhat/thermostat/storage/model/BasePojo.java
diffstat 77 files changed, 816 insertions(+), 3305 deletions(-) [+]
line wrap: on
line diff
--- a/common/plugin/pom.xml	Mon Oct 23 16:50:12 2017 -0400
+++ b/common/plugin/pom.xml	Wed Oct 25 12:53:20 2017 -0400
@@ -100,6 +100,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common</artifactId>
+      <version>${thermostat.common.version}</version>
+    </dependency>
+    <dependency>
       <groupId>com.redhat.thermostat.agent</groupId>
       <artifactId>thermostat-common-core</artifactId>
       <version>${project.version}</version>
--- a/common/plugin/src/main/java/com/redhat/thermostat/common/plugin/PluginDAOBase.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/common/plugin/src/main/java/com/redhat/thermostat/common/plugin/PluginDAOBase.java	Wed Oct 25 12:53:20 2017 -0400
@@ -46,16 +46,19 @@
 
 abstract public class PluginDAOBase<Tobj> {
 
-    protected abstract String toJsonString(Tobj obj) throws IOException;
     protected abstract HttpRequestService getHttpRequestService();
     protected abstract BackendConfigurationUtil getConfig();
     protected abstract URI getPostURI(final URI basepath, final Tobj obj);
     protected abstract Logger getLogger();
+    protected abstract String serialise(Tobj obj);
+
+    protected PluginDAOBase() {
+    }
 
     public void put(final Tobj obj) {
         try {
-            HttpRequestService httpRequestService = getHttpRequestService();
-            String json = toJsonString(obj);
+            final HttpRequestService httpRequestService = getHttpRequestService();
+            final String json = serialise(obj);
             final URI gatewayURI = getConfig().getGatewayURL();
             final URI postURI = getPostURI(gatewayURI, obj);
             httpRequestService.sendHttpRequest(json, postURI, HttpRequestService.Method.POST);
--- a/plugins/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,13 +36,12 @@
 
 package com.redhat.thermostat.host.cpu.agent.internal;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -57,7 +56,6 @@
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.host.cpu.model.CpuStat;
-import com.redhat.thermostat.host.cpu.model.CpuStatTypeAdapter;
 
 @Component(
         policy = ConfigurationPolicy.REQUIRE,
@@ -70,7 +68,6 @@
 
     public static final String PLUGIN_ID = "host-cpu";
 
-    private final JsonHelper jsonHelper;
     private final ConfigurationCreator configCreator;
     private BackendConfigurationUtil config;
 
@@ -78,17 +75,19 @@
     private ConfigurationInfoSource configurationInfoSource;
 
     @Reference
-    private SystemID systemID;
+    private HttpRequestService httpRequestService;
 
     @Reference
-    private HttpRequestService httpRequestService;
+    private JSONService jsonService;
+
+    @Reference
+    private SystemID systemID;
 
     public CpuStatDAOImpl() {
-        this(new JsonHelper(new CpuStatTypeAdapter()), new ConfigurationCreator());
+        this(new ConfigurationCreator());
     }
 
-    CpuStatDAOImpl(JsonHelper jh, ConfigurationCreator creator) {
-        this.jsonHelper = jh;
+    CpuStatDAOImpl(ConfigurationCreator creator) {
         this.configCreator = creator;
     }
 
@@ -111,8 +110,14 @@
         return PLUGIN_ID;
     }
 
-    public Logger getLogger() {
-        return logger;
+    @Override
+    protected URI getPostURI(URI basepath, CpuStat obj) {
+        return basepath.resolve("systems/" + systemID.getSystemID());
+    }
+
+    @Override
+    protected String serialise(CpuStat obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
@@ -121,27 +126,12 @@
     }
 
     @Override
-    protected String toJsonString(CpuStat obj) throws IOException {
-        return jsonHelper.toJson(Arrays.asList(obj));
-    }
-
-    @Override
     protected BackendConfigurationUtil getConfig() {
         return config;
     }
 
-    @Override
-    protected URI getPostURI(URI basepath, CpuStat obj) {
-        return basepath.resolve("systems/" + systemID.getSystemID());
-    }
-
-    // DS bind method
-    protected void bindSystemID(SystemID systemid) {
-        this.systemID = systemid;
-    }
-
-    protected void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
-        this.configurationInfoSource = cfg;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
 
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
@@ -150,21 +140,21 @@
 
     protected void unbindHttpRequestService(HttpRequestService httpRequestService) {
         this.httpRequestService = null;
+        logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
+    }
+
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
     }
 
-    // For testing purposes
-    static class JsonHelper {
-
-        private final CpuStatTypeAdapter typeAdapter;
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
 
-        JsonHelper(CpuStatTypeAdapter typeAdapter) {
-            this.typeAdapter = typeAdapter;
-        }
+    protected Logger getLogger() {
+        return logger;
+    }
 
-        String toJson(List<CpuStat> infos) throws IOException {
-            return typeAdapter.toJson(infos);
-        }
-    }
     // For Testing purposes
     static class ConfigurationCreator {
 
--- a/plugins/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/model/CpuStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/model/CpuStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.host.cpu.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -46,7 +47,10 @@
 
     public static final double INVALID_LOAD = Double.MIN_VALUE;
 
+    @Schema
     private long timeStamp;
+
+    @Schema
     private double[] perProcessorUsage;
 
     public CpuStat() {
--- a/plugins/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/model/CpuStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.cpu.model;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.google.gson.TypeAdapter;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-public class CpuStatTypeAdapter extends TypeAdapter<List<CpuStat>> {
-
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String PROCESSOR_USAGE = "perProcessorUsage";
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String SERVER_TIME = "time";
-    private static final String RESPONSE_ROOT = "response";
-    private static final String AGENT_ID = "agentId";
-
-    private static final Logger logger = LoggingUtils.getLogger(CpuStatTypeAdapter.class);
-
-    @Override
-    public void write(JsonWriter out, List<CpuStat> value) throws IOException {
-        out.beginArray();
-
-        for (CpuStat stat : value) {
-            writeCpuStat(out, stat);
-        }
-
-        out.endArray();
-    }
-
-    private void writeCpuStat(JsonWriter out, CpuStat stat) throws IOException {
-        out.beginObject();
-        out.name(PROCESSOR_USAGE);
-        out.beginArray();
-        for (double val : stat.getPerProcessorUsage()) {
-            out.value(val);
-        }
-        out.endArray();
-        out.name(TIMESTAMP);
-        writeLong(out, stat.getTimeStamp());
-        out.name(AGENT_ID);
-        out.value(stat.getAgentId());
-        out.endObject();
-    }
-
-    @Override
-    public List<CpuStat> read(JsonReader in) throws IOException {
-        List<CpuStat> values = null;
-        try {
-            in.beginObject();
-            while (in.hasNext()) {
-                String name = in.nextName();
-                switch (name) {
-                    case RESPONSE_ROOT:
-                        values = readResponse(in);
-                        break;
-                    case SERVER_TIME:
-                        in.nextString();
-                        break;
-                    default:
-                        throw new IOException("Unexpected JSON name: " + name);
-                }
-            }
-            in.endObject();
-        } catch (IllegalStateException e) {
-            throw new IOException("Reading JSON response failed.");
-        }
-        return values;
-    }
-
-    private List<CpuStat> readResponse(JsonReader in) throws IOException {
-        List<CpuStat> values = new ArrayList<>();
-
-        in.beginArray();
-
-        while (in.hasNext()) {
-            try {
-                CpuStat stat = readCpuStat(in);
-                values.add(stat);
-            } catch(IOException | IllegalStateException | NumberFormatException e) {
-                logger.log(Level.WARNING, "Skipping malformed cpu stat record", e);
-            }
-        }
-        in.endArray();
-
-        return values;
-    }
-
-    private CpuStat readCpuStat(JsonReader in) throws IOException {
-        String agentId = null;
-        double[] perProcessorUsage = null;
-        long timestamp = -1;
-
-        in.beginObject();
-
-        while (in.hasNext()) {
-            String name = in.nextName();
-            switch (name) {
-                case PROCESSOR_USAGE:
-                    perProcessorUsage = readProcessorUsage(in);
-                    break;
-                case TIMESTAMP:
-                    timestamp = readLong(in);
-                    break;
-                case AGENT_ID:
-                    agentId = in.nextString();
-                    break;
-                default:
-                    throw new IOException("Unexpected JSON name: " + name);
-            }
-        }
-
-        in.endObject();
-
-        if (perProcessorUsage == null || agentId == null || timestamp < 0) {
-            throw new IOException("CpuStat information is incomplete.");
-        }
-        return new CpuStat(agentId, timestamp,  perProcessorUsage);
-    }
-
-    private double[] readProcessorUsage(JsonReader in) throws IOException {
-        List<Double> procUsage = new ArrayList<Double>();
-        in.beginArray();
-        while (in.hasNext()) {
-            procUsage.add(in.nextDouble());
-        }
-        in.endArray();
-        double[] result = new double[procUsage.size()];
-        for (int i = 0; i < result.length; i++) {
-            result[i] = procUsage.get(i);
-        }
-        return result;
-    }
-
-    private long readLong(JsonReader in) throws IOException {
-        // Read MongoDB representation of a Long
-        in.beginObject();
-        String name = in.nextName();
-        expectName(TYPE_LONG, name);
-        long ret = Long.valueOf(in.nextString());
-        in.endObject();
-        return ret;
-    }
-
-    private void writeLong(JsonWriter out, long timestamp) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(timestamp));
-        out.endObject();
-    }
-
-    private void expectName(String expected, String actual) throws IOException {
-        if (!expected.equals(actual)) {
-            throw new IOException("Expected JSON name '" + expected + "', got '" + actual + "'");
-        }
-    }
-
-}
--- a/plugins/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatDAOTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatDAOTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -44,6 +44,7 @@
 
 import java.net.URI;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -64,7 +65,7 @@
     private static final String HOST_NAME = "somehostname";
 
     private CpuStat info;
-    private CpuStatDAOImpl.JsonHelper jsonHelper;
+    private JSONService jsonService;
     private ConfigurationInfoSource cfiSource;
     private CpuStatDAOImpl.ConfigurationCreator configCreator;
 
@@ -76,8 +77,8 @@
         Clock clock = new SystemClock();
         info = new CpuStat("foo-agent", clock.getRealTimeMillis(), times);
 
-        jsonHelper = mock(CpuStatDAOImpl.JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(CpuStat.class))).thenReturn(SOME_JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(CpuStat.class))).thenReturn(SOME_JSON);
 
         cfiSource = mock(ConfigurationInfoSource.class);
         configCreator = mock(ConfigurationCreator.class);
@@ -93,7 +94,8 @@
     @Test
     public void testPut() throws Exception {
 
-        CpuStatDAOImpl dao = new CpuStatDAOImpl(jsonHelper, configCreator);
+        CpuStatDAOImpl dao = new CpuStatDAOImpl(configCreator);
+        dao.bindJsonService(jsonService);
         dao.bindSystemID(idservice);
         dao.bindConfigurationInfoSource(cfiSource);
         dao.bindHttpRequestService(httpRequestService);
--- a/plugins/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/model/CpuStatTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.cpu.model;
-
-import com.google.gson.GsonBuilder;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import org.junit.Test;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertArrayEquals;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.lang.reflect.Type;
-
-public class CpuStatTypeAdapterTest {
-
-    @Test
-    public void testTypeAdapterSerializesSingletonCorrectly() {
-        GsonBuilder builder = new GsonBuilder();
-        Type cpuStatListType = new TypeToken<ArrayList<CpuStat>>(){}.getType();
-        builder.registerTypeAdapter(cpuStatListType, new CpuStatTypeAdapter().nullSafe());
-        Gson gson = builder.create();
-        List<CpuStat> stats = new ArrayList<>();
-        stats.add(new CpuStat("1", 1234567890l, new double[]{9.99, 8.88, 3.1415, 7.777}));
-        String result = gson.toJson(stats, cpuStatListType);
-        assertJsonEquals("[{\"perProcessorUsage\":[9.99,8.88,3.1415,7.777],\"timeStamp\":{\"$numberLong\":\"1234567890\"},\"agentId\":\"1\"}]", result);
-    }
-
-    @Test
-    public void testTypeAdapterSerializesListCorrectly() {
-        GsonBuilder builder = new GsonBuilder();
-        Type cpuStatListType = new TypeToken<ArrayList<CpuStat>>(){}.getType();
-        builder.registerTypeAdapter(cpuStatListType, new CpuStatTypeAdapter().nullSafe());
-        Gson gson = builder.create();
-        List<CpuStat> stats = new ArrayList<>();
-        stats.add(new CpuStat("1", 1000230101l, new double[]{1.23, 4.56, 7.89, 10.1112}));
-        stats.add(new CpuStat("2", 10002333101l, new double[]{1.323, 4.456, 7.789, 10.101112}));
-        stats.add(new CpuStat("3", 10002320101l, new double[]{1.234, 4.567, 7.8910, 10.111213}));
-        stats.add(new CpuStat("4", 100023313101l, new double[]{1.3235, 4.4567, 7.78911, 10.10111241}));
-        String result = gson.toJson(stats, cpuStatListType);
-        assertJsonEquals("[{\"perProcessorUsage\":[1.23,4.56,7.89,10.1112],\"timeStamp\":{\"$numberLong\":\"1000230101\"},\"agentId\":\"1\"}," +
-                "{\"perProcessorUsage\":[1.323,4.456,7.789,10.101112],\"timeStamp\":{\"$numberLong\":\"10002333101\"},\"agentId\":\"2\"}," +
-                "{\"perProcessorUsage\":[1.234,4.567,7.891,10.111213],\"timeStamp\":{\"$numberLong\":\"10002320101\"},\"agentId\":\"3\"}," +
-                "{\"perProcessorUsage\":[1.3235,4.4567,7.78911,10.10111241],\"timeStamp\":{\"$numberLong\":\"100023313101\"},\"agentId\":\"4\"}]", result);
-    }
-
-    @Test
-    public void testTypeAdapterDeserializesSingletonCorrectly() {
-        GsonBuilder builder = new GsonBuilder();
-        Type cpuStatListType = new TypeToken<ArrayList<CpuStat>>(){}.getType();
-        builder.registerTypeAdapter(cpuStatListType, new CpuStatTypeAdapter().nullSafe());
-        Gson gson = builder.create();
-        String serialized = "{\"response\":[{\"perProcessorUsage\":[1.23,4.56,7.89,11.1],\"timeStamp\":{\"$numberLong\":\"12345\"},\"agentId\":\"1\"}],\"time\":\"123\"}";
-        List<CpuStat> result = gson.fromJson(serialized, cpuStatListType);
-        CpuStat stat = result.get(0);
-        assertEquals(12345, stat.getTimeStamp());
-        assertArrayEquals(new double[]{1.23, 4.56, 7.89, 11.1}, stat.getPerProcessorUsage(), 0.000001);
-        assertEquals("1", stat.getAgentId());
-    }
-
-    @Test
-    public void testTypeAdapterDeserializesListCorrectly() {
-        GsonBuilder builder = new GsonBuilder();
-        Type cpuStatListType = new TypeToken<List<CpuStat>>(){}.getType();
-        builder.registerTypeAdapter(cpuStatListType, new CpuStatTypeAdapter().nullSafe());
-        Gson gson = builder.create();
-        String serialized = "{\"response\":[" +
-                "{\"perProcessorUsage\":[1.23,4.56,7.89,11.1],\"timeStamp\":{\"$numberLong\":\"12345\"},\"agentId\":\"1\"}," +
-                "{\"perProcessorUsage\":[3.21,6.54,9.87,1.11],\"timeStamp\":{\"$numberLong\":\"54321\"},\"agentId\":\"2\"}," +
-                "{\"perProcessorUsage\":[3.1415,2.765,9.999,1.11234],\"timeStamp\":{\"$numberLong\":\"98765\"},\"agentId\":\"3\"}," +
-                "{\"perProcessorUsage\":[444.678,9000.99,1243.5654,7.897867],\"timeStamp\":{\"$numberLong\":\"56789\"},\"agentId\":\"4\"}" +
-                "],\"time\":\"123\"}";
-        List<CpuStat> result = gson.fromJson(serialized, cpuStatListType);
-        CpuStat stat = result.get(0);
-        assertEquals(12345, stat.getTimeStamp());
-        assertArrayEquals(new double[]{1.23, 4.56, 7.89, 11.1}, stat.getPerProcessorUsage(), 0.000001);
-        assertEquals("1", stat.getAgentId());
-        stat = result.get(1);
-        assertEquals(54321, stat.getTimeStamp());
-        assertArrayEquals(new double[]{3.21,6.54,9.87,1.11}, stat.getPerProcessorUsage(), 0.000001);
-        assertEquals("2", stat.getAgentId());
-        stat = result.get(2);
-        assertEquals(98765, stat.getTimeStamp());
-        assertArrayEquals(new double[]{3.1415,2.765,9.999,1.11234}, stat.getPerProcessorUsage(), 0.000001);
-        assertEquals("3", stat.getAgentId());
-        stat = result.get(3);
-        assertEquals(56789, stat.getTimeStamp());
-        assertArrayEquals(new double[]{444.678,9000.99,1243.5654,7.897867}, stat.getPerProcessorUsage(), 0.000001);
-        assertEquals("4", stat.getAgentId());
-    }
-
-}
--- a/plugins/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,12 +36,12 @@
 
 package com.redhat.thermostat.host.memory.agent.internal;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -56,7 +56,6 @@
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.host.memory.model.MemoryStat;
-import com.redhat.thermostat.host.memory.model.MemoryStatTypeAdapter;
 
 @Component(
         policy = ConfigurationPolicy.REQUIRE,
@@ -69,7 +68,6 @@
 
     public static final String PLUGIN_ID = "host-memory";
 
-    private final JsonHelper jsonHelper;
     private final ConfigurationCreator configCreator;
     private BackendConfigurationUtil config;
 
@@ -77,17 +75,19 @@
     private ConfigurationInfoSource configurationInfoSource;
 
     @Reference
-    private SystemID systemID;
+    private HttpRequestService httpRequestService;
 
     @Reference
-    private HttpRequestService httpRequestService;
+    private JSONService jsonService;
+
+    @Reference
+    private SystemID systemID;
 
     public MemoryStatDAOImpl() {
-        this(new JsonHelper(new MemoryStatTypeAdapter()), new ConfigurationCreator());
+        this(new ConfigurationCreator());
     }
 
-    MemoryStatDAOImpl(JsonHelper jh, ConfigurationCreator creator) {
-        this.jsonHelper = jh;
+    MemoryStatDAOImpl(ConfigurationCreator creator) {
         this.configCreator = creator;
     }
 
@@ -110,13 +110,13 @@
         return PLUGIN_ID;
     }
 
-    public Logger getLogger() {
-        return logger;
+    protected URI getPostURI(URI basepath, MemoryStat obj) {
+        return basepath.resolve("systems/" + systemID.getSystemID());
     }
 
     @Override
-    protected BackendConfigurationUtil getConfig() {
-        return config;
+    protected String serialise(MemoryStat obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
@@ -125,22 +125,13 @@
     }
 
     @Override
-    protected String toJsonString(MemoryStat obj) throws IOException {
-        return jsonHelper.toJson(Arrays.asList(obj));
+    protected BackendConfigurationUtil getConfig() {
+        return config;
     }
 
-    @Override
-    protected URI getPostURI(URI basepath, MemoryStat obj) {
-        return basepath.resolve("systems/" + systemID.getSystemID());
-    }
 
-    // DS bind methods
-    protected void bindSystemID(SystemID systemid) {
-        this.systemID = systemid;
-    }
-
-    protected void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
-        this.configurationInfoSource = cfg;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
 
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
@@ -149,20 +140,19 @@
 
     protected void unbindHttpRequestService(HttpRequestService httpRequestService) {
         this.httpRequestService = null;
+        logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
+    }
+
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
     }
 
-    // For testing purposes
-    static class JsonHelper {
-
-        private final MemoryStatTypeAdapter typeAdapter;
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
 
-        JsonHelper(MemoryStatTypeAdapter typeAdapter) {
-            this.typeAdapter = typeAdapter;
-        }
-
-        String toJson(List<MemoryStat> infos) throws IOException {
-            return typeAdapter.toJson(infos);
-        }
+    protected Logger getLogger() {
+        return logger;
     }
 
     // For Testing purposes
--- a/plugins/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/model/MemoryStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/model/MemoryStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.host.memory.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -44,13 +45,28 @@
 @Entity
 public class MemoryStat extends BasePojo implements TimeStampedPojo {
 
+    @Schema
     private long timeStamp;
+
+    @Schema
     private long total;
+
+    @Schema
     private long free;
+
+    @Schema
     private long buffers;
+
+    @Schema
     private long cached;
+
+    @Schema
     private long swapTotal;
+
+    @Schema
     private long swapFree;
+
+    @Schema
     private long commitLimit;
 
     public MemoryStat() {
--- a/plugins/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/model/MemoryStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.memory.model;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-
-import java.io.IOException;
-import java.util.List;
-
-public class MemoryStatTypeAdapter extends TypeAdapter<List<MemoryStat>> {
-
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String TOTAL = "total";
-    private static final String FREE = "free";
-    private static final String BUFFERS = "buffers";
-    private static final String CACHED = "cached";
-    private static final String SWAP_TOTAL = "swapTotal";
-    private static final String SWAP_FREE = "swapFree";
-    private static final String COMMIT_LIMIT = "commitLimit";
-    private static final String AGENT_ID = "agentId";
-
-
-    public void write(JsonWriter out, List<MemoryStat> stats) throws IOException {
-        out.beginArray();
-
-        for (MemoryStat stat : stats) {
-            writeMemoryStat(out, stat);
-        }
-
-        out.endArray();
-    }
-
-    public void writeMemoryStat(JsonWriter out, MemoryStat stats) throws IOException {
-        out.beginObject();
-        out.name(TIMESTAMP);
-        writeLong(out, stats.getTimeStamp());
-        out.name(TOTAL);
-        writeLong(out, stats.getTotal());
-        out.name(FREE);
-        writeLong(out, stats.getFree());
-        out.name(BUFFERS);
-        writeLong(out, stats.getBuffers());
-        out.name(CACHED);
-        writeLong(out, stats.getCached());
-        out.name(SWAP_TOTAL);
-        writeLong(out, stats.getSwapTotal());
-        out.name(SWAP_FREE);
-        writeLong(out, stats.getSwapFree());
-        out.name(COMMIT_LIMIT);
-        writeLong(out, stats.getCommitLimit());
-        out.name(AGENT_ID);
-        out.value(stats.getAgentId());
-        out.endObject();
-    }
-
-    public void writeLong(JsonWriter out, long input) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(input));
-        out.endObject();
-    }
-
-    public List<MemoryStat> read(JsonReader in) throws IOException {
-        return null;
-    }
-
-}
--- a/plugins/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatDAOTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatDAOTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -44,6 +44,7 @@
 
 import java.net.URI;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -63,7 +64,7 @@
     private static final String HOST_NAME = "somehostname";
 
     private MemoryStat info;
-    private MemoryStatDAOImpl.JsonHelper jsonHelper;
+    private JSONService jsonService;
     private ConfigurationInfoSource cfiSource;
     private MemoryStatDAOImpl.ConfigurationCreator configCreator;
     private SystemID idservice;
@@ -74,8 +75,8 @@
         Clock clock = new SystemClock();
         this.info = new MemoryStat("foo-agent", clock.getRealTimeMillis(), 0, 0, 0, 0, 0, 0, 0);
 
-        this.jsonHelper = mock(MemoryStatDAOImpl.JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(MemoryStat.class))).thenReturn(SOME_JSON);
+        this.jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(MemoryStat.class))).thenReturn(SOME_JSON);
 
         cfiSource = mock(ConfigurationInfoSource.class);
         configCreator = mock(ConfigurationCreator.class);
@@ -90,7 +91,8 @@
 
     @Test
     public void testPut() throws Exception {
-        MemoryStatDAOImpl dao = new MemoryStatDAOImpl(jsonHelper, configCreator);
+        MemoryStatDAOImpl dao = new MemoryStatDAOImpl(configCreator);
+        dao.bindJsonService(jsonService);
         dao.bindSystemID(idservice);
         dao.bindConfigurationInfoSource(cfiSource);
         dao.bindHttpRequestService(httpRequestService);
--- a/plugins/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/model/MemoryStatTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.memory.model;
-
-import com.google.gson.GsonBuilder;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import org.junit.Test;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-public class MemoryStatTypeAdapterTest {
-
-    @Test
-    public void testMemoryStatGetsSerializedCorrectly() {
-        GsonBuilder builder = new GsonBuilder();
-        Type memoryStatListType = new TypeToken<ArrayList<MemoryStat>>(){}.getType();
-        builder.registerTypeAdapter(memoryStatListType, new MemoryStatTypeAdapter().nullSafe());
-        Gson gson = builder.create();
-        List<MemoryStat> stats = new ArrayList<>();
-        stats.add(new MemoryStat("1", 123l, 456l, 789l, 101112l, 131415l,
-                161718l, 192021l, 222324l));
-        System.out.println(gson.toJson(stats, memoryStatListType));
-        assertJsonEquals("[{\"timeStamp\":{\"$numberLong\":\"123\"}," +
-                "\"total\":{\"$numberLong\":\"456\"}," +
-                "\"free\":{\"$numberLong\":\"789\"}," +
-                "\"buffers\":{\"$numberLong\":\"101112\"}," +
-                "\"cached\":{\"$numberLong\":\"131415\"}," +
-                "\"swapTotal\":{\"$numberLong\":\"161718\"}," +
-                "\"swapFree\":{\"$numberLong\":\"192021\"}," +
-                "\"commitLimit\":{\"$numberLong\":\"222324\"}," +
-                "\"agentId\":\"1\"}]",
-                gson.toJson(stats, memoryStatListType));
-    }
-
-    @Test
-    public void testMultipleMemoryStatsGetSerializedCorrectly() {
-        GsonBuilder builder = new GsonBuilder();
-        Type memoryStatListType = new TypeToken<ArrayList<MemoryStat>>(){}.getType();
-        builder.registerTypeAdapter(memoryStatListType, new MemoryStatTypeAdapter().nullSafe());
-        Gson gson = builder.create();
-        List<MemoryStat> stats = new ArrayList<>();
-        stats.add(new MemoryStat("1", 123l, 456l, 789l, 101112l, 131415l,
-                161718l, 192021l, 222324l));
-        stats.add(new MemoryStat("2", 1l, 2l, 3l, 4l, 5l,6l, 7l, 8l));
-        stats.add(new MemoryStat("3", 17756l, 25365323l, 3124213l, 4465434l, 578687l,
-                689821l, 786711l, 823542l));
-        stats.add(new MemoryStat("4", 13332l, 24441l, 37721l, 4321345l, 542131l,
-                64522l, 71232l, 8231321l));
-        assertJsonEquals("[{\"timeStamp\":{\"$numberLong\":\"123\"},\"total\":{\"$numberLong\":\"456\"},\"free\":{\"$numberLong\":\"789\"},\"buffers\":{\"$numberLong\":\"101112\"},\"cached\":{\"$numberLong\":\"131415\"},\"swapTotal\":{\"$numberLong\":\"161718\"},\"swapFree\":{\"$numberLong\":\"192021\"},\"commitLimit\":{\"$numberLong\":\"222324\"},\"agentId\":\"1\"}," +
-                "{\"timeStamp\":{\"$numberLong\":\"1\"},\"total\":{\"$numberLong\":\"2\"},\"free\":{\"$numberLong\":\"3\"},\"buffers\":{\"$numberLong\":\"4\"},\"cached\":{\"$numberLong\":\"5\"},\"swapTotal\":{\"$numberLong\":\"6\"},\"swapFree\":{\"$numberLong\":\"7\"},\"commitLimit\":{\"$numberLong\":\"8\"},\"agentId\":\"2\"}," +
-                "{\"timeStamp\":{\"$numberLong\":\"17756\"},\"total\":{\"$numberLong\":\"25365323\"},\"free\":{\"$numberLong\":\"3124213\"},\"buffers\":{\"$numberLong\":\"4465434\"},\"cached\":{\"$numberLong\":\"578687\"},\"swapTotal\":{\"$numberLong\":\"689821\"},\"swapFree\":{\"$numberLong\":\"786711\"},\"commitLimit\":{\"$numberLong\":\"823542\"},\"agentId\":\"3\"}," +
-                "{\"timeStamp\":{\"$numberLong\":\"13332\"},\"total\":{\"$numberLong\":\"24441\"},\"free\":{\"$numberLong\":\"37721\"},\"buffers\":{\"$numberLong\":\"4321345\"},\"cached\":{\"$numberLong\":\"542131\"},\"swapTotal\":{\"$numberLong\":\"64522\"},\"swapFree\":{\"$numberLong\":\"71232\"},\"commitLimit\":{\"$numberLong\":\"8231321\"},\"agentId\":\"4\"}]",
-                gson.toJson(stats, memoryStatListType));
-    }
-
-}
--- a/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,12 +36,12 @@
 
 package com.redhat.thermostat.host.network.internal;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -56,7 +56,6 @@
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.host.network.model.NetworkInfoList;
-import com.redhat.thermostat.host.network.model.NetworkInfoListTypeAdapter;
 
 @Component(
         policy = ConfigurationPolicy.REQUIRE,
@@ -72,19 +71,24 @@
     private final ConfigurationCreator configCreator;
     private BackendConfigurationUtil config;
 
-    private final JsonHelper jsonHelper;
-
     @Reference
-    private SystemID systemID;
+    private ConfigurationInfoSource configurationInfoSource;
 
     @Reference
     private HttpRequestService httpRequestService;
 
     @Reference
-    private ConfigurationInfoSource configurationInfoSource;
+    private JSONService jsonService;
+
+    @Reference
+    private SystemID systemID;
 
     public NetworkInfoListDAOImpl() throws Exception {
-        this(new JsonHelper(new NetworkInfoListTypeAdapter()), new ConfigurationCreator());
+        this(new ConfigurationCreator());
+    }
+
+    NetworkInfoListDAOImpl(ConfigurationCreator creator) throws Exception {
+        this.configCreator = creator;
     }
 
     @Activate
@@ -102,14 +106,14 @@
         logger.config("Doing nothing on configuration change for plugin " + PLUGIN_ID);
     }
 
-    NetworkInfoListDAOImpl(JsonHelper jsonHelper, ConfigurationCreator creator) throws Exception {
-        this.jsonHelper = jsonHelper;
-        this.configCreator = creator;
+    @Override
+    protected URI getPostURI(URI basepath, NetworkInfoList obj) {
+        return basepath.resolve("systems/" + systemID.getSystemID());
     }
 
     @Override
-    protected String toJsonString(NetworkInfoList obj) throws IOException {
-        return jsonHelper.toJson(Arrays.asList(obj));
+    protected String serialise(NetworkInfoList obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
@@ -122,41 +126,29 @@
         return config;
     }
 
-    @Override
-    protected URI getPostURI(URI basepath, NetworkInfoList obj) {
-        return basepath.resolve("systems/" + systemID.getSystemID());
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return logger;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
 
-    // DS bind method
-    void bindSystemID(SystemID systemid) {
-        this.systemID = systemid;
-    }
-
-    void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
-        this.configurationInfoSource = cfg;
-    }
-
-    void bindHttpRequestService(HttpRequestService httpRequestService) {
+    protected void bindHttpRequestService(HttpRequestService httpRequestService) {
         this.httpRequestService = httpRequestService;
     }
 
-    // For testing purposes
-    static class JsonHelper {
-        
-        private final NetworkInfoListTypeAdapter typeAdapter;
-        
-        JsonHelper(NetworkInfoListTypeAdapter typeAdapter) {
-            this.typeAdapter = typeAdapter;
-        }
+    protected void unbindHttpRequestService(HttpRequestService httpRequestService) {
+        this.httpRequestService = null;
+        logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
+    }
 
-        String toJson(List<NetworkInfoList> infos) throws IOException {
-            return typeAdapter.toJson(infos);
-        }
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
+    }
+
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
+
+    protected Logger getLogger() {
+        return logger;
     }
 
     // For Testing purposes
--- a/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoList.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoList.java	Wed Oct 25 12:53:20 2017 -0400
@@ -39,13 +39,17 @@
 import java.util.List;
 import java.util.Objects;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.model.BasePojo;
 
 @Entity
 public class NetworkInfoList extends BasePojo {
 
+    @Schema
     private long timeStamp;
+
+    @Schema
     private List<NetworkInterfaceInfo> interfaces;
 
     public NetworkInfoList(String writerID, long timeStamp, List<NetworkInterfaceInfo> list) {
--- a/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInfoListTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.network.model;
-
-import java.io.IOException;
-import java.util.List;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-
-public class NetworkInfoListTypeAdapter extends TypeAdapter<List<NetworkInfoList>> {
-
-    private static final String AGENT_ID = "agentId";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String INTERFACE_LIST = "interfaces";
-    private static final String TYPE_LONG = "$numberLong";
-
-    private final NetworkInterfaceInfoTypeAdapter infoTypeAdapter = new NetworkInterfaceInfoTypeAdapter();
-
-    private void write(final JsonWriter out, final NetworkInfoList value) throws IOException {
-
-        out.beginObject();
-
-        out.name(AGENT_ID);
-        out.value(value.getAgentId());
-
-        out.name(TIMESTAMP);
-        writeLong(out, value.getTimeStamp());
-
-        out.name(INTERFACE_LIST);
-        infoTypeAdapter.write(out, value.getList());
-
-        out.endObject();
-    }
-
-    private void writeLong(final JsonWriter out, final long input) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(input));
-        out.endObject();
-    }
-
-    private long readLong(final JsonReader in) throws IOException {
-        // Read MongoDB representation of a Long
-        in.beginObject();
-        String name = in.nextName();
-        expectName(TYPE_LONG, name);
-        long ret = Long.valueOf(in.nextString());
-        in.endObject();
-        return ret;
-    }
-
-    private void expectName(final String expected, final String actual) throws IOException {
-        if (!expected.equals(actual)) {
-            throw new IOException("Expected JSON name '" + expected + "', got '" + actual + "'");
-        }
-    }
-
-    @Override
-    public void write(JsonWriter out, List<NetworkInfoList> list) throws IOException {
-        out.beginArray();
-
-        for (NetworkInfoList info : list) {
-            write(out, info);
-        }
-
-        out.endArray();
-    }
-
-    @Override
-    public List<NetworkInfoList> read(JsonReader jsonReader) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-}
--- a/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfo.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfo.java	Wed Oct 25 12:53:20 2017 -0400
@@ -38,15 +38,23 @@
 
 import java.util.Objects;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 
 @Entity
 public class NetworkInterfaceInfo {
 
+    @Schema
     private String interfaceName;
+
+    @Schema
     private String displayName;
+
+    @Schema
     private String ip4Addr;
+
+    @Schema
     private String ip6Addr;
 
 
--- a/plugins/host-network/agent/src/main/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.network.model;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import com.google.gson.stream.JsonWriter;
-
-public class NetworkInterfaceInfoTypeAdapter extends TypeAdapter<List<NetworkInterfaceInfo>> {
-
-    private static final String INTERFACE_NAME = "interfaceName";
-    private static final String DISPLAY_NAME = "displayName";
-    private static final String IP4_ADDR = "ip4Addr";
-    private static final String IP6_ADDR = "ip6Addr";
-    private static final String RESPONSE_ROOT = "response";
-    private static final String SERVER_TIME = "time";
-
-    @Override
-    public void write(JsonWriter out, List<NetworkInterfaceInfo> value) throws IOException {
-
-        // Request is an array of NetworkInterfaceInfo objects
-        out.beginArray();
-        
-        for (NetworkInterfaceInfo info : value) {
-            writeNetworkInterfaceInfo(out, info);
-        }
-        
-        out.endArray();
-    }
-
-    private void writeNetworkInterfaceInfo(JsonWriter out, NetworkInterfaceInfo info) throws IOException {
-        out.beginObject();
-        
-        // Write each field of NetworkInterfaceInfo as part of a JSON object
-        out.name(INTERFACE_NAME);
-        out.value(info.getInterfaceName());
-
-        if (info.getDisplayName() != null) {
-            out.name(DISPLAY_NAME);
-            out.value(info.getDisplayName());
-        }
-        out.name(IP4_ADDR);
-        out.value(info.getIp4Addr());
-        out.name(IP6_ADDR);
-        out.value(info.getIp6Addr());
-        
-        out.endObject();
-    }
-
-    @Override
-    public List<NetworkInterfaceInfo> read(JsonReader in) throws IOException {
-        List<NetworkInterfaceInfo> infos = null;
-        
-        try {
-            // Parse root object
-            in.beginObject();
-            while (in.hasNext()) {
-                String name = in.nextName();
-                switch (name) {
-                case RESPONSE_ROOT:
-                    infos = readList(in);
-                    break;
-                case SERVER_TIME:
-                    in.nextString();
-                    break;
-                default:
-                    throw new IOException("Unexpected JSON name in gateway response: '" + name + "'");
-                }
-            }
-            in.endObject();
-        } catch (IllegalStateException e) {
-            throw new IOException("Reading JSON response from web gateway failed", e);
-        }
-        
-        return infos;
-    }
-    
-    List<NetworkInterfaceInfo> readList(JsonReader in) throws IOException {
-        List<NetworkInterfaceInfo> infos = new ArrayList<>();
-        
-        // Parse array of NetworkInterfaceInfos
-        in.beginArray();
-        
-        while (in.hasNext()) {
-            NetworkInterfaceInfo info = readNetworkInterfaceInfo(in);
-            infos.add(info);
-        }
-        in.endArray();
-        
-        return infos;
-    }
-    
-    private NetworkInterfaceInfo readNetworkInterfaceInfo(JsonReader in) throws IOException {
-        String interfaceName = null;
-        String ipv4Addr = null;
-        String ipv6Addr = null;
-        String displayName = null;
-        
-        // Begin parsing a NetworkInterfaceInfo record
-        in.beginObject();
-        
-        while (in.hasNext()) {
-            String name = in.nextName();
-            switch (name) {
-            case INTERFACE_NAME:
-                interfaceName = in.nextString();
-                break;
-            case DISPLAY_NAME:
-                displayName = in.nextString();
-                break;
-            case IP4_ADDR: // Addresses may be null
-                ipv4Addr = readStringOrNull(in);
-                break;
-            case IP6_ADDR:
-                ipv6Addr = readStringOrNull(in);
-                break;
-            default:
-                throw new IOException("Unexpected JSON name in record: '" + name + "'");
-            }
-        }
-        
-        in.endObject();
-        
-        // Create NetworkInterfaceInfo if all required fields present
-        if (interfaceName == null) {
-            throw new IOException("Network interface information record is incomplete");
-        }
-        NetworkInterfaceInfo result = new NetworkInterfaceInfo(interfaceName);
-        result.setIp4Addr(ipv4Addr);
-        result.setIp6Addr(ipv6Addr);
-        result.setDisplayName(displayName);
-        
-        return result;
-    }
-    
-    private String readStringOrNull(JsonReader in) throws IOException {
-        String result = null;
-        JsonToken token = in.peek();
-        if (token == JsonToken.NULL) {
-            in.nextNull();
-        } else {
-            result = in.nextString();
-        }
-        return result;
-    }
-}
--- a/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/internal/NetworkInfoListDAOTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -46,6 +46,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -54,7 +55,6 @@
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.host.network.internal.NetworkInfoListDAOImpl.ConfigurationCreator;
-import com.redhat.thermostat.host.network.internal.NetworkInfoListDAOImpl.JsonHelper;
 import com.redhat.thermostat.host.network.model.NetworkInfoList;
 import com.redhat.thermostat.host.network.model.NetworkInterfaceInfo;
 
@@ -69,7 +69,7 @@
     private static final String HOST_NAME = "somehostname";
     private static final String AGENT_ID = "xxx some agent";
 
-    private JsonHelper jsonHelper;
+    private JSONService jsonService;
 
     private ConfigurationInfoSource cfiSource;
     private NetworkInfoListDAOImpl.ConfigurationCreator configCreator;
@@ -83,8 +83,8 @@
         info.setIp4Addr(IPV4_ADDR);
         info.setIp6Addr(IPV6_ADDR);
         
-        jsonHelper = mock(JsonHelper.class);
-        when(jsonHelper.toJson(any(List.class))).thenReturn(SOME_JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(any(List.class))).thenReturn(SOME_JSON);
 
         cfiSource = mock(ConfigurationInfoSource.class);
         configCreator = mock(ConfigurationCreator.class);
@@ -100,7 +100,8 @@
     @Test
     public void testPut() throws Exception {
 
-        NetworkInfoListDAOImpl dao = new NetworkInfoListDAOImpl(jsonHelper, configCreator);
+        NetworkInfoListDAOImpl dao = new NetworkInfoListDAOImpl(configCreator);
+        dao.bindJsonService(jsonService);
         dao.bindSystemID(idservice);
         dao.bindConfigurationInfoSource(cfiSource);
         dao.bindHttpRequestService(httpRequestService);
--- a/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInfoListTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.network.model;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import org.junit.Test;
-
-public class NetworkInfoListTypeAdapterTest {
-
-    private static final String WRITER_ID = "some-agent-id";
-    private static final long TIMESTAMP = 333;
-
-    @Test
-    public void testWrite() throws Exception {
-        NetworkInfoListTypeAdapter adapter = new NetworkInfoListTypeAdapter();
-        final String expected = "[{\"agentId\":\"some-agent-id\",\"timeStamp\":{\"$numberLong\":\"333\"},\"interfaces\":[{\"interfaceName\":\"lo\",\"ip4Addr\":\"127.0.0.1\","
-                + "\"ip6Addr\":\"0:0:0:0:0:0:0:1%lo\"},{\"interfaceName\":\"if1\","
-                + "\"ip4Addr\":\"1.2.3.4\",\"ip6Addr\":\"1:2:3:4:5:6:7:8%if1\"}]}]";
-
-        NetworkInterfaceInfo first = createInfo("lo", "127.0.0.1", "0:0:0:0:0:0:0:1%lo");
-        NetworkInterfaceInfo second = createInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:8%if1");
-        NetworkInfoList infos = createNetworkInfoList(first, second);
-
-        String json = adapter.toJson(Arrays.asList(infos));
-        assertJsonEquals(expected, json);
-    }
-
-    private NetworkInfoList createNetworkInfoList(String iFace, String ip4Addr, String ip6Addr) {
-        NetworkInterfaceInfo info = new NetworkInterfaceInfo(iFace);
-        info.setIp4Addr(ip4Addr);
-        info.setIp6Addr(ip6Addr);
-        ArrayList<NetworkInterfaceInfo> list = new ArrayList<NetworkInterfaceInfo>(1);
-        list.add(info);
-        final NetworkInfoList ilist = new NetworkInfoList(WRITER_ID, TIMESTAMP, list);
-        return ilist;
-    }
-
-    private NetworkInfoList createNetworkInfoList(NetworkInterfaceInfo n1, NetworkInterfaceInfo n2) {
-        ArrayList<NetworkInterfaceInfo> list = new ArrayList<NetworkInterfaceInfo>(2);
-        list.add(n1);
-        list.add(n2);
-        final NetworkInfoList ilist = new NetworkInfoList(WRITER_ID, TIMESTAMP, list);
-        return ilist;
-    }
-
-    private NetworkInterfaceInfo createInfo(String iFace, String ip4Addr, String ip6Addr) {
-        NetworkInterfaceInfo info = new NetworkInterfaceInfo(iFace);
-        info.setIp4Addr(ip4Addr);
-        info.setIp6Addr(ip6Addr);
-        return info;
-    }
-}
--- a/plugins/host-network/agent/src/test/java/com/redhat/thermostat/host/network/model/NetworkInterfaceInfoTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.network.model;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.Test;
-
-public class NetworkInterfaceInfoTypeAdapterTest {
-    
-    @Test
-    public void testWrite() throws Exception {
-        NetworkInterfaceInfoTypeAdapter adapter = new NetworkInterfaceInfoTypeAdapter();
-        final String expected = "[{\"interfaceName\":\"lo\",\"ip4Addr\":\"127.0.0.1\","
-                + "\"ip6Addr\":\"0:0:0:0:0:0:0:1%lo\"},{\"interfaceName\":\"if1\","
-                + "\"ip4Addr\":\"1.2.3.4\",\"ip6Addr\":\"1:2:3:4:5:6:7:8%if1\"}]";
-        
-        NetworkInterfaceInfo first = createNetworkInterfaceInfo("lo", "127.0.0.1", "0:0:0:0:0:0:0:1%lo");
-        NetworkInterfaceInfo second = createNetworkInterfaceInfo("if1", "1.2.3.4", "1:2:3:4:5:6:7:8%if1");
-        List<NetworkInterfaceInfo> infos = Arrays.asList(first, second);
-        
-        String json = adapter.toJson(infos);
-        assertJsonEquals(expected, json);
-    }
-    
-    @Test
-    public void testRead() throws Exception {
-        NetworkInterfaceInfoTypeAdapter adapter = new NetworkInterfaceInfoTypeAdapter();
-        final String json = "{\"response\" : [{\"interfaceName\" : \"lo\", "
-                + "\"ip4Addr\" : \"127.0.0.1\", \"ip6Addr\" : \"0:0:0:0:0:0:0:1%lo\"}, "
-                + "{\"interfaceName\" : \"if1\", "
-                + "\"ip4Addr\" : \"1.2.3.4\", \"ip6Addr\" : null}], "
-                + "\"time\" : \"500000000\"}";
-        
-        List<NetworkInterfaceInfo> infos = adapter.fromJson(json);
-        assertEquals(2, infos.size());
-        
-        NetworkInterfaceInfo first = infos.get(0);
-        assertEquals("lo", first.getInterfaceName());
-        assertEquals("127.0.0.1", first.getIp4Addr());
-        assertEquals("0:0:0:0:0:0:0:1%lo", first.getIp6Addr());
-        
-        NetworkInterfaceInfo second = infos.get(1);
-        assertEquals("if1", second.getInterfaceName());
-        assertEquals("1.2.3.4", second.getIp4Addr());
-        assertNull(second.getIp6Addr());
-    }
-    
-    private NetworkInterfaceInfo createNetworkInterfaceInfo(String iFace, String ip4Addr, String ip6Addr) {
-        NetworkInterfaceInfo info = new NetworkInterfaceInfo(iFace);
-        info.setIp4Addr(ip4Addr);
-        info.setIp6Addr(ip6Addr);
-        info.setDisplayName(null);
-        return info;
-    }
-
-}
--- a/plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/internal/models/HostInfoDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/internal/models/HostInfoDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,12 +36,12 @@
 
 package com.redhat.thermostat.host.overview.internal.models;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -56,7 +56,6 @@
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.host.overview.model.HostInfo;
-import com.redhat.thermostat.host.overview.model.HostInfoTypeAdapter;
 
 @Component(
         policy = ConfigurationPolicy.REQUIRE,
@@ -69,8 +68,6 @@
     
     public static final String PLUGIN_ID = "host-overview";
 
-    private final JsonHelper jsonHelper;
-
     private final ConfigurationCreator configCreator;
 
     private BackendConfigurationUtil config;
@@ -82,14 +79,16 @@
     private HttpRequestService httpRequestService;
 
     @Reference
+    private JSONService jsonService;
+
+    @Reference
     private SystemID systemID;
 
     public HostInfoDAOImpl() {
-        this(new JsonHelper(new HostInfoTypeAdapter()), new ConfigurationCreator());
+        this(new ConfigurationCreator());
     }
 
-    HostInfoDAOImpl(JsonHelper jh, ConfigurationCreator creator) {
-        this.jsonHelper = jh;
+    HostInfoDAOImpl(ConfigurationCreator creator) {
         this.configCreator = creator;
     }
 
@@ -116,8 +115,9 @@
         return PLUGIN_ID;
     }
 
-    public Logger getLogger() {
-        return logger;
+    @Override
+    protected String serialise(HostInfo obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
@@ -126,22 +126,12 @@
     }
 
     @Override
-    protected String toJsonString(HostInfo obj) throws IOException {
-        return jsonHelper.toJson(Arrays.asList(obj));
-    }
-    
-    @Override
     protected BackendConfigurationUtil getConfig() {
     	return config;
     }
 
-    // DS bind method
-    protected void bindSystemID(SystemID systemid) {
-        this.systemID = systemid;
-    }
-
-    protected void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
-        this.configurationInfoSource = cfg;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
 
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
@@ -150,21 +140,21 @@
 
     protected void unbindHttpRequestService(HttpRequestService httpRequestService) {
         this.httpRequestService = null;
+        logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
+    }
+
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
     }
 
-    static class JsonHelper {
-        
-        private final HostInfoTypeAdapter typeAdapter;
-        
-        JsonHelper(HostInfoTypeAdapter typeAdapter) {
-            this.typeAdapter = typeAdapter;
-        }
-        
-        String toJson(List<HostInfo> infos) throws IOException {
-            return typeAdapter.toJson(infos);
-        }
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
     }
-    
+
+    protected Logger getLogger() {
+        return logger;
+    }
+
     // For Testing purposes
     static class ConfigurationCreator {
         
--- a/plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/model/HostInfo.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/model/HostInfo.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.host.overview.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -43,12 +44,25 @@
 @Entity
 public class HostInfo extends BasePojo {
 
+    @Schema
     private String hostname;
+
+    @Schema
     private String osName;
+
+    @Schema
     private String osKernel;
+
+    @Schema
     private String cpuModel;
+
+    @Schema
     private int cpuCount;
+
+    @Schema
     private long totalMemory;
+
+    @Schema
     private long timeStamp;
 
     public HostInfo() {
--- a/plugins/host-overview/agent/src/main/java/com/redhat/thermostat/host/overview/model/HostInfoTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.overview.model;
-
-import java.io.IOException;
-import java.util.List;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-
-public class HostInfoTypeAdapter extends TypeAdapter<List<HostInfo>> {
-    
-    private static final String AGENT_ID = "agentId";
-    private static final String HOSTNAME = "hostname";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String OS_NAME = "osName";
-    private static final String OS_KERNEL = "osKernel";
-    private static final String CPU_MODEL = "cpuModel";
-    private static final String CPU_COUNT = "cpuCount";
-    private static final String TOTAL_MEMORY = "totalMemory";
-    private static final String TYPE_LONG = "$numberLong";
-
-    @Override
-    public void write(JsonWriter out, List<HostInfo> value) throws IOException {
-        // Request is an array of HostInfo objects
-        out.beginArray();
-        
-        for (HostInfo info : value) {
-            writeHostInfo(out, info);
-        }
-        
-        out.endArray();
-    }
-
-    private void writeHostInfo(JsonWriter out, HostInfo info) throws IOException {
-        out.beginObject();
-        
-        // Write each field of HostInfo as part of a JSON object
-        out.name(AGENT_ID);
-        out.value(info.getAgentId());
-        out.name(HOSTNAME);
-        out.value(info.getHostname());
-        out.name(TIMESTAMP);
-        writeLong(out, info.getTimeStamp());
-        out.name(OS_NAME);
-        out.value(info.getOsName());
-        out.name(OS_KERNEL);
-        out.value(info.getOsKernel());
-        out.name(CPU_MODEL);
-        out.value(info.getCpuModel());
-        out.name(CPU_COUNT);
-        out.value(info.getCpuCount());
-        out.name(TOTAL_MEMORY);
-        writeLong(out, info.getTotalMemory());
-        
-        out.endObject();
-    }
-
-    private void writeLong(JsonWriter out, long totalMemory) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(totalMemory));
-        out.endObject();
-    }
-
-    @Override
-    public List<HostInfo> read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-}
--- a/plugins/host-overview/agent/src/test/java/com/redhat/thermostat/host/overview/internal/models/HostInfoDAOImplTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/host-overview/agent/src/test/java/com/redhat/thermostat/host/overview/internal/models/HostInfoDAOImplTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -44,6 +44,7 @@
 
 import java.net.URI;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -68,9 +69,9 @@
     private static final long MEMORY_TOTAL = 0xCAFEBABEl;
 
     private HostInfo info;
-    private HostInfoDAOImpl.JsonHelper jsonHelper;
     private ConfigurationInfoSource cfiSource;
     private ConfigurationCreator configCreator;
+    private JSONService jsonService;
     private SystemID idservice;
     private HttpRequestService httpRequestService;
     
@@ -79,8 +80,8 @@
         info = new HostInfo("foo-agent", TIMESTAMP, HOST_NAME, OS_NAME, OS_KERNEL, CPU_MODEL, CPU_NUM, MEMORY_TOTAL);
 
         httpRequestService = mock(HttpRequestService.class);
-        jsonHelper = mock(HostInfoDAOImpl.JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(HostInfo.class))).thenReturn(SOME_JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(HostInfo.class))).thenReturn(SOME_JSON);
 
         cfiSource = mock(ConfigurationInfoSource.class);
         configCreator = mock(ConfigurationCreator.class);
@@ -95,7 +96,8 @@
     @Test
     public void testPutHostInfo() throws Exception {
 
-        HostInfoDAOImpl dao = new HostInfoDAOImpl(jsonHelper, configCreator);
+        HostInfoDAOImpl dao = new HostInfoDAOImpl(configCreator);
+        dao.bindJsonService(jsonService);
         dao.bindSystemID(idservice);
         dao.bindConfigurationInfoSource(cfiSource);
         dao.bindHttpRequestService(httpRequestService);
--- a/plugins/host-overview/agent/src/test/java/com/redhat/thermostat/host/overview/model/HostInfoTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.host.overview.model;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class HostInfoTypeAdapterTest {
-    
-    private HostInfoTypeAdapter adapter;
-    
-    @Before
-    public void setup() {
-        adapter = new HostInfoTypeAdapter();
-    }
-
-    @Test
-    public void testWrite() throws Exception {
-        final String expected = "[{\"agentId\":\"myAgent1\",\"hostname\":\"myHost1\","
-                + "\"timeStamp\":{\"$numberLong\":\"111\"},"
-                + "\"osName\":\"myOS1\",\"osKernel\":\"myKernel1\",\"cpuModel\":\"myCPU1\"," 
-                + "\"cpuCount\":4,\"totalMemory\":{\"$numberLong\":\"400000000\"}}," 
-                + "{\"agentId\":\"myAgent2\",\"hostname\":\"myHost2\","
-                + "\"timeStamp\":{\"$numberLong\":\"222\"},"
-                + "\"osName\":\"myOS2\",\"osKernel\":\"myKernel2\",\"cpuModel\":\"myCPU2\",\"cpuCount\":2,"
-                + "\"totalMemory\":{\"$numberLong\":\"800000000\"}}]";
-        
-        HostInfo first = new HostInfo("myAgent1", 111, "myHost1", "myOS1", "myKernel1", "myCPU1", 4, 400000000L);
-        HostInfo second = new HostInfo("myAgent2", 222, "myHost2", "myOS2", "myKernel2", "myCPU2", 2, 800000000L);
-        List<HostInfo> infos = Arrays.asList(first, second);
-        
-        String json = adapter.toJson(infos);
-        assertJsonEquals(expected, json);
-    }
-
-}
--- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -35,16 +35,16 @@
  */
 
 package com.redhat.thermostat.jvm.overview.agent.internal.model;
-
-import java.io.IOException;
+;
 import java.net.URI;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.lang.schema.models.Timestamp;
+import com.sun.org.apache.bcel.internal.generic.RETURN;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -58,7 +58,8 @@
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoTypeAdapter.VmInfoUpdateTypeAdapter;
+import com.redhat.thermostat.lang.schema.JSONService;
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.jvm.overview.agent.model.VmId;
 import com.redhat.thermostat.jvm.overview.agent.model.VmInfo;
 import com.redhat.thermostat.storage.core.AgentId;
@@ -76,7 +77,6 @@
 
     private final Logger logger = LoggingUtils.getLogger(VmInfoDAOImpl.class);
 
-    private final JsonHelper jsonHelper;
     private final ConfigurationCreator configCreator;
 
     private URI gatewayURL;
@@ -88,14 +88,16 @@
     private HttpRequestService httpRequestService;
 
     @Reference
+    private JSONService jsonService;
+
+    @Reference
     private SystemID systemID;
 
     public VmInfoDAOImpl() throws Exception {
-        this(new JsonHelper(new VmInfoTypeAdapter(), new VmInfoUpdateTypeAdapter()), new ConfigurationCreator(), null);
+        this(new ConfigurationCreator(), null);
     }
 
-    VmInfoDAOImpl(JsonHelper jsonHelper, ConfigurationCreator creator, ConfigurationInfoSource source) throws Exception {
-        this.jsonHelper = jsonHelper;
+    VmInfoDAOImpl(ConfigurationCreator creator, ConfigurationInfoSource source) throws Exception {
         this.configCreator = creator;
         this.configInfoSource = source;
     }
@@ -130,10 +132,10 @@
     public void putVmInfo(final VmInfo info) {
         try {
             // Encode as JSON and send as POST request
-            String json = jsonHelper.toJson(Arrays.asList(info));
+            String json = jsonService.serialiase(Arrays.asList(info));
             URI uri = getAddURI();
             httpRequestService.sendHttpRequest(json, uri, HttpRequestService.Method.POST);
-        } catch (IOException | RequestFailedException e) {
+        } catch (RequestFailedException e) {
             logger.log(Level.WARNING, "Failed to send JVM information to web gateway");
             logger.log(Level.INFO, e.getMessage());
         }
@@ -144,11 +146,11 @@
         URI uri = getUpdateURI(vmId);
         try {
             // Encode as JSON and send as PUT request
-            VmInfoUpdate update = new VmInfoLongUpdate(timestamp);
-            String json = jsonHelper.toJson(update);
+            VmInfoTimestampUpdate update = new VmInfoTimestampUpdate(timestamp);
+            String json = jsonService.serialiase(update);
             httpRequestService.sendHttpRequest(json, uri, HttpRequestService.Method.PUT);
-        } catch (IOException | RequestFailedException e) {
-            logger.log(Level.WARNING, "Failed to send JVM information update to web gateway at: " + uri);
+        } catch (RequestFailedException e) {
+            logger.log(Level.WARNING, "Failed to send JVM stop update to web gateway at: " + uri);
             logger.log(Level.INFO, e.getMessage());
         }
     }
@@ -158,11 +160,11 @@
         URI uri = getUpdateURI(vmId);
         try {
             // Encode as JSON and send as PUT request
-            VmInfoUpdate update = new VmInfoStringArrayUpdate(newLibs);
-            String json = jsonHelper.toJson(update);
+            VmInfoNativeLibUpdate update = new VmInfoNativeLibUpdate(newLibs);
+            String json = jsonService.serialiase(update);
             httpRequestService.sendHttpRequest(json, uri, HttpRequestService.Method.PUT);
-        } catch (IOException | RequestFailedException e) {
-            logger.log(Level.WARNING, "Failed to send JVM information update to web gateway at: " + uri);
+        } catch (RequestFailedException e) {
+            logger.log(Level.WARNING, "Failed to send JVM native library update to web gateway at: " + uri);
             logger.log(Level.INFO, e.getMessage());
         }
     }
@@ -192,6 +194,10 @@
         logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
     }
 
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
+    }
+
     protected void bindSystemId(SystemID id) {
         this.systemID = id;
     }
@@ -200,52 +206,54 @@
         this.systemID = null;
     }
 
-    static abstract class VmInfoUpdate<T> {
+
+    static class VmInfoTimestampUpdate {
+
+        static class UpdateSet {
 
-        private final T param;
+            @Schema
+            long stopTime;
 
-        VmInfoUpdate(T param) {
-            this.param = param;
+            UpdateSet(long ts) {
+                stopTime = ts;
+            }
         }
 
-        T getParam() {
-            return param;
-        }
-    }
+        @Schema
+        UpdateSet set;
 
-    static class VmInfoLongUpdate extends VmInfoUpdate<Long>  {
+        VmInfoTimestampUpdate(long ts) {
+            this.set = new UpdateSet(ts);
+        }
 
-        public VmInfoLongUpdate(Long param) {
-            super(param);
+        long getStopTime() {
+            return set.stopTime;
         }
+
     }
 
-    static class VmInfoStringArrayUpdate extends VmInfoUpdate<String[]>  {
+    static class VmInfoNativeLibUpdate {
 
-        public VmInfoStringArrayUpdate(String[] param) {
-            super(param);
-        }
-    }
+        static class UpdateSet {
 
-    // For testing purposes
-    static class JsonHelper {
+            @Schema
+            private String[] loadedNativeLibraries;
 
-        private final VmInfoTypeAdapter typeAdapter;
-        private final VmInfoUpdateTypeAdapter updateTypeAdapter;
-
-        public JsonHelper(VmInfoTypeAdapter typeAdapter, VmInfoUpdateTypeAdapter updateTypeAdapter) {
-            this.typeAdapter = typeAdapter;
-            this.updateTypeAdapter = updateTypeAdapter;
+            UpdateSet(String[] param) {
+                loadedNativeLibraries = param;
+            }
         }
 
-        String toJson(List<VmInfo> infos) throws IOException {
-            return typeAdapter.toJson(infos);
+        @Schema
+        UpdateSet set;
+
+        VmInfoNativeLibUpdate(String[] param) {
+            set = new UpdateSet(param);
         }
 
-        String toJson(VmInfoUpdate<?> update) throws IOException {
-            return updateTypeAdapter.toJson(update);
+        String[] getLoadedNativeLibraries() {
+            return set.loadedNativeLibraries;
         }
-
     }
 
     // For Testing purposes
--- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.jvm.overview.agent.internal.model;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.VmInfoLongUpdate;
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.VmInfoStringArrayUpdate;
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.VmInfoUpdate;
-import com.redhat.thermostat.jvm.overview.agent.model.VmInfo;
-
-public class VmInfoTypeAdapter extends TypeAdapter<List<VmInfo>> {
-
-    private static final String AGENT_ID = "agentId";
-    private static final String JVM_ID = "jvmId";
-    private static final String JVM_PID = "jvmPid";
-    private static final String JAVA_VERSION = "javaVersion";
-    private static final String JAVA_HOME = "javaHome";
-    private static final String MAIN_CLASS = "mainClass";
-    private static final String JAVA_COMMAND_LINE = "javaCommandLine";
-    private static final String JVM_ARGUMENTS = "jvmArguments";
-    private static final String JVM_NAME = "jvmName";
-    private static final String JVM_INFO = "jvmInfo";
-    private static final String JVM_VERSION = "jvmVersion";
-    private static final String PROPERTIES_AS_ARRAY = "properties";
-    private static final String ENVIRONMENT_AS_ARRAY = "environment";
-    private static final String LOADED_NATIVE_LIBRARIES = "loadedNativeLibraries";
-    private static final String START_TIME_STAMP = "startTime";
-    private static final String STOP_TIME_STAMP = "stopTime";
-    private static final String UID = "uid";
-    private static final String USERNAME = "username";
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String KEY = "key";
-    private static final String VALUE = "value";
-
-    @Override
-    public void write(JsonWriter out, List<VmInfo> value) throws IOException {
-        // Request is an array of VmInfo objects
-        out.beginArray();
-
-        for (VmInfo info : value) {
-            writeVmInfo(out, info);
-        }
-
-        out.endArray();
-    }
-
-    private void writeVmInfo(JsonWriter out, VmInfo info) throws IOException {
-        out.beginObject();
-
-        // Write each field of VmInfo as part of a JSON object
-        out.name(AGENT_ID);
-        out.value(info.getAgentId());
-        out.name(JVM_ID);
-        out.value(info.getJvmId());
-        out.name(JVM_PID);
-        out.value(info.getJvmPid());
-        out.name(START_TIME_STAMP);
-        writeLong(out, info.getStartTimeStamp());
-        out.name(STOP_TIME_STAMP);
-        writeLong(out, info.getStopTimeStamp());
-        out.name(JAVA_VERSION);
-        out.value(info.getJavaVersion());
-        out.name(JAVA_HOME);
-        out.value(info.getJavaHome());
-        out.name(MAIN_CLASS);
-        out.value(info.getMainClass());
-        out.name(JAVA_COMMAND_LINE);
-        out.value(info.getJavaCommandLine());
-        out.name(JVM_NAME);
-        out.value(info.getJvmName());
-        out.name(JVM_ARGUMENTS);
-        out.value(info.getJvmArguments());
-        out.name(JVM_INFO);
-        out.value(info.getJvmInfo());
-        out.name(JVM_VERSION);
-        out.value(info.getJvmVersion());
-        out.name(PROPERTIES_AS_ARRAY);
-        writeStringMap(out, info.getProperties());
-        out.name(ENVIRONMENT_AS_ARRAY);
-        writeStringMap(out, info.getEnvironment());
-        out.name(LOADED_NATIVE_LIBRARIES);
-        writeStringArray(out, info.getLoadedNativeLibraries());
-        out.name(UID);
-        writeLong(out, info.getUid());
-        out.name(USERNAME);
-        out.value(info.getUsername());
-
-        out.endObject();
-    }
-
-    private void writeStringMap(JsonWriter out, Map<String, String> map) throws IOException {
-        // Write contents of Map as an array of JSON objects
-        out.beginArray();
-
-        Set<Entry<String, String>> entries = map.entrySet();
-        for (Map.Entry<String, String> entry : entries) {
-            // Create JSON object with key and value labeled as JSON names
-            out.beginObject();
-            out.name(KEY);
-            out.value(entry.getKey());
-            out.name(VALUE);
-            out.value(entry.getValue());
-            out.endObject();
-        }
-
-        out.endArray();
-    }
-
-    private static void writeStringArray(JsonWriter out, String[] array) throws IOException {
-        // Write String[] as JSON array
-        out.beginArray();
-
-        for (String item : array) {
-            out.value(item);
-        }
-
-        out.endArray();
-    }
-
-    private static void writeLong(JsonWriter out, long value) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(value));
-        out.endObject();
-    }
-
-    @Override
-    public List<VmInfo> read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    static class VmInfoUpdateTypeAdapter extends TypeAdapter<VmInfoUpdate> {
-
-        private static final String SET = "set";
-
-        @Override
-        public void write(JsonWriter out, VmInfoUpdate value) throws IOException {
-            // List fields to update as part of a JSON object with name "set"
-            out.beginObject();
-            out.name(SET);
-
-            out.beginObject();
-            if (value instanceof VmInfoLongUpdate) {
-                VmInfoLongUpdate castVal = (VmInfoLongUpdate) value;
-                out.name(STOP_TIME_STAMP);
-                writeLong(out, castVal.getParam());
-            } else if (value instanceof VmInfoStringArrayUpdate) {
-                VmInfoStringArrayUpdate castVal = (VmInfoStringArrayUpdate) value;
-                out.name(LOADED_NATIVE_LIBRARIES);
-                writeStringArray(out, castVal.getParam());
-            } else {
-                throw new IllegalArgumentException("illegal update data type");
-            }
-            out.endObject();
-
-            out.endObject();
-        }
-
-        @Override
-        public VmInfoUpdate read(JsonReader in) throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-    }
-
-}
--- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/VmInfo.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/VmInfo.java	Wed Oct 25 12:53:20 2017 -0400
@@ -40,6 +40,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.AgentInformation;
@@ -61,8 +62,11 @@
 
     @Entity
     public static class KeyValuePair implements Pojo {
-    
+
+        @Schema
         private String key;
+
+        @Schema
         private String value;
 
         public KeyValuePair() {
@@ -93,26 +97,61 @@
         public void setValue(String value) {
             this.value = value;
         }
-
-        
     }
 
+
+    @Schema
     private String jvmId;
+
+    @Schema
     private int jvmPid = 0;
+
+    @Schema
     private long startTime = System.currentTimeMillis();
+
+    @Schema
     private long stopTime = Long.MIN_VALUE;
+
+    @Schema
     private String javaVersion = "unknown";
+
+    @Schema
     private String javaHome = "unknown";
+
+    @Schema
     private String javaCommandLine = "unknown";
+
+    @Schema
     private String mainClass = "unknown";
+
+    @Schema
     private String jvmName = "unknown";
+
+    @Schema
     private String jvmInfo = "unknown";
+
+    @Schema
     private String jvmVersion = "unknown";
+
+    @Schema
     private String jvmArguments = "unknown";
+
+    @Schema
     private Map<String, String> properties = new HashMap<String, String>();
-    private Map<String, String> environment = new HashMap<String, String>();
+
+    private Map<String, String> environmentMap = new HashMap<String, String>();
+
+    // avoid sending environment names as JSON object names; some of them are illegal (on Windows)
+    @Schema(name = "environment")
+    private KeyValuePair[]  environment = new KeyValuePair[0];
+
+    @Schema
     private String[] loadedNativeLibraries;
+
+    @Schema
     private long uid;
+
+    @Schema
     private String username;
 
     public VmInfo() {
@@ -124,7 +163,7 @@
                   String javaVersion, String javaHome,
                   String mainClass, String commandLine,
                   String jvmName, String vmInfo, String vmVersion, String jvmArguments,
-                  Map<String, String> properties, Map<String, String> environment, String[] loadedNativeLibraries,
+                  Map<String, String> properties, Map<String, String> environmentMap, String[] loadedNativeLibraries,
                   long uid, String username) {
         super(writerId);
         this.jvmId = vmId;
@@ -140,7 +179,8 @@
         this.jvmVersion = vmVersion;
         this.jvmArguments = jvmArguments;
         this.properties = properties;
-        this.environment = environment;
+        this.environmentMap = environmentMap;
+        this.environment = getMapAsArray(environmentMap);
         this.loadedNativeLibraries = loadedNativeLibraries;
         this.uid = uid;
         this.username = username;
@@ -307,21 +347,23 @@
     }
 
     public Map<String, String> getEnvironment() {
-        return environment;
+        return environmentMap;
     }
 
-    public void setEnvironment(Map<String, String> environment) {
-        this.environment = environment;
+    public void setEnvironment(Map<String, String> environmentMap) {
+        this.environmentMap = environmentMap;
+        this.environment = getMapAsArray(environmentMap);
     }
 
     @Persist
     public KeyValuePair[] getEnvironmentAsArray() {
-        return getMapAsArray(environment);
+        return getMapAsArray(environmentMap);
     }
 
     @Persist
     public void setEnvironmentAsArray(KeyValuePair[] environment) {
-        this.environment = getArrayAsMap(environment);
+        this.environmentMap = getArrayAsMap(environment);
+        this.environment = environment;
     }
 
     private KeyValuePair[] getMapAsArray(Map<String, String> map) {
--- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/VmRef.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/VmRef.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,14 +36,22 @@
 
 package com.redhat.thermostat.jvm.overview.agent.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.Ref;
 
 public class VmRef implements Ref {
 
+    @Schema
     private final HostRef hostRef;
+
+    @Schema
     private final String id;
+
+    @Schema
     private final Integer pid;
+
+    @Schema
     private final String name;
 
     public VmRef(HostRef hostRef, String id, Integer pid, String name) {
--- a/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoDAOImplTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoDAOImplTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -37,8 +37,6 @@
 package com.redhat.thermostat.jvm.overview.agent.internal.model;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -49,6 +47,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -58,10 +57,13 @@
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.ConfigurationCreator;
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.JsonHelper;
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.VmInfoUpdate;
 import com.redhat.thermostat.jvm.overview.agent.model.VmInfo;
 
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
 public class VmInfoDAOImplTest {
 
     private static final URI GATEWAY_URI = URI.create("http://localhost:30000/jvms/0.0.1/");
@@ -71,7 +73,7 @@
     private static final String SOME_OTHER_JSON = "{\"some\" : {\"other\" : \"json\"}}";
 
     private VmInfo info;
-    private JsonHelper jsonHelper;
+    private JSONService jsonService;
     private HttpRequestService httpRequestService;
     private SystemID systemID;
     private ConfigurationCreator creator;
@@ -110,35 +112,48 @@
         when(systemID.getSystemID()).thenReturn("foo");
 
         httpRequestService = mock(HttpRequestService.class);
-        jsonHelper = mock(JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(VmInfo.class))).thenReturn(SOME_JSON);
-        when(jsonHelper.toJson(any(VmInfoUpdate.class))).thenReturn(SOME_OTHER_JSON);
+        jsonService = mock(JSONService.class);
+        //when(jsonService.serialiase(anyListOf(VmInfo.class))).thenReturn(SOME_JSON);
+        //when(jsonService.serialiase(any(VmInfoUpdate.class))).thenReturn(SOME_OTHER_JSON);
+
+        Mockito.doAnswer(new Answer<String>() {
+            @Override
+            public String answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                if (args[0] instanceof VmInfoDAOImpl.VmInfoNativeLibUpdate || args[0] instanceof VmInfoDAOImpl.VmInfoTimestampUpdate)
+                    return SOME_OTHER_JSON;
+                else
+                    return SOME_JSON;
+            }
+        }).when(jsonService).serialiase(Matchers.any());
     }
 
     @Test
     public void testPutVmInfo() throws Exception {
-        VmInfoDAOImpl dao = new VmInfoDAOImpl(jsonHelper, creator, source);
+        VmInfoDAOImpl dao = new VmInfoDAOImpl(creator, source);
+        dao.bindJsonService(jsonService);
         dao.bindSystemId(systemID);
         dao.bindHttpRequestService(httpRequestService);
         dao.activate();
         dao.putVmInfo(info);
 
-        verify(jsonHelper).toJson(eq(Arrays.asList(info)));
+        verify(jsonService).serialiase(eq(Arrays.asList(info)));
         verify(httpRequestService).sendHttpRequest(SOME_JSON, POST_URI, HttpRequestService.Method.POST);
     }
 
     @Test
     public void testPutVmStoppedTime() throws Exception {
-        VmInfoDAOImpl dao = new VmInfoDAOImpl(jsonHelper, creator, source);
+        VmInfoDAOImpl dao = new VmInfoDAOImpl(creator, source);
+        dao.bindJsonService(jsonService);
         dao.bindSystemId(systemID);
         dao.bindHttpRequestService(httpRequestService);
         dao.activate();
         dao.putVmStoppedTime("foo-agent", "vmId", 3L);
 
-        ArgumentCaptor<VmInfoUpdate> updateCaptor = ArgumentCaptor.forClass(VmInfoUpdate.class);
-        verify(jsonHelper).toJson(updateCaptor.capture());
-        VmInfoUpdate update = updateCaptor.getValue();
-        assertEquals(3L, update.getParam());
+        ArgumentCaptor<VmInfoDAOImpl.VmInfoTimestampUpdate> updateCaptor = ArgumentCaptor.forClass(VmInfoDAOImpl.VmInfoTimestampUpdate.class);
+        verify(jsonService).serialiase(updateCaptor.capture());
+        VmInfoDAOImpl.VmInfoTimestampUpdate update = updateCaptor.getValue();
+        assertEquals(3L, update.getStopTime());
 
         verify(httpRequestService).sendHttpRequest(SOME_OTHER_JSON, UPDATE_URI, HttpRequestService.Method.PUT);
     }
--- a/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmInfoTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.jvm.overview.agent.internal.model;
-
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.VmInfoLongUpdate;
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.VmInfoStringArrayUpdate;
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAOImpl.VmInfoUpdate;
-import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoTypeAdapter.VmInfoUpdateTypeAdapter;
-import com.redhat.thermostat.jvm.overview.agent.model.VmInfo;
-import org.junit.Test;
-
-public class VmInfoTypeAdapterTest {
-
-    @Test
-    public void testWrite() throws Exception {
-        VmInfoTypeAdapter adapter = new VmInfoTypeAdapter();
-        final String expected = "[{\"agentId\":\"agent1\",\"jvmId\":\"vm1\",\"jvmPid\":8000," +
-                "\"startTime\":{\"$numberLong\":\"50000\"},\"stopTime\":{\"$numberLong\":\"-9223372036854775808\"}," +
-                "\"javaVersion\":\"1.8.0\",\"javaHome\":\"/path/to/java\",\"mainClass\":\"myClass\"," +
-                "\"javaCommandLine\":\"java myClass\",\"jvmName\":\"myJVM\",\"jvmArguments\":\"-Dhello\",\"" +
-                "jvmInfo\":\"interesting\",\"jvmVersion\":\"1800\"," +
-                "\"properties\":[{\"key\":\"A\",\"value\":\"B\"},{\"key\":\"C\",\"value\":\"D\"}]," +
-                "\"environment\":[{\"key\":\"E\",\"value\":\"F\"},{\"key\":\"G\",\"value\":\"H\"}]," +
-                "\"loadedNativeLibraries\":[],\"uid\":{\"$numberLong\":\"1234\"},\"username\":\"test\"}," +
-                "{\"agentId\":\"agent2\",\"jvmId\":\"vm2\",\"jvmPid\":9000,\"startTime\":{\"$numberLong\":\"100000\"}," +
-                "\"stopTime\":{\"$numberLong\":\"200000\"},\"javaVersion\":\"1.7.0\",\"javaHome\":\"/path/to/jre\"," +
-                "\"mainClass\":\"myOtherClass\",\"javaCommandLine\":\"otherClass.sh\",\"jvmName\":\"myOtherJVM\"," +
-                "\"jvmArguments\":\"-Dworld\",\"jvmInfo\":\"info\",\"jvmVersion\":\"1700\",\"properties\":[]," +
-                "\"environment\":[{\"key\":\"A\",\"value\":\"B\"},{\"key\":\"C\",\"value\":\"D\"}]," +
-                "\"loadedNativeLibraries\":[\"libhello\",\"libworld\"],\"uid\":{\"$numberLong\":\"5678\"}," +
-                "\"username\":\"user\"}]";
-
-        final Map<String, String> props = new HashMap<>();
-        props.put("A", "B");
-        props.put("C", "D");
-        final Map<String, String> env = new HashMap<>();
-        env.put("E", "F");
-        env.put("G", "H");
-        VmInfo first = new VmInfo("agent1", "vm1", 8000, 50000L, Long.MIN_VALUE, "1.8.0", "/path/to/java", "myClass",
-                "java myClass", "myJVM", "interesting", "1800", "-Dhello", props, env, new String[0], 1234L, "test");
-
-        final Map<String, String> props2 = new HashMap<>();
-        final Map<String, String> env2 = new HashMap<>();
-        env2.put("A", "B");
-        env2.put("C", "D");
-        final String[] libs = { "libhello", "libworld" };
-        VmInfo second = new VmInfo("agent2", "vm2", 9000, 100000L, 200000L, "1.7.0", "/path/to/jre", "myOtherClass",
-                                   "otherClass.sh", "myOtherJVM", "info", "1700", "-Dworld", props2, env2, libs, 5678L, "user");
-        List<VmInfo> infos = Arrays.asList(first, second);
-
-        String json = adapter.toJson(infos);
-        assertJsonEquals(expected, json);
-    }
-
-    @Test
-    public void testUpdateLong() throws Exception {
-        VmInfoUpdateTypeAdapter adapter = new VmInfoUpdateTypeAdapter();
-        final String expected = "{\"set\":{\"stopTime\":{\"$numberLong\":\"5000\"}}}";
-
-        VmInfoUpdate update = new VmInfoLongUpdate(5000L);
-        String json = adapter.toJson(update);
-        assertJsonEquals(expected, json);
-    }
-
-    @Test
-    public void testUpdateStringArray() throws Exception {
-        VmInfoUpdateTypeAdapter adapter = new VmInfoUpdateTypeAdapter();
-        final String expected = "{\"set\":{\"loadedNativeLibraries\":[\"libupdate\",\"libthree\",\"libitems\"]}}";
-        String[] libs = new String[]{"libupdate", "libthree", "libitems"};
-        VmInfoUpdate update = new VmInfoStringArrayUpdate(libs);
-        String json = adapter.toJson(update);
-        assertJsonEquals(expected, json);
-    }
-
-}
--- a/plugins/jvm-overview/pom.xml.orig	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright 2012-2017 Red Hat, Inc.
-
- This file is part of Thermostat.
-
- Thermostat is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
- option) any later version.
-
- Thermostat is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Thermostat; see the file COPYING.  If not see
- <http://www.gnu.org/licenses/>.
-
- Linking this code with other modules is making a combined work
- based on this code.  Thus, the terms and conditions of the GNU
- General Public License cover the whole combination.
-
- As a special exception, the copyright holders of this code give
- you permission to link this code with independent modules to
- produce an executable, regardless of the license terms of these
- independent modules, and to copy and distribute the resulting
- executable under terms of your choice, provided that you also
- meet, for each linked independent module, the terms and conditions
- of the license of that module.  An independent module is a module
- which is not derived from or based on this code.  If you modify
- this code, you may extend this exception to your version of the
- library, but you are not obligated to do so.  If you do not wish
- to do so, delete this exception statement from your version.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>com.redhat.thermostat</groupId>
-    <artifactId>thermostat-plugins</artifactId>
-    <version>1.99.12-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>thermostat-host-overview</artifactId>
-  <packaging>pom</packaging>
-
-  <name>Thermostat Host Overview plugin</name>
-
-  <modules>
-    <module>agent</module>
-    <module>distribution</module>
-  </modules>
-
-</project>
-
--- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/BytemanMetric.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/BytemanMetric.java	Wed Oct 25 12:53:20 2017 -0400
@@ -42,6 +42,7 @@
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonSyntaxException;
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -54,10 +55,18 @@
     public static final String MARKER_NAME = "marker";
     public static final String TIMESTAMP_NAME = "timestamp";
     public static final String DATA_NAME = "data";
+
+    @Schema
     private String jvmId;
+
+    @Schema
     private String marker;
+
+    @Schema
     private String payload;
-    private long timestamp;
+
+    @Schema
+    private long timeStamp;
     
     public BytemanMetric(String writerId) {
         super(writerId);
@@ -95,13 +104,13 @@
 
     @Persist
     public void setTimeStamp(long timestamp) {
-        this.timestamp = timestamp;
+        this.timeStamp = timestamp;
     }
 
     @Persist
     @Override
     public long getTimeStamp() {
-        return timestamp;
+        return timeStamp;
     }
     
     @Persist
--- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanStatus.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanStatus.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.byteman.agent;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -44,9 +45,16 @@
 @Entity
 public class VmBytemanStatus extends BasePojo implements TimeStampedPojo {
 
+    @Schema
     private String jvmId;
+
+    @Schema
     private long timeStamp;
+
+    @Schema
     private String rule;
+
+    @Schema
     private int listenPort;
     
     public VmBytemanStatus(String writerId) {
--- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,12 +36,12 @@
 
 package com.redhat.thermostat.vm.byteman.agent.internal;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
 
-import com.google.gson.Gson;
 import com.redhat.thermostat.agent.http.HttpRequestService;
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
@@ -49,7 +49,6 @@
 import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
 import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
 import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
-import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.GsonCreator;
 
 @Component
 @Service(value = VmBytemanDAO.class)
@@ -58,12 +57,16 @@
     private static final String PLUGIN_ID = "vm-byteman";
 
     private final ConfigurationCreator configCreator;
-    private final GsonCreator gsonCreator;
+
+    @Reference
+    private ConfigurationInfoSource configInfoSource;
 
     @Reference
     private HttpRequestService httpRequestService;
+
     @Reference
-    private ConfigurationInfoSource configInfoSource;
+    private JSONService jsonService;
+
     @Reference
     private SystemID systemId;
 
@@ -72,20 +75,18 @@
     private VmBytemanStatusStore statusStore;
 
     public VmBytemanDAOImpl() {
-        this(new ConfigurationCreator(), new GsonCreator());
+        this(new ConfigurationCreator());
     }
 
-    VmBytemanDAOImpl(ConfigurationCreator configCreator, GsonCreator creator) {
+    VmBytemanDAOImpl(ConfigurationCreator configCreator) {
         this.configCreator = configCreator;
-        this.gsonCreator = creator;
     }
 
     @Activate
     private void activate() {
         BackendConfigurationUtil config = configCreator.create(configInfoSource);
-        Gson gson = gsonCreator.create();
-        metricsStore = new VmBytemanMetricsStore(httpRequestService, config, systemId, gson);
-        statusStore = new VmBytemanStatusStore(httpRequestService, config, systemId, gson);
+        metricsStore = new VmBytemanMetricsStore(httpRequestService, config, systemId, jsonService);
+        statusStore = new VmBytemanStatusStore(httpRequestService, config, systemId, jsonService);
     }
 
     @Override
@@ -104,7 +105,5 @@
         BackendConfigurationUtil create(ConfigurationInfoSource source) {
             return new BackendConfigurationUtil(source, PLUGIN_ID);
         }
-
     }
-
 }
--- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanMetricsStore.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanMetricsStore.java	Wed Oct 25 12:53:20 2017 -0400
@@ -48,6 +48,7 @@
 import com.redhat.thermostat.common.plugin.PluginDAOBase;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
 
 class VmBytemanMetricsStore extends PluginDAOBase<BytemanMetric> {
@@ -57,22 +58,16 @@
     private final HttpRequestService httpRequestService;
     private final BackendConfigurationUtil pluginConfig;
     private final SystemID systemId;
-    private final Gson gson;
+    private final JSONService jsonService;
 
     VmBytemanMetricsStore(HttpRequestService httpRequestService,
                           BackendConfigurationUtil pluginConfig,
                           SystemID systemId,
-                          Gson gson) {
+                          JSONService jsonService) {
         this.httpRequestService = httpRequestService;
         this.pluginConfig = pluginConfig;
         this.systemId = systemId;
-        this.gson = gson;
-    }
-
-    @Override
-    protected String toJsonString(BytemanMetric obj) throws IOException {
-        List<BytemanMetric> bytemanMetrics = Arrays.asList(obj);
-        return gson.toJson(bytemanMetrics);
+        this.jsonService = jsonService;
     }
 
     @Override
@@ -91,6 +86,11 @@
     }
 
     @Override
+    protected String serialise(BytemanMetric obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
+    }
+
+    @Override
     protected Logger getLogger() {
         return LOGGER;
     }
--- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanStatusStore.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanStatusStore.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,19 +36,17 @@
 
 package com.redhat.thermostat.vm.byteman.agent.internal;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.google.gson.Gson;
 import com.redhat.thermostat.agent.http.HttpRequestService;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.common.plugin.PluginDAOBase;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.lang.schema.JSONService;
+
 import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
 
 class VmBytemanStatusStore extends PluginDAOBase<VmBytemanStatus> {
@@ -58,22 +56,16 @@
     private final HttpRequestService httpRequestService;
     private final BackendConfigurationUtil pluginConfig;
     private final SystemID systemId;
-    private final Gson gson;
+    private final JSONService jsonService;
 
     VmBytemanStatusStore(HttpRequestService httpRequestService,
-                          BackendConfigurationUtil pluginConfig,
-                          SystemID systemId,
-                          Gson gson) {
+                         BackendConfigurationUtil pluginConfig,
+                         SystemID systemId,
+                         JSONService jsonService) {
         this.httpRequestService = httpRequestService;
         this.pluginConfig = pluginConfig;
         this.systemId = systemId;
-        this.gson = gson;
-    }
-
-    @Override
-    protected String toJsonString(VmBytemanStatus obj) throws IOException {
-        List<VmBytemanStatus> vmBytemanStatuses = Arrays.asList(obj);
-        return gson.toJson(vmBytemanStatuses);
+        this.jsonService = jsonService;
     }
 
     @Override
@@ -92,6 +84,11 @@
     }
 
     @Override
+    protected String serialise(VmBytemanStatus obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
+    }
+
+    @Override
     protected Logger getLogger() {
         return LOGGER;
     }
--- a/plugins/vm-classstat/agent/src/main/java/com/redhat/thermostat/vm/classstat/agent/internal/VmClassStatDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-classstat/agent/src/main/java/com/redhat/thermostat/vm/classstat/agent/internal/VmClassStatDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,10 +36,8 @@
 
 package com.redhat.thermostat.vm.classstat.agent.internal;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -49,8 +47,9 @@
 import com.redhat.thermostat.common.plugin.PluginDAOBase;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.classstat.model.VmClassStat;
-import com.redhat.thermostat.vm.classstat.model.VmClassStatTypeAdapter;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -70,9 +69,7 @@
 
     private static final String PLUGIN_ID = "vm-classstat";
 
-    private final JsonHelper jsonHelper;
     private final ConfigurationCreator configCreator;
-    private URI gatewayURL;
     private BackendConfigurationUtil config;
 
     @Reference
@@ -82,21 +79,22 @@
     private HttpRequestService httpRequestService;
 
     @Reference
+    private JSONService jsonService;
+
+    @Reference
     private SystemID systemID;
 
     public VmClassStatDAOImpl() {
-        this(new JsonHelper(new VmClassStatTypeAdapter()), new ConfigurationCreator());
+        this(new ConfigurationCreator());
     }
 
-    VmClassStatDAOImpl(JsonHelper jsonHelper, ConfigurationCreator creator) {
-        this.jsonHelper = jsonHelper;
+    VmClassStatDAOImpl(ConfigurationCreator creator) {
         this.configCreator = creator;
     }
 
     @Activate
     public void activate() throws Exception {
         config = configCreator.create(configurationInfoSource);
-        this.gatewayURL = config.getGatewayURL();
     }
 
     /*
@@ -110,8 +108,13 @@
     }
 
     @Override
-    protected String toJsonString(VmClassStat obj) throws IOException {
-        return jsonHelper.toJson(Arrays.asList(obj));
+    protected URI getPostURI(URI basepath, VmClassStat obj) {
+        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + obj.getJvmId());
+    }
+
+    @Override
+    protected String serialise(VmClassStat obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
@@ -124,26 +127,8 @@
         return config;
     }
 
-    @Override
-    protected URI getPostURI(URI basepath, VmClassStat obj) {
-        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + obj.getJvmId());
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return logger;
-    }
-
-    public String getPluginId() {
-        return PLUGIN_ID;
-    }
-
-    protected void bindSystemID(final SystemID id) {
-        this.systemID = id;
-    }
-
-    protected void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
-        this.configurationInfoSource = cfg;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
 
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
@@ -155,17 +140,16 @@
         logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
     }
 
-    // For testing purposes
-    static class JsonHelper {
-        private final VmClassStatTypeAdapter typeAdapter;
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
+    }
 
-        public JsonHelper(VmClassStatTypeAdapter typeAdapter) {
-            this.typeAdapter = typeAdapter;
-        }
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
 
-        public String toJson(List<VmClassStat> info) throws IOException {
-            return typeAdapter.toJson(info);
-        }
+    protected Logger getLogger() {
+        return logger;
     }
 
     // For Testing purposes
--- a/plugins/vm-classstat/agent/src/main/java/com/redhat/thermostat/vm/classstat/model/VmClassStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-classstat/agent/src/main/java/com/redhat/thermostat/vm/classstat/model/VmClassStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.classstat.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.model.BasePojo;
 import com.redhat.thermostat.storage.model.TimeStampedPojo;
@@ -49,12 +50,25 @@
 
     public static final int UNKNOWN = -1;
 
+    @Schema
     private String jvmId;
+
+    @Schema
     private long timestamp;
+
+    @Schema
     private long loadedClasses;
+
+    @Schema
     private long loadedBytes;
+
+    @Schema
     private long unloadedClasses;
+
+    @Schema
     private long unloadedBytes;
+
+    @Schema
     private long classLoadTime;
 
     public VmClassStat() {
--- a/plugins/vm-classstat/agent/src/main/java/com/redhat/thermostat/vm/classstat/model/VmClassStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.classstat.model;
-
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-
-import com.google.gson.TypeAdapter;
-
-import java.io.IOException;
-import java.util.List;
-
-public class VmClassStatTypeAdapter extends TypeAdapter<List<VmClassStat>> {
-
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String JVM_ID = "jvmId";
-    private static final String AGENT_ID = "agentId";
-    private static final String LOADED_CLASSES = "loadedClasses";
-    private static final String LOADED_BYTES = "loadedBytes";
-    private static final String UNLOADED_CLASSES = "unloadedClasses";
-    private static final String UNLOADED_BYTES = "unloadedBytes";
-    private static final String CLASS_LOAD_TIME = "classLoadTime";
-    private static final String TIMESTAMP = "timeStamp";
-
-    @Override
-    public List<VmClassStat> read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void write(JsonWriter out, List<VmClassStat> stats) throws IOException {
-        out.beginArray();
-        for (VmClassStat stat : stats) {
-            write(out, stat);
-        }
-        out.endArray();
-    }
-
-    private void write(JsonWriter out, VmClassStat stat) throws IOException {
-        out.beginObject();
-        out.name(JVM_ID);
-        out.value(stat.getJvmId());
-        out.name(AGENT_ID);
-        out.value(stat.getAgentId());
-        out.name(LOADED_CLASSES);
-        writeLong(out, stat.getLoadedClasses());
-        out.name(LOADED_BYTES);
-        writeLong(out, stat.getLoadedBytes());
-        out.name(UNLOADED_CLASSES);
-        writeLong(out, stat.getUnloadedClasses());
-        out.name(UNLOADED_BYTES);
-        writeLong(out, stat.getUnloadedBytes());
-        out.name(CLASS_LOAD_TIME);
-        writeLong(out, stat.getClassLoadTime());
-        out.name(TIMESTAMP);
-        writeLong(out, stat.getTimeStamp());
-        out.endObject();
-    }
-
-    private void writeLong(JsonWriter out, long timestamp) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(timestamp));
-        out.endObject();
-    }
-}
--- a/plugins/vm-classstat/agent/src/test/java/com/redhat/thermostat/vm/classstat/agent/internal/VmClassStatDAOTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-classstat/agent/src/test/java/com/redhat/thermostat/vm/classstat/agent/internal/VmClassStatDAOTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,7 +36,6 @@
 
 package com.redhat.thermostat.vm.classstat.agent.internal;
 
-
 import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
@@ -52,6 +51,7 @@
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.classstat.model.VmClassStat;
 
 import org.junit.Before;
@@ -79,7 +79,7 @@
     }
 
     private VmClassStat classStat;
-    private VmClassStatDAOImpl.JsonHelper jsonHelper;
+    private JSONService jsonService;
     private VmClassStatDAOImpl dao;
     private HttpRequestService httpRequestService;
 
@@ -95,8 +95,8 @@
                 CLASS_LOAD_TIME
         );
 
-        jsonHelper = mock(VmClassStatDAOImpl.JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(VmClassStat.class))).thenReturn(JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(VmClassStat.class))).thenReturn(JSON);
 
         ConfigurationInfoSource source = mock(ConfigurationInfoSource.class);
         BackendConfigurationUtil config = mock(BackendConfigurationUtil.class);
@@ -105,7 +105,8 @@
         when(creator.create(source)).thenReturn(config);
 
         httpRequestService = mock(HttpRequestService.class);
-        dao = new VmClassStatDAOImpl(jsonHelper, creator);
+        dao = new VmClassStatDAOImpl(creator);
+        dao.bindJsonService(jsonService);
         dao.bindHttpRequestService(httpRequestService);
         dao.bindConfigurationInfoSource(source);
     }
@@ -118,7 +119,7 @@
         dao.activate();
         dao.put(classStat);
 
-        verify(jsonHelper).toJson(eq(Arrays.asList(classStat)));
+        verify(jsonService).serialiase(eq(Arrays.asList(classStat)));
         String s = verify(httpRequestService).sendHttpRequest(JSON, GATEWAY_URI.resolve("systems/" + SOME_SYSTEM_ID + "/jvms/" + VM_ID), HttpRequestService.Method.POST);
     }
 }
--- a/plugins/vm-classstat/agent/src/test/java/com/redhat/thermostat/vm/classstat/model/VmClassStatTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.classstat.model;
-
-import com.google.gson.GsonBuilder;
-import com.google.gson.Gson;
-import org.junit.Test;
-
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-public class VmClassStatTypeAdapterTest {
-
-}
--- a/plugins/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatDaoImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatDaoImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,10 +36,8 @@
 
 package com.redhat.thermostat.vm.compiler.agent.internal;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -56,8 +54,8 @@
 import com.redhat.thermostat.common.plugin.PluginDAOBase;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.compiler.model.VmCompilerStat;
-import com.redhat.thermostat.vm.compiler.model.VmCompilerStatTypeAdapter;
 
 @Component(
         policy = ConfigurationPolicy.REQUIRE,
@@ -69,9 +67,7 @@
     private static final Logger logger = LoggingUtils.getLogger(VmCompilerStatDaoImpl.class);
     private static final String PLUGIN_ID = "vm-compiler";
 
-    private final JsonHelper jsonHelper;
     private final ConfigurationCreator configCreator;
-    private URI gatewayURL;
     private BackendConfigurationUtil config;
 
     @Reference
@@ -81,21 +77,22 @@
     private HttpRequestService httpRequestService;
 
     @Reference
+    private JSONService jsonService;
+
+    @Reference
     private SystemID systemID;
 
     public VmCompilerStatDaoImpl() {
-        this(new JsonHelper(new VmCompilerStatTypeAdapter()), new ConfigurationCreator());
+        this(new ConfigurationCreator());
     }
 
-    VmCompilerStatDaoImpl(JsonHelper jsonHelper, ConfigurationCreator creator) {
-        this.jsonHelper = jsonHelper;
+    VmCompilerStatDaoImpl(ConfigurationCreator creator) {
         this.configCreator = creator;
     }
 
     @Activate
     public void activate() throws Exception {
         config = configCreator.create(configurationInfoSource);
-        this.gatewayURL = config.getGatewayURL();
     }
 
 
@@ -110,8 +107,13 @@
     }
 
     @Override
-    protected String toJsonString(VmCompilerStat obj) throws IOException {
-        return jsonHelper.toJson(Arrays.asList(obj));
+    protected URI getPostURI(URI basepath, VmCompilerStat obj) {
+        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + obj.getJvmId());
+    }
+
+    @Override
+    protected String serialise(VmCompilerStat obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
@@ -124,26 +126,8 @@
         return config;
     }
 
-    @Override
-    protected URI getPostURI(URI basepath, VmCompilerStat obj) {
-        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + obj.getJvmId());
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return logger;
-    }
-
-    public String getPluginId() {
-        return PLUGIN_ID;
-    }
-
-    protected void bindSystemID(final SystemID id) {
-        this.systemID = id;
-    }
-
-    protected void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
-        this.configurationInfoSource = cfg;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
 
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
@@ -155,17 +139,16 @@
         logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
     }
 
-    // For testing purposes
-    static class JsonHelper {
-        private final VmCompilerStatTypeAdapter typeAdapter;
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
+    }
 
-        public JsonHelper(VmCompilerStatTypeAdapter typeAdapter) {
-            this.typeAdapter = typeAdapter;
-        }
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
 
-        public String toJson(List<VmCompilerStat> info) throws IOException {
-            return typeAdapter.toJson(info);
-        }
+    protected Logger getLogger() {
+        return logger;
     }
 
     // For Testing purposes
--- a/plugins/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/model/VmCompilerStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/model/VmCompilerStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.compiler.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.model.BasePojo;
 import com.redhat.thermostat.storage.model.TimeStampedPojo;
@@ -49,11 +50,19 @@
 
     public static final int UNKNOWN = -1;
 
+    @Schema
     private String jvmId;
+
+    @Schema
     private long timestamp;
 
+    @Schema
     private long totalCompiles;
+
+    @Schema
     private long totalBailouts;
+
+    @Schema
     private long totalInvalidates;
 
     /**
@@ -62,30 +71,36 @@
      * implementation referring to ComplilationMXBean which mentions the
      * return value is in milliseconds.
      */
+    @Schema
     private long compilationTime;
 
+    @Schema
     private long lastSize;
 
     /**
      * From hotspot code, this is an enum with the values:
      * { no_compile, normal_compile, osr_compile, native_compile }
      */
+    @Schema
     private long lastType;
 
     /**
      *  is of the form "name/of/package/Class$InnerClass methodName"
      */
+    @Schema
     private String lastMethod;
 
     /**
      * From hotspot code, this is an enum with the values:
      * { no_compile, normal_compile, osr_compile, native_compile }
      */
+    @Schema
     private long lastFailedType;
 
     /**
      *  is of the form "name/of/package/Class$InnerClass methodName"
      */
+    @Schema
     private String lastFailedMethod;
 
     public VmCompilerStat(String writerId, String vmId, long timestamp, long totalCompiles, long totalBailouts,
--- a/plugins/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/model/VmCompilerStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.compiler.model;
-
-import java.io.IOException;
-import java.util.List;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-
-public class VmCompilerStatTypeAdapter extends TypeAdapter<List<VmCompilerStat>> {
-
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String AGENT_ID = "agentId";
-    private static final String JVM_ID = "jvmId";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String TOTAL_COMPILES = "totalCompiles";
-    private static final String TOTAL_BAILOUTS = "totalBailouts";
-    private static final String TOTAL_INVALIDATES = "totalInvalidates";
-    private static final String COMPILATION_TIME = "compilationTime";
-    private static final String LAST_SIZE = "lastSize";
-    private static final String LAST_TYPE = "lastType";
-    private static final String LAST_METHOD = "lastMethod";
-    private static final String LAST_FAILED_TYPE = "lastFailedType";
-    private static final String LAST_FAILED_METHOD = "lastFailedMethod";
-
-
-    @Override
-    public List<VmCompilerStat> read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void write(JsonWriter out, List<VmCompilerStat> stats) throws IOException {
-        out.beginArray();
-        for (VmCompilerStat stat : stats) {
-            writeCompilerStat(out, stat);
-        }
-        out.endArray();
-    }
-
-    public void writeCompilerStat(JsonWriter out, VmCompilerStat stat) throws IOException {
-        out.beginObject();
-        out.name(AGENT_ID);
-        out.value(stat.getAgentId());
-        out.name(JVM_ID);
-        out.value(stat.getJvmId());
-        out.name(TIMESTAMP);
-        writeLong(out, stat.getTimeStamp());
-        out.name(TOTAL_COMPILES);
-        writeLong(out, stat.getTotalCompiles());
-        out.name(TOTAL_BAILOUTS);
-        writeLong(out, stat.getTotalBailouts());
-        out.name(TOTAL_INVALIDATES);
-        writeLong(out, stat.getTotalInvalidates());
-        out.name(COMPILATION_TIME);
-        writeLong(out, stat.getCompilationTime());
-        out.name(LAST_SIZE);
-        writeLong(out, stat.getLastSize());
-        out.name(LAST_TYPE);
-        writeLong(out, stat.getLastType());
-        out.name(LAST_METHOD);
-        out.value(stat.getLastMethod());
-        out.name(LAST_FAILED_TYPE);
-        writeLong(out, stat.getLastFailedType());
-        out.name(LAST_FAILED_METHOD);
-        out.value(stat.getLastFailedMethod());
-        out.endObject();
-    }
-
-
-    private void writeLong(JsonWriter out, long value) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(value));
-        out.endObject();
-    }
-}
--- a/plugins/vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatDaoImplTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatDaoImplTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -53,6 +53,7 @@
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.compiler.model.VmCompilerStat;
 
 public class VmCompilerStatDaoImplTest {
@@ -81,7 +82,7 @@
     }
 
     private VmCompilerStat compilerStat;
-    private VmCompilerStatDaoImpl.JsonHelper jsonHelper;
+    private JSONService jsonService;
     private VmCompilerStatDaoImpl dao;
     private HttpRequestService httpRequestService;
 
@@ -101,8 +102,8 @@
                 LAST_FAILED_METHOD
         );
 
-        jsonHelper = mock(VmCompilerStatDaoImpl.JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(VmCompilerStat.class))).thenReturn(JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(VmCompilerStat.class))).thenReturn(JSON);
 
         ConfigurationInfoSource source = mock(ConfigurationInfoSource.class);
         BackendConfigurationUtil config = mock(BackendConfigurationUtil.class);
@@ -111,9 +112,10 @@
         when(creator.create(source)).thenReturn(config);
 
         httpRequestService = mock(HttpRequestService.class);
-        dao = new VmCompilerStatDaoImpl(jsonHelper, creator);
+        dao = new VmCompilerStatDaoImpl(creator);
         dao.bindHttpRequestService(httpRequestService);
         dao.bindConfigurationInfoSource(source);
+        dao.bindJsonService(jsonService);
     }
 
     @Test
@@ -124,7 +126,7 @@
         dao.activate();
         dao.put(compilerStat);
 
-        verify(jsonHelper).toJson(eq(Arrays.asList(compilerStat)));
+        verify(jsonService).serialiase(eq(Arrays.asList(compilerStat)));
         String s = verify(httpRequestService).sendHttpRequest(JSON, GATEWAY_URI.resolve("systems/" + SOME_SYSTEM_ID + "/jvms/" + SOME_VM_ID), HttpRequestService.Method.POST);
     }
 }
--- a/plugins/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,10 +36,9 @@
 
 package com.redhat.thermostat.vm.cpu.agent.internal;
 
-import java.io.IOException;
 import java.net.URI;
-import java.util.Collections;
-import java.util.List;
+import java.util.Arrays;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import com.redhat.thermostat.agent.http.HttpRequestService;
@@ -48,8 +47,9 @@
 import com.redhat.thermostat.common.plugin.PluginDAOBase;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.cpu.agent.model.VmCpuStat;
-import com.redhat.thermostat.vm.cpu.agent.model.VmCpuStatTypeAdapter;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -71,21 +71,22 @@
     private ConfigurationInfoSource configurationInfoSource;
 
     @Reference
-    private SystemID systemID;
+    private HttpRequestService httpRequestService;
 
     @Reference
-    private HttpRequestService httpRequestService;
+    private JSONService jsonService;
 
-    private final JsonHelper jsonHelper;
+    @Reference
+    private SystemID systemID;
+
     private final ConfigurationCreator configurationCreator;
     private BackendConfigurationUtil pluginConfiguration;
 
     public VmCpuStatDAOImpl() {
-        this(new JsonHelper(new VmCpuStatTypeAdapter()), new ConfigurationCreator());
+        this(new ConfigurationCreator());
     }
 
-    VmCpuStatDAOImpl(JsonHelper jsonHelper, ConfigurationCreator configurationCreator) {
-        this.jsonHelper = jsonHelper;
+    VmCpuStatDAOImpl(ConfigurationCreator configurationCreator) {
         this.configurationCreator = configurationCreator;
     }
 
@@ -93,6 +94,10 @@
     public void activate() throws Exception {
         pluginConfiguration = configurationCreator.create(configurationInfoSource);
     }
+    @Override
+    protected URI getPostURI(URI basepath, VmCpuStat vmCpuStat) {
+        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + vmCpuStat.getJvmId());
+    }
 
 
     /*
@@ -106,8 +111,8 @@
     }
 
     @Override
-    protected String toJsonString(VmCpuStat obj) throws IOException {
-        return jsonHelper.toJson(Collections.singletonList(obj));
+    protected String serialise(VmCpuStat obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
@@ -120,42 +125,29 @@
         return pluginConfiguration;
     }
 
-    @Override
-    protected URI getPostURI(URI basepath, VmCpuStat vmCpuStat) {
-        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + vmCpuStat.getVmId());
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return logger;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
 
-    // DS bind method.
-    protected void bindSystemID(SystemID systemid) {
-        this.systemID = systemid;
-    }
-
-    // DS bind method.
-    protected void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
-        this.configurationInfoSource = cfg;
-    }
-
-    // DS bind method.
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
         this.httpRequestService = httpRequestService;
     }
 
-    // For testing.
-    static class JsonHelper {
-        private final VmCpuStatTypeAdapter typeAdapter;
+    protected void unbindHttpRequestService(HttpRequestService httpRequestService) {
+        this.httpRequestService = null;
+        logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
+    }
 
-        JsonHelper(VmCpuStatTypeAdapter typeAdapter) {
-            this.typeAdapter = typeAdapter;
-        }
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
+    }
 
-        String toJson(List<VmCpuStat> infos) throws IOException {
-            return typeAdapter.toJson(infos);
-        }
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
+
+    protected Logger getLogger() {
+        return logger;
     }
 
     // For testing.
--- a/plugins/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/model/VmCpuStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/model/VmCpuStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.cpu.agent.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -44,18 +45,23 @@
 @Entity
 public class VmCpuStat extends BasePojo implements TimeStampedPojo {
 
+    @Schema
     private long timeStamp;
-    private String vmId;
+
+    @Schema
+    private String jvmId;
+
+    @Schema
     private double cpuLoad;
 
     public VmCpuStat() {
         super(null);
     }
 
-    public VmCpuStat(String writerId, long timeStamp, String vmId, double cpuLoad) {
+    public VmCpuStat(String writerId, long timeStamp, String jvmId, double cpuLoad) {
         super(writerId);
         this.timeStamp = timeStamp;
-        this.vmId = vmId;
+        this.jvmId = jvmId;
         this.cpuLoad = cpuLoad;
     }
 
@@ -71,13 +77,13 @@
     }
 
     @Persist
-    public String getVmId() {
-        return vmId;
+    public String getJvmId() {
+        return jvmId;
     }
 
     @Persist
-    public void setVmId(String vmId) {
-        this.vmId = vmId;
+    public void setJvmId(String jvmId) {
+        this.jvmId = jvmId;
     }
 
     /**
--- a/plugins/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/model/VmCpuStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.cpu.agent.model;
-
-import java.io.IOException;
-import java.util.List;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-
-public class VmCpuStatTypeAdapter extends TypeAdapter<List<VmCpuStat>> {
-
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String VM_ID = "jvmId";
-    private static final String CPU_LOAD = "cpuLoad";
-    private static final String AGENT_ID = "agentId";
-
-    private void writeMemoryStat(JsonWriter out, VmCpuStat stat) throws IOException {
-        out.beginObject();
-        out.name(TIMESTAMP);
-        writeLong(out, stat.getTimeStamp());
-        out.name(VM_ID);
-        out.value(stat.getVmId());
-        out.name(CPU_LOAD);
-        out.value(stat.getCpuLoad());
-        out.name(AGENT_ID);
-        out.value(stat.getAgentId());
-        out.endObject();
-    }
-
-    private void writeLong(JsonWriter out, long input) throws IOException {
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(input));
-        out.endObject();
-    }
-
-    @Override
-    public void write(JsonWriter jsonWriter, List<VmCpuStat> vmCpuStats) throws IOException {
-        jsonWriter.beginArray();
-        for (VmCpuStat stat : vmCpuStats) {
-            writeMemoryStat(jsonWriter, stat);
-        }
-        jsonWriter.endArray();
-    }
-
-    @Override
-    public List<VmCpuStat> read(JsonReader jsonReader) throws IOException {
-        return null;
-    }
-}
--- a/plugins/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatBuilderTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatBuilderTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -149,7 +149,7 @@
         VmCpuStat stat = builder.build(VM_ID, PID);
 
         assertNotNull(stat);
-        assertEquals(VM_ID, stat.getVmId());
+        assertEquals(VM_ID, stat.getJvmId());
         assertEquals(CLOCK2, stat.getTimeStamp());
         assertEquals(CPU_LOAD_PERCENT, stat.getCpuLoad(), 0.0001);
     }
--- a/plugins/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatDAOImplTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuStatDAOImplTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -37,7 +37,7 @@
 package com.redhat.thermostat.vm.cpu.agent.internal;
 
 import static com.redhat.thermostat.vm.cpu.agent.internal.VmCpuStatDAOImpl.ConfigurationCreator;
-import static com.redhat.thermostat.vm.cpu.agent.internal.VmCpuStatDAOImpl.JsonHelper;
+
 import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
@@ -51,6 +51,7 @@
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.cpu.agent.model.VmCpuStat;
 import org.junit.Before;
 import org.junit.Test;
@@ -61,10 +62,10 @@
     private static final String JSON = "{\"this\":\"is\",\"also\":\"JSON\"}";
     private static final URI GATEWAY_URI = URI.create("http://example.com/jvm-cpu/");
     private static final String SYSTEM_ID = "1234";
-    public static final String JVM_ID = "vm-123";
+    private static final String JVM_ID = "vm-123";
 
     private VmCpuStat stat;
-    private JsonHelper jsonHelper;
+    private JSONService jsonService;
     private VmCpuStatDAOImpl dao;
 
     private HttpRequestService httpRequestService;
@@ -75,10 +76,10 @@
         stat.setAgentId(AGENT_ID);
         stat.setTimeStamp(1234L);
         stat.setCpuLoad(42.0);
-        stat.setVmId(JVM_ID);
+        stat.setJvmId(JVM_ID);
 
-        jsonHelper = mock(JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(VmCpuStat.class))).thenReturn(JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(VmCpuStat.class))).thenReturn(JSON);
 
         ConfigurationInfoSource source = mock(ConfigurationInfoSource.class);
         BackendConfigurationUtil config = mock(BackendConfigurationUtil.class);
@@ -89,7 +90,8 @@
         when(systemID.getSystemID()).thenReturn(SYSTEM_ID);
 
         httpRequestService = mock(HttpRequestService.class);
-        dao = new VmCpuStatDAOImpl(jsonHelper, creator);
+        dao = new VmCpuStatDAOImpl(creator);
+        dao.bindJsonService(jsonService);
         dao.bindHttpRequestService(httpRequestService);
         dao.bindConfigurationInfoSource(source);
         dao.bindSystemID(systemID);
@@ -99,7 +101,7 @@
     public void verifyAddVmCpuStat() throws Exception {
         dao.activate();
         dao.put(stat);
-        verify(jsonHelper).toJson(eq(Collections.singletonList(stat)));
+        verify(jsonService).serialiase(eq(Collections.singletonList(stat)));
         verify(httpRequestService).sendHttpRequest(JSON, GATEWAY_URI.resolve("systems/" + SYSTEM_ID + "/jvms/" + JVM_ID), HttpRequestService.Method.POST);
     }
 }
--- a/plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,14 +36,11 @@
 
 package com.redhat.thermostat.vm.gc.agent.internal.models;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.redhat.thermostat.common.plugin.SystemID;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -51,6 +48,8 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
 
+import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.agent.http.HttpRequestService;
 import com.redhat.thermostat.agent.http.RequestFailedException;
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
@@ -67,26 +66,27 @@
     
     private static final Logger logger = LoggingUtils.getLogger(VmGcStatDAOImpl.class);
     private static final String PLUGIN_ID = "vm-gc";
-    
-    private final JsonHelper jsonHelper;
+
     private final ConfigurationCreator configCreator;
-    
+    private URI gatewayURL;
+
     @Reference
     private ConfigurationInfoSource configInfoSource;
-    private URI gatewayURL;
 
     @Reference
     private HttpRequestService httpRequestService;
 
     @Reference
+    private JSONService jsonService;
+
+    @Reference
     private SystemID systemID;
 
     public VmGcStatDAOImpl() {
-        this(new JsonHelper(new VmGcStatTypeAdapter()), new ConfigurationCreator(), null);
+        this(new ConfigurationCreator(), null);
     }
 
-    VmGcStatDAOImpl(JsonHelper jh, ConfigurationCreator creator, ConfigurationInfoSource source) {
-        this.jsonHelper = jh;
+    VmGcStatDAOImpl(ConfigurationCreator creator, ConfigurationInfoSource source) {
         this.configCreator = creator;
         this.configInfoSource = source;
     }
@@ -107,6 +107,11 @@
         logger.config("Doing nothing on configuration change for plugin " + PLUGIN_ID);
     }
 
+    // DS bind method - for testing
+    public void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
+    }
+
     void bindSystemID(final SystemID id) {
         this.systemID = id;
     }
@@ -127,29 +132,14 @@
     @Override
     public void putVmGcStat(final VmGcStat stat) {
         try {
-            String json = jsonHelper.toJson(Arrays.asList(stat));
+            String json = jsonService.serialiase(Arrays.asList(stat));
             httpRequestService.sendHttpRequest(json, getPostURI(stat.getJvmId()), HttpRequestService.Method.POST);
-        } catch (RequestFailedException | IOException e) {
+        } catch (RequestFailedException e) {
             logger.log(Level.WARNING, "Failed to send VmGcStat information to web gateway", e);
         }
     }
 
     // For Testing purposes
-    static class JsonHelper {
-
-        private final VmGcStatTypeAdapter adapter;
-
-        public JsonHelper(VmGcStatTypeAdapter adapter) {
-            this.adapter = adapter;
-        }
-
-        public String toJson(List<VmGcStat> list) throws IOException {
-            return adapter.toJson(list);
-        }
-
-    }
-
-    // For Testing purposes
     static class ConfigurationCreator {
         
         BackendConfigurationUtil create(ConfigurationInfoSource source) {
--- a/plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.gc.agent.internal.models;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.redhat.thermostat.vm.gc.agent.model.VmGcStat;
-
-import java.io.IOException;
-import java.util.List;
-
-public class VmGcStatTypeAdapter extends TypeAdapter<List<VmGcStat>> {
-
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String AGENT_ID = "agentId";
-    private static final String JVM_ID = "jvmId";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String COLLECTOR_NAME = "collectorName";
-    private static final String RUN_COUNT = "runCount";
-    private static final String WALL_TIME_IN_MICROS = "wallTimeInMicros";
-
-    @Override
-    public List<VmGcStat> read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void write(JsonWriter out, List<VmGcStat> stats) throws IOException {
-        out.beginArray();
-        for (VmGcStat stat : stats) {
-            writeGcStat(out, stat);
-        }
-        out.endArray();
-    }
-    
-    private void writeGcStat(JsonWriter out, VmGcStat stat) throws IOException {
-        out.beginObject();
-        out.name(AGENT_ID);
-        out.value(stat.getAgentId());
-        out.name(JVM_ID);
-        out.value(stat.getJvmId());
-        out.name(TIMESTAMP);
-        writeLong(out, stat.getTimeStamp());
-        out.name(COLLECTOR_NAME);
-        out.value(stat.getCollectorName());
-        out.name(RUN_COUNT);
-        writeLong(out, stat.getRunCount());
-        out.name(WALL_TIME_IN_MICROS);
-        writeLong(out, stat.getWallTime());
-        out.endObject();
-    }
-
-    private void writeLong(JsonWriter out, long value) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(value));
-        out.endObject();
-    }
-}
--- a/plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/model/VmGcStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-gc/agent/src/main/java/com/redhat/thermostat/vm/gc/agent/model/VmGcStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.gc.agent.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -44,10 +45,19 @@
 @Entity
 public class VmGcStat extends BasePojo implements TimeStampedPojo {
 
+    @Schema
     private long timeStamp;
+
+    @Schema
     private String jvmId;
+
+    @Schema
     private String collectorName;
+
+    @Schema
     private long runCount;
+
+    @Schema
     private long wallTimeInMicros;
 
     public VmGcStat() {
--- a/plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatDAOImplTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatDAOImplTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -46,6 +46,7 @@
 import java.util.Arrays;
 
 import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -53,7 +54,6 @@
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.vm.gc.agent.internal.models.VmGcStatDAOImpl.ConfigurationCreator;
-import com.redhat.thermostat.vm.gc.agent.internal.models.VmGcStatDAOImpl.JsonHelper;
 import com.redhat.thermostat.vm.gc.agent.model.VmGcStat;
 
 public class VmGcStatDAOImplTest {
@@ -63,7 +63,7 @@
     private static final URI GATEWAY_URI = URI.create("http://example.com/jvm-gc/");
 
     private VmGcStat stat;
-    private JsonHelper jsonHelper;
+    private JSONService jsonService;
     private VmGcStatDAOImpl dao;
 
     private HttpRequestService httpRequestService;
@@ -78,8 +78,8 @@
         stat.setJvmId("Vm-1");
         stat.setCollectorName("Collector");
 
-        jsonHelper = mock(JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(VmGcStat.class))).thenReturn(JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(VmGcStat.class))).thenReturn(JSON);
 
         ConfigurationInfoSource source = mock(ConfigurationInfoSource.class);
         BackendConfigurationUtil config = mock(BackendConfigurationUtil.class);
@@ -88,7 +88,8 @@
         when(creator.create(source)).thenReturn(config);
 
         httpRequestService = mock(HttpRequestService.class);
-        dao = new VmGcStatDAOImpl(jsonHelper, creator, source);
+        dao = new VmGcStatDAOImpl(creator, source);
+        dao.bindJsonService(jsonService);
         dao.bindHttpRequestService(httpRequestService);
     }
 
@@ -100,7 +101,7 @@
         dao.activate();
         dao.putVmGcStat(stat);
 
-        verify(jsonHelper).toJson(eq(Arrays.asList(stat)));
+        verify(jsonService).serialiase(eq(Arrays.asList(stat)));
 
         verify(httpRequestService).sendHttpRequest(JSON, GATEWAY_URI.resolve("systems/systemid/jvms/Vm-1"), HttpRequestService.Method.POST);
     }
--- a/plugins/vm-gc/agent/src/test/java/com/redhat/thermostat/vm/gc/agent/internal/models/VmGcStatTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.gc.agent.internal.models;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-import java.util.Arrays;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.vm.gc.agent.model.VmGcStat;
-
-public class VmGcStatTypeAdapterTest {
-
-    @Test
-    public void testWrite() throws Exception {
-        VmGcStatTypeAdapter typeAdapter = new VmGcStatTypeAdapter();
-        VmGcStat stat = new VmGcStat();
-        stat.setAgentId("1");
-        stat.setJvmId("2");
-        stat.setTimeStamp(100l);
-        stat.setCollectorName("Collector");
-        stat.setRunCount(10l);
-        stat.setWallTime(200l);
-        assertJsonEquals("[{\"agentId\":\"1\",\"jvmId\":\"2\",\"timeStamp\":{\"$numberLong\":\"100\"},\"collectorName\":\"Collector\",\"runCount\":{\"$numberLong\":\"10\"},\"wallTimeInMicros\":{\"$numberLong\":\"200\"}}]",
-                typeAdapter.toJson(Arrays.asList(stat)));
-    }
-}
--- a/plugins/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,10 +36,9 @@
 
 package com.redhat.thermostat.vm.io.agent.internal;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import com.redhat.thermostat.agent.http.HttpRequestService;
@@ -48,8 +47,9 @@
 import com.redhat.thermostat.common.plugin.PluginDAOBase;
 import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.io.model.VmIoStat;
-import com.redhat.thermostat.vm.io.model.VmIoStatTypeAdapter;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -67,7 +67,6 @@
     private static final Logger logger = LoggingUtils.getLogger(VmIoStatDAOImpl.class);
     public static final String PLUGIN_ID = "vm-io";
 
-    private final JsonHelper jsonHelper;
     private final ConfigurationCreator configCreator;
     private BackendConfigurationUtil config;
 
@@ -75,17 +74,19 @@
     private ConfigurationInfoSource configurationInfoSource;
 
     @Reference
-    private SystemID systemID;
+    private HttpRequestService httpRequestService;
 
     @Reference
-    private HttpRequestService httpRequestService;
+    private JSONService jsonService;
+
+    @Reference
+    private SystemID systemID;
 
     public VmIoStatDAOImpl() {
-        this(new JsonHelper(new VmIoStatTypeAdapter()), new ConfigurationCreator());
+        this(new ConfigurationCreator());
     }
 
-    VmIoStatDAOImpl(JsonHelper jh, ConfigurationCreator creator) {
-        this.jsonHelper = jh;
+    VmIoStatDAOImpl(ConfigurationCreator creator) {
         this.configCreator = creator;
     }
 
@@ -108,13 +109,14 @@
         return PLUGIN_ID;
     }
 
-    public Logger getLogger() {
-        return logger;
+    @Override
+    protected URI getPostURI(final URI basepath, final VmIoStat iostat) {
+        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + iostat.getJvmId());
     }
 
     @Override
-    protected BackendConfigurationUtil getConfig() {
-        return config;
+    protected String serialise(VmIoStat obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
@@ -123,22 +125,12 @@
     }
 
     @Override
-    protected String toJsonString(VmIoStat obj) throws IOException {
-        return jsonHelper.toJson(Arrays.asList(obj));
+    protected BackendConfigurationUtil getConfig() {
+        return config;
     }
 
-    @Override
-    protected URI getPostURI(final URI basepath, final VmIoStat iostat) {
-        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + iostat.getJvmId());
-    }
-
-    // DS bind methods
-    protected void bindSystemID(SystemID systemid) {
-        this.systemID = systemid;
-    }
-
-    protected void bindConfigurationInfoSource(ConfigurationInfoSource cfg) {
-        this.configurationInfoSource = cfg;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
 
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
@@ -147,20 +139,19 @@
 
     protected void unbindHttpRequestService(HttpRequestService httpRequestService) {
         this.httpRequestService = null;
+        logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
+    }
+
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
     }
 
-    // For testing purposes
-    static class JsonHelper {
-
-        private final VmIoStatTypeAdapter typeAdapter;
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
 
-        JsonHelper(VmIoStatTypeAdapter typeAdapter) {
-            this.typeAdapter = typeAdapter;
-        }
-
-        String toJson(List<VmIoStat> infos) throws IOException {
-            return typeAdapter.toJson(infos);
-        }
+    protected Logger getLogger() {
+        return logger;
     }
 
     // For Testing purposes
--- a/plugins/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/model/VmIoStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/model/VmIoStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.io.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -44,12 +45,22 @@
 @Entity
 public class VmIoStat extends BasePojo implements TimeStampedPojo {
 
+    @Schema
     private long timeStamp;
+
+    @Schema
     private String jvmId;
 
+    @Schema
     private long charactersRead;
+
+    @Schema
     private long charactersWritten;
+
+    @Schema
     private long readSyscalls;
+
+    @Schema
     private long writeSyscalls;
 
     public VmIoStat() {
--- a/plugins/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/model/VmIoStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.io.model;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-
-import java.io.IOException;
-import java.util.List;
-
-public class VmIoStatTypeAdapter extends TypeAdapter<List<com.redhat.thermostat.vm.io.model.VmIoStat>> {
-
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String AGENT_ID = "agentId";
-    private static final String JVM_ID = "jvmId";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String CHARACTERS_READ = "charactersRead";
-    private static final String CHARACTERS_WRITTEN = "charactersWritten";
-    private static final String READ_SYSCALLS = "readSyscalls";
-    private static final String WRITE_SYSCALLS = "writeSyscalls";
-
-    @Override
-    public List<com.redhat.thermostat.vm.io.model.VmIoStat> read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void write(JsonWriter out, List<com.redhat.thermostat.vm.io.model.VmIoStat> stats) throws IOException {
-        out.beginArray();
-        for (com.redhat.thermostat.vm.io.model.VmIoStat stat : stats) {
-            writeVmIoStat(out, stat);
-        }
-        out.endArray();
-    }
-
-    private void writeVmIoStat(JsonWriter out, com.redhat.thermostat.vm.io.model.VmIoStat stat) throws IOException {
-        out.beginObject();
-        out.name(TIMESTAMP);
-        writeLong(out, stat.getTimeStamp());
-        out.name(JVM_ID);
-        out.value(stat.getJvmId());
-        out.name(AGENT_ID);
-        out.value(stat.getAgentId());
-        out.name(CHARACTERS_READ);
-        writeLong(out, stat.getCharactersRead());
-        out.name(CHARACTERS_WRITTEN);
-        writeLong(out, stat.getCharactersWritten());
-        out.name(READ_SYSCALLS);
-        writeLong(out, stat.getReadSyscalls());
-        out.name(WRITE_SYSCALLS);
-        writeLong(out, stat.getWriteSyscalls());
-        out.endObject();
-    }
-
-    private void writeLong(JsonWriter out, long value) throws IOException {
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(value));
-        out.endObject();
-    }
-}
--- a/plugins/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatDAOImplTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatDAOImplTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,10 +36,9 @@
 
 package com.redhat.thermostat.vm.io.agent.internal;
 
-
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.io.model.VmIoStat;
 import com.redhat.thermostat.vm.io.agent.internal.VmIoStatDAOImpl.ConfigurationCreator;
-import com.redhat.thermostat.vm.io.agent.internal.VmIoStatDAOImpl.JsonHelper;
 
 import com.redhat.thermostat.agent.http.HttpRequestService;
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
@@ -75,7 +74,7 @@
     private static final URI GATEWAY_URI = URI.create("http://example.com/jvm-io/");
 
     private VmIoStat ioStat;
-    private JsonHelper jsonHelper;
+    private JSONService jsonService;
     private VmIoStatDAOImpl dao;
     private HttpRequestService httpRequestService;
 
@@ -85,8 +84,8 @@
                 SOME_CHARACTERS_READ, SOME_CHARACTERS_WRITTEN,
                 SOME_READ_SYSCALLS, SOME_WRITE_SYSCALLS);
 
-        jsonHelper = mock(JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(VmIoStat.class))).thenReturn(JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(VmIoStat.class))).thenReturn(JSON);
 
         ConfigurationInfoSource source = mock(ConfigurationInfoSource.class);
         BackendConfigurationUtil config = mock(BackendConfigurationUtil.class);
@@ -95,7 +94,8 @@
         when(creator.create(source)).thenReturn(config);
 
         httpRequestService = mock(HttpRequestService.class);
-        dao = new VmIoStatDAOImpl(jsonHelper, creator);
+        dao = new VmIoStatDAOImpl(creator);
+        dao.bindJsonService(jsonService);
         dao.bindHttpRequestService(httpRequestService);
         dao.bindConfigurationInfoSource(source);
     }
@@ -108,7 +108,7 @@
         dao.activate();
         dao.put(ioStat);
 
-        verify(jsonHelper).toJson(eq(Arrays.asList(ioStat)));
+        verify(jsonService).serialiase(eq(Arrays.asList(ioStat)));
         verify(httpRequestService).sendHttpRequest(JSON, GATEWAY_URI.resolve("systems/" + SOME_SYSTEM_ID + "/jvms/" + SOME_VM_ID), HttpRequestService.Method.POST);
     }
 
--- a/plugins/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/model/VmIoStatTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.io.model;
-
-import com.redhat.thermostat.vm.io.model.VmIoStat;
-import com.redhat.thermostat.vm.io.model.VmIoStatTypeAdapter;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-public class VmIoStatTypeAdapterTest {
-
-    @Test
-    public void testWrite() throws IOException {
-        VmIoStatTypeAdapter typeAdapter = new VmIoStatTypeAdapter();
-        VmIoStat stat = new VmIoStat();
-        stat.setTimeStamp(100l);
-        stat.setAgentId("AGENT-1");
-        stat.setJvmId("VM-1");
-        stat.setCharactersRead(2000l);
-        stat.setCharactersWritten(1000l);
-        stat.setReadSyscalls(30l);
-        stat.setWriteSyscalls(40l);
-        final String expected = "[{\"timeStamp\":{\"$numberLong\":\"100\"},\"jvmId\":\"VM-1\",\"agentId\":\"AGENT-1\",\"charactersRead\":{\"$numberLong\":\"2000\"},\"charactersWritten\":{\"$numberLong\":\"1000\"},\"readSyscalls\":{\"$numberLong\":\"30\"},\"writeSyscalls\":{\"$numberLong\":\"40\"}}]";
-        assertJsonEquals(expected, typeAdapter.toJson(Arrays.asList(stat)));
-    }
-
-}
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListener.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListener.java	Wed Oct 25 12:53:20 2017 -0400
@@ -135,7 +135,7 @@
                         generations.toArray(new Generation[generations.size()]),
                         metaspaceMaxCapacity, metaspaceMinCapacity, metaspaceCapacity,
                         metaspaceUsed, residentMemory);
-                memDAO.putVmMemoryStat(stat);
+                memDAO.put(stat);
             }
             else {
                 logWarningOnce("Unable to determine number of generations for VM " + vmId);
@@ -240,7 +240,7 @@
                 slowWaste, maxSlowWaste,
                 fastWaste, maxFastWaste);
 
-        tlabDAO.putStat(stat);
+        tlabDAO.put(stat);
     }
 
     private void logWarningOnce(String message) {
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAO.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAO.java	Wed Oct 25 12:53:20 2017 -0400
@@ -42,7 +42,7 @@
 @Service
 public interface VmMemoryStatDAO {
 
-    public void putVmMemoryStat(VmMemoryStat stat);
+    public void put(VmMemoryStat stat);
 
 }
 
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,14 +36,11 @@
 
 package com.redhat.thermostat.vm.memory.agent.internal.models;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.redhat.thermostat.common.plugin.SystemID;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -51,9 +48,11 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
 
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.agent.http.HttpRequestService;
-import com.redhat.thermostat.agent.http.RequestFailedException;
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
+import com.redhat.thermostat.common.plugin.PluginDAOBase;
+import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat;
@@ -63,39 +62,41 @@
         configurationPid = "vm-memory"
 )
 @Service(value = VmMemoryStatDAO.class)
-public class VmMemoryStatDAOImpl implements VmMemoryStatDAO {
+public class VmMemoryStatDAOImpl extends PluginDAOBase<VmMemoryStat> implements VmMemoryStatDAO {
 
     private static final Logger logger = LoggingUtils.getLogger(VmMemoryStatDAOImpl.class);
     private static final String PLUGIN_ID = "vm-memory";
 
-    private final JsonHelper jsonHelper;
     private final ConfigurationCreator configCreator;
-
-    private URI gatewayURL;
+    private BackendConfigurationUtil config;
 
     @Reference
-    private ConfigurationInfoSource configInfoSource;
+    private ConfigurationInfoSource configurationInfoSource;
     
     @Reference
     private HttpRequestService httpRequestService;
 
     @Reference
+    private JSONService jsonService;
+
+    @Reference
     private SystemID systemID;
 
     public VmMemoryStatDAOImpl() {
-        this(new JsonHelper(new VmMemoryStatTypeAdapter()), new ConfigurationCreator(), null);
+        this(new ConfigurationCreator());
     }
 
-    VmMemoryStatDAOImpl(JsonHelper jh, ConfigurationCreator creator, ConfigurationInfoSource source) {
-        this.jsonHelper = jh;
+    VmMemoryStatDAOImpl(ConfigurationCreator creator) {
         this.configCreator = creator;
-        this.configInfoSource = source;
     }
 
     @Activate
     void activate() throws Exception {
-        BackendConfigurationUtil config = configCreator.create(configInfoSource);
-        this.gatewayURL = config.getGatewayURL();
+         config = configCreator.create(configurationInfoSource);
+    }
+
+    protected URI getPostURI(final URI basepath, final VmMemoryStat obj) {
+        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + obj.getJvmId());
     }
 
     /*
@@ -108,26 +109,23 @@
         logger.config("Doing nothing on configuration change for plugin vm-memory");
     }
 
-    void bindSystemID(final SystemID id) {
-        this.systemID = id;
+    @Override
+    protected String serialise(VmMemoryStat obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
     }
 
     @Override
-    public void putVmMemoryStat(final VmMemoryStat stat) {
-        try {
-            String json = jsonHelper.toJson(Arrays.asList(stat));
-            httpRequestService.sendHttpRequest(json, getPostURI(stat.getJvmId()), HttpRequestService.Method.POST);
-        } catch (RequestFailedException | IOException e) {
-            logger.log(Level.WARNING, "Failed to send VmMemoryStat to Web Gateway", e);
-        }
+    protected HttpRequestService getHttpRequestService() {
+        return httpRequestService;
     }
 
-    protected URI getPostURI(final String jvmID) {
-        return gatewayURL.resolve("systems/" + systemID.getSystemID() + "/jvms/" + jvmID);
+    @Override
+    protected BackendConfigurationUtil getConfig() {
+        return config;
     }
 
-    protected Logger getLogger() {
-        return logger;
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
     }
     
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
@@ -139,18 +137,16 @@
         logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
     }
 
-    // For testing purposes
-    static class JsonHelper {
-
-        private final VmMemoryStatTypeAdapter adapter;
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
+    }
 
-        public JsonHelper(VmMemoryStatTypeAdapter adapter) {
-            this.adapter = adapter;
-        }
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
 
-        String toJson(List<VmMemoryStat> stats) throws IOException {
-            return adapter.toJson(stats);
-        }
+    protected Logger getLogger() {
+        return logger;
     }
 
     // For Testing purposes
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.memory.agent.internal.models;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat;
-
-import java.io.IOException;
-import java.util.List;
-
-import static com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat.Generation;
-import static com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat.Space;
-
-public class VmMemoryStatTypeAdapter extends TypeAdapter<List<VmMemoryStat>> {
-
-    private static final String GENERATIONS = "generations";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String AGENT_ID = "agentId";
-    private static final String JVM_ID = "jvmId";
-    private static final String METASPACE_MAX_CAPACITY = "metaspaceMaxCapacity";
-    private static final String METASPACE_MIN_CAPACITY = "metaspaceMinCapacity";
-    private static final String METASPACE_CAPACITY = "metaspaceCapacity";
-    private static final String METASPACE_USED = "metaspaceUsed";
-    private static final String RESIDENT_MEMORY = "residentMemory";
-    private static final String NAME = "name";
-    private static final String CAPACITY = "capacity";
-    private static final String MAX_CAPACITY = "maxCapacity";
-    private static final String SPACES = "spaces";
-    private static final String COLLECTOR = "collector";
-    private static final String INDEX = "index";
-    private static final String USED = "used";
-    private static final String TYPE_LONG = "$numberLong";
-
-    @Override
-    public List<VmMemoryStat> read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void write(JsonWriter out, List<VmMemoryStat> stats) throws IOException {
-        out.beginArray();
-        for (VmMemoryStat stat : stats) {
-            writeStat(out, stat);
-        }
-        out.endArray();
-    }
-
-    private void writeStat(JsonWriter out, VmMemoryStat stat) throws IOException {
-        out.beginObject();
-        out.name(AGENT_ID);
-        writeString(out, stat.getAgentId());
-        out.name(JVM_ID);
-        writeString(out, stat.getJvmId());
-        out.name(TIMESTAMP);
-        writeLong(out, stat.getTimeStamp());
-        out.name(METASPACE_MAX_CAPACITY);
-        writeLong(out, stat.getMetaspaceMaxCapacity());
-        out.name(METASPACE_MIN_CAPACITY);
-        writeLong(out, stat.getMetaspaceMinCapacity());
-        out.name(METASPACE_CAPACITY);
-        writeLong(out, stat.getMetaspaceCapacity());
-        out.name(METASPACE_USED);
-        writeLong(out, stat.getMetaspaceUsed());
-        out.name(RESIDENT_MEMORY);
-        writeLong(out, stat.getResidentMemory());
-        out.name(GENERATIONS);
-        writeGenerations(out, stat.getGenerations());
-        out.endObject();
-    }
-
-    private void writeString(JsonWriter out, String value) throws IOException {
-        out.value(value);
-    }
-
-    private void writeLong(JsonWriter out, long value) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(value));
-        out.endObject();
-    }
-
-    private void writeGenerations(JsonWriter out, Generation[] generations) throws IOException {
-        out.beginArray();
-        for (Generation g : generations) {
-            writeGeneration(out, g);
-        }
-        out.endArray();
-    }
-
-    private void writeGeneration(JsonWriter out, Generation g) throws IOException {
-        out.beginObject();
-        out.name(NAME);
-        out.value(g.getName());
-        out.name(CAPACITY);
-        writeLong(out, g.getCapacity());
-        out.name(MAX_CAPACITY);
-        writeLong(out, g.getMaxCapacity());
-        out.name(COLLECTOR);
-        out.value(g.getCollector());
-        out.name(SPACES);
-        out.beginArray();
-        for (Space s : g.getSpaces()) {
-            writeSpace(out, s);
-        }
-        out.endArray();
-        out.endObject();
-    }
-
-    private void writeSpace(JsonWriter out, Space s) throws IOException {
-        out.beginObject();
-        out.name(INDEX);
-        out.value(s.getIndex());
-        out.name(NAME);
-        out.value(s.getName());
-        out.name(CAPACITY);
-        writeLong(out, s.getCapacity());
-        out.name(MAX_CAPACITY);
-        writeLong(out, s.getMaxCapacity());
-        out.name(USED);
-        writeLong(out, s.getUsed());
-        out.endObject();
-    }
-}
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAO.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAO.java	Wed Oct 25 12:53:20 2017 -0400
@@ -42,6 +42,6 @@
 @Service
 public interface VmTlabStatDAO {
 
-    public void putStat(VmTlabStat stat);
+    void put(VmTlabStat stat);
 
 }
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAOImpl.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAOImpl.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,10 +36,8 @@
 
 package com.redhat.thermostat.vm.memory.agent.internal.models;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -49,83 +47,107 @@
 import org.apache.felix.scr.annotations.Service;
 
 import com.redhat.thermostat.agent.http.HttpRequestService;
-import com.redhat.thermostat.agent.http.HttpRequestService.Method;
-import com.redhat.thermostat.agent.http.RequestFailedException;
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
+import com.redhat.thermostat.common.plugin.PluginDAOBase;
+import com.redhat.thermostat.common.plugin.SystemID;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.vm.memory.agent.model.VmTlabStat;
 
 @Component
 @Service(value = VmTlabStatDAO.class)
-public class VmTlabStatDAOImpl implements VmTlabStatDAO {
+public class VmTlabStatDAOImpl extends PluginDAOBase<VmTlabStat> implements VmTlabStatDAO {
 
     private static final Logger logger = LoggingUtils.getLogger(VmTlabStatDAOImpl.class);
     private static final String PLUGIN_ID = "vm-memory";
 
-    private final JsonHelper jsonHelper;
     private final ConfigurationCreator configurationCreator;
-
-    private URI gatewayURL;
+    private BackendConfigurationUtil config;
 
     @Reference
-    private ConfigurationInfoSource configInfoSource;
+    private ConfigurationInfoSource configurationInfoSource;
     
     @Reference
     private HttpRequestService httpRequestService;
 
+    @Reference
+    private JSONService jsonService;
+
+    @Reference
+    private SystemID systemID;
+
     public VmTlabStatDAOImpl() throws Exception {
-        this(new JsonHelper(new VmTlabStatTypeAdapter()), new ConfigurationCreator(), null);
+        this(new ConfigurationCreator());
     }
 
-    VmTlabStatDAOImpl(JsonHelper jsonHelper,
-            ConfigurationCreator configurationCreator, ConfigurationInfoSource configInfoSource) throws Exception {
-        this.jsonHelper = jsonHelper;
+    VmTlabStatDAOImpl(ConfigurationCreator configurationCreator) throws Exception {
         this.configurationCreator = configurationCreator;
-        this.configInfoSource = configInfoSource;
     }
 
     @Activate
     void activate() throws Exception {
-        BackendConfigurationUtil config = configurationCreator.create(configInfoSource);
-        this.gatewayURL = config.getGatewayURL();
+        config = configurationCreator.create(configurationInfoSource);
     }
 
     @Override
-    public void putStat(final VmTlabStat stat) {
+    public void put(final VmTlabStat stat) {
 //      TODO: Re-enable when web-gateway service for TLAB stats is available
 //      Also see VmTlabStatDAOTest for disabled tests
         return;
 //        try {
-//            String json = jsonHelper.toJson(Arrays.asList(stat));
+//            String json = jsonService.toJson(Arrays.asList(stat));
 //            httpRequestService.sendHttpRequest(json, gatewayURL, Method.POST);
 //        } catch (RequestFailedException | IOException e) {
 //            logger.log(Level.WARNING, "Failed to send VmTlabStat to Web Gateway", e);
 //        }
     }
-    
-    // DS bind method
+
+    @Override
+    protected URI getPostURI(final URI basepath, final VmTlabStat obj) {
+        return basepath.resolve("systems/" + systemID.getSystemID() + "/jvms/" + obj.getJvmId());
+    }
+
+    @Override
+    protected String serialise(VmTlabStat obj) {
+        return jsonService.serialiase(Arrays.asList(obj));
+    }
+
+    @Override
+    protected HttpRequestService getHttpRequestService() {
+        return httpRequestService;
+    }
+
+    @Override
+    protected BackendConfigurationUtil getConfig() {
+        return config;
+    }
+
+    protected void bindConfigurationInfoSource(ConfigurationInfoSource configurationInfoSource) {
+        this.configurationInfoSource = configurationInfoSource;
+    }
+
     protected void bindHttpRequestService(HttpRequestService httpRequestService) {
         this.httpRequestService = httpRequestService;
     }
 
+    protected void unbindHttpRequestService(HttpRequestService httpRequestService) {
+        this.httpRequestService = null;
+        logger.log(Level.INFO, "Unbound HTTP service. Further attempts to store data will fail until bound again.");
+    }
+
+    protected void bindJsonService(JSONService jsonService) {
+        this.jsonService = jsonService;
+    }
+
+    void bindSystemID(final SystemID id) {
+        this.systemID = id;
+    }
+
     protected Logger getLogger() {
         return logger;
     }
 
-    static class JsonHelper {
-
-        private final VmTlabStatTypeAdapter adapter;
-
-        public JsonHelper(VmTlabStatTypeAdapter adapter) {
-            this.adapter = adapter;
-        }
-
-        String toJson(List<VmTlabStat> stats) throws IOException {
-            return adapter.toJson(stats);
-        }
-    }
-
     // For testing purposes
     static class ConfigurationCreator {
 
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatTypeAdapter.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.memory.agent.internal.models;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.redhat.thermostat.vm.memory.agent.model.VmTlabStat;
-
-import java.io.IOException;
-import java.util.List;
-
-public class VmTlabStatTypeAdapter extends TypeAdapter<List<VmTlabStat>> {
-
-    private static final String AGENT_ID = "agentId";
-    private static final String JVM_ID = "jvmId";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String ALLOC_THREADS = "allocThreads";
-    private static final String TOTAL_ALLOCATIONS = "totalAllocations";
-    private static final String REFILLS = "refills";
-    private static final String MAX_REFILLS = "maxRefills";
-    private static final String SLOW_ALLOCATIONS = "slowAllocations";
-    private static final String MAX_SLOW_ALLOCATIONS = "maxSlowAllocations";
-    private static final String GC_WASTE = "gcWaste";
-    private static final String MAX_GC_WASTE = "maxGcWaste";
-    private static final String SLOW_WASTE = "slowWaste";
-    private static final String MAX_SLOW_WASTE = "maxSlowWaste";
-    private static final String FAST_WASTE = "fastWaste";
-    private static final String MAX_FAST_WASTE = "maxFastWaste";
-    private static final String TYPE_LONG = "$numberLong";
-
-    @Override
-    public List<VmTlabStat> read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void write(JsonWriter out, List<VmTlabStat> stats) throws IOException {
-        out.beginArray();
-        for (VmTlabStat tlabStat : stats) {
-            writeStat(out, tlabStat);
-        }
-        out.endArray();
-    }
-
-    public void writeStat(JsonWriter out, VmTlabStat stat) throws IOException {
-        out.beginObject();
-        out.name(JVM_ID);
-        out.value(stat.getJvmId());
-        out.name(AGENT_ID);
-        out.value(stat.getAgentId());
-        out.name(TIMESTAMP);
-        writeLong(out, stat.getTimeStamp());
-        out.name(ALLOC_THREADS);
-        writeLong(out, stat.getTotalAllocatingThreads());
-        out.name(TOTAL_ALLOCATIONS);
-        writeLong(out, stat.getTotalAllocations());
-        out.name(REFILLS);
-        writeLong(out, stat.getTotalRefills());
-        out.name(MAX_REFILLS);
-        writeLong(out, stat.getMaxRefills());
-        out.name(SLOW_ALLOCATIONS);
-        writeLong(out, stat.getTotalSlowAllocations());
-        out.name(MAX_SLOW_ALLOCATIONS);
-        writeLong(out, stat.getMaxSlowAllocations());
-        out.name(GC_WASTE);
-        writeLong(out, stat.getTotalGcWaste());
-        out.name(MAX_GC_WASTE);
-        writeLong(out, stat.getMaxGcWaste());
-        out.name(SLOW_WASTE);
-        writeLong(out, stat.getTotalSlowWaste());
-        out.name(MAX_SLOW_WASTE);
-        writeLong(out, stat.getMaxSlowWaste());
-        out.name(FAST_WASTE);
-        writeLong(out, stat.getTotalFastWaste());
-        out.name(MAX_FAST_WASTE);
-        writeLong(out, stat.getMaxFastWaste());
-        out.endObject();
-    }
-
-    public void writeLong(JsonWriter out, long value) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(value));
-        out.endObject();
-    }
-}
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/model/VmMemoryStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/model/VmMemoryStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.memory.agent.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -52,10 +53,20 @@
     @Entity
     public static class Generation implements Pojo {
         public static final String COLLECTOR_NONE = "none";
+
+        @Schema
         private String name;
+
+        @Schema
         private long capacity;
+
+        @Schema
         private long maxCapacity;
+
+        @Schema
         private Space[] spaces;
+
+        @Schema
         private String collector;
 
         @Persist
@@ -121,10 +132,19 @@
     @Entity
     public static class Space implements Pojo {
 
+        @Schema
         private int index;
+
+        @Schema
         private String name;
+
+        @Schema
         private long capacity;
+
+        @Schema
         private long maxCapacity;
+
+        @Schema
         private long used;
 
         @Persist
@@ -179,13 +199,28 @@
 
     }
 
+    @Schema
     private Generation[] generations;
+
+    @Schema
     private long timeStamp;
+
+    @Schema
     private String jvmId;
+
+    @Schema
     private long metaspaceMaxCapacity;
+
+    @Schema
     private long metaspaceMinCapacity;
+
+    @Schema
     private long metaspaceCapacity;
+
+    @Schema
     private long metaspaceUsed;
+
+    @Schema
     private long residentMemory;
 
     public VmMemoryStat() {
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/model/VmTlabStat.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/model/VmTlabStat.java	Wed Oct 25 12:53:20 2017 -0400
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.vm.memory.agent.model;
 
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.storage.core.Entity;
 import com.redhat.thermostat.storage.core.Persist;
 import com.redhat.thermostat.storage.model.BasePojo;
@@ -49,25 +50,46 @@
 
     public static final long UNKNOWN = -1;
 
+    @Schema
     private String jvmId;
+
+    @Schema
     private long timeStamp;
 
+    @Schema
     private long allocThreads;
+
+    @Schema
     private long totalAllocations;
 
+    @Schema
     private long refills;
+
+    @Schema
     private long maxRefills;
 
+    @Schema
     private long slowAllocations;
+
+    @Schema
     private long maxSlowAllocations;
 
+    @Schema
     private long gcWaste;
+
+    @Schema
     private long maxGcWaste;
 
+    @Schema
     private long slowWaste;
+
+    @Schema
     private long maxSlowWaste;
 
+    @Schema
     private long fastWaste;
+
+    @Schema
     private long maxFastWaste;
 
     /** for de-serialization only */
--- a/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListenerTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListenerTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -187,15 +187,15 @@
         VmUpdate update = mock(VmUpdate.class);
         vmListener.countersUpdated(update, vmResidentSizeExtractor);
 
-        verify(vmMemoryStatDAO).putVmMemoryStat(isA(VmMemoryStat.class));
-        verify(vmTlabStatDAO).putStat(isA(VmTlabStat.class));
+        verify(vmMemoryStatDAO).put(isA(VmMemoryStat.class));
+        verify(vmTlabStatDAO).put(isA(VmTlabStat.class));
     }
 
     @Test
     public void testRecordMemoryStat() {
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -235,7 +235,7 @@
     public void testRecordMemoryStatNoTotal() throws VmUpdateException {
         when(extractor.getTotalGcGenerations()).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
-        verify(vmMemoryStatDAO, never()).putVmMemoryStat(any(VmMemoryStat.class));
+        verify(vmMemoryStatDAO, never()).put(any(VmMemoryStat.class));
     }
 
     @Test
@@ -243,7 +243,7 @@
         when(extractor.getGenerationName(0)).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -269,7 +269,7 @@
         when(extractor.getGenerationCapacity(0)).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -295,7 +295,7 @@
         when(extractor.getGenerationMaxCapacity(0)).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -321,7 +321,7 @@
         when(extractor.getGenerationCollector(0)).thenReturn(null);
         vmListener.recordMemoryStat(extractor,vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -347,7 +347,7 @@
         when(extractor.getTotalSpaces(0)).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -373,7 +373,7 @@
         when(extractor.getSpaceName(0, 1)).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -407,7 +407,7 @@
         when(extractor.getSpaceCapacity(0, 1)).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -441,7 +441,7 @@
         when(extractor.getSpaceMaxCapacity(0, 1)).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -475,7 +475,7 @@
         when(extractor.getSpaceUsed(0, 1)).thenReturn(null);
         vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor);
         ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class);
-        verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture());
+        verify(vmMemoryStatDAO).put(captor.capture());
         VmMemoryStat memoryStat = captor.getValue();
 
         Generation[] gens = memoryStat.getGenerations();
@@ -522,7 +522,7 @@
         vmListener.recordTlabStat(extractor);
 
         ArgumentCaptor<VmTlabStat> captor = ArgumentCaptor.forClass(VmTlabStat.class);
-        verify(vmTlabStatDAO).putStat(captor.capture());
+        verify(vmTlabStatDAO).put(captor.capture());
         VmTlabStat tlabStat = captor.getValue();
 
         assertEquals(VmTlabStat.UNKNOWN, tlabStat.getTotalAllocatingThreads());
--- a/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAOImplTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAOImplTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -47,13 +47,13 @@
 import java.util.List;
 
 import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.lang.schema.JSONService;
 import org.junit.Before;
 import org.junit.Test;
 
 import com.redhat.thermostat.agent.http.HttpRequestService;
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
-import com.redhat.thermostat.vm.memory.agent.internal.models.VmMemoryStatDAOImpl.JsonHelper;
 import com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat;
 import com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat.Generation;
 import com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat.Space;
@@ -63,24 +63,24 @@
     private static final String JSON = "{\"this\":\"is\",\"test\":\"JSON\"}";
     private static final URI GATEWAY_URI = URI.create("http://example.com/jvm-memory/0.0.2/");
 
-    private JsonHelper jsonHelper;
+    private JSONService jsonService;
     private BackendConfigurationUtil config;
     VmMemoryStatDAOImpl.ConfigurationCreator creator;
-    ConfigurationInfoSource source;
+    ConfigurationInfoSource configurationInfoSource;
     private HttpRequestService httpRequestService;
 
     @Before
     public void setUp() throws Exception {
-        jsonHelper = mock(JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(VmMemoryStat.class))).thenReturn(JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(VmMemoryStat.class))).thenReturn(JSON);
 
         config = mock(BackendConfigurationUtil.class);
         when(config.getGatewayURL()).thenReturn(GATEWAY_URI);
 
-        source = mock(ConfigurationInfoSource.class);
+        configurationInfoSource = mock(ConfigurationInfoSource.class);
 
         creator = mock(VmMemoryStatDAOImpl.ConfigurationCreator.class);
-        when(creator.create(source)).thenReturn(config);
+        when(creator.create(configurationInfoSource)).thenReturn(config);
         httpRequestService = mock(HttpRequestService.class);
     }
 
@@ -117,16 +117,18 @@
         VmMemoryStat stat = new VmMemoryStat("foo-agent", 1, "jvmId", generations.toArray(new Generation[generations.size()]),
                 2, 3, 4, 5, 0);
 
-        VmMemoryStatDAOImpl dao = new VmMemoryStatDAOImpl(jsonHelper, creator, source);
+        VmMemoryStatDAOImpl dao = new VmMemoryStatDAOImpl(creator);
+        dao.bindJsonService(jsonService);
         dao.bindHttpRequestService(httpRequestService);
+        dao.bindConfigurationInfoSource(configurationInfoSource);
         SystemID id = mock(SystemID.class);
         when(id.getSystemID()).thenReturn("systemid");
         dao.bindSystemID(id);
         dao.activate();
 
-        dao.putVmMemoryStat(stat);
+        dao.put(stat);
 
-        verify(jsonHelper).toJson(Arrays.asList(stat));
+        verify(jsonService).serialiase(Arrays.asList(stat));
         verify(httpRequestService).sendHttpRequest(JSON, GATEWAY_URI.resolve("systems/systemid/jvms/jvmId"), HttpRequestService.Method.POST);
     }
 
--- a/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.memory.agent.internal.models;
-
-import com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-import static com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat.Generation;
-import static com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat.Space;
-
-public class VmMemoryStatTypeAdapterTest {
-
-    @Test
-    public void testWrite() throws IOException {
-        VmMemoryStatTypeAdapter typeAdapter = new VmMemoryStatTypeAdapter();
-        VmMemoryStat stat = new VmMemoryStat();
-        stat.setTimeStamp(100l);
-        stat.setJvmId("VM-1");
-        stat.setAgentId("AGENT-1");
-        stat.setMetaspaceCapacity(2000l);
-        stat.setMetaspaceMaxCapacity(4096l);
-        stat.setMetaspaceMinCapacity(2048l);
-        stat.setMetaspaceUsed(3000l);
-        stat.setResidentMemory(10000l);
-        Generation[] gens = new Generation[1];
-        Generation gen1 = new Generation();
-        gen1.setCapacity(1002l);
-        gen1.setCollector("Collector 1");
-        gen1.setMaxCapacity(2048l);
-        gen1.setName("Name");
-        Space[] spaces = new Space[1];
-        Space space = new Space();
-        space.setName("Space Name");
-        space.setMaxCapacity(1024l);
-        space.setCapacity(500l);
-        space.setIndex(1);
-        space.setUsed(400l);
-        spaces[0] = space;
-        gen1.setSpaces(spaces);
-        gens[0] = gen1;
-        stat.setGenerations(gens);
-        assertJsonEquals("[{\"agentId\":\"AGENT-1\",\"jvmId\":\"VM-1\","
-                         + "\"timeStamp\":{\"$numberLong\":\"100\"},"
-                         + "\"metaspaceMaxCapacity\":{\"$numberLong\":\"4096\"},"
-                         + "\"metaspaceMinCapacity\":{\"$numberLong\":\"2048\"},"
-                         + "\"metaspaceCapacity\":{\"$numberLong\":\"2000\"},"
-                         + "\"metaspaceUsed\":{\"$numberLong\":\"3000\"},"
-                         + "\"residentMemory\":{\"$numberLong\":\"10000\"},"
-                         + "\"generations\":[{\"name\":\"Name\",\"capacity\":{\"$numberLong\":\"1002\"},\"maxCapacity\":{\"$numberLong\":\"2048\"},\"collector\":\"Collector 1\",\"spaces\":[{\"index\":1,\"name\":\"Space Name\",\"capacity\":{\"$numberLong\":\"500\"},\"maxCapacity\":{\"$numberLong\":\"1024\"},\"used\":{\"$numberLong\":\"400\"}}]}]}]",
-                typeAdapter.toJson(Arrays.asList(stat)));
-    }
-}
\ No newline at end of file
--- a/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAOTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatDAOTest.java	Wed Oct 25 12:53:20 2017 -0400
@@ -50,12 +50,13 @@
 import org.junit.Ignore;
 import org.junit.Test;
 
+import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.lang.schema.JSONService;
 import com.redhat.thermostat.agent.http.HttpRequestService;
 import com.redhat.thermostat.agent.http.HttpRequestService.Method;
 import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
 import com.redhat.thermostat.common.plugin.BackendConfigurationUtil;
 import com.redhat.thermostat.vm.memory.agent.internal.models.VmTlabStatDAOImpl.ConfigurationCreator;
-import com.redhat.thermostat.vm.memory.agent.internal.models.VmTlabStatDAOImpl.JsonHelper;
 import com.redhat.thermostat.vm.memory.agent.model.VmTlabStat;
 
 public class VmTlabStatDAOTest {
@@ -65,7 +66,7 @@
     private static final String AGENT_ID = "agent";
     private static final URI GATEWAY_URI = URI.create("http://example.com/jvm-memory/0.0.2/");
     
-    private JsonHelper jsonHelper;
+    private JSONService jsonService;
     private BackendConfigurationUtil config;
     private HttpRequestService httpRequestService;
     private ConfigurationCreator configCreator;
@@ -74,8 +75,8 @@
     @Before
     public void setUp() throws Exception {
         httpRequestService = mock(HttpRequestService.class);
-        jsonHelper = mock(JsonHelper.class);
-        when(jsonHelper.toJson(anyListOf(VmTlabStat.class))).thenReturn(JSON);
+        jsonService = mock(JSONService.class);
+        when(jsonService.serialiase(anyListOf(VmTlabStat.class))).thenReturn(JSON);
         
         config = mock(BackendConfigurationUtil.class);
         when(config.getGatewayURL()).thenReturn(GATEWAY_URI);
@@ -87,10 +88,15 @@
     @Test
     public void testActivation() throws Exception {
 
-        VmTlabStatDAOImpl dao = new VmTlabStatDAOImpl(jsonHelper, configCreator, configInfoSource);
+        VmTlabStatDAOImpl dao = new VmTlabStatDAOImpl(configCreator);
+        dao.bindJsonService(jsonService);
+        dao.bindHttpRequestService(httpRequestService);
+        dao.bindConfigurationInfoSource(configInfoSource);
+        SystemID id = mock(SystemID.class);
+        when(id.getSystemID()).thenReturn("systemid");
         dao.activate();
 
-        verify(config, times(1)).getGatewayURL();
+        verify(configCreator, times(1)).create(configInfoSource);
     }
 
     @Test
@@ -116,12 +122,14 @@
         stat.setTotalFastWaste(678l);
         stat.setMaxFastWaste(333l);
 
-        VmTlabStatDAOImpl dao = new VmTlabStatDAOImpl(jsonHelper, configCreator, configInfoSource);
+        VmTlabStatDAOImpl dao = new VmTlabStatDAOImpl(configCreator);
+        dao.bindJsonService(jsonService);
         dao.bindHttpRequestService(httpRequestService);
+        dao.bindConfigurationInfoSource(configInfoSource);
         dao.activate();
-        dao.putStat(stat);
+        dao.put(stat);
 
-        verify(jsonHelper).toJson(Arrays.asList(stat));
+        verify(jsonService).serialiase(Arrays.asList(stat));
         verify(httpRequestService).sendHttpRequest(eq(JSON), eq(GATEWAY_URI), eq(Method.POST));
     }
 }
--- a/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmTlabStatTypeAdapterTest.java	Mon Oct 23 16:50:12 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.memory.agent.internal.models;
-
-import com.redhat.thermostat.vm.memory.agent.model.VmTlabStat;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-public class VmTlabStatTypeAdapterTest {
-
-    @Test
-    public void testWrite() throws IOException {
-        VmTlabStatTypeAdapter typeAdapter = new VmTlabStatTypeAdapter();
-        VmTlabStat stat = new VmTlabStat();
-        stat.setAgentId("AGENT-1");
-        stat.setJvmId("VM-1");
-        stat.setTimeStamp(1000l);
-        stat.setTotalAllocatingThreads(10l);
-        stat.setTotalAllocations(1342l);
-        stat.setTotalRefills(58l);
-        stat.setMaxRefills(90l);
-        stat.setTotalSlowAllocations(343l);
-        stat.setMaxSlowAllocations(989l);
-        stat.setTotalGcWaste(788l);
-        stat.setMaxGcWaste(992l);
-        stat.setTotalSlowWaste(899l);
-        stat.setMaxSlowWaste(634l);
-        stat.setTotalFastWaste(678l);
-        stat.setMaxFastWaste(333l);
-        assertJsonEquals("[{\"jvmId\":\"VM-1\",\"agentId\":\"AGENT-1\",\"timeStamp\":{\"$numberLong\":\"1000\"},\"allocThreads\":{\"$numberLong\":\"10\"},\"totalAllocations\":{\"$numberLong\":\"1342\"},\"refills\":{\"$numberLong\":\"58\"},\"maxRefills\":{\"$numberLong\":\"90\"},\"slowAllocations\":{\"$numberLong\":\"343\"},\"maxSlowAllocations\":{\"$numberLong\":\"989\"},\"gcWaste\":{\"$numberLong\":\"788\"},\"maxGcWaste\":{\"$numberLong\":\"992\"},\"slowWaste\":{\"$numberLong\":\"899\"},\"maxSlowWaste\":{\"$numberLong\":\"634\"},\"fastWaste\":{\"$numberLong\":\"678\"},\"maxFastWaste\":{\"$numberLong\":\"333\"}}]", typeAdapter.toJson(Arrays.asList(stat)));
-    }
-
-}
--- a/pom.xml	Mon Oct 23 16:50:12 2017 -0400
+++ b/pom.xml	Wed Oct 25 12:53:20 2017 -0400
@@ -235,7 +235,7 @@
     <thermostat.web.deploy.dir>${thermostat.build.directory}/${project.build.finalName}</thermostat.web.deploy.dir>
 
     <!-- common Thermostat package from base repo (loaded from Maven central) -->
-    <thermostat.common.version>0.1.0</thermostat.common.version>
+    <thermostat.common.version>0.1.2</thermostat.common.version>
 
     <junit.version>4.10</junit.version>
     <mockito.version>1.9.5</mockito.version>
--- a/storage/core/src/main/java/com/redhat/thermostat/storage/model/BasePojo.java	Mon Oct 23 16:50:12 2017 -0400
+++ b/storage/core/src/main/java/com/redhat/thermostat/storage/model/BasePojo.java	Wed Oct 25 12:53:20 2017 -0400
@@ -40,10 +40,12 @@
 import java.util.Objects;
 
 import com.redhat.thermostat.storage.core.Persist;
+import com.redhat.thermostat.lang.schema.annotations.Schema;
 
 @Deprecated
 public class BasePojo implements Pojo {
 
+    @Schema
     private String agentId;
     
     public BasePojo(String writerId) {