changeset 30:d0304caad13a version 0.1.2

Modify JSON service to serve current JSON This patch modifies the JSONService to serve the current (Agent-produced) flavour of JSON to the web-gateway. The current flavour (called "phase 1" in the patch) is the Gson typeadapter defaults + the Mongo $numberLong. This is what the current typeadapters in the current Agent are sending to the web-gateway. Reviewed-by: neugens, sgehwolf Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-October/025520.html
author Simon Tooke <stooke@redhat.com>
date Wed, 25 Oct 2017 09:15:49 -0400
parents dafb9de45e69
children 1a3ece19e2fd
files common/pom.xml common/src/main/java/com/redhat/thermostat/lang/schema/internal/JSONServiceImpl.java common/src/test/java/com/redhat/thermostat/lang/schema/internal/JSONServiceTest.java
diffstat 3 files changed, 120 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/common/pom.xml	Thu Oct 19 10:00:02 2017 -0400
+++ b/common/pom.xml	Wed Oct 25 09:15:49 2017 -0400
@@ -6,7 +6,7 @@
 
     <groupId>com.redhat.thermostat</groupId>
     <artifactId>thermostat-common</artifactId>
-    <version>0.1.1</version>
+    <version>0.1.2</version>
     <packaging>bundle</packaging>
 
     <!-- required for uploading to Maven Central -->
--- a/common/src/main/java/com/redhat/thermostat/lang/schema/internal/JSONServiceImpl.java	Thu Oct 19 10:00:02 2017 -0400
+++ b/common/src/main/java/com/redhat/thermostat/lang/schema/internal/JSONServiceImpl.java	Wed Oct 25 09:15:49 2017 -0400
@@ -39,6 +39,7 @@
 import com.google.gson.ExclusionStrategy;
 import com.google.gson.FieldAttributes;
 import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
 import com.google.gson.TypeAdapter;
 import com.google.gson.stream.JsonReader;
 import com.google.gson.stream.JsonWriter;
@@ -46,30 +47,58 @@
 import com.redhat.thermostat.lang.schema.*;
 
 import com.redhat.thermostat.lang.schema.annotations.Schema;
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Service;
 
 import java.io.IOException;
 
-@Component
+@Component(name = "JSONService")
 @Service(JSONService.class)
 public class JSONServiceImpl implements JSONService {
 
-    private GsonBuilder builder;
+    private final GsonBuilder builder;
+
+    /**
+     * set mode to phase 1 or phase 2
+     * phase 1- JSONService converts using existing JSON formats (with MongoDB $numberLong)
+     * phase 2 - JSONService converts using "everything is a string" format (requires changes in web-client)
+     */
+    private static int PHASE_DEFAULT = 1;
 
     public JSONServiceImpl() {
         this(false);
     }
 
     public JSONServiceImpl(boolean prettyPrinting) {
+        this(PHASE_DEFAULT, prettyPrinting);
+    }
 
+    JSONServiceImpl(int phase, boolean prettyPrinting) {
 
         builder = new GsonBuilder();
         if (prettyPrinting) {
             builder.setPrettyPrinting();
         }
 
-        AutoAdapter autoAdapter = new AutoAdapter();
+        if (phase == 1) {
+            registerPhase1TypeAdapters();
+        } else {
+            registerPhase2TypeAdapters();
+        }
+
+        builder.addSerializationExclusionStrategy(new AutoExclusionStategy());
+    }
+
+    private void registerPhase1TypeAdapters() {
+        final LongTypeAdapter longTypeAdapter = new LongTypeAdapter();
+        builder.registerTypeAdapter(long.class, longTypeAdapter);
+        builder.registerTypeAdapter(Long.class, longTypeAdapter);
+    }
+
+    private void registerPhase2TypeAdapters() {
+
+        final AutoAdapter autoAdapter = new AutoAdapter();
 
         builder.registerTypeAdapter(boolean.class, autoAdapter);
         builder.registerTypeAdapter(byte.class, autoAdapter);
@@ -86,9 +115,10 @@
         builder.registerTypeAdapter(Long.class, autoAdapter);
         builder.registerTypeAdapter(Double.class, autoAdapter);
         builder.registerTypeAdapter(Float.class, autoAdapter);
+    }
 
-        builder.addSerializationExclusionStrategy(new AutoExclusionStategy());
-
+    @Activate
+    public void activate() {
     }
 
     @Override
@@ -110,6 +140,35 @@
         }
     }
 
