Treequel::

ContentSyncControl

module
Included Modules
Treequel::Control
Treequel::Constants

A Treequel::Control module that implements the “Content Sync” control (RFC 4533)

NOTICE: This control currently doesn't do anything, as it depends on Intermediate Responses, which the underlying Ruby-LDAP library doesn't support (yet).

== Usage

As with all Controls, you must first register the control with the Treequel::Directory object you're intending to search:

dir = Treequel.directory( 'ldap://ldap.acme.com/dc=acme,dc=com' ) dir.register_controls( Treequel::ContentSyncControl )

Once that's done, any Treequel::Branchset you create will have the on_sync method:

# Build DHCP records out of all the hosts in the directory, then rebuild # everything when a host record changes. hosts = dir.filter( :ou => Hosts ).collection hosts.filter( :objectClass => :ipHost ).on_sync do || # end

See deveiate.org/projects/Treequel/ticket/6 Ticket: Add support for the RFC4533 Content Sync operation.

Constants

OID

The control's OID

SYNC_MODE_REFRESH

Sync mode constants (from RFC4533, section 2.2)

SYNC_MODE_REFRESH_AND_PERSIST

Attributes

content_sync_callback[RW]

The callback to call when results change

Public Class Methods

anchor
new()

Add the requisite instance variables to including Branchsets.

# File lib/treequel/controls/contentsync.rb, line 52
def initialize
        self.log.notice "The ContentSync control doesn't work yet -- it requires support for " +
                "IntermediateResponses, which Ruby-LDAP doesn't do yet. " +
                "See http://deveiate.org/projects/Treequel/ticket/6 for updates on the " +
                "status of this."
        @content_sync_callback = nil
end

Public Instance Methods

anchor
each( &block )

Override the Enumerable method to update the cookie value each time a page is fetched.

# File lib/treequel/controls/contentsync.rb, line 80
def each( &block )
        super do |branch|
                self.log.debug "Looking for the sync control in controls: %p" % [ branch.controls ]
                branch.controls.each do |control|
                        self.log.debug "  got a %s control: %p" % [
                                CONTROL_NAMES[control.oid],
                                control.decode,
                        ]

                        case control.oid
                        when CONTROL_OIDS[:sync_state]
                                self.log.debug "  got a 'state' control"
                                block.call( branch )
                        when CONTROL_OIDS[:sync_done]
                                self.log.debug "  got a 'done' control"
                                break
                        else
                                self.log.info "  got an unexpected control (%p)" % [ control ]
                        end
                end
        end
end
anchor
on_sync( &callback )

Clone the Branchset with a persistent change callback.

# File lib/treequel/controls/contentsync.rb, line 70
def on_sync( &callback )
        newset = self.clone
        newset.content_sync_callback = callback

        return newset
end

Protected Instance Methods

anchor
get_server_controls()

Treequel::Control API – Get a configured LDAP::Control object for this Branchset.

# File lib/treequel/controls/contentsync.rb, line 131
def get_server_controls
        controls = super
        value = self.make_sync_control_value( 1, '', false )
        return controls << LDAP::Control.new( OID, value, true )
end
anchor
make_sync_control_value( mode, cookie, reload_hint )

Make the ASN.1 string for the control value out of the given mode, cookie, reload_hint.

# File lib/treequel/controls/contentsync.rb, line 110
def make_sync_control_value( mode, cookie, reload_hint )
        # (http://tools.ietf.org/html/rfc4533#section-2.2):
        # syncRequestValue ::= SEQUENCE {
        #     mode ENUMERATED {
        #         -- 0 unused
        #         refreshOnly       (1),
        #         -- 2 reserved
        #         refreshAndPersist (3)
        #     },
        #     cookie     syncCookie OPTIONAL,
        #     reloadHint BOOLEAN DEFAULT FALSE
        # }
        encoded_vals = [
                OpenSSL::ASN1::Enumerated.new( SYNC_MODE_REFRESH_AND_PERSIST )
        ]
        return OpenSSL::ASN1::Sequence.new( encoded_vals ).to_der
end