Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
SPOPS::LDAP::MultiDataUsercContributed Perl DocSPOPS::LDAP::MultiDatasource(3)

       SPOPS::LDAP::MultiDatasource -- SPOPS::LDAP functionality but fetching
       objects from multiple datasources

	# In your configuration
	my $config = {
	   class      => 'My::LDAPThings',
	   datasource => [ 'main', 'secondary',	'tertiary' ],
	   isa	      => [ ... 'SPOPS::LDAP::MultiDatasource' ],

	# Fetch	an object and see where	it came	from

	my $object = My::LDAPThings->fetch( 'superuser'	);
	print "My DN is	", $object->dn,	" and I	came from $object->{_datasource}";

       This class extends SPOPS::LDAP with one purpose:	be able	to fetch
       objects from multiple datasources. This can happen when you have	got
       objects dispersed among multiple	directories -- for instance, your
       'Accounting' department is on one LDAP server and your 'Development'
       department on another. One class	can (more or less -- see below)	link
       the two LDAP servers.

       Every object is tagged with the datasource it came from (in the
       "_datasource" property, if you ever need	it), and any calls to "save()"
       or "remove()" will use this datasource to retrieve the proper
       connection for the object.

       The "fetch()" method is the only	functional method overridden from
       SPOPS::LDAP. The	"fetch_group()"	or "fetch_iterator()" methods will
       only use	the first datasource in	the listing, whatever datasource you
       pass in with the	parameter 'connect_key'	or whatever LDAP connection
       handle you pass in with the parameter 'ldap'. If	you want to retrieve
       objects from multiple datasources using the same	filter,	use the
       "fetch_group_all()" method.

       The "fetch_iterator()" method is	not supported at all for multiple
       datasources -- use "fetch_group_all()" in conjunction with
       SPOPS::Iterator::WrapList if your implementation	expects	an
       SPOPS::Iterator object.

       There are a number of items to configure	and setup to use this class.
       Please see SPOPS::Manual::Configuration for the configuration keys used
       by this module.

   Methods You Must Implement
       connection_info(	$connect_key )

       This method should look at the $connect_key and return a	hashref	of
       information used	to connect to the LDAP directory. Keys (hopefully
       self-explanatory) should	be:

       o   host	($)

       o   base_dn ($)

       Other keys are optional and can be used in conjunction with a
       connection/resource manager (example below).

       o   port	($) (optional, default is '389')

       o   bind_dn ($) (optional, will use anonymous bind without)

       o   bind_password ($) (optional,	only used if 'bind_dn' specified)

       For example:

	package	My::ConnectionManage;

	use strict;

	my $connections	= {
	   main	       => { host => 'localhost',
			    base_dn => 'dc=MyCompanyEast,dc=com' },
	   accounting  => { host => '',
			    base_dn => 'dc=MyCompanyWest,dc=com' },
	   development => { host => '',
			    base_dn => 'dc=MyCompanyNorth,dc=com' },
	   etc	       => { host => '',
			    base_dn => 'dc=MyCompanyBranch,dc=com' },

	sub connection_info {
	    my ( $class, $connect_key )	= @_;
	    return \%{ $connections->{ $connect_key } };

       Then put	this class into	the 'isa' for your SPOPS class:

	my $spops = {
	  class	     =>	'My::Person',
	  isa	     =>	[ 'My::ConnectionManage', 'SPOPS::LDAP::MultiDatasource' ],

       global_datasource_handle( $connect_key )

       You will	need an	implementation that deals with multiple
       configurations. For example:

	package	My::DSManage;

	use strict;
	use Net::LDAP;

	my %DS = ();

	sub global_datasource_handle {
	    my ( $class, $connect_key )	= @_;
	    unless ( $connect_key ) {
		SPOPS::Exception->throw( "Cannot retrieve handle without connect key" );
	    unless ( $DS{ $connect_key } ) {
		my $ldap_info =	$class->connection_info( $connect_key );
		$ldap_info->{port} ||= 389;
		my $ldap = Net::LDAP->new( $ldap_info->{host},
					   port	=> $ldap_info->{port} );
		unless ( $ldap ) {
		    SPOPS::Exception->throw( "Cannot create LDAP connection: $@" );
		my ( %bind_params );
		if ( $ldap_info->{bind_dn} ) {
		    $bind_params{dn}	   = $ldap_info->{bind_dn};
		    $bind_params{password} = $ldap_info->{bind_password};
		my $bind_msg = $ldap->bind( %bind_params );
		if ( $bind_msg->code ) {
		    SPOPS::Exception::LDAP->throw( "Cannot bind	to directory: "	. $bind_msg->error,
						   { code   => $bind_msg->code,
						     action => 'global_datasource_handle' } );
		$DS{ $connect_key } = $ldap;
	    return $DS{	$connect_key };

       Then put	this class into	the 'isa' for your SPOPS class:

	my $spops = {
	  class	     =>	'My::Person',
	  isa	     =>	[ 'My::DSManage', 'SPOPS::LDAP::MultiDatasource' ],

       Someone with a thinking cap on might put	the previous two items in the
       same class :-)

       fetch( $id, \%params )

       Given the normal	parameters for "fetch()", tries	to retrieve an object
       matching	either the $id or the 'filter' specified in "\%params" from
       one of the datasources. When it finds an	object it is immediately

       If you pass in the key 'ldap' in	\%params, this functions as the
       "fetch()" does in SPOPS::LDAP and multiple datasources are not used.

       Returns:	SPOPS object (if found), or undef.

       fetch_group_all(	\%params )

       Given the normal	parameters for "fetch_group()",	retrieves all objects
       matching	the parameters from all	datasources. Use with caution.

       Returns:	Arrayref of SPOPS objects.

       save( \%params )

       Just pass along the right handle	to the actual "save()" method in

       remove( \%params	)

       Just pass along the right handle	to the actual "remove()" method	in

       base_dn(	$connect_key )

       Returns the full	base DN	associated with	$connect_key.

       get_partial_dn( $connect_key )

       Retrieves the partial base DN associated	with $connect_key.


       If called, returns either the value of the config key
       'default_datasource' or the value of the	class constant
       'DEFAULT_CONNECT_KEY', which is normally	'main'.

       None known.

       Test some more.


       Example in SPOPS	distribution: eg/

       Copyright (c) 2001-2004 MSN Marketing Service Nordwest, GmbH. All
       rights reserved.

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

       Chris Winters <>

perl v5.32.1			  2004-06-02   SPOPS::LDAP::MultiDatasource(3)


Want to link to this manual page? Use this URL:

home | help