You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2020/03/29 17:14:48 UTC
[syncope] branch 2_1_X updated: Upgrading ApacheDS (#170)
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/2_1_X by this push:
new 8f2402e Upgrading ApacheDS (#170)
8f2402e is described below
commit 8f2402e6a41125e97cdf715a60d4339a8312dbb9
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Sun Mar 29 19:14:41 2020 +0200
Upgrading ApacheDS (#170)
---
fit/build-tools/pom.xml | 17 +-
.../normalization/NormalizationInterceptor.java | 628 +++++++++++++++++++++
.../fit/buildtools/ApacheDSStartStopListener.java | 115 ++--
pom.xml | 24 +-
4 files changed, 694 insertions(+), 90 deletions(-)
diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml
index 2a5c9d5..4fb23dc 100644
--- a/fit/build-tools/pom.xml
+++ b/fit/build-tools/pom.xml
@@ -55,24 +55,15 @@ under the License.
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
- <artifactId>apacheds-service-builder</artifactId>
- <version>${apacheds.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.directory.api</groupId>
- <artifactId>api-ldap-codec-standalone</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.directory.api</groupId>
- <artifactId>api-ldap-model</artifactId>
+ <artifactId>apacheds-core-annotations</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.directory.api</groupId>
- <artifactId>api-ldap-schema-data</artifactId>
+ <groupId>org.apache.directory.server</groupId>
+ <artifactId>apacheds-service-builder</artifactId>
</dependency>
<dependency>
<groupId>org.apache.directory.api</groupId>
- <artifactId>api-util</artifactId>
+ <artifactId>api-ldap-codec-standalone</artifactId>
</dependency>
<dependency>
diff --git a/fit/build-tools/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java b/fit/build-tools/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java
new file mode 100644
index 0000000..e5cfb5a
--- /dev/null
+++ b/fit/build-tools/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java
@@ -0,0 +1,628 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.normalization;
+
+// Remove this class as soon as upgrade to ApacheDS 2.0.0.AM27 is available
+
+// CHECKSTYLE:OFF
+
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.EmptyCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Modification;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeTypeException;
+import org.apache.directory.api.ldap.model.filter.AndNode;
+import org.apache.directory.api.ldap.model.filter.BranchNode;
+import org.apache.directory.api.ldap.model.filter.EqualityNode;
+import org.apache.directory.api.ldap.model.filter.ExprNode;
+import org.apache.directory.api.ldap.model.filter.LeafNode;
+import org.apache.directory.api.ldap.model.filter.NotNode;
+import org.apache.directory.api.ldap.model.filter.ObjectClassNode;
+import org.apache.directory.api.ldap.model.filter.OrNode;
+import org.apache.directory.api.ldap.model.filter.PresenceNode;
+import org.apache.directory.api.ldap.model.filter.UndefinedNode;
+import org.apache.directory.api.ldap.model.name.Ava;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.ldap.model.name.Rdn;
+import org.apache.directory.api.ldap.model.schema.AttributeType;
+import org.apache.directory.api.ldap.model.schema.normalizers.ConcreteNameComponentNormalizer;
+import org.apache.directory.api.ldap.model.schema.normalizers.NameComponentNormalizer;
+import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.api.InterceptorEnum;
+import org.apache.directory.server.core.api.filtering.EntryFilteringCursorImpl;
+import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.api.interceptor.BaseInterceptor;
+import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.CompareOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.api.normalization.FilterNormalizingVisitor;
+import org.apache.directory.server.i18n.I18n;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A name normalization service. This service makes sure all relative and distinguished
+ * names are normalized before calls are made against the respective interface methods
+ * on DefaultPartitionNexus.
+ *
+ * The Filters are also normalized.
+ *
+ * If the Rdn AttributeTypes are not present in the entry for an Add request,
+ * they will be added.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class NormalizationInterceptor extends BaseInterceptor
+{
+ /** logger used by this class */
+ private static final Logger LOG = LoggerFactory.getLogger( NormalizationInterceptor.class );
+
+ /** a filter node value normalizer and undefined node remover */
+ private FilterNormalizingVisitor normVisitor;
+
+
+ /**
+ * Creates a new instance of a NormalizationInterceptor.
+ */
+ public NormalizationInterceptor()
+ {
+ super( InterceptorEnum.NORMALIZATION_INTERCEPTOR );
+ }
+
+
+ /**
+ * Initialize the registries, normalizers.
+ */
+ @Override
+ public void init( DirectoryService directoryService ) throws LdapException
+ {
+ LOG.debug( "Initialiazing the NormalizationInterceptor" );
+
+ super.init( directoryService );
+
+ NameComponentNormalizer ncn = new ConcreteNameComponentNormalizer( schemaManager );
+ normVisitor = new FilterNormalizingVisitor( ncn, schemaManager );
+ }
+
+
+ /**
+ * The destroy method does nothing
+ */
+ @Override
+ public void destroy()
+ {
+ }
+
+
+ // ------------------------------------------------------------------------
+ // Normalize all Name based arguments for ContextPartition interface operations
+ // ------------------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void add( AddOperationContext addContext ) throws LdapException
+ {
+ Dn addDn = addContext.getDn();
+
+ if ( !addDn.isSchemaAware() )
+ {
+ addContext.setDn( new Dn( schemaManager, addDn ) );
+ }
+
+ Dn entryDn = addContext.getEntry().getDn();
+
+ if ( !entryDn.isSchemaAware() )
+ {
+ addContext.getEntry().setDn( new Dn( schemaManager, entryDn ) );
+ }
+
+ addRdnAttributesToEntry( addContext.getDn(), addContext.getEntry() );
+
+ next( addContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean compare( CompareOperationContext compareContext ) throws LdapException
+ {
+ Dn dn = compareContext.getDn();
+
+ if ( !dn.isSchemaAware() )
+ {
+ compareContext.setDn( new Dn( schemaManager, dn ) );
+ }
+
+ // Get the attributeType from the OID
+ try
+ {
+ AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( compareContext.getOid() );
+
+ // Translate the value from binary to String if the AT is HR
+ if ( attributeType.getSyntax().isHumanReadable() && ( !compareContext.getValue().isHumanReadable() ) )
+ {
+ compareContext.setValue( compareContext.getValue() );
+ }
+
+ compareContext.setAttributeType( attributeType );
+ }
+ catch ( LdapException le )
+ {
+ throw new LdapInvalidAttributeTypeException( I18n.err( I18n.ERR_266, compareContext.getOid() ) );
+ }
+
+ return next( compareContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void delete( DeleteOperationContext deleteContext ) throws LdapException
+ {
+ Dn dn = deleteContext.getDn();
+
+ if ( !dn.isSchemaAware() )
+ {
+ deleteContext.setDn( new Dn( schemaManager, dn ) );
+ }
+
+ next( deleteContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasEntry( HasEntryOperationContext hasEntryContext ) throws LdapException
+ {
+ Dn dn = hasEntryContext.getDn();
+
+ if ( !dn.isSchemaAware() )
+ {
+ hasEntryContext.setDn( new Dn( schemaManager, dn ) );
+ }
+
+ return next( hasEntryContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Entry lookup( LookupOperationContext lookupContext ) throws LdapException
+ {
+ Dn dn = lookupContext.getDn();
+
+ if ( !dn.isSchemaAware() )
+ {
+ lookupContext.setDn( new Dn( schemaManager, dn ) );
+ }
+
+ return next( lookupContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void modify( ModifyOperationContext modifyContext ) throws LdapException
+ {
+ Dn dn = modifyContext.getDn();
+
+ if ( !dn.isSchemaAware() )
+ {
+ modifyContext.setDn( new Dn( schemaManager, dn ) );
+ }
+
+ if ( modifyContext.getModItems() != null )
+ {
+ for ( Modification modification : modifyContext.getModItems() )
+ {
+ AttributeType attributeType = schemaManager.getAttributeType( modification.getAttribute().getId() );
+ modification.apply( attributeType );
+ }
+ }
+
+ next( modifyContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void move( MoveOperationContext moveContext ) throws LdapException
+ {
+ Dn moveDn = moveContext.getDn();
+
+ if ( !moveDn.isSchemaAware() )
+ {
+ moveContext.setDn( new Dn( schemaManager, moveDn ) );
+ }
+
+ Dn oldSuperiorDn = moveContext.getOldSuperior();
+
+ if ( !oldSuperiorDn.isSchemaAware() )
+ {
+ moveContext.setOldSuperior( new Dn( schemaManager, oldSuperiorDn ) );
+ }
+
+ Dn newSuperiorDn = moveContext.getNewSuperior();
+
+ if ( !newSuperiorDn.isSchemaAware() )
+ {
+ moveContext.setNewSuperior( new Dn( schemaManager, newSuperiorDn ) );
+ }
+
+ Dn newDn = moveContext.getNewDn();
+
+ if ( !newDn.isSchemaAware() )
+ {
+ moveContext.setNewDn( new Dn( schemaManager, newDn ) );
+ }
+
+ Rdn rdn = moveContext.getRdn();
+
+ if ( !rdn.isSchemaAware() )
+ {
+ moveContext.setRdn( new Rdn( schemaManager, rdn ) );
+ }
+
+ next( moveContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException
+ {
+ Rdn newRdn = moveAndRenameContext.getNewRdn();
+
+ if ( !newRdn.isSchemaAware() )
+ {
+ moveAndRenameContext.setNewRdn( new Rdn( schemaManager, newRdn ) );
+ }
+
+ Dn dn = moveAndRenameContext.getDn();
+
+ if ( !dn.isSchemaAware() )
+ {
+ moveAndRenameContext.setDn( new Dn( schemaManager, dn ) );
+ }
+
+ Dn newDn = moveAndRenameContext.getNewDn();
+
+ if ( !newDn.isSchemaAware() )
+ {
+ moveAndRenameContext.setNewDn( new Dn( schemaManager, newDn ) );
+ }
+
+ Dn newSuperiorDn = moveAndRenameContext.getNewSuperiorDn();
+
+ if ( !newSuperiorDn.isSchemaAware() )
+ {
+ moveAndRenameContext.setNewSuperiorDn( new Dn( schemaManager, newSuperiorDn ) );
+ }
+
+ next( moveAndRenameContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void rename( RenameOperationContext renameContext ) throws LdapException
+ {
+ // Normalize the new Rdn and the Dn if needed
+ Dn dn = renameContext.getDn();
+
+ if ( !dn.isSchemaAware() )
+ {
+ renameContext.setDn( new Dn( schemaManager, dn ) );
+ }
+
+ Rdn newRdn = renameContext.getNewRdn();
+
+ if ( !newRdn.isSchemaAware() )
+ {
+ renameContext.setNewRdn( new Rdn( schemaManager, newRdn ) );
+ }
+
+ Dn newDn = renameContext.getNewDn();
+
+ if ( !newDn.isSchemaAware() )
+ {
+ renameContext.setNewDn( new Dn( schemaManager, newDn ) );
+ }
+
+ // Push to the next interceptor
+ next( renameContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException
+ {
+ Dn dn = searchContext.getDn();
+
+ if ( !dn.isSchemaAware() )
+ {
+ searchContext.setDn( new Dn( schemaManager, dn ) );
+ }
+
+ ExprNode filter = searchContext.getFilter();
+
+ if ( filter == null )
+ {
+ LOG.warn( "undefined filter based on undefined attributeType not evaluted at all. Returning empty enumeration." );
+ return new EntryFilteringCursorImpl( new EmptyCursor<Entry>(), searchContext, schemaManager );
+ }
+
+ // Normalize the filter
+ filter = ( ExprNode ) filter.accept( normVisitor );
+
+ if ( filter == null )
+ {
+ LOG.warn( "undefined filter based on undefined attributeType not evaluted at all. Returning empty enumeration." );
+ return new EntryFilteringCursorImpl( new EmptyCursor<Entry>(), searchContext, schemaManager );
+ }
+
+ // We now have to remove the (ObjectClass=*) filter if it's present, and to add the scope filter
+ ExprNode modifiedFilter = removeObjectClass( filter );
+
+ searchContext.setFilter( modifiedFilter );
+
+ // TODO Normalize the returned Attributes, storing the UP attributes to format the returned values.
+ return next( searchContext );
+ }
+
+
+ /**
+ * Remove the (ObjectClass=*) node from an AndNode, if we have one.
+ */
+ private ExprNode handleAndNode( ExprNode node )
+ {
+ int nbNodes = 0;
+ AndNode newAndNode = new AndNode();
+
+ for ( ExprNode child : ( ( BranchNode ) node ).getChildren() )
+ {
+ ExprNode modifiedNode = removeObjectClass( child );
+
+ if ( !( modifiedNode instanceof ObjectClassNode ) )
+ {
+ newAndNode.addNode( modifiedNode );
+ nbNodes++;
+ }
+
+ if ( modifiedNode instanceof UndefinedNode )
+ {
+ // We can just return an Undefined node as nothing will get selected
+ return UndefinedNode.UNDEFINED_NODE;
+ }
+ }
+
+ switch ( nbNodes )
+ {
+ case 0:
+ // Unlikely... But (&(ObjectClass=*)) or (|(ObjectClass=*)) are still an option
+ return ObjectClassNode.OBJECT_CLASS_NODE;
+
+ case 1:
+ // We can safely remove the AND/OR node and replace it with its first child
+ return newAndNode.getFirstChild();
+
+ default:
+ return newAndNode;
+ }
+ }
+
+
+ /**
+ * Remove the (ObjectClass=*) node from a NotNode, if we have one.
+ */
+ private ExprNode handleNotNode( ExprNode node )
+ {
+ NotNode newNotNode = new NotNode();
+
+ for ( ExprNode child : ( ( BranchNode ) node ).getChildren() )
+ {
+ ExprNode modifiedNode = removeObjectClass( child );
+
+ if ( modifiedNode instanceof ObjectClassNode )
+ {
+ // We don't want any entry which has an ObjectClass, return an undefined node
+ return UndefinedNode.UNDEFINED_NODE;
+ }
+
+ if ( modifiedNode instanceof UndefinedNode )
+ {
+ // Here, we will select everything
+ return ObjectClassNode.OBJECT_CLASS_NODE;
+ }
+
+ newNotNode.addNode( modifiedNode );
+
+ }
+
+ return newNotNode;
+ }
+
+
+ /**
+ * Remove the (ObjectClass=*) node from an OrNode, if we have one.
+ */
+ private ExprNode handleOrNode( ExprNode node )
+ {
+ OrNode newOrNode = new OrNode();
+
+ for ( ExprNode child : ( ( BranchNode ) node ).getChildren() )
+ {
+ ExprNode modifiedNode = removeObjectClass( child );
+
+ if ( modifiedNode instanceof ObjectClassNode )
+ {
+ // We can return immediately with an ObjectClass node
+ return ObjectClassNode.OBJECT_CLASS_NODE;
+ }
+
+ newOrNode.addNode( modifiedNode );
+ }
+
+ return newOrNode;
+ }
+
+
+ /**
+ * Remove the (ObjectClass=*) and ( ObjectClass=top) nodes from the filter, if we have one.
+ */
+ private ExprNode removeObjectClass( ExprNode node )
+ {
+ if ( node instanceof LeafNode )
+ {
+ LeafNode leafNode = ( LeafNode ) node;
+
+ if ( leafNode.getAttributeType() == directoryService.getAtProvider().getObjectClass() )
+ {
+ if ( leafNode instanceof PresenceNode )
+ {
+ // We can safely remove the node and return an undefined node
+ return ObjectClassNode.OBJECT_CLASS_NODE;
+ }
+ else if ( leafNode instanceof EqualityNode )
+ {
+ Value value = ( ( EqualityNode<String> ) leafNode ).getValue();
+
+ if ( value.equals( SchemaConstants.TOP_OC ) )
+ {
+ // Here too we can safely remove the node and return an undefined node
+ return ObjectClassNode.OBJECT_CLASS_NODE;
+ }
+ }
+ }
+ }
+
+ // --------------------------------------------------------------------
+ // H A N D L E B R A N C H N O D E S
+ // --------------------------------------------------------------------
+
+ if ( node instanceof AndNode )
+ {
+ return handleAndNode( node );
+ }
+ else if ( node instanceof OrNode )
+ {
+ return handleOrNode( node );
+ }
+ else if ( node instanceof NotNode )
+ {
+ return handleNotNode( node );
+ }
+ else
+ {
+ // Failover : we return the initial node as is
+ return node;
+ }
+ }
+
+
+ // ------------------------------------------------------------------------
+ // Normalize all Name based arguments for other interface operations
+ // ------------------------------------------------------------------------
+ /**
+ * Adds missing Rdn's attributes and values to the entry.
+ *
+ * @param dn the Dn
+ * @param entry the entry
+ */
+ private void addRdnAttributesToEntry( Dn dn, Entry entry ) throws LdapException
+ {
+ if ( dn == null || entry == null )
+ {
+ return;
+ }
+
+ Rdn rdn = dn.getRdn();
+
+ // Loop on all the AVAs
+ for ( Ava ava : rdn )
+ {
+ Value value = ava.getValue();
+ String upValue = ava.getValue().getString();
+ String upId = ava.getType();
+
+ // Check that the entry contains this Ava
+ if ( !entry.contains( upId, value ) )
+ {
+ String message = "The Rdn '" + upId + "=" + upValue + "' is not present in the entry";
+ LOG.warn( message );
+
+ // We don't have this attribute : add it.
+ // Two cases :
+ // 1) The attribute does not exist
+ if ( !entry.containsAttribute( upId ) )
+ {
+ entry.add( upId, upValue );
+ }
+ // 2) The attribute exists
+ else
+ {
+ AttributeType at = schemaManager.lookupAttributeTypeRegistry( upId );
+
+ // 2.1 if the attribute is single valued, replace the value
+ if ( at.isSingleValued() )
+ {
+ entry.removeAttributes( upId );
+ entry.add( upId, upValue );
+ }
+ // 2.2 the attribute is multi-valued : add the missing value
+ else
+ {
+ entry.add( upId, upValue );
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSStartStopListener.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSStartStopListener.java
index 1f42fee..10126e2 100644
--- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSStartStopListener.java
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSStartStopListener.java
@@ -19,15 +19,21 @@
package org.apache.syncope.fit.buildtools;
import java.io.File;
-import java.util.HashSet;
+import java.io.IOException;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.ldap.model.schema.LdapComparator;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.ldap.model.schema.comparators.NormalizingComparator;
+import org.apache.directory.api.ldap.model.schema.registries.ComparatorRegistry;
import org.apache.directory.api.ldap.model.schema.registries.SchemaLoader;
import org.apache.directory.api.ldap.schema.extractor.SchemaLdifExtractor;
import org.apache.directory.api.ldap.schema.extractor.impl.DefaultSchemaLdifExtractor;
@@ -36,12 +42,12 @@ import org.apache.directory.api.ldap.schema.manager.impl.DefaultSchemaManager;
import org.apache.directory.api.util.exception.Exceptions;
import org.apache.directory.server.constants.ServerDNConstants;
import org.apache.directory.server.core.DefaultDirectoryService;
-import org.apache.directory.server.core.api.CacheService;
import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.DnFactory;
import org.apache.directory.server.core.api.InstanceLayout;
import org.apache.directory.server.core.api.partition.Partition;
import org.apache.directory.server.core.api.schema.SchemaPartition;
+import org.apache.directory.server.core.factory.JdbmPartitionFactory;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
import org.apache.directory.server.core.partition.ldif.LdifPartition;
@@ -74,7 +80,7 @@ public class ApacheDSStartStopListener implements ServletContextListener {
* @return The newly added partition
* @throws Exception If the partition can't be added
*/
- private Partition addPartition(final String partitionId, final String partitionDn, final DnFactory dnFactory)
+ private void addPartition(final String partitionId, final String partitionDn, final DnFactory dnFactory)
throws Exception {
// Create a new partition with the given partition id
@@ -84,24 +90,11 @@ public class ApacheDSStartStopListener implements ServletContextListener {
partition.setSuffixDn(new Dn(partitionDn));
service.addPartition(partition);
- return partition;
- }
-
- /**
- * Add a new set of index on the given attributes.
- *
- * @param partition The partition on which we want to add index
- * @param attrs The list of attributes to index
- */
- private void addIndex(final Partition partition, final String... attrs) {
- // Index some attributes on the apache partition
- Set<Index<?, String>> indexedAttributes = new HashSet<>();
-
- for (String attribute : attrs) {
- indexedAttributes.add(new JdbmIndex<String>(attribute, false));
- }
-
- ((JdbmPartition) partition).setIndexedAttributes(indexedAttributes);
+ Set<Index<?, String>> indexedAttributes = Stream.of(
+ SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.OU_AT,
+ SchemaConstants.UID_AT, SchemaConstants.CN_AT).
+ map(attr -> new JdbmIndex<String>(attr, false)).collect(Collectors.toSet());
+ partition.setIndexedAttributes(indexedAttributes);
}
/**
@@ -110,41 +103,63 @@ public class ApacheDSStartStopListener implements ServletContextListener {
* @throws Exception if the schema LDIF files are not found on the classpath
*/
private void initSchemaPartition() throws Exception {
- InstanceLayout instanceLayout = service.getInstanceLayout();
-
- File schemaPartitionDirectory = new File(instanceLayout.getPartitionsDirectory(), "schema");
+ File workingDirectory = service.getInstanceLayout().getPartitionsDirectory();
// Extract the schema on disk (a brand new one) and load the registries
- if (schemaPartitionDirectory.exists()) {
- LOG.debug("schema partition already exists, skipping schema extraction");
- } else {
- SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor(instanceLayout.getPartitionsDirectory());
+ File schemaRepository = new File(workingDirectory, "schema");
+ SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor(workingDirectory);
+ try {
extractor.extractOrCopy();
+ } catch (IOException ioe) {
+ // The schema has already been extracted, bypass
}
- SchemaLoader loader = new LdifSchemaLoader(schemaPartitionDirectory);
+ SchemaLoader loader = new LdifSchemaLoader(schemaRepository);
SchemaManager schemaManager = new DefaultSchemaManager(loader);
// We have to load the schema now, otherwise we won't be able
- // to initialize the Partitions, as we won't be able to parse
+ // to initialize the Partitions, as we won't be able to parse
// and normalize their suffix Dn
schemaManager.loadAllEnabled();
+ // Tell all the normalizer comparators that they should not normalize anything
+ ComparatorRegistry comparatorRegistry = schemaManager.getComparatorRegistry();
+ for (LdapComparator<?> comparator : comparatorRegistry) {
+ if (comparator instanceof NormalizingComparator) {
+ ((NormalizingComparator) comparator).setOnServer();
+ }
+ }
+
+ service.setSchemaManager(schemaManager);
+
+ // Init the LdifPartition
+ LdifPartition ldifPartition = new LdifPartition(schemaManager, service.getDnFactory());
+ ldifPartition.setPartitionPath(new File(workingDirectory, "schema").toURI());
+ SchemaPartition schemaPartition = new SchemaPartition(schemaManager);
+ schemaPartition.setWrappedPartition(ldifPartition);
+ service.setSchemaPartition(schemaPartition);
+
List<Throwable> errors = schemaManager.getErrors();
if (!errors.isEmpty()) {
throw new IllegalStateException(I18n.err(I18n.ERR_317, Exceptions.printErrors(errors)));
}
+ }
- service.setSchemaManager(schemaManager);
+ private void initSystemPartition() throws Exception {
+ JdbmPartitionFactory partitionFactory = new JdbmPartitionFactory();
- // Init the LdifPartition with schema
- LdifPartition schemaLdifPartition = new LdifPartition(schemaManager, service.getDnFactory());
- schemaLdifPartition.setPartitionPath(schemaPartitionDirectory.toURI());
+ Partition systemPartition = partitionFactory.createPartition(
+ service.getSchemaManager(),
+ service.getDnFactory(),
+ "system",
+ ServerDNConstants.SYSTEM_DN,
+ 500,
+ new File(service.getInstanceLayout().getPartitionsDirectory(), "system"));
+ systemPartition.setSchemaManager(service.getSchemaManager());
- // The schema partition
- SchemaPartition schemaPartition = new SchemaPartition(schemaManager);
- schemaPartition.setWrappedPartition(schemaLdifPartition);
- service.setSchemaPartition(schemaPartition);
+ partitionFactory.addIndex(systemPartition, SchemaConstants.OBJECT_CLASS_AT, 100);
+
+ service.setSystemPartition(systemPartition);
}
/**
@@ -162,38 +177,18 @@ public class ApacheDSStartStopListener implements ServletContextListener {
service = new DefaultDirectoryService();
service.setInstanceLayout(new InstanceLayout(workDir));
- CacheService cacheService = new CacheService();
- cacheService.initialize(service.getInstanceLayout());
-
- service.setCacheService(cacheService);
-
// first load the schema
initSchemaPartition();
// then the system partition
- // this is a MANDATORY partition
- // DO NOT add this via addPartition() method, trunk code complains about duplicate partition
- // while initializing
- JdbmPartition systemPartition = new JdbmPartition(service.getSchemaManager(), service.getDnFactory());
- systemPartition.setId("system");
- systemPartition.setPartitionPath(
- new File(service.getInstanceLayout().getPartitionsDirectory(), systemPartition.getId()).toURI());
- systemPartition.setSuffixDn(new Dn(ServerDNConstants.SYSTEM_DN));
- systemPartition.setSchemaManager(service.getSchemaManager());
-
- // mandatory to call this method to set the system partition
- // Note: this system partition might be removed from trunk
- service.setSystemPartition(systemPartition);
+ initSystemPartition();
// Disable the ChangeLog system
service.getChangeLog().setEnabled(false);
service.setDenormalizeOpAttrsEnabled(true);
// Now we can create as many partitions as we need
- Partition ispPartition = addPartition("isp", "o=isp", service.getDnFactory());
-
- // Index some attributes on the apache partition
- addIndex(ispPartition, "objectClass", "ou", "uid");
+ addPartition("isp", "o=isp", service.getDnFactory());
// And start the service
service.startup();
diff --git a/pom.xml b/pom.xml
index aac6e6f..938a43a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -432,8 +432,8 @@ under the License.
<elasticsearch.version>6.8.7</elasticsearch.version>
- <apacheds.version>2.0.0.AM25</apacheds.version>
- <apachedirapi.version>2.0.0.AM2</apachedirapi.version>
+ <apacheds.version>2.0.0.AM26</apacheds.version>
+ <apachedirapi.version>2.0.0</apachedirapi.version>
<log4j.version>2.13.1</log4j.version>
<disruptor.version>3.4.2</disruptor.version>
@@ -1135,6 +1135,11 @@ under the License.
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
+ <artifactId>apacheds-core-annotations</artifactId>
+ <version>${apacheds.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-service-builder</artifactId>
<version>${apacheds.version}</version>
<exclusions>
@@ -1149,21 +1154,6 @@ under the License.
<artifactId>api-ldap-codec-standalone</artifactId>
<version>${apachedirapi.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.directory.api</groupId>
- <artifactId>api-ldap-model</artifactId>
- <version>${apachedirapi.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.directory.api</groupId>
- <artifactId>api-ldap-schema-data</artifactId>
- <version>${apachedirapi.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.directory.api</groupId>
- <artifactId>api-util</artifactId>
- <version>${apachedirapi.version}</version>
- </dependency>
<dependency>
<groupId>com.icegreen</groupId>