Class: UU::ObjectStore::ObjectStore

Inherits:
Object
  • Object
show all
Defined in:
uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb,
uu_objectstore-0.6.5/lib/uu/object_store/object_store/uu_object.rb,
uu_objectstore-0.6.5/lib/uu/object_store/object_store/uu_object_query.rb,
uu_objectstore-0.6.5/lib/uu/object_store/object_store/concurrency_strategy.rb,
uu_objectstore-0.6.5/lib/uu/object_store/object_store/object_store_exception.rb,
uu_objectstore-0.6.5/lib/uu/object_store/object_store/object_store_fatal_exception.rb

Overview

Object store component providing external storage for uuApps data.

Examples:

Basic usage:

obj_store = UU::ObjectStore::ObjectStore.init(object_store_uri)
begin
  object = obj_store.load(:dataKey => data_key, :schemaUri => schema_uri)
  object.data[:attribute] = value
  obj_store.save(object)
ensure
  obj_store.close
end

Defined Under Namespace

Classes: ConcurrencyStrategy, ObjectStoreException, ObjectStoreFatalException, UUObject, UUObjectQuery

Constant Summary

Class Method Summary (collapse)

Instance Method Summary (collapse)

Class Method Details

+ (Object) init(object_store_uri, parameters = {})

Creates new instance of object store.

Parameters:

  • object_store_uri (String, UU::OS::UESURI)

    URI of object store

  • parameters (Hash) (defaults to: {})

    Additional initialization parameters

Options Hash (parameters):

  • concurrencyStrategy (ConcurrencyStrategy)

    Concurrency strategy to be used (optional, defaults to VERSION_BASED)

  • credentials (String, File)

    Authentication token to be used for object store operations (optional, see Session.login for possible values)

  • session (UU::OS::Security::Session)

    Instance of session to be used for object store operations (optional, alternative to using credentials parameter)

  • waitTimeout (Fixnum)

    Maximum time (in seconds) to wait for uuObject unlock when loading uuObject (defaults to 30 seconds, usable only for locking concurrency strategies)



73
74
75
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 73

def self.init(object_store_uri, parameters = {})
  ObjectStore.new(object_store_uri, parameters)
end

Instance Method Details

- (UUObject) attach(uu_object)

Attaches given serialized uuObject (value obtained from detach) to this object store instance. Attached uuObject must use same type of concurrency strategy as this instance of object store. Also in case of locking concurrency strategy, attach method can be called only before any other uuObject is loaded using this instance of object store.

Parameters:

  • uu_object (String)

    Serialized uuObject (value obtained from detach)

Returns:



440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 440

def attach(uu_object)
  uu_object = ObjectStore::UUObject.new(uu_object)
  lock_uri = uu_object.send(:lock_uri)
  if (((lock_uri.nil?) && ((@concurrency_strategy == ConcurrencyStrategy::SINGLE_LOCKING) || (@concurrency_strategy == ConcurrencyStrategy::BULK_LOCKING))) ||
  (!lock_uri.nil?) && (@concurrency_strategy != ConcurrencyStrategy::SINGLE_LOCKING) && (@concurrency_strategy != ConcurrencyStrategy::BULK_LOCKING))
    raise 'uuObject can be attached only to ObjectStore using same type of concurrency strategy as ObjectStore from which it was detached.'
  end
  if ((!@lock_uri.nil?) && (lock_uri != @lock_uri))
    raise 'Instance of ObjectStore uses locking concurrency strategy and has already some loaded uuObjects. Attach can be called only on fresh instance of ObjectStore.'
  end
  @lock_uri = lock_uri if @lock_uri.nil?
  return uu_object
end

- (Object) close

Method closes instance of object store and also removes all existing locks on managed uuObjects. Once instance of object store is closed, it cannot be used (Throws exception for each invoked operation. New instance must be created to access object store).



404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 404

