Add Scheduler.testSerialization, some new JsonDeserializer in RedisScheduler, and a bunch of tests to test (de)serialization

This commit is contained in:
Travis Burtrum 2015-05-11 11:24:50 -04:00
parent f690ef92cc
commit 2e22c95dd0
5 changed files with 107 additions and 2 deletions

View File

@ -38,6 +38,10 @@ public class ScheduledItem<T> implements Runnable {
this(null, null);
}
public ScheduledItem(T dto) {
this(null, dto);
}
public ScheduledItem(Class<? extends BackgroundJob<T>> bgClass, T dto) {
this.bgClass = bgClass;
this.dto = dto;
@ -72,6 +76,10 @@ public class ScheduledItem<T> implements Runnable {
this.result = result;
}
public T getDto() {
return dto;
}
@Override
public String toString() {
return "ScheduledItem{" +

View File

@ -49,4 +49,13 @@ public interface Scheduler extends Closeable {
public <T> boolean schedule(final String queue, final Class<? extends BackgroundJob<T>> bgClass, final T dto);
public <T> boolean schedule(final String queue, final ScheduledItem<T> 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 <T> Type of DTO
* @return t serialized and deserialized
* @throws Exception
*/
public <T> T testSerialization(final T t) throws Exception;
}

View File

@ -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)));
}
}

View File

@ -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<Set> singleton = (Class<Set>) Collections.singleton(5L).getClass();
@SuppressWarnings({"unchecked"})
final Class<Map> singletonMap = (Class<Map>) Collections.singletonMap(5L, 5L).getClass();
@SuppressWarnings({"unchecked"})
final Class<List> singletonList = (Class<List>) Collections.singletonList(5L).getClass();
@SuppressWarnings({"unchecked"})
final Class<List> asList = (Class<List>) Arrays.asList(5L).getClass();
redisModule = new SimpleModule("OrderedMap", new Version(1, 0, 0, null, null, null)).addDeserializer(
singleton, new JsonDeserializer<Set>() {
@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<Map>() {
@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<List>() {
@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<List>() {
@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> T testSerialization(final T t) throws IOException {
final String singleton = om.writeValueAsString(new ScheduledItem<T>(null, t));
System.out.printf("singleton: '%s', dto.getClass: '%s'", singleton, t.getClass());
final ScheduledItem<T> singletonCol = (ScheduledItem<T>) 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.Entry>) ((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();
}
}

View File

@ -41,6 +41,11 @@ public class ThreadScheduler extends AbstractScheduler {
}
}
@Override
public <T> T testSerialization(final T t) {
return t; // do nothing here
}
@Override
public void close() {
super.close();