IGNITE-4949 - Fixed CacheJdbcPojoStore for BinaryMarshaller. This closes #1803.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0cb2c921 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0cb2c921 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0cb2c921 Branch: refs/heads/ignite-1794 Commit: 0cb2c92152ea944d3313aa493bfce1f5191bc263 Parents: 1cd3cac Author: Dmitriy Govorukhin <dmitriy.govoruk...@gmail.com> Authored: Wed Apr 19 19:44:49 2017 +0300 Committer: Alexey Goncharuk <alexey.goncha...@gmail.com> Committed: Wed Apr 19 19:45:40 2017 +0300 ---------------------------------------------------------------------- .../store/jdbc/CacheAbstractJdbcStore.java | 37 +++-- .../cache/store/jdbc/CacheJdbcPojoStore.java | 1 - .../store/jdbc/CacheJdbcPojoStoreTest.java | 147 ++++++++++++++----- .../ignite/testframework/junits/IgniteMock.java | 4 + 4 files changed, 129 insertions(+), 60 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/0cb2c921/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java index 1c7e9dd..625d3cd 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java @@ -537,23 +537,36 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>, /** * @param type Type name to check. + * @param binarySupported True if binary marshaller enable. * @return {@code True} if class not found. */ - protected TypeKind kindForName(String type) { + protected TypeKind kindForName(String type, boolean binarySupported) { if (BUILT_IN_TYPES.contains(type)) return TypeKind.BUILT_IN; + if (binarySupported) + return TypeKind.BINARY; + try { Class.forName(type); return TypeKind.POJO; } - catch(ClassNotFoundException ignored) { - return TypeKind.BINARY; + catch (ClassNotFoundException e) { + throw new CacheException("Failed to find class " + type + + " (make sure the class is present in classPath or use BinaryMarshaller)", e); } } /** + * @param type Type name to check. + * @return {@code True} if class not found. + */ + protected TypeKind kindForName(String type) { + return kindForName(type, ignite.configuration().getMarshaller() instanceof BinaryMarshaller); + } + + /** * @param cacheName Cache name to check mappings for. * @return Type mappings for specified cache name. * @throws CacheException If failed to initialize cache mappings. @@ -587,11 +600,7 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>, String keyType = type.getKeyType(); String valType = type.getValueType(); - TypeKind keyKind = kindForName(keyType); - - if (!binarySupported && keyKind == TypeKind.BINARY) - throw new CacheException("Key type has no class [cache=" + U.maskName(cacheName) + - ", type=" + keyType + "]"); + TypeKind keyKind = kindForName(keyType, binarySupported); checkTypeConfiguration(cacheName, keyKind, keyType, type.getKeyFields()); @@ -601,21 +610,11 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>, throw new CacheException("Key type must be unique in type metadata [cache=" + U.maskName(cacheName) + ", type=" + keyType + "]"); - TypeKind valKind = kindForName(valType); + TypeKind valKind = kindForName(valType, binarySupported); checkTypeConfiguration(cacheName, valKind, valType, type.getValueFields()); entryMappings.put(keyTypeId, new EntryMapping(cacheName, dialect, type, keyKind, valKind, sqlEscapeAll)); - - // Add one more binding to binary typeId for POJOs, - // because object could be passed to store in binary format. - if (binarySupported && keyKind == TypeKind.POJO) { - keyTypeId = typeIdForTypeName(TypeKind.BINARY, keyType); - - valKind = valKind == TypeKind.POJO ? TypeKind.BINARY : valKind; - - entryMappings.put(keyTypeId, new EntryMapping(cacheName, dialect, type, TypeKind.BINARY, valKind, sqlEscapeAll)); - } } Map<String, Map<Object, EntryMapping>> mappings = new HashMap<>(cacheMappings); http://git-wip-us.apache.org/repos/asf/ignite/blob/0cb2c921/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java index 00a8ade..8244c6c 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java @@ -23,7 +23,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; http://git-wip-us.apache.org/repos/asf/ignite/blob/0cb2c921/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java index be38541..1a76321 100644 --- a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java +++ b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java @@ -17,6 +17,7 @@ package org.apache.ignite.cache.store.jdbc; +import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -28,14 +29,16 @@ import java.util.Collection; import java.util.UUID; import java.util.concurrent.ConcurrentLinkedQueue; import javax.cache.integration.CacheWriterException; - +import org.apache.ignite.Ignite; import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.binary.BinaryObjectBuilder; import org.apache.ignite.cache.store.jdbc.dialect.H2Dialect; import org.apache.ignite.cache.store.jdbc.model.Organization; import org.apache.ignite.cache.store.jdbc.model.OrganizationKey; import org.apache.ignite.cache.store.jdbc.model.Person; import org.apache.ignite.cache.store.jdbc.model.PersonComplexKey; import org.apache.ignite.cache.store.jdbc.model.PersonKey; +import org.apache.ignite.internal.binary.BinaryMarshaller; import org.apache.ignite.internal.processors.cache.CacheEntryImpl; import org.apache.ignite.internal.util.typedef.CI2; import org.apache.ignite.internal.util.typedef.internal.U; @@ -57,6 +60,12 @@ public class CacheJdbcPojoStoreTest extends GridAbstractCacheStoreSelfTest<Cache /** Person count. */ protected static final int PERSON_CNT = 100000; + /** Ignite. */ + private Ignite ig; + + /** Binary enable. */ + private boolean binaryEnable; + /** * @throws Exception If failed. */ @@ -226,6 +235,12 @@ public class CacheJdbcPojoStoreTest extends GridAbstractCacheStoreSelfTest<Cache U.closeQuiet(conn); super.beforeTest(); + + Ignite ig = U.field(store, "ignite"); + + this.ig = ig; + + binaryEnable = ig.configuration().getMarshaller() instanceof BinaryMarshaller; } /** @@ -290,32 +305,49 @@ public class CacheJdbcPojoStoreTest extends GridAbstractCacheStoreSelfTest<Cache U.closeQuiet(conn); - final Collection<OrganizationKey> orgKeys = new ConcurrentLinkedQueue<>(); - final Collection<PersonKey> prnKeys = new ConcurrentLinkedQueue<>(); - final Collection<PersonComplexKey> prnComplexKeys = new ConcurrentLinkedQueue<>(); + final Collection<Object> orgKeys = new ConcurrentLinkedQueue<>(); + final Collection<Object> prnKeys = new ConcurrentLinkedQueue<>(); + final Collection<Object> prnComplexKeys = new ConcurrentLinkedQueue<>(); IgniteBiInClosure<Object, Object> c = new CI2<Object, Object>() { @Override public void apply(Object k, Object v) { - if (k instanceof BinaryObject) - k = ((BinaryObject)k).deserialize(); - - if (v instanceof BinaryObject) - v = ((BinaryObject)k).deserialize(); - - if (k instanceof OrganizationKey && v instanceof Organization) - orgKeys.add((OrganizationKey)k); - else if (k instanceof PersonKey && v instanceof Person) - prnKeys.add((PersonKey)k); - else if (k instanceof PersonComplexKey && v instanceof Person) { - PersonComplexKey key = (PersonComplexKey)k; - - Person val = (Person)v; - - assertTrue("Key ID should be the same as value ID", key.getId() == val.getId()); - assertTrue("Key orgID should be the same as value orgID", key.getOrgId() == val.getOrgId()); - assertEquals("name" + key.getId(), val.getName()); - - prnComplexKeys.add((PersonComplexKey)k); + if (binaryEnable){ + if (k instanceof BinaryObject && v instanceof BinaryObject) { + BinaryObject key = (BinaryObject)k; + BinaryObject val = (BinaryObject)v; + + String keyType = key.type().typeName(); + String valType = val.type().typeName(); + + if (OrganizationKey.class.getName().equals(keyType) + && Organization.class.getName().equals(valType)) + orgKeys.add(key); + + if (PersonKey.class.getName().equals(keyType) + && Person.class.getName().equals(valType)) + prnKeys.add(key); + + if (PersonComplexKey.class.getName().equals(keyType) + && Person.class.getName().equals(valType)) + prnComplexKeys.add(key); + } + } + else { + if (k instanceof OrganizationKey && v instanceof Organization) + orgKeys.add(k); + else if (k instanceof PersonKey && v instanceof Person) + prnKeys.add(k); + else if (k instanceof PersonComplexKey && v instanceof Person) { + PersonComplexKey key = (PersonComplexKey)k; + + Person val = (Person)v; + + assertTrue("Key ID should be the same as value ID", key.getId() == val.getId()); + assertTrue("Key orgID should be the same as value orgID", key.getOrgId() == val.getOrgId()); + assertEquals("name" + key.getId(), val.getName()); + + prnComplexKeys.add(k); + } } } }; @@ -326,15 +358,16 @@ public class CacheJdbcPojoStoreTest extends GridAbstractCacheStoreSelfTest<Cache assertEquals(PERSON_CNT, prnKeys.size()); assertEquals(PERSON_CNT, prnComplexKeys.size()); - Collection<OrganizationKey> tmpOrgKeys = new ArrayList<>(orgKeys); - Collection<PersonKey> tmpPrnKeys = new ArrayList<>(prnKeys); - Collection<PersonComplexKey> tmpPrnComplexKeys = new ArrayList<>(prnComplexKeys); + Collection<Object> tmpOrgKeys = new ArrayList<>(orgKeys); + Collection<Object> tmpPrnKeys = new ArrayList<>(prnKeys); + Collection<Object> tmpPrnComplexKeys = new ArrayList<>(prnComplexKeys); orgKeys.clear(); prnKeys.clear(); prnComplexKeys.clear(); - store.loadCache(c, OrganizationKey.class.getName(), "SELECT name, city, id FROM ORGANIZATION", + store.loadCache( + c, OrganizationKey.class.getName(), "SELECT name, city, id FROM ORGANIZATION", PersonKey.class.getName(), "SELECT org_id, id, name FROM Person WHERE id < 1000"); assertEquals(ORGANIZATION_CNT, orgKeys.size()); @@ -384,20 +417,29 @@ public class CacheJdbcPojoStoreTest extends GridAbstractCacheStoreSelfTest<Cache U.closeQuiet(conn); - final Collection<PersonComplexKey> prnComplexKeys = new ConcurrentLinkedQueue<>(); + final Collection<Object> prnComplexKeys = new ConcurrentLinkedQueue<>(); IgniteBiInClosure<Object, Object> c = new CI2<Object, Object>() { @Override public void apply(Object k, Object v) { - if (k instanceof BinaryObject) - k = ((BinaryObject)k).deserialize(); - - if (v instanceof BinaryObject) - v = ((BinaryObject)k).deserialize(); - - if (k instanceof PersonComplexKey && v instanceof Person) - prnComplexKeys.add((PersonComplexKey)k); - else - fail("Unexpected entry [key=" + k + ", value=" + v + "]"); + if (binaryEnable) { + if (k instanceof BinaryObject && v instanceof BinaryObject) { + BinaryObject key = (BinaryObject)k; + BinaryObject val = (BinaryObject)v; + + String keyType = key.type().typeName(); + String valType = val.type().typeName(); + + if (PersonComplexKey.class.getName().equals(keyType) + && Person.class.getName().equals(valType)) + prnComplexKeys.add(key); + } + } + else { + if (k instanceof PersonComplexKey && v instanceof Person) + prnComplexKeys.add(k); + else + fail("Unexpected entry [key=" + k + ", value=" + v + "]"); + } } }; @@ -450,7 +492,7 @@ public class CacheJdbcPojoStoreTest extends GridAbstractCacheStoreSelfTest<Cache ses.newSession(null); try { - store.write(new CacheEntryImpl<>(k1, v1)); + store.write(new CacheEntryImpl<>(wrap(k1), wrap(v1))); fail("CacheWriterException wasn't thrown."); } @@ -479,4 +521,29 @@ public class CacheJdbcPojoStoreTest extends GridAbstractCacheStoreSelfTest<Cache assertNull(store.load(k)); } + + /** + * @param obj Object. + */ + private Object wrap(Object obj) throws IllegalAccessException { + if (binaryEnable) { + Class<?> cls = obj.getClass(); + + BinaryObjectBuilder builder = ig.binary().builder(cls.getName()); + + for (Field f : cls.getDeclaredFields()) { + if (f.getName().contains("serialVersionUID")) + continue; + + f.setAccessible(true); + + builder.setField(f.getName(), f.get(obj)); + } + + return builder.build(); + } + + return obj; + } + } http://git-wip-us.apache.org/repos/asf/ignite/blob/0cb2c921/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java index ab918e5..ea53345 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java @@ -56,6 +56,7 @@ import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.NearCacheConfiguration; import org.apache.ignite.internal.binary.BinaryCachingMetadataHandler; import org.apache.ignite.internal.binary.BinaryContext; +import org.apache.ignite.internal.binary.BinaryMarshaller; import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl; import org.apache.ignite.internal.processors.cacheobject.NoOpBinary; import org.apache.ignite.internal.util.typedef.internal.U; @@ -328,6 +329,9 @@ public class IgniteMock implements Ignite { return typeName.hashCode(); } }; + + if (marshaller instanceof BinaryMarshaller) + ctx.configure((BinaryMarshaller)marshaller, configuration()); } binaryMock = new NoOpBinary() {