def close
  @closed = true
  if @lock_uri.nil?
    @authn_token = nil
    return
  end
  authenticate do
    svc = UU::OS::REST::RemoteClient.new(self.class)
    svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
    svc.post(:unlock, @object_store_uri, {:lockUri => @lock_uri}.to_json)
  end
  @authn_token = nil
  return
end

- (Object) delete(parameters)

Method deletes existing uuObject. In case deleted object is locked by concurrent process, deletion of object fails and concurrent modification exception is thrown.

Parameters:

  • parameters (UUObject)

    Instance of loaded uuObject

  • parameters (String, UU::OS::UESURI)

    URI of uuObject

  • parameters (Hash)

    Unique uuObject identification data

Options Hash (parameters):

  • :uri (String, UU::OS::UESURI)

    URI of uuObject

  • :dataKey (String)

    Unique identifier of uuObject within schema (must be set if :uri parameter is not used)

  • :schemaUri (String, UU::OS::UESURI)

    URI of schema where to look for object (must be set if :uri parameter is not used)

Raises:

  • (ObjectStoreException)

    Exception caused by wrong input or wrong usage of API. Specific cause can be determined based on error code.

  • (ObjectStoreFatalException)

    Internal uuObjectStore exception. Specific cause can be determined based on error code.



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 319

def delete(parameters)
  if @closed
    raise 'Instance of object store is closed. Initialize new instance of object store.'
  end
  if ((parameters.kind_of?UUObject) && (parameters.send(:lock_uri) != @lock_uri))
    raise 'Instance of uuObject was loaded by another instance of ObjectStore. You have to use same instance of ObjectStore.'
  end
  authenticate do
    obj_uri = nil
    if (parameters.kind_of?UUObject)
      # Parameter was instance of uuObject
      obj_uri = parameters.uri
      return if obj_uri.nil?
    elsif (parameters.kind_of?String) || (parameters.kind_of?UU::OS::UESURI)
      # Parameter was uuObject URI
      obj_uri = parameters
    elsif parameters.kind_of?Hash
      if parameters.has_key?:uri
        # Parameter was Hash with uuObject URI
        obj_uri = parameters[:uri]
      else
        # We have to find uuObject URI via query (using dataKey and schema)
        data_key = parameters[:dataKey]
        data_key = parameters[:data_key] if data_key.nil?
        schema_uri = parameters[:schemaUri]
        schema_uri = parameters[:schema_uri] if schema_uri.nil?
        raise ArgumentError.new('Parameters must contain uuObject URI or dataKey and schema URI.') if (data_key.nil?) || (schema_uri.nil?)

        svc = UU::OS::REST::RemoteClient.new(self.class)
        svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
        svc.add_parameter(:query, "dataKey = '#{data_key}'")
        svc.add_parameter(:schemaUri, schema_uri)
        raw = svc.raw_get(:getObjectList, @object_store_uri)
        result = svc.process_result(raw)
        @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
        result = UU::OS::REST::ResultList.new(ObjectStore::UUObjectQuery, ObjectStore::UUObject, result)
        if result.size == 0
          # Raise fake main entity exception which is valid for this situation
          init_data = "{\"code\":\"UU.OS/E05207.M00\",\"errorMessages\":[{\"code\":\"UU.OS/E05207.M00\",\"localizedMessage\":\"Object with dataKey #{data_key} does not exist in schema #{schema_uri}.\"}]}"
          raise UU::OS::REST::MainEntityException.new(init_data)
        end

        obj_attr = result[0]
        obj_uri = obj_attr.uri
      end
    else
      raise ArgumentError.new('Parameter must be uuObject URI or Hash (containing unique object identification).')
    end
    svc = UU::OS::REST::RemoteClient.new(self.class)
    svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
    svc.add_parameter(:lockUri, @lock_uri)
    raw = svc.raw_post(:deleteObject, obj_uri)
    svc.process_result(raw)
    @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
  end
  return
end

- (String) detach(uu_object)

