ignite-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Denis Magda <dma...@gridgain.com>
Subject Controlling type of object inserted in IgniteCache
Date Tue, 29 Mar 2016 08:56:43 GMT
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

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message