Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for custom serializer #2

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 47 additions & 16 deletions src/main/java/com/arhs/spring/cache/mongo/MongoCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
package com.arhs.spring.cache.mongo;

import com.arhs.spring.cache.mongo.domain.CacheDocument;
import com.arhs.spring.cache.mongo.serializer.JavaSerializer;
import com.arhs.spring.cache.mongo.serializer.Serializer;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import org.mockito.internal.matchers.Null;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
Expand Down Expand Up @@ -68,6 +69,7 @@ public class MongoCache implements Cache {
private final long ttl;

private final Object lock = new Object();
private final Serializer serializer;

/**
* Constructor.
Expand All @@ -89,7 +91,20 @@ public MongoCache(String cacheName, String collectionName, MongoTemplate mongoTe
* @param ttl a time-to-live (in seconds).
*/
public MongoCache(String cacheName, String collectionName, MongoTemplate mongoTemplate, long ttl) {
this(cacheName, collectionName, mongoTemplate, ttl, false);
this(cacheName, collectionName, mongoTemplate, ttl, false, new JavaSerializer());
}

/**
* Constructor.
*
* @param cacheName a cache name.
* @param collectionName a collection name.
* @param mongoTemplate a {@link MongoTemplate} instance.
* @param ttl a time-to-live (in seconds).
* @param serializer a serializer.
*/
public MongoCache(String cacheName, String collectionName, MongoTemplate mongoTemplate, long ttl, Serializer serializer) {
this(cacheName, collectionName, mongoTemplate, ttl, false, serializer);
}

/**
Expand All @@ -102,6 +117,20 @@ public MongoCache(String cacheName, String collectionName, MongoTemplate mongoTe
* @param flushOnBoot a value that indicates if the collection must be always flush.
*/
public MongoCache(String cacheName, String collectionName, MongoTemplate mongoTemplate, long ttl, boolean flushOnBoot) {
this(cacheName, collectionName, mongoTemplate, ttl, flushOnBoot, new JavaSerializer());
}

/**
* Constructor.
*
* @param cacheName a cache name.
* @param collectionName a collection name.
* @param mongoTemplate a {@link MongoTemplate} instance.
* @param ttl a time-to-live (in seconds).
* @param flushOnBoot a value that indicates if the collection must be always flush.
* @param serializer a serializer.
*/
public MongoCache(String cacheName, String collectionName, MongoTemplate mongoTemplate, long ttl, boolean flushOnBoot, Serializer serializer) {
Assert.hasText(cacheName, "'cacheName' must be not null and not empty.");
Assert.notNull(collectionName, "'collectionName' must be not null.");
Assert.notNull(collectionName, "'mongoTemplate' must be not null.");
Expand All @@ -111,6 +140,7 @@ public MongoCache(String cacheName, String collectionName, MongoTemplate mongoTe
this.mongoTemplate = mongoTemplate;
this.cacheName = cacheName;
this.ttl = ttl;
this.serializer = serializer == null ? new JavaSerializer() : serializer;

initialize();
}
Expand Down Expand Up @@ -214,6 +244,18 @@ public Object getNativeCache() {
return mongoTemplate;
}

public MongoTemplate getMongoTemplate() {
return mongoTemplate;
}

public Serializer getSerializer() {
return serializer;
}

public String getCacheName() {
return cacheName;
}

/**
* Returns the TTL value for this cache.
*
Expand Down Expand Up @@ -269,10 +311,7 @@ public ValueWrapper putIfAbsent(Object key, Object value) {
private Object deserialize(String value) throws IOException, ClassNotFoundException {
final Base64.Decoder decoder = Base64.getDecoder();
final byte[] data = decoder.decode(value);
try (final ByteArrayInputStream buffer = new ByteArrayInputStream(data);
final ObjectInputStream output = new ObjectInputStream(buffer)) {
return output.readObject();
}
return serializer.deserialize(data);
}

private Object getFromCache(Object key) {
Expand Down Expand Up @@ -307,16 +346,8 @@ private void initialize() {
}

private String serialize(Object value) throws IOException {
try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
final ObjectOutputStream output = new ObjectOutputStream(buffer)) {

output.writeObject(value);

final byte[] data = buffer.toByteArray();

final Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(data);
}
final Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(serializer.serialize(value));
}

private Index createExpireIndex() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
package com.arhs.spring.cache.mongo;

import com.arhs.spring.cache.mongo.serializer.Serializer;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.Assert;

Expand All @@ -42,6 +43,7 @@ public class MongoCacheBuilder {
private String collectionName;
private MongoTemplate mongoTemplate;
private long ttl;
private Serializer serializer;

/**
* Constructor.
Expand Down Expand Up @@ -79,7 +81,7 @@ public static MongoCacheBuilder newInstance(String collectionName, MongoTemplate
* @return a {@link MongoCache} instance.
*/
public MongoCache build() {
return new MongoCache(cacheName, collectionName, mongoTemplate, ttl, flushOnBoot);
return new MongoCache(cacheName, collectionName, mongoTemplate, ttl, flushOnBoot, serializer);
}

/**
Expand All @@ -104,4 +106,9 @@ public MongoCacheBuilder withTTL(long ttl) {
return this;
}

public MongoCacheBuilder withSerializer(Serializer serializer) {
this.serializer = serializer;
return this;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.arhs.spring.cache.mongo.serializer;

import java.io.*;

public class JavaSerializer implements Serializer {
@Override
public byte[] serialize(Object obj) throws IOException {
try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
final ObjectOutputStream output = new ObjectOutputStream(buffer)) {

output.writeObject(obj);

return buffer.toByteArray();
}
}

@Override
public Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
try (final ByteArrayInputStream buffer = new ByteArrayInputStream(bytes);
final ObjectInputStream output = new ObjectInputStream(buffer)) {
return output.readObject();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.arhs.spring.cache.mongo.serializer;

import java.io.IOException;

public interface Serializer {

public byte[] serialize(Object obj) throws IOException;

public Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.arhs.spring.cache.mongo;

import com.arhs.spring.cache.mongo.serializer.JavaSerializer;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = TestConfiguration.class)
public class MongoCacheBuilderTest {

private static final String CACHE_NAME = "cache";
private static final String COLLECTION_NAME = "test";
private static final long TTL = 0;
private static final JavaSerializer serializer = new JavaSerializer();

@Autowired
private MongoTemplate mongoTemplate;

@Test
public void testBuildWithSerializer() {
MongoCacheBuilder builder = new MongoCacheBuilder(
COLLECTION_NAME,
mongoTemplate,
CACHE_NAME
);

builder.withSerializer(serializer);
builder.withTTL(TTL);
builder.withFlushOnBoot(false);

MongoCache cache = builder.build();
Assert.assertEquals(COLLECTION_NAME, cache.getCollectionName());
Assert.assertEquals(mongoTemplate, cache.getMongoTemplate());
Assert.assertEquals(CACHE_NAME, cache.getCacheName());
Assert.assertEquals(serializer, cache.getSerializer());
Assert.assertEquals(TTL, cache.getTtl());
}

@Test
public void testBuildWithoutSerializer() {
MongoCacheBuilder builder = new MongoCacheBuilder(
COLLECTION_NAME,
mongoTemplate,
CACHE_NAME
);
builder.withTTL(TTL);
builder.withFlushOnBoot(false);
MongoCache cache = builder.build();

Assert.assertEquals(COLLECTION_NAME, cache.getCollectionName());
Assert.assertEquals(mongoTemplate, cache.getMongoTemplate());
Assert.assertEquals(CACHE_NAME, cache.getCacheName());
Assert.assertEquals(TTL, cache.getTtl());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.arhs.spring.cache.mongo.serializer;

import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.io.Serializable;
import java.util.Date;

public class JavaSerializerTest {

public static class SerializableBean implements Serializable {
Date date;
String string;
Integer integer;
}

@Test
public void testSerializeDeserialize() throws IOException, ClassNotFoundException {
JavaSerializer serializer = new JavaSerializer();

Date date = new Date();
String string = "foobar";
Integer integer = 1234;

SerializableBean in = new SerializableBean();
in.date = date;
in.string = string;
in.integer = integer;

byte[] bytes = serializer.serialize(in);

SerializableBean out = (SerializableBean) serializer.deserialize(bytes);

Assert.assertEquals(string, out.string);
Assert.assertEquals(integer, out.integer);
Assert.assertEquals(date, out.date);
}


}