Detaches instance of given uuObject from this object store instance. Result of method is serialized uuObject in JSON format. This result should be used only for calling of attach method. For common serialization of uuObject use method to_json directly on instance of uuObject.

Parameters:

  • uu_object (UUObject)

    Instance of uuObject

Returns:

  • (String)

    Serialized uuObject



426
427
428
429
430
431
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 426

def detach(uu_object)
  if ((!uu_object.uri.nil?) && (uu_object.send(:lock_uri) != @lock_uri))
    raise 'Instance of uuObject was loaded by another instance of ObjectStore. You have to use same instance of ObjectStore.'
  end
  return uu_object.to_json(:detach_format => true, :inc_orig_data => (@concurrency_strategy == ConcurrencyStrategy::MERGE))
end

- (UUObject) load(parameters)

Loads object according to given parameters. In case of locking concurrency strategy is used (SINGLE_LOCKING or BULK_LOCKING) loaded object is locked, or concurrent modification exception is thrown if object is already locked by concurrent process.

Parameters:

  • parameters (String, UU::OS::UESURI)

    URI of uuObject

  • parameters (Hash)

    Unique uuObject identification data

Options Hash (parameters):

  • :uri (String, UU::OS::UESURI)

    URI of uuObject

  • :dataKey (String)

    Unique identifier of uuObject within schema (must be set if :uri parameter is not used)

  • :schemaUri (String, UU::OS::UESURI)

    URI of schema where to look for object (must be set if :uri parameter is not used)

Returns:

Raises:

  • (ObjectStoreException)

    Exception caused by wrong input or wrong usage of API. Specific cause can be determined based on error code.

  • (ObjectStoreFatalException)

    Internal uuObjectStore exception. Specific cause can be determined based on error code.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 125

def load(parameters)
  if @closed
    raise 'Instance of object store is closed. Initialize new instance of object store.'
  end
  authenticate do
    obj_uri = nil
    if (parameters.kind_of?String) || (parameters.kind_of?UU::OS::UESURI)
      # Parameter was uuObject URI
      obj_uri = parameters
    elsif (parameters.kind_of?Hash) && (parameters.has_key?:uri)
      # Parameter was Hash with uuObject URI
      obj_uri = parameters[:uri]
    end
    uu_object = nil
    if !obj_uri.nil?
      # In case of locking strategies do not load object immediately. It has to be loaded after lock (to fetch most recent data).
      if (@concurrency_strategy != ConcurrencyStrategy::SINGLE_LOCKING) && (@concurrency_strategy != ConcurrencyStrategy::BULK_LOCKING)
        # uuObject URI was given as parameter, we have to load uuObject
        svc = UU::OS::REST::RemoteClient.new(self.class)
        svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
        raw = svc.raw_get(:getObjectAttributes, obj_uri)
        result = svc.process_result(raw)
        @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
        uu_object = ObjectStore::UUObject.new(result)
      end
    elsif (parameters.kind_of?Hash)
      # We have to find uuObject URI via query (using dataKey and schema).
      # This needs to be done even for locking strategies, because we have no object URI to call lock on.
      data_key = parameters[:dataKey]
      data_key = parameters[:data_key] if data_key.nil?
      schema_uri = parameters[:schemaUri]
      schema_uri = parameters[:schema_uri] if schema_uri.nil?
      raise ArgumentError.new('Parameters must contain uuObject URI or dataKey and schema URI.') if (data_key.nil?) || (schema_uri.nil?)

      svc = UU::OS::REST::RemoteClient.new(self.class)
      svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
      svc.add_parameter(:schemaUri, schema_uri)
      svc.add_parameter(:query, "dataKey = '#{data_key}'")
      raw = svc.raw_get(:getObjectList, @object_store_uri)
      result = svc.process_result(raw)
      @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
      result = UU::OS::REST::ResultList.new(ObjectStore::UUObjectQuery, ObjectStore::UUObject, result)
      if result.size == 0
        # Raise fake main entity exception which is valid for this situation
        init_data = "{\"code\":\"UU.OS/E05207.M00\",\"errorMessages\":[{\"code\":\"UU.OS/E05207.M00\",\"localizedMessage\":\"Object with dataKey #{data_key} does not exist in schema #{schema_uri}.\"}]}"
        raise UU::OS::REST::MainEntityException.new(init_data)
      end

      uu_object = result[0]
      obj_uri = uu_object.uri
    else
      raise ArgumentError.new('Parameter must be uuObject URI or Hash (containing unique object identification).')
    end

    if (@concurrency_strategy == ConcurrencyStrategy::SINGLE_LOCKING) || (@concurrency_strategy == ConcurrencyStrategy::BULK_LOCKING)
      # In case of locking strategy, we have to lock and reload object
      svc = UU::OS::REST::RemoteClient.new(self.class)
      svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
      result = nil
      wait_for_unlock(@wait_timeout) do
        raw = svc.raw_post(:lockAndGetObjectAttributes, @object_store_uri, {:lockUri => @lock_uri, :objectUri => obj_uri, :objects => [obj_uri]}.to_json)
        result = svc.process_result(raw)
      end
      @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
      uu_object = ObjectStore::UUObject.new(result)
      @lock_uri = uu_object.send(:lock_uri)
    end

    return uu_object
  end
