ignite-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Vladislav Pyatkov <vpyat...@gridgain.com>
Subject Re: Controlling type of object inserted in IgniteCache
Date Mon, 04 Apr 2016 16:32:49 GMT
Hi Ignite dev comunity,

I an start to work on https://issues.apache.org/jira/browse/IGNITE-2909
The problem occurs when we add objects in cache in node where no
information abut types (for example server node without end user classes in
classpath).
After reserch, I try to find way to solve issue.
The intention:
1) Add method to CacheConfiguration#setTypeNames(String keyClass String
valClass) (like suggested earlier)
2) Before every modification cache need check class matching (in put(),
putAll(), replace() etc).
Maybe it not simple string comparison.
3) If class is matching then continue saving, else throwing exception.

In my opinion, it actualy only if put cache value as BynaryObject (get
class binaryObject.type().typeName()).
If we check the class name, it is not relevant objects do not put to cache.

I would like to hear the comunity opinion.

On Wed, Mar 30, 2016 at 7:08 AM, Denis Magda <dmagda@gridgain.com> wrote:

> 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 <
>> valentin.kulichenko@gmail.com> 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 <dmagda@gridgain.com>
>>> 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
>>>>
>>>>
>

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