directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Gerald Turner (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (DIRAPI-156) LdapNetworkConnection.addSchema doesn't register attribute types
Date Fri, 21 Mar 2014 17:47:47 GMT

    [ https://issues.apache.org/jira/browse/DIRAPI-156?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13943297#comment-13943297
] 

Gerald Turner commented on DIRAPI-156:
--------------------------------------

Opps!  Kiran was correct (although I didn't find out until late yesterday).  This bug/patch
fixes LdapNetworkConnection, but ultimately (due to DIRAPI-153 being fixed), I really want
to import the OpenLDAP schema to the SchemaManager to be shared with future connections. 
So instead I lifted the loadSchema code out of LdapNetworkConnection and hard-coded it into
my initialization routine.

I suppose it would be more elegant to move this method to DefaultSchemaManager.

Some background:

Last summer I began working with M20 to work with our OpenLDAP server that has mostly generic
stuff: "nis" and a few custom objectClasses and attributes that extend "inetorgperson".  I
tried three flavors of loading the schema (of which the first two failed, settled on the third):
  * Load the schema from the OpenLDAP server (DIRAPI-154).
  * Load the schema with combination of ApacheDS native schema via JarLdifSchemaLoader plus
external OpenLDAP schema file (DIRAPI-156).
  * Hack a copy ApacheDS native schema with our custom objectClasses and attributes via LdifSchemaLoader.

That last choice isn't very good because performance is bad (in lieu of DIRAPI-153) and it
seems dirty having a copy of the ApacheDS schema.

Yesterday I updated to M21 to see how the initialization code could be improved, ended up
with the following:
{code}
    private SchemaManager configureSchemaManager() throws UserManagerException {
        String[] schemas = config.getStringArray("LDAP.Schemas");
        if (schemas == null || schemas.length == 0)
            schemas = new String[] {
                    "system",
                    "core",
                    "cosine",
                    "inetorgperson",
                    "nis",
                    "apache", // Need "apache" for UUID
                };
        if (log.isLoggable(Level.FINEST))
            log.finest("configureSchemaManager: Loading the following internal ApacheDS schemas:
" + StringUtils.join(schemas, ", "));

        JarLdifSchemaLoader loader;
        Collection<Schema> loaderSchemas;
        try {
            loader = new JarLdifSchemaLoader();
            loaderSchemas = loader.getAllSchemas();
        }
        catch (Exception e) {
            throw new UserManagerException("Failed to initialize schema loader: " + e.getMessage(),
e);
        }

        for (Schema schema : loaderSchemas) {
            String name = schema.getSchemaName();
            if (ArrayUtils.contains(schemas, name)) {
                if (schema.isEnabled()) {
                    if (log.isLoggable(Level.FINEST))
                        log.finest("configureSchemaManager: Schema " + name + " is enabled
by default");
                }
                else {
                    if (log.isLoggable(Level.FINEST))
                        log.finest("configureSchemaManager: Enabling Schema " + name);
                    schema.enable();
                }
            }
            else {
                if (schema.isEnabled()) {
                    if (log.isLoggable(Level.FINEST))
                        log.finest("configureSchemaManager: Disabling Schema " + name);
                    schema.disable();
                }
            }
        }

        SchemaManager schemaManager = new DefaultSchemaManager(loader);
        try {
            schemaManager.loadAllEnabled();
        }
        catch (Exception e) {
            throw new UserManagerException("Failed to load schemas: " + e.getMessage(), e);
        }

        File schemaDirectory;
        try {
            String schemaDirectoryConfig =
                config.getString("LDAP.SchemaDirectory", null);
            if (schemaDirectoryConfig != null)
                schemaDirectory = new File(schemaDirectoryConfig);
            else
                schemaDirectory = findSchemaDirectory();
        }
        catch (Exception e) {
            throw new UserManagerException("Failed to determine OpenLDAP schema directory:
" + e.getMessage(), e);
        }

        if (log.isLoggable(Level.FINEST))
            log.finest("configureSchemaManager: Importing OpenLDAP schema files from directory
" + schemaDirectory + " (*.schema)");
        Registries registries = schemaManager.getRegistries();
        List<Throwable> errors = new ArrayList<>();
        Collection<File> files =
            FileUtils.listFiles(schemaDirectory,
                                new String[] { "schema" },
                                true);
        for (File file : files) {
            if (log.isLoggable(Level.FINEST))
                log.finest("configureSchemaManager: Importing OpenLDAP schema from file "
+ file);
            OpenLdapSchemaParser parser;
            try {
                parser = new OpenLdapSchemaParser();
                parser.setQuirksMode(true);
                parser.parse(file);
            }
            catch (Exception e) {
                throw new UserManagerException("Failed to parse OpenLDAP schema file " + file
+ ": " + e.getMessage(), e);
            }

            for (AttributeType attributeType : parser.getAttributeTypes()) {
                registries.buildReference(errors, attributeType);
                if (!errors.isEmpty())
                    throw new UserManagerException("Errors accumlated while importing attributeType
" + attributeType + " from OpenLDAP schema " + file + ": " + errors, errors.get(0));
                try {
                    registries.getAttributeTypeRegistry().register(attributeType);
                }
                catch (Exception e) {
                    throw new UserManagerException("Failed to register attributeType " + attributeType
+ " from OpenLDAP schema " + file + ": " + e.getMessage(), e);
                }
            }

            for (ObjectClass objectClass : parser.getObjectClassTypes()) {
                registries.buildReference(errors, objectClass);
                if (!errors.isEmpty())
                    throw new UserManagerException("Errors accumlated while importing objectClass
" + objectClass + " from OpenLDAP schema " + file + ": " + errors, errors.get(0));
                try {
                    registries.getObjectClassRegistry().register(objectClass);
                }
                catch (Exception e) {
                    throw new UserManagerException("Failed to register objectClass " + objectClass
+ " from OpenLDAP schema " + file + ": " + e.getMessage(), e);
                }
            }
        }

        return schemaManager;
    }
{code}

This is much cleaner, I can drop the copy of ApacheDS schema and only carry our internal/custom
OpenLDAP schema (which is a direct copy from what the Sys Admins use rather than have to be
reformated for JarLdifSchemaLoader metadata).

Note that I discovered that I had to enable the "apache" schema - our OpenLDAP schema makes
use of UUID attribute types.  Without "apache" enabled the initialization fails with the following
logging output:
{noformat}
  10:29:41,920 INFO  [org.apache.directory.api.ldap.model.schema.registries.helper.AttributeTypeHelper]
(main) ERR_04306 Cannot find a Syntax object 1.3.6.1.1.16.1 while building cross-references
for the uuid AttributeType.
  10:29:41,921 INFO  [org.apache.directory.api.ldap.model.schema.registries.helper.AttributeTypeHelper]
(main) ERR_04308 Cannot find an Equality MatchingRule object for UUIDMatch while building
cross-references for the uuid AttributeType.
{noformat}
... makes me wonder whether 1.3.6.1.1.16.* syntaxes should move to "system"?


> LdapNetworkConnection.addSchema doesn't register attribute types
> ----------------------------------------------------------------
>
>                 Key: DIRAPI-156
>                 URL: https://issues.apache.org/jira/browse/DIRAPI-156
>             Project: Directory Client API
>          Issue Type: Bug
>    Affects Versions: 1.0.0-M20
>            Reporter: Gerald Turner
>            Assignee: Kiran Ayyagari
>             Fix For: 1.0.0-M22
>
>         Attachments: DIRAPI-156.patch
>
>
> I'm loading schema with code like:
>   con.loadSchema(new JarLdifSchemaLoader());
>   con.addSchema("custom.schema");
> Later an exception is thrown while I'm handling some search results.  The entry in question
looks like:
>   dn: cn=ICRCSSTAccess,ou=Roles,o=jaas,dc=xoint,dc=net
>   objectClass: groupOfNames
>   cn: ICRCSSTAccess
>   member: uid=gturner,ou=people,dc=xoint,dc=net
>   member: uuid=98bb35ee-9ff3-444f-9925-7fe762810d50,o=Asus,ou=customers,dc=xoint,dc=net
> The code where the exception is thrown looks like:
>   Attribute memberAttribute = entry.get("member");
>   if (memberAttribute != null)
>     for (Iterator<Value<?>> iterator = memberAttribute.iterator();
>          iterator.hasNext();) {
>       @SuppressWarnings("unchecked")
>       Value<String> value = (Value<String>) iterator.next();
>       String member = value.getValue();
>       Dn memberDn = new Dn(context.getSchemaManager(), member);
>       members.add(memberDn);
>     }
> It is the Dn instantiation that throws the following stacktrace:
>   
>   org.apache.directory.api.ldap.model.exception.LdapInvalidDnException: ERR_04188 The
type cannot be empty or null
>     at org.apache.directory.api.ldap.model.name.Dn.atavOidToName(Dn.java:1106)
>     at org.apache.directory.api.ldap.model.name.Dn.rdnOidToName(Dn.java:1143)
>     at org.apache.directory.api.ldap.model.name.Rdn.apply(Rdn.java:454)
>     at org.apache.directory.api.ldap.model.name.Dn.apply(Dn.java:1202)
>     at org.apache.directory.api.ldap.model.name.Dn.apply(Dn.java:1281)
>     at org.apache.directory.api.ldap.model.name.Dn.<init>(Dn.java:287)
>     at net.xoint.usermanager.model.Role.<init>(Role.java:45)
>     at net.xoint.usermanager.model.LDAPLoader.loadRoles(LDAPLoader.java:75)
>     at net.xoint.usermanager.model.LDAPLoader.load(LDAPLoader.java:52)
>     at net.xoint.usermanager.UserManagerTest.test2(UserManagerTest.java:134)
>   Caused by: org.apache.directory.api.ldap.model.exception.LdapInvalidDnException: ERR_04188
The type cannot be empty or null
>     at org.apache.directory.api.ldap.model.name.Ava.apply(Ava.java:476)
>     at org.apache.directory.api.ldap.model.name.Dn.atavOidToName(Dn.java:1100)
>     ... 36 more
>   Caused by: org.apache.directory.api.ldap.model.exception.LdapNoSuchAttributeException:
ERR_04269 ATTRIBUTE_TYPE for OID 1.3.6.1.4.1.38541.2.1.3 do\
> es not exist!
>     at org.apache.directory.api.ldap.model.schema.registries.DefaultAttributeTypeRegistry.lookup(DefaultAttributeTypeRegistry.java:293)
>     at org.apache.directory.api.ldap.model.schema.registries.DefaultAttributeTypeRegistry.lookup(DefaultAttributeTypeRegistry.java:47)
>     at org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager.lookupAttributeTypeRegistry(DefaultSchemaManager.java:1604)
>     at org.apache.directory.api.ldap.model.name.Ava.apply(Ava.java:470)
>     ... 37 more
>   Caused by: org.apache.directory.api.ldap.model.exception.LdapException: ERR_04269 ATTRIBUTE_TYPE
for OID 1.3.6.1.4.1.38541.2.1.3 does not exist!
>     at org.apache.directory.api.ldap.model.schema.registries.DefaultSchemaObjectRegistry.lookup(DefaultSchemaObjectRegistry.java:176)
>     at org.apache.directory.api.ldap.model.schema.registries.DefaultAttributeTypeRegistry.lookup(DefaultAttributeTypeRegistry.java:289)
>     ... 40 more
> OID 1.3.6.1.4.1.38541.2.1.3 is the uuid attribute that is part of a member DN.  "custom.schema"
defines it as follows:
>   
>   attributetype ( 1.3.6.1.4.1.38541.2.1.3
>                   NAME 'uuid'
>                   DESC 'The customer UUID'
>                   EQUALITY UUIDMatch
>                   SYNTAX 1.3.6.1.1.16.1
>                   SINGLE-VALUE )
> While scrutinizing the source, looking for why this attribute wouldn't be found in the
DefaultSchemaObjectRegistry#byName Map for the AttributeTypeRegistry, I'm beginning to suspect
that somewhere around where LdapNetworkConnection#addSchema is calling AttributeTypeRegistry#addMappingFor,
it hasn't quite finished the job, perhaps something like calling AttributeTypeRegistry#register
(which seems to be the only method that put's into the byName Map).
> Mailing List reference: https://mail-archives.apache.org/mod_mbox/directory-api/201308.mbox/%3C87eh9mhl46.fsf@zoth-ommog.unzane.com%3E



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Mime
View raw message