end

- (UU::OS::REST::ResultList<UUObjectQuery, UUObject>) query(schema_uri, query = nil)

Method finds all uuObjects matching given criteria. Keep in mind, that in case of locking version strategy (SINGLE_LOCKING or BULK_LOCKING) returned objects are not automatically locked. Each of object to be modified must be explicitly locked using load method, else concurrent modification exception will be thrown upon object save. It is not possible to query attributes of nested structures, only first level attributes are supported.

Parameters:

Returns:

Raises:

  • (ObjectStoreException)

    Exception caused by wrong input or wrong usage of API. Specific cause can be determined based on error code.

  • (ObjectStoreFatalException)

    Internal uuObjectStore exception. Specific cause can be determined based on error code.



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 285

def query(schema_uri, query = nil)
  if @closed
    raise 'Instance of object store is closed. Initialize new instance of object store.'
  end
  authenticate do
    dto = ObjectStore::UUObjectQuery.new(query)
    svc = UU::OS::REST::RemoteClient.new(self.class)
    svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
    svc.add_parameter(:query, dto.query)
    svc.add_parameter(:schemaUri, schema_uri)
    svc.add_parameter(:pageIndex, dto.page_index) if !dto.page_index.nil?
    svc.add_parameter(:pageSize, dto.page_size) if !dto.page_size.nil?
    if ((dto.query_parameters.kind_of?Hash) && (dto.query_parameters.size > 0))
      svc.add_parameter(:queryParameters, dto.query_parameters.to_json)
    end
    raw = svc.raw_get(:getObjectList, @object_store_uri)
    result = svc.process_result(raw)
    @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
    return UU::OS::REST::ResultList.new(ObjectStore::UUObjectQuery, ObjectStore::UUObject, result)
  end
end

- (UU::OS::UESURI) save(uu_object)

Method saves given uuObject (updates existing or creates new). Method may throw concurrent modification exception in case saved object is locked by another process, or if current object state violates constraints required by used concurrency strategy.

Each object can be saved only once, it has to be re-loaded before next modification (with exception of concurrency strategy NONE). Method will throw exception on repeated object save.

Parameters:

  • uu_object (UUObject)

    Instance of uuObject

Returns:

Raises:

  • (ObjectStoreException)

    Exception caused by wrong input or wrong usage of API. Specific cause can be determined based on error code.

  • (ObjectStoreFatalException)

    Internal uuObjectStore exception. Specific cause can be determined based on error code.



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 210

