Class: LdapChangelogConnector

Inherits:
RubySync::Connectors::LdapConnector show all
Defined in:
lib/ruby_sync/connectors/ldap_changelog_connector.rb

Overview

$VERBOSE = true

Instance Attribute Summary

Attributes inherited from RubySync::Connectors::BaseConnector

#is_vault, #name, #once_only, #pipeline

Instance Method Summary collapse

Methods inherited from RubySync::Connectors::LdapConnector

#[], #add, #delete, #each_entry, fields, #modify, sample_config, #started, #target_transform

Methods inherited from RubySync::Connectors::BaseConnector

#add, #associate, #association_context, #association_for, #association_key_for, #association_to_path_dbm_filename, #associations_for, #can_act_as_vault?, class_for, class_name_for, #clean, #create_operations_for, #dbm_path, #digest, #each_entry, #entry_for_own_association_key, fields, #find_associated, #has_entry_for_key?, #is_delete_echo?, #is_echo?, #is_vault?, #mirror_dbm_filename, #own_association_key_for, #path_for_association, #path_for_own_association_key, #path_to_association_dbm_filename, #remove_association, #remove_associations, #remove_mirror, sample_config, #start, #started, #stop, #stopped, #sync_started, #sync_stopped, #test_delete, #test_modify

Methods included from RubySync::Utilities

#as_array, #base_path, #call_if_exists, #connector_called, #effective_operations, #ensure_dir_exists, #find_base_path, #get_preference, #get_preference_file_path, #include_in_search_path, #log_progress, #perform_operations, #pipeline_called, #set_preference, #something_called, #with_rescue

Constructor Details

#initialize(options = {}) ⇒ LdapChangelogConnector

Returns a new instance of LdapChangelogConnector.



32
33
34
35
36
37
# File 'lib/ruby_sync/connectors/ldap_changelog_connector.rb', line 32

def initialize options={}
  super options 
  @last_change_number = 1
  # TODO: Persist the current CSN, for now we'll just skip to the end of the changelog
  skip_existing_changelog_entries
end

Instance Method Details

#each_changeObject

Look for changelog entries. This is not supported by all LDAP servers Changelog entries have these attributes targetdn changenumber objectclass changes changetime changetype dn

TODO: Detect presence/location of changelog from root DSE



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/ruby_sync/connectors/ldap_changelog_connector.rb', line 49

def each_change
  with_ldap do |ldap|
    log.debug "@last_change_number = #{@last_change_number}"
    filter = "(changenumber>=#{@last_change_number})"
    first = true
    @full_refresh_required = false
    ldap.search :base => changelog_dn, :filter =>filter do |change|
      change_number = change.changenumber[0].to_i
      if first
        first = false
        # TODO: Persist the change_number so that we don't do a full resync everytime rubysync starts
        if change_number != @last_change_number
          log.warn "Earliest change number (#{change_number}) differs from that recorded (#{@last_change_number})."
          log.warn "A full refresh is required."
          @full_refresh_required = true
          break
        end
      else
        @last_change_number = change_number if change_number > @last_change_number
        # todo: A proper DN object would be nice instead of string manipulation
        target_dn = change.targetdn[0].gsub(/\s*,\s*/,',')
        if target_dn =~ /#{search_base}$/oi
          change_type = change.changetype[0]
          event = event_for_changelog_entry(change)
          yield event
        end
      end
    end
  end
end

#skip_existing_changelog_entriesObject



81
82
83
84
85
86
87
88
89
90
# File 'lib/ruby_sync/connectors/ldap_changelog_connector.rb', line 81

def skip_existing_changelog_entries
  with_ldap do |ldap|
    filter = "(changenumber>=#{@last_change_number})"
    @full_refresh_required = false
    ldap.search :base => changelog_dn, :filter =>filter do |change|
      change_number = change.changenumber[0].to_i
      @last_change_number = change_number if change_number > @last_change_number
    end
  end
end

#test_add(id, details) ⇒ Object

Called by unit tests to inject data



94
95
96
97
# File 'lib/ruby_sync/connectors/ldap_changelog_connector.rb', line 94

def test_add id, details
  details << RubySync::Operation.new(:add, "objectclass", ['inetOrgPerson', 'organizationalPerson', 'person', 'top', 'RubySyncSynchable'])
  add id, details
end