Ejemplo n.º 1
0
 def save_object(self, obj_type, obj_id, values={}):
     """
     Save cache data for an object in the database.
     """
 
     # If the ACL object exists
     if len(ACLObjects.get_values(obj_type)) > 0:
         try:
             
             # If supplied, values argument must be a dictionary
             if values and not isinstance(values, dict):
                 self.log.error('Failed to cache object <%s> of type <%s>, values keyword must contain a dictionary' % (obj_id, obj_type))
                 return False
             
             # Get the ACL object definition
             acl_object = ACLObjects.get(type=obj_type)
     
             # Get an instance of the object class
             obj_mod    = importlib.import_module(getattr(acl_object, 'obj_mod'))
             obj_class  = getattr(obj_mod, getattr(acl_object, 'obj_cls'))
             obj_key    = getattr(acl_object, 'obj_key')
             
             # Create the object filter
             obj_filter = {}
             obj_filter[obj_key] = obj_id
             
             # Define the cache object filter
             cache_filter = {
                 'object_type': obj_type,
                 'object_id':   obj_id
             }
             
             # If the object doesn't exist anymore
             if not obj_class.objects.filter(**obj_filter).count():
                 
                 # If an expired cache entry exists
                 if DBClusterCache.objects.filter(**cache_filter).count():
                     self.log.info('Base object <%s> of type <%s> no longer exists, flushing cached entry' % (obj_id, obj_type))
                     
                     # Flush the old cache entry
                     DBClusterCache.objects.filter(**cache_filter).delete()
                     
                 # Expired cache object cleared
                 return True
             
             # Get the object details
             obj_details = base64.encodestring(json.dumps(list(obj_class.objects.filter(**obj_filter).values(**values))[0], cls=DjangoJSONEncoder))
             obj_size    = sys.getsizeof(obj_details)
             obj_hash    = hashlib.md5(obj_details).hexdigest()
             
             # If the object already has a cache entry
             if DBClusterCache.objects.filter(**cache_filter).count():
                 
                 # Get the current cache entry
                 cache_row = list(DBClusterCache.objects.filter(**cache_filter).values())[0]
                 
                 # If the cached data hasn't changed
                 if cache_row['object_hash'] == obj_hash:
                     return self.log.info('Cached data unchanged for object <%s> of type <%s>' % (obj_id, obj_type))
                 
                 # Update the cached data
                 DBClusterCache.objects.filter(**cache_filter).update(object_data=obj_details, object_size=obj_size)
                 
             # Create a new cache entry
             else:
             
                 # Create the cache entry
                 DBClusterCache(
                     object_type = acl_object,
                     object_id   = obj_id,
                     object_data = obj_details,
                     object_hash = obj_hash,
                     object_size = obj_size
                 ).save()
             
             # Object successfull cached
             self.log.info('Cached data for object <%s> of type <%s>: bytes_cached=%s, hash=%s' % (obj_id, obj_type, str(obj_size), obj_hash))
             
         # Critical error when caching object
         except Exception as e:
             self.log.exception('Failed to cache object <%s> of type <%s>: %s' % (obj_id, obj_type, str(e)))
         
     # ACL object does not exist
     else:
         self.log.error('Cannot cache object <%s> of type <%s>, ACL object type not found' % (obj_id, obj_type))
Ejemplo n.º 2
0
 def _get_from_model(self, obj_type, obj_id, values={}, filters={}):
     """
     Retrieve object details directly from the model.
     
     @param obj_type: The type of object to retrieve
     @type  obj_type: str
     @param obj_id:   The ID of the object to retrieve
     @type  obj_id:   str
     @param values:   Extra parameters to pass to the values QuerySet method
     @type  values:   dict
     @param filters:  Extra filter parameters
     @type  filters:  dict
     """
     self.log.info('Retrieving object data from model: type=%s, id=%s' % (obj_type, repr(obj_id)))
     
     # Get the ACL object definition
     acl_object  = ACLObjects.get(obj_type)
     
     # Get an instance of the object class
     obj_mod     = importlib.import_module(getattr(acl_object, 'obj_mod'))
     obj_class   = getattr(obj_mod, getattr(acl_object, 'obj_cls'))
     obj_key     = getattr(acl_object, 'obj_key')
     
     # Create the object filter
     obj_filter  = {}
     
     # If retrieving a single object
     if obj_id:
         obj_filter[obj_key] = obj_id
     
     # Create the query object
     query_obj = obj_class.objects
     
     # If an object filter is defined
     if obj_filter:
         self.log.info('Applying object filters: %s' % json.dumps(obj_filter))
         query_obj = query_obj.filter(**obj_filter)
         
     # If a values filter is defined
     if filters:
         self.log.info('Applying value filters: %s' % json.dumps(filters))
         query_obj = query_obj.filter(**filters)
     
     # If no filters were defined
     if not obj_filter and not filters:
         self.log.info('No filters defined, retrieving all objects')
         query_obj = query_obj.all()
     
     # Log the constructed query object
     self.log.info('Constructed object query: %s' % str(query_obj))
     
     # Attempt to retrieve the object
     obj_details = list(query_obj.values())
     
     # Log the retrieved details
     log_data = json.dumps(obj_details, cls=DjangoJSONEncoder)
     self.log.info('Retrieved object details: length=%s, data=%s' % (len(log_data), (log_data[:75] + '...') if len(log_data) > 75 else log_data))
     
     # If the object doesn't exist
     if len(obj_details) == 0:
         return None
     
     # Return the object details
     if not obj_id:
         return obj_details
     return obj_details[0]