def save(uu_object)
  if @closed
    raise 'Instance of object store is closed. Initialize new instance of object store.'
  end
  if (@concurrency_strategy != ConcurrencyStrategy::NONE) && (uu_object.send(:saved))
    raise 'Instance of uuObject was already saved. Re-load uuObject before next modification.'
  end
  if (!uu_object.uri.nil?)
    if ((uu_object.send(:lock_uri).nil?) && ((@concurrency_strategy == ConcurrencyStrategy::SINGLE_LOCKING) || (@concurrency_strategy == ConcurrencyStrategy::BULK_LOCKING)))
      # Check-in can be called only if object is locked
      raise 'Instance of uuObject cannot be saved. It has to be loaded via load method when locking concurrency strategy is used.'
    end
    if (uu_object.send(:lock_uri) != @lock_uri)
      raise 'Instance of uuObject was loaded by another instance of ObjectStore. You have to use same instance of ObjectStore.'
    end
  end
  authenticate do
    obj_uri = nil
    if uu_object.uri.nil?
      # New object
      payload = {:schemaUri => uu_object.schema_uri, :dataKey => uu_object.data_key, :data => uu_object.data}
      svc = UU::OS::REST::RemoteClient.new(self.class)
      svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
      raw = svc.raw_post(:createObject, @object_store_uri, payload.to_json)
      result = svc.process_result(raw)
      @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
      obj_uri = UU::OS::UESURI.new(result)
    else
      # Updated object
      svc = UU::OS::REST::RemoteClient.new(self.class)
      svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
      payload = {:version => uu_object.version, :concurrencyStrategy => @concurrency_strategy, :lockUri => @lock_uri}
      if @concurrency_strategy == ConcurrencyStrategy::MERGE
        # For concurrency strategy MERGE, prepare custom set of data
        orig_data = uu_object.data.send(:orig_data)
        data = {}
        orig_data.each_key do |key|
          data[key] = uu_object.data[key]
        end
        payload[:originalData] = orig_data
        payload[:data] = data
        if uu_object.send(:data_key_changed)
          payload[:originalDataKey] = uu_object.send(:orig_data_key)
          payload[:dataKey] = uu_object.data_key
        end
      else
        if uu_object.send(:data_key_changed)
          payload[:originalDataKey] = uu_object.send(:orig_data_key)
        end
        payload[:dataKey] = uu_object.data_key
        payload[:data] = uu_object.data
      end
      raw = svc.raw_post(:setObjectAttributes, uu_object.uri, payload.to_json)
      result = svc.process_result(raw)
      @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
      obj_uri = UU::OS::UESURI.new(result)
    end
    uu_object.send(:saved=, true)
    return obj_uri
  end
end

- (Object) unlock(uu_object)

This method is usable only for locking concurrency strategies. It allows to unlock uuObject without calling save method (for SINGLE_LOCKING strategy) or closing of object store instance (for both SINGLE_LOCKING or BULK_LOCKING). In case object is not locked, or locking strategy is not used, method does nothing.

Parameters:

  • uu_object (UUObject)

    Instance of locked uuObject

Raises:

  • (ObjectStoreException)

    Exception caused by wrong input or wrong usage of API. Specific cause can be determined based on error code.

  • (ObjectStoreFatalException)

    Internal uuObjectStore exception. Specific cause can be determined based on error code.



387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'uu_objectstore-0.6.5/lib/uu/object_store/object_store.rb', line 387

def unlock(uu_object)
  return if uu_object.nil?
  return if uu_object.uri.nil?
  return if @lock_uri.nil?
  authenticate do
    svc = UU::OS::REST::RemoteClient.new(self.class)
    svc.add_header(:uu_objectstore_authorization, @@wallet.get_token(@object_store_uri))
    raw = svc.raw_post(:unlock, @object_store_uri, {:lockUri => @lock_uri, :objects => [uu_object.uri]}.to_json)
    svc.process_result(raw)
    @@wallet.put_token(@object_store_uri, raw[2][:uu_objectstore_authorization])
  end
  return
end