From 2e22c95dd0ad9a03a3ce938add55b2b8c9010e64 Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Mon, 11 May 2015 11:24:50 -0400 Subject: [PATCH] Add Scheduler.testSerialization, some new JsonDeserializer in RedisScheduler, and a bunch of tests to test (de)serialization --- .../moparisthebest/jbgjob/ScheduledItem.java | 8 +++ .../com/moparisthebest/jbgjob/Scheduler.java | 9 +++ .../jbgjob/AbstractSchedulerTests.java | 23 +++++++ .../moparisthebest/jbgjob/RedisScheduler.java | 64 ++++++++++++++++++- .../jbgjob/ThreadScheduler.java | 5 ++ 5 files changed, 107 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/moparisthebest/jbgjob/ScheduledItem.java b/core/src/main/java/com/moparisthebest/jbgjob/ScheduledItem.java index cc2b64b..dde7abe 100644 --- a/core/src/main/java/com/moparisthebest/jbgjob/ScheduledItem.java +++ b/core/src/main/java/com/moparisthebest/jbgjob/ScheduledItem.java @@ -38,6 +38,10 @@ public class ScheduledItem implements Runnable { this(null, null); } + public ScheduledItem(T dto) { + this(null, dto); + } + public ScheduledItem(Class> bgClass, T dto) { this.bgClass = bgClass; this.dto = dto; @@ -72,6 +76,10 @@ public class ScheduledItem implements Runnable { this.result = result; } + public T getDto() { + return dto; + } + @Override public String toString() { return "ScheduledItem{" + diff --git a/core/src/main/java/com/moparisthebest/jbgjob/Scheduler.java b/core/src/main/java/com/moparisthebest/jbgjob/Scheduler.java index 7007b4f..91c62a2 100644 --- a/core/src/main/java/com/moparisthebest/jbgjob/Scheduler.java +++ b/core/src/main/java/com/moparisthebest/jbgjob/Scheduler.java @@ -49,4 +49,13 @@ public interface Scheduler extends Closeable { public boolean schedule(final String queue, final Class> bgClass, final T dto); public boolean schedule(final String queue, final ScheduledItem scheduledItem); + + /** + * This serializes and deserialized T and returns the deserialized version for the calling app to compare is correct + * @param t to be serialized + * @param Type of DTO + * @return t serialized and deserialized + * @throws Exception + */ + public T testSerialization(final T t) throws Exception; } diff --git a/core/src/test/java/com/moparisthebest/jbgjob/AbstractSchedulerTests.java b/core/src/test/java/com/moparisthebest/jbgjob/AbstractSchedulerTests.java index d7259eb..d00f37a 100644 --- a/core/src/test/java/com/moparisthebest/jbgjob/AbstractSchedulerTests.java +++ b/core/src/test/java/com/moparisthebest/jbgjob/AbstractSchedulerTests.java @@ -27,6 +27,9 @@ import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; +import java.util.Arrays; +import java.util.Collections; + public class AbstractSchedulerTests { public static Scheduler bg; @@ -61,4 +64,24 @@ public class AbstractSchedulerTests { for (; x < 20; ++x) Assert.assertTrue(bg.schedule(PrintingJob.class, new PrintDTO("fastJob " + x))); } + + @Test + public void testSerializationSingleton() throws Throwable { + Assert.assertEquals(Collections.singleton(5), bg.testSerialization(Collections.singleton(5))); + } + + @Test + public void testSerializationSingletonMap() throws Throwable { + Assert.assertEquals(Collections.singletonMap("5", 5), bg.testSerialization(Collections.singletonMap("5", 5))); + } + + @Test + public void testSerializationSingletonList() throws Throwable { + Assert.assertEquals(Collections.singletonList(5), bg.testSerialization(Collections.singletonList(5))); + } + + @Test + public void testSerializationAsList() throws Throwable { + Assert.assertEquals(Arrays.asList(2, 3, 4, 5), bg.testSerialization(Arrays.asList(2, 3, 4, 5))); + } } diff --git a/redisscheduler/src/main/java/com/moparisthebest/jbgjob/RedisScheduler.java b/redisscheduler/src/main/java/com/moparisthebest/jbgjob/RedisScheduler.java index 7ce966a..cb29e2e 100644 --- a/redisscheduler/src/main/java/com/moparisthebest/jbgjob/RedisScheduler.java +++ b/redisscheduler/src/main/java/com/moparisthebest/jbgjob/RedisScheduler.java @@ -20,11 +20,16 @@ package com.moparisthebest.jbgjob; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.module.SimpleModule; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; +import java.io.IOException; +import java.util.*; + /** * This implementation of Scheduler that serializes the DTO into a redis list for processing elsewhere. */ @@ -34,6 +39,8 @@ public class RedisScheduler extends AbstractScheduler { public static final String defaultQueuePrefix; + public static final Module redisModule; + static { String prefix = System.getProperty("redis.queuePrefix"); if (isEmpty(prefix)) @@ -42,11 +49,47 @@ public class RedisScheduler extends AbstractScheduler { } catch (Throwable e) { } defaultQueuePrefix = defaultIfEmpty(prefix, ""); + + @SuppressWarnings({"unchecked"}) + final Class singleton = (Class) Collections.singleton(5L).getClass(); + @SuppressWarnings({"unchecked"}) + final Class singletonMap = (Class) Collections.singletonMap(5L, 5L).getClass(); + @SuppressWarnings({"unchecked"}) + final Class singletonList = (Class) Collections.singletonList(5L).getClass(); + @SuppressWarnings({"unchecked"}) + final Class asList = (Class) Arrays.asList(5L).getClass(); + + redisModule = new SimpleModule("OrderedMap", new Version(1, 0, 0, null, null, null)).addDeserializer( + singleton, new JsonDeserializer() { + @Override + public Set deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + return Collections.singleton(jp.getCodec().readValue(jp, Object[].class)[0]); + } + }).addDeserializer( + singletonMap, new JsonDeserializer() { + @Override + public Map deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + final Map.Entry entry = (Map.Entry) jp.getCodec().readValue(jp, HashMap.class).entrySet().iterator().next(); + return Collections.singletonMap(entry.getKey(), entry.getValue()); + } + }).addDeserializer( + singletonList, new JsonDeserializer() { + @Override + public List deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + return Collections.singletonList(jp.getCodec().readValue(jp, Object[].class)[0]); + } + }).addDeserializer( + asList, new JsonDeserializer() { + @Override + public List deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + return Arrays.asList(jp.getCodec().readValue(jp, Object[].class)); + } + }); } protected final String queuePrefix; - protected final ObjectMapper om = new ObjectMapper().enableDefaultTyping(); + protected final ObjectMapper om = new ObjectMapper().enableDefaultTyping().registerModule(redisModule); protected final JedisPool pool; public RedisScheduler() { @@ -87,4 +130,21 @@ public class RedisScheduler extends AbstractScheduler { } } } + + @Override + @SuppressWarnings({"unchecked"}) + public T testSerialization(final T t) throws IOException { + final String singleton = om.writeValueAsString(new ScheduledItem(null, t)); + System.out.printf("singleton: '%s', dto.getClass: '%s'", singleton, t.getClass()); + final ScheduledItem singletonCol = (ScheduledItem) om.readValue(singleton, ScheduledItem.class); + System.out.printf(", singletonCol: '%s', dto.getClass: '%s'", singletonCol, singletonCol.getDto().getClass()); + if (singletonCol.getDto() instanceof Collection) + for (Object ob : ((Collection) singletonCol.getDto())) + System.out.printf(", val: '%s', val.getClass: '%s'", ob, ob.getClass()); + else if (singletonCol.getDto() instanceof Map) + for (Map.Entry entry : (Set) ((Map) singletonCol.getDto()).entrySet()) + System.out.printf(", key: '%s', key.getClass: '%s', val: '%s', val.getClass: '%s'", entry.getKey(), entry.getKey().getClass(), entry.getValue(), entry.getValue().getClass()); + System.out.println(); + return singletonCol.getDto(); + } } diff --git a/threadscheduler/src/main/java/com/moparisthebest/jbgjob/ThreadScheduler.java b/threadscheduler/src/main/java/com/moparisthebest/jbgjob/ThreadScheduler.java index 93fab66..d82b978 100644 --- a/threadscheduler/src/main/java/com/moparisthebest/jbgjob/ThreadScheduler.java +++ b/threadscheduler/src/main/java/com/moparisthebest/jbgjob/ThreadScheduler.java @@ -41,6 +41,11 @@ public class ThreadScheduler extends AbstractScheduler { } } + @Override + public T testSerialization(final T t) { + return t; // do nothing here + } + @Override public void close() { super.close();