Sounds good. Created the ticket
https://issues.apache.org/jira/browse/IGNITE-2909
On 3/30/2016 2:40 AM, Dmitriy Setrakyan wrote:
On Tue, Mar 29, 2016 at 3:49 PM, Valentin Kulichenko <
[email protected]> wrote:
How about adding setTypeNames() configuration property that will be similar
to setTypes(), but for binary objects?
Agree. Sounds like it will solve the problem, no?
-Val
On Tue, Mar 29, 2016 at 1:56 AM, Denis Magda <[email protected]> wrote:
Igniters,
In some cases there is necessity to control a type of object that is
being
inserted into a cache.
Presently this kind of check is accomplished at compile time only relying
on Java Generics. However it doesn't prevent us from connecting to a
cluster using a non-generic instance of a cache and put any kind of data
in
it.
This may be not a harmful intention but rather a silly developer mistake.
I see the following options here.
1) First CacheInterceptor based approach.
Specify a unique interceptor per cache setting expected typeName/typeId
to
it at construction time and the interceptor will validate object type in
onBeforePut() method.
Disadvantages:
- cache interceptor have to be created for every cache;
- cache interceptor class has to be located in servers classpath. It
means
that we won't be able to start a new cache with its interceptor later.
2) Second CacheInterceptor based approach.
A generic cache interceptor can be created. It will be populated with a
map of cacheName->typeName values at initialization time and validation
may
look like below
@CacheNameResource String cacheName;
public Object onBeforePut(Cache.Entry<String,BinaryObject>
entry,BinaryObject newVal) {
if (typeId ==null) {
synchronized (cachesTypes) {
if (typeId ==null) {
String allowedType =cachesTypes.get(cacheName);
if (allowedType ==null) {
typeId =0;
throw new IgniteException("No type for cache name:"
+cacheName);
}
typeId = Ignition.ignite().binary().typeId(allowedType);
}
}
}
if (newVal.type().typeId() !=typeId)
throw new IgniteException("Invalid object type [validType="
+typeId +", wrongType=" + newVal.type().typeId());
return newVal;
}
However if we want to start a new cache then we won't be able to add a
new
entry to "cacheTypes" map. 3) MutableConfiguration.setTypes(Class<K>
keyType, Class<V> valueType) based approach According to the spec
Implementations may further perform type checking on mutative cache
operations * and throw a {@link ClassCastException} if these checks fail.
If we see that value type is BinaryObject (this can be a case if there
BinaryObject is not going to be deserialized because no real class exists
for it) then we can take its typeName/typeId and compare it with the same
parameters at the time instances of BinaryObjects will be put to cache
using cache.put(). So, every time cache.put()/putAll() are called we can
check type on client nodes before sending values to servers. In case of
CacheEntryProcessors servers will double-check an entry type after the
entry processor does its job. I prefer the latest approach. Any thoughts
on
this? -- Denis