+    private static class LongTypeAdapter extends TypeAdapter<Long> {
+
+        private static final String NUMBER_LONG_IDENTIFIER = "$numberLong";
+
+        @Override
+        public void write(JsonWriter out, Long value) throws IOException {
+            if (value == null) {
+                out.nullValue();
+            } else {
+                out.beginObject();
+                out.name(NUMBER_LONG_IDENTIFIER);
+                out.value(value.toString());
+                out.endObject();
+            }
+        }
+
+        @Override
+        public Long read(JsonReader in) throws IOException {
+            in.beginObject();
+            String name = in.nextName();
+            if (!name.equals(NUMBER_LONG_IDENTIFIER)) {
+                throw new JsonSyntaxException("Unexpected name: " + name);
+            }
+            long returnValue = in.nextLong();
+            in.endObject();
+            return returnValue;
+        }
+    }
+
     public class AutoExclusionStategy implements ExclusionStrategy {
 
         public boolean shouldSkipClass(Class<?> arg0) {
--- a/common/src/test/java/com/redhat/thermostat/lang/schema/internal/JSONServiceTest.java	Thu Oct 19 10:00:02 2017 -0400
+++ b/common/src/test/java/com/redhat/thermostat/lang/schema/internal/JSONServiceTest.java	Wed Oct 25 09:15:49 2017 -0400
@@ -38,7 +38,7 @@
 
 import com.redhat.thermostat.lang.schema.annotations.Schema;
 import com.redhat.thermostat.lang.schema.annotations.Type;
-import com.redhat.thermostat.lang.schema.internal.JSONServiceImpl;
+
 import com.redhat.thermostat.lang.schema.models.Timestamp;
 import org.junit.Assert;
 import org.junit.Before;
@@ -154,51 +154,97 @@
         }
     }
 
-    private JSONServiceImpl service;
+    private JSONServiceImpl phase1service;
+    private JSONServiceImpl phase2service;
 
     @Before
     public void setUp() {
-        service = new JSONServiceImpl(false);
+        phase1service = new JSONServiceImpl(1, false);
+        phase2service = new JSONServiceImpl(2, false);
+    }
+
+    // phase 1 - default, with $numberLong
+    @Test
+    public void testSimpleType1() {
+        Timestamp timestamp = new Timestamp(123456L);
+        assertEquals("{\"timestamp\":{\"$numberLong\":\"123456\"}}", phase1service.serialiase(timestamp));
+    }
+
+    @Test
+    public void testComplexType1() {
+        SomeMoreComplexType type = new SomeMoreComplexType(42, "test");
+        assertEquals("{\"aLong\":{\"$numberLong\":\"42\"},\"aString\":\"test\"}",
+                phase1service.serialiase(type));
+    }
+
+    @Test
+    public void testComplexType1_2() {
+        SomeMoreComplexType2 type = new SomeMoreComplexType2(42, "test");
+        assertEquals("{\"aLong\":{\"$numberLong\":\"42\"}}",
+                phase1service.serialiase(type));
     }
 
     @Test
+    public void testCompoundType1() {
+        CompoundType type = new CompoundType(42, new SomeMoreComplexType(10, "test"));
+        assertEquals("{\"aLong\":{\"$numberLong\":\"42\"},\"complexType\":{\"aLong\":{\"$numberLong\":\"10\"},\"aString\":\"test\"}}",
+                phase1service.serialiase(type));
+    }
+
+    @Test
+    public void testCompoundTypeMissingSchema1() {
+        CompoundTypeMissingSchema type = new CompoundTypeMissingSchema(42, new SomeMoreComplexType(10, "test"));
+        assertEquals("{\"aLong\":{\"$numberLong\":\"42\"}}",
+                phase1service.serialiase(type));
+    }
+
+    @Test
+    public void testExtendedType1() {
+        ExtendedType type = new ExtendedType(50, 42, new SomeMoreComplexType(10, "test"));
+        assertEquals("{\"anotherLong\":{\"$numberLong\":\"42\"},\"aLong\":{\"$numberLong\":\"50\"},\"complexType\":{\"aLong\":{\"$numberLong\":\"10\"},\"aString\":\"test\"}}",
+                phase1service.serialiase(type));
+    }
+
+    // phase 2 - "everything is a string"
+
+    @Test
     public void testSimpleType() {
         Timestamp timestamp = new Timestamp(123456L);
-        assertEquals("{\"timestamp\":\"123456\"}", service.serialiase(timestamp));
+        assertEquals("{\"timestamp\":\"123456\"}", phase2service.serialiase(timestamp));
     }
 
     @Test
     public void testComplexType() {
         SomeMoreComplexType type = new SomeMoreComplexType(42, "test");
         assertEquals("{\"aLong\":\"42\",\"aString\":\"test\"}",
-                service.serialiase(type));
+                phase2service.serialiase(type));
     }
 
     @Test
     public void testComplexType2() {
         SomeMoreComplexType2 type = new SomeMoreComplexType2(42, "test");
         assertEquals("{\"aLong\":\"42\"}",
-                service.serialiase(type));
+                phase2service.serialiase(type));
     }
 
     @Test
     public void testCompoundType() {
         CompoundType type = new CompoundType(42, new SomeMoreComplexType(10, "test"));
         assertEquals("{\"aLong\":\"42\",\"complexType\":{\"aLong\":\"10\",\"aString\":\"test\"}}",
-                service.serialiase(type));
+                phase2service.serialiase(type));
     }
 
     @Test
     public void testCompoundTypeMissingSchema() {
         CompoundTypeMissingSchema type = new CompoundTypeMissingSchema(42, new SomeMoreComplexType(10, "test"));
         assertEquals("{\"aLong\":\"42\"}",
-                service.serialiase(type));
+                phase2service.serialiase(type));
     }
 
     @Test
     public void testExtendedType() {
         ExtendedType type = new ExtendedType(50, 42, new SomeMoreComplexType(10, "test"));
         assertEquals("{\"anotherLong\":\"42\",\"aLong\":\"50\",\"complexType\":{\"aLong\":\"10\",\"aString\":\"test\"}}",
-                service.serialiase(type));
+                phase2service.serialiase(type));
     }
 }