diff options
Diffstat (limited to 'app/models/gs_cluster_sync_log_entry.rb')
-rw-r--r-- | app/models/gs_cluster_sync_log_entry.rb | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/app/models/gs_cluster_sync_log_entry.rb b/app/models/gs_cluster_sync_log_entry.rb new file mode 100644 index 0000000..063ff23 --- /dev/null +++ b/app/models/gs_cluster_sync_log_entry.rb @@ -0,0 +1,99 @@ +class GsClusterSyncLogEntry < ActiveRecord::Base + attr_accessible :gs_node_id, :class_name, :action, :content, :status, :history, + :homebase_ip_address, :waiting_to_be_synced, :association_method, + :association_uuid + + validates :class_name, + :presence => true + + validates :action, + :presence => true + + validates :content, + :presence => true + + after_create :apply_to_local_database + + def apply_to_local_database + if self.homebase_ip_address != HOMEBASE_IP_ADDRESS + if self.class_name.constantize.new.attribute_names.include?('is_native') + case self.action + when 'create' + new_local_copy = self.class_name.constantize.new( + JSON(self.content). + delete_if{|key, value| ['id','updated_at','created_at']. + include?(key) }, + :without_protection => true) + new_local_copy.is_native = false + find_and_connect_to_an_association(new_local_copy) + if new_local_copy.save(:validate => false) + logger.info "Created local copy of #{self.class_name} with the ID #{new_local_copy.id}. #{new_local_copy.to_s}" + else + logger.error "Couldn't create a local copy of #{self.class_name} with the ID #{new_local_copy.id}. #{new_local_copy.errors.to_yaml}" + end + + when 'update' + local_copy = find_local_copy + if local_copy + # Only update an object if the update it self is newer than the local object. + # + if local_copy.updated_at < JSON(self.content)['updated_at'].to_time + local_copy.update_attributes(JSON(self.content).delete_if{|key, value| ['id','updated_at','created_at'].include?(key) }, :without_protection => true) + find_and_connect_to_an_association(local_copy) + if local_copy.save(:validate => false) + logger.info "Updated local copy of #{self.class_name} with the ID #{local_copy.id}. #{local_copy.to_s}" + else + logger.error "Couldn't update local copy of #{self.class_name} with the ID #{local_copy.id}. #{local_copy.errors.to_yaml}" + end + else + logger.error "Didn't update local copy of #{self.class_name} with the ID #{local_copy.id} because of a race condition (the local version was newer than the update). Please check GsClusterSyncLogEntry ID #{self.id}." + end + else + logger.error "Couldn't find local copy of #{self.class_name}. #{self.content}" + end + + when 'destroy' + local_copy = find_local_copy + if local_copy + local_copy.destroy + logger.info "Destroyed local copy of #{self.class_name} with the ID #{local_copy.id}. #{local_copy.to_s}" + else + logger.error "Couldn't find local copy of #{self.class_name}. #{self.content}" + end + end + else + logger.error "The class #{self.class_name} doesn't offer the attribute is_native. Can't synchronize without." + end + end + end + + def find_local_copy + self.class_name.constantize.find_by_uuid(JSON(self.content)['uuid']) + end + + # Connect to the association (e.g. User to a SipAccount) + # + def find_and_connect_to_an_association(local_copy) + if !(self.association_method.blank? || self.association_uuid.blank?) && (self.association_method_changed? || self.association_uuid_changed?) + name_of_the_association_type = local_copy.attribute_names.delete_if{|x| !x.include?('_type')}.first + association = local_copy.send(name_of_the_association_type).constantize.where(:uuid => self.association_uuid).first + if association + local_copy.send "#{association_method}=", association + end + end + end + + def populate_other_cluster_nodes + if self.homebase_ip_address == HOMEBASE_IP_ADDRESS && self.waiting_to_be_synced == true + if GsNode.where(:push_updates_to => true).count > 0 + GsNode.where(:push_updates_to => true).each do |gs_node| + RemoteGsNode::GsClusterSyncLogEntry.site = gs_node.site + remote_enty = RemoteGsNode::GsClusterSyncLogEntry.create(self.attributes.delete_if{|key, value| ['id','updated_at','created_at'].include?(key) }) + self.update_attributes(:waiting_to_be_synced => false) + self.save + end + end + end + end + +end |