[
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/%[email protected]%3E
--
This message was sent by Atlassian JIRA
(v6.2#6252)