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 > > >
