blob: 105040b7044f7665bf174139a0c693fd70660c84 [file] [log] [blame]
/*=========================================================================
* Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. Pivotal products are covered by
* more patents listed at http://www.pivotal.io/patents.
*=========================================================================
*/
package com.gemstone.gemfire.pdx;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Properties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gemstone.gemfire.cache.AttributesFactory;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.Scope;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
import com.gemstone.gemfire.cache.server.CacheServer;
import com.gemstone.gemfire.cache30.CacheTestCase;
import com.gemstone.gemfire.distributed.internal.DistributionConfig;
import com.gemstone.gemfire.internal.Assert;
import com.gemstone.gemfire.internal.AvailablePortHelper;
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import dunit.Host;
import dunit.SerializableCallable;
import dunit.VM;
import com.gemstone.gemfire.pdx.internal.json.PdxToJSON;
import com.gemstone.gemfire.util.test.TestUtil;
import org.json.JSONException;
import org.json.JSONObject;
/**
* @author hiteshk
*
*/
public class JSONPdxClientServerDUnitTest extends CacheTestCase {
public JSONPdxClientServerDUnitTest(String name) {
super(name);
}
@Override
public void tearDown2() {
// this test creates client caches in some VMs and so
// breaks the contract of CacheTestCase to hold caches in
// that class's "cache" instance variable
disconnectAllFromDS();
}
public void testSimplePut() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
VM vm2 = host.getVM(2);
VM vm3 = host.getVM(3);
createServerRegion(vm0);
int port = createServerRegion(vm3);
createClientRegion(vm1, port);
createClientRegion(vm2, port);
vm1.invoke(new SerializableCallable() {
public Object call() throws Exception {
JSONAllStringTest();
return null;
}
});
vm2.invoke(new SerializableCallable() {
public Object call() throws Exception {
JSONAllByteArrayTest();
return null;
}
});
}
//this is for unquote fielnames in json string
public void testSimplePut2() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
VM vm2 = host.getVM(2);
VM vm3 = host.getVM(3);
createServerRegion(vm0);
int port = createServerRegion(vm3);
createClientRegion(vm1, port);
createClientRegion(vm2, port);
vm1.invoke(new SerializableCallable() {
public Object call() throws Exception {
JSONUnQuoteFields();
return null;
}
});
}
public void testPdxInstanceAndJSONConversion() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
VM vm2 = host.getVM(2);
VM vm3 = host.getVM(3);
createServerRegion(vm0, true);
int port = createServerRegion(vm3, true);
createClientRegion(vm1, port, false, true);
createClientRegion(vm2, port, false, true);
vm1.invoke(new SerializableCallable() {
public Object call() throws Exception {
VerifyPdxInstanceAndJsonConversion();
return null;
}
});
}
public void VerifyPdxInstanceAndJsonConversion() {
Region region = getRootRegion("testSimplePdx");
//Create Object and initialize its members.
TestObjectForPdxFormatter testObject = new TestObjectForPdxFormatter();
testObject.defaultInitialization();
// put the object into cache.
region.put("101", testObject);
//Get the object as PdxInstance
Object result = (Object)region.get("101");
if (result instanceof PdxInstance) {
PdxInstance pi = (PdxInstance)result;
String json = JSONFormatter.toJSON(pi);
try {
JSONObject jsonObject = new JSONObject(json);
//Testcase-1: Validate json string against the pdxInstance.
//validation for primitive types
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: Int type values are not matched",
testObject.getP_int(), jsonObject.getInt(testObject.getP_intFN()));
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: long type values are not matched",
testObject.getP_long(), jsonObject.getLong(testObject.getP_longFN()));
//validation for wrapper types
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: Boolean type values are not matched",
testObject.getW_bool().booleanValue(), jsonObject.getBoolean(testObject.getW_boolFN()));
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: Float type values are not matched",
testObject.getW_double().doubleValue(), jsonObject.getDouble(testObject.getW_doubleFN()));
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: bigDec type values are not matched",
testObject.getW_bigDec().longValue(), jsonObject.getLong(testObject.getW_bigDecFN()));
//vlidation for array types
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: Byte[] type values are not matched",
(int)testObject.getW_byteArray()[1], jsonObject.getJSONArray(testObject.getW_byteArrayFN()).getInt(1));
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: Double[] type values are not matched",
testObject.getW_doubleArray()[0], jsonObject.getJSONArray(testObject.getW_doubleArrayFN()).getDouble(0));
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: String[] type values are not matched",
testObject.getW_strArray()[2], jsonObject.getJSONArray(testObject.getW_strArrayFN()).getString(2));
//validation for collection types
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: list type values are not matched",
testObject.getC_list().get(0),
jsonObject.getJSONArray(testObject.getC_listFN()).getString(0));
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: stack type values are not matched",
testObject.getC_stack().get(2),
jsonObject.getJSONArray(testObject.getC_stackFN()).getString(2));
//validation for Map
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: Map type values are not matched",
testObject.getM_empByCity().get("Ahmedabad").get(0).getFname(),
jsonObject.getJSONObject(testObject.getM_empByCityFN()).getJSONArray("Ahmedabad").getJSONObject(0).getString("fname"));
//validation Enum
junit.framework.Assert.assertEquals("VerifyPdxInstanceToJson: Enum type values are not matched",
testObject.getDay().toString(),
jsonObject.getString(testObject.getDayFN()));
} catch (JSONException e) {
fail("Error in VerifyPdxInstanceToJson, Malformed json, can not create JSONArray from it");
}
}else {
fail("Error in VerifyPdxInstanceToJson, result must be of type PdxInstance");
}
//TestCase-2 : Validate Java-->JSON-->PdxInstance --> Java Mapping
TestObjectForPdxFormatter actualTestObject = new TestObjectForPdxFormatter();
actualTestObject.defaultInitialization();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("MM/dd/yyyy"));
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
//1. get the json from the object using Jackosn Object Mapper
String json = objectMapper.writeValueAsString(actualTestObject);
String jsonWithClassType = actualTestObject.addClassTypeToJson(json);
//2. convert json into the PdxInstance and put it into the region
PdxInstance pi = JSONFormatter.fromJSON(jsonWithClassType);
region.put("201", pi);
//3. get the value on key "201" and validate PdxInstance.getObject() API.
Object receivedObject = region.get("201");
if (receivedObject instanceof PdxInstance){
PdxInstance receivedPdxInstance = (PdxInstance)receivedObject;
//4. get the actualType testObject from the pdxInstance and compare it with actualTestObject
Object getObj = receivedPdxInstance.getObject();
if(getObj instanceof TestObjectForPdxFormatter){
TestObjectForPdxFormatter receivedTestObject = (TestObjectForPdxFormatter)getObj;
boolean isEqual = actualTestObject.equals(receivedTestObject);
Assert.assertTrue(isEqual, "actualTestObject and receivedTestObject should be equal");
}else {
fail("getObj is expected to be an instance of TestObjectForPdxFormatter");
}
}else {
fail("receivedObject is expected to be of type PdxInstance");
}
} catch (JsonProcessingException e) {
fail("JsonProcessingException: error encountered while converting JSON from Java object: " + e.getMessage());
} catch (JSONException e) {
fail("JSONException: error encountered while adding @type classType into Json: " + e.getMessage());
}
}
String getJSONDir(String file) {
String path = TestUtil.getResourcePath(getClass(), file);
return new File(path).getParent();
}
public void JSONUnQuoteFields() {
System.setProperty("pdxToJson.unqouteFieldNames", "true");
PdxToJSON.PDXTOJJSON_UNQUOTEFIELDNAMES = true;
String jsonStringsDir = getJSONDir("/com/gemstone/gemfire/pdx/jsonStrings/unquoteJsonStrings/json1.txt");
JSONAllStringTest(jsonStringsDir);
PdxToJSON.PDXTOJJSON_UNQUOTEFIELDNAMES = false;
}
public void JSONAllStringTest() {
String jsonStringsDir = getJSONDir("jsonStrings/json1.txt");
JSONAllStringTest(jsonStringsDir);
}
public void JSONAllStringTest(String dirname) {
JSONData[] allJsons = loadAllJSON(dirname);
int i = 0;
for(JSONData jsonData : allJsons)
{
if(jsonData != null) {
i++;
VerifyJSONString(jsonData);
}
}
Assert.assertTrue(i >= 1, "Number of files should be more than 10 : " + i);
}
public void JSONAllByteArrayTest() {
String jsonStringsDir = getJSONDir("jsonStrings/json1.txt");
JSONData[] allJsons = loadAllJSON(jsonStringsDir);
int i = 0;
for(JSONData jsonData : allJsons)
{
if(jsonData != null) {
i++;
VerifyJSONByteArray(jsonData);
}
}
Assert.assertTrue(i > 10, "Number of files should be more than 10");
}
static class JSONData {
String jsonFileName;
byte[] jsonByteArray;
public JSONData(String fn, byte[] js) {
jsonFileName = fn;
jsonByteArray = js;
}
public String getFileName () {
return jsonFileName;
}
public String getJsonString() {
return new String(jsonByteArray);
}
public byte[] getJsonByteArray(){
return jsonByteArray;
}
}
public void VerifyJSONString(JSONData jd) {
Region r = getRootRegion("testSimplePdx");
PdxInstance pdx = JSONFormatter.fromJSON(jd.getJsonString());
r.put(1, pdx);
pdx = (PdxInstance)r.get(1);
String getJsonString = JSONFormatter.toJSON(pdx);
String o1 = jsonParse(jd.getJsonString());
String o2 = jsonParse(getJsonString);
junit.framework.Assert.assertEquals("Json Strings are not equal " + jd.getFileName() + " " + Boolean.getBoolean("pdxToJson.unqouteFieldNames"), o1, o2);
PdxInstance pdx2 = JSONFormatter.fromJSON(getJsonString);
junit.framework.Assert.assertEquals("Pdx are not equal; json filename " + jd.getFileName(), pdx, pdx2);
}
protected final static int INT_TAB = '\t';
protected final static int INT_LF = '\n';
protected final static int INT_CR = '\r';
protected final static int INT_SPACE = 0x0020;
public String jsonParse(String jsonSting) {
byte[] ba = jsonSting.getBytes();
byte [] withoutspace = new byte[ba.length];
int i = 0;
int j = 0;
for(i =0; i< ba.length; i++) {
int cbyte = ba[i];
if(cbyte == INT_TAB || cbyte == INT_LF || cbyte == INT_CR || cbyte == INT_SPACE)
continue;
withoutspace[j++] = ba[i];
}
return new String(withoutspace, 0, j);
}
public void VerifyJSONByteArray(JSONData jd) {
Region r = getRootRegion("testSimplePdx");
PdxInstance pdx = JSONFormatter.fromJSON(jd.getJsonByteArray());
r.put(1, pdx);
pdx = (PdxInstance)r.get(1);
byte[] jsonByteArray = JSONFormatter.toJSONByteArray(pdx);
byte[] o1 = jsonParse(jd.getJsonByteArray());
byte[] o2 = jsonParse(jsonByteArray);
// junit.framework.Assert.assertEquals("Pdx byte aray are not equal after fetching from cache " + jd.getFileName(), o1, o2);
compareByteArray(o1, o2);
PdxInstance pdx2 = JSONFormatter.fromJSON(jsonByteArray);
boolean pdxequals = pdx.equals(pdx2);
junit.framework.Assert.assertEquals("Pdx are not equal for byte array ; json filename " + jd.getFileName(), pdx, pdx2 );
}
public void compareByteArray(byte[] b1, byte[] b2) {
if(b1.length != b2.length)
throw new IllegalStateException("Json byte array length are not equal " + b1.length + " ; " + b2.length);
for(int i =0; i< b1.length; i++) {
if(b1[i] != b2[i])
throw new IllegalStateException("Json byte arrays are not equal ");
}
}
public byte[] jsonParse(byte[] jsonBA) {
byte[] ba = jsonBA;
byte [] withoutspace = new byte[ba.length];
int i = 0;
int j = 0;
for(i =0; i< ba.length; i++) {
int cbyte = ba[i];
if(cbyte == INT_TAB || cbyte == INT_LF || cbyte == INT_CR || cbyte == INT_SPACE)
continue;
withoutspace[j++] = ba[i];
}
byte[] retBA = new byte[j];
for(i =0 ; i< j ; i++) {
retBA[i] = withoutspace[i];
}
return retBA;
}
public static JSONData[] loadAllJSON(String jsondir) {
File dir = new File(jsondir);
JSONData [] JSONDatas = new JSONData[dir.list().length];
int i = 0;
for(String jsonFileName : dir.list()) {
if(!jsonFileName.contains(".txt"))
continue;
try {
byte[] ba = getBytesFromFile(dir.getAbsolutePath() + File.separator + jsonFileName);
JSONDatas[i++] = new JSONData(jsonFileName, ba);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return JSONDatas;
}
public static byte[] getBytesFromFile(String fileName) throws IOException {
File file = new File(fileName);
java.io.InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
is.close();
return bytes;
}
private void closeCache(VM vm) {
vm.invoke(new SerializableCallable() {
public Object call() throws Exception {
closeCache();
return null;
}
});
}
private int createServerRegion(VM vm) {
SerializableCallable createRegion = new SerializableCallable() {
public Object call() throws Exception {
AttributesFactory af = new AttributesFactory();
//af.setScope(Scope.DISTRIBUTED_ACK);
af.setDataPolicy(DataPolicy.PARTITION);
createRootRegion("testSimplePdx", af.create());
CacheServer server = getCache().addCacheServer();
int port = AvailablePortHelper.getRandomAvailableTCPPort();
server.setPort(port);
server.start();
return port;
}
};
return (Integer) vm.invoke(createRegion);
}
private int createServerRegion(VM vm, final boolean isPdxReadSerialized) {
SerializableCallable createRegion = new SerializableCallable() {
public Object call() throws Exception {
AttributesFactory af = new AttributesFactory();
//af.setScope(Scope.DISTRIBUTED_ACK);
af.setDataPolicy(DataPolicy.PARTITION);
createRootRegion("testSimplePdx", af.create());
((GemFireCacheImpl)getCache()).getCacheConfig().setPdxReadSerialized(isPdxReadSerialized);
CacheServer server = getCache().addCacheServer();
int port = AvailablePortHelper.getRandomAvailableTCPPort();
server.setPort(port);
server.start();
return port;
}
};
return (Integer) vm.invoke(createRegion);
}
private int createServerRegionWithPersistence(VM vm,
final boolean persistentPdxRegistry) {
SerializableCallable createRegion = new SerializableCallable() {
public Object call() throws Exception {
CacheFactory cf = new CacheFactory();
if(persistentPdxRegistry) {
cf.setPdxPersistent(true)
.setPdxDiskStore("store");
}
//
Cache cache = getCache(cf);
cache.createDiskStoreFactory()
.setDiskDirs(getDiskDirs())
.create("store");
AttributesFactory af = new AttributesFactory();
af.setScope(Scope.DISTRIBUTED_ACK);
af.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
af.setDiskStoreName("store");
createRootRegion("testSimplePdx", af.create());
CacheServer server = getCache().addCacheServer();
int port = AvailablePortHelper.getRandomAvailableTCPPort();
server.setPort(port);
server.start();
return port;
}
};
return (Integer) vm.invoke(createRegion);
}
private int createServerAccessor(VM vm) {
SerializableCallable createRegion = new SerializableCallable() {
public Object call() throws Exception {
AttributesFactory af = new AttributesFactory();
//af.setScope(Scope.DISTRIBUTED_ACK);
af.setDataPolicy(DataPolicy.EMPTY);
createRootRegion("testSimplePdx", af.create());
CacheServer server = getCache().addCacheServer();
int port = AvailablePortHelper.getRandomAvailableTCPPort();
server.setPort(port);
server.start();
return port;
}
};
return (Integer) vm.invoke(createRegion);
}
private int createLonerServerRegion(VM vm, final String regionName, final String dsId) {
SerializableCallable createRegion = new SerializableCallable() {
public Object call() throws Exception {
Properties props = new Properties();
props.setProperty("locators", "");
props.setProperty(DistributionConfig.DISTRIBUTED_SYSTEM_ID_NAME, dsId);
getSystem(props);
AttributesFactory af = new AttributesFactory();
af.setScope(Scope.DISTRIBUTED_ACK);
af.setDataPolicy(DataPolicy.REPLICATE);
createRootRegion(regionName, af.create());
CacheServer server = getCache().addCacheServer();
int port = AvailablePortHelper.getRandomAvailableTCPPort();
server.setPort(port);
server.start();
return port;
}
};
return (Integer) vm.invoke(createRegion);
}
private void createClientRegion(final VM vm, final int port) {
createClientRegion(vm, port, false);
}
private void createClientRegion(final VM vm, final int port,
final boolean threadLocalConnections) {
SerializableCallable createRegion = new SerializableCallable() {
public Object call() throws Exception {
ClientCacheFactory cf = new ClientCacheFactory();
cf.addPoolServer(getServerHostName(vm.getHost()), port);
cf.setPoolThreadLocalConnections(threadLocalConnections);
ClientCache cache = getClientCache(cf);
cache.createClientRegionFactory(ClientRegionShortcut.PROXY)
.create("testSimplePdx");
return null;
}
};
vm.invoke(createRegion);
}
private void createClientRegion(final VM vm, final int port,
final boolean threadLocalConnections, final boolean isPdxReadSerialized) {
SerializableCallable createRegion = new SerializableCallable() {
public Object call() throws Exception {
ClientCacheFactory cf = new ClientCacheFactory();
cf.addPoolServer(getServerHostName(vm.getHost()), port);
cf.setPoolThreadLocalConnections(threadLocalConnections);
cf.setPdxReadSerialized(isPdxReadSerialized);
ClientCache cache = getClientCache(cf);
cache.createClientRegionFactory(ClientRegionShortcut.PROXY)
.create("testSimplePdx");
return null;
}
};
vm.invoke(createRegion);
}
}