You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2019/04/19 23:52:50 UTC
[directory-server] branch master updated: Implemented RFC 4525
(Modify Increment operation)
This is an automated email from the ASF dual-hosted git repository.
elecharny pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/directory-server.git
The following commit(s) were added to refs/heads/master by this push:
new 78d65a8 Implemented RFC 4525 (Modify Increment operation)
78d65a8 is described below
commit 78d65a8994ec65e415c86bbdfb5ee18a9268ce0d
Author: emmanuel lecharny <el...@apache.org>
AuthorDate: Sat Apr 20 01:52:42 2019 +0200
Implemented RFC 4525 (Modify Increment operation)
---
.../core/operations/getRootDse/GetRootDseIT.java | 50 ++++++-
.../shared/partition/DefaultPartitionNexus.java | 4 +-
.../server/core/schema/SchemaInterceptor.java | 43 ++++++
.../impl/btree/AbstractBTreePartition.java | 162 +++++++++++++++++++++
4 files changed, 250 insertions(+), 9 deletions(-)
diff --git a/core-integ/src/test/java/org/apache/directory/server/core/operations/getRootDse/GetRootDseIT.java b/core-integ/src/test/java/org/apache/directory/server/core/operations/getRootDse/GetRootDseIT.java
index 17c601a..fb553d7 100644
--- a/core-integ/src/test/java/org/apache/directory/server/core/operations/getRootDse/GetRootDseIT.java
+++ b/core-integ/src/test/java/org/apache/directory/server/core/operations/getRootDse/GetRootDseIT.java
@@ -25,6 +25,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.server.core.api.DirectoryService;
@@ -249,11 +251,13 @@ public class GetRootDseIT extends AbstractLdapTestUnit
{
DirectoryService service = getService();
service.setAccessControlEnabled( false );
- LdapCoreSessionConnection connection = new LdapCoreSessionConnection( service );
-
- Entry rootDse = connection.getRootDse();
-
- assertNotNull( rootDse );
+
+ try ( LdapCoreSessionConnection connection = new LdapCoreSessionConnection( service ) )
+ {
+ Entry rootDse = connection.getRootDse();
+
+ assertNotNull( rootDse );
+ }
}
@@ -266,10 +270,40 @@ public class GetRootDseIT extends AbstractLdapTestUnit
{
DirectoryService service = getService();
service.setAccessControlEnabled( true );
- LdapCoreSessionConnection connection = new LdapCoreSessionConnection( service );
+
+ try ( LdapCoreSessionConnection connection = new LdapCoreSessionConnection( service ) )
+ {
+ Entry rootDse = connection.getRootDse();
+
+ assertNotNull( rootDse );
+ }
+ }
- Entry rootDse = connection.getRootDse();
- assertNotNull( rootDse );
+ /**
+ * Check the supportedFeatures attribute
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testGetSupportedFeatures() throws Exception
+ {
+ DirectoryService service = getService();
+ service.setAccessControlEnabled( true );
+
+ try ( LdapCoreSessionConnection connection = new LdapCoreSessionConnection( service ) )
+ {
+ Entry rootDse = connection.getRootDse( SchemaConstants.SUPPORTED_FEATURES_AT );
+
+ assertNotNull( rootDse );
+ assertTrue( rootDse.containsAttribute( SchemaConstants.SUPPORTED_FEATURES_AT ) );
+
+ Attribute supportedFeatures = rootDse.get( SchemaConstants.SUPPORTED_FEATURES_AT );
+
+ assertEquals( 2, supportedFeatures.size() );
+ assertTrue( supportedFeatures.contains(
+ SchemaConstants.FEATURE_ALL_OPERATIONAL_ATTRIBUTES,
+ SchemaConstants.FEATURE_MODIFY_INCREMENT ) );
+ }
}
}
diff --git a/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java b/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
index 2503628..9f40bf5 100644
--- a/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
+++ b/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
@@ -150,7 +150,9 @@ public class DefaultPartitionNexus extends AbstractPartition implements Partitio
// Add the basic informations
rootDse.put( SchemaConstants.SUBSCHEMA_SUBENTRY_AT, ServerDNConstants.CN_SCHEMA_DN );
rootDse.put( SchemaConstants.SUPPORTED_LDAP_VERSION_AT, "3" );
- rootDse.put( SchemaConstants.SUPPORTED_FEATURES_AT, SchemaConstants.FEATURE_ALL_OPERATIONAL_ATTRIBUTES );
+ rootDse.put( SchemaConstants.SUPPORTED_FEATURES_AT,
+ SchemaConstants.FEATURE_ALL_OPERATIONAL_ATTRIBUTES,
+ SchemaConstants.FEATURE_MODIFY_INCREMENT );
rootDse.put( SchemaConstants.SUPPORTED_EXTENSION_AT, NoticeOfDisconnect.EXTENSION_OID );
// Add the objectClasses
diff --git a/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java b/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
index cc688dc..f415ef2 100644
--- a/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
+++ b/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
@@ -813,6 +813,49 @@ public class SchemaInterceptor extends BaseInterceptor
}
break;
+
+ case INCREMENT_ATTRIBUTE:
+ // The incremented attribute might not exist
+ if ( !tempEntry.containsAttribute( attributeType ) )
+ {
+ throw new IllegalArgumentException( "Increment operation on a non existing attribute"
+ + attributeType );
+ }
+ else if ( !SchemaConstants.INTEGER_SYNTAX.equals( attributeType.getSyntax().getOid() ) )
+ {
+ throw new IllegalArgumentException( "Increment operation on a non integer attribute"
+ + attributeType );
+ }
+ else
+ {
+ Attribute modified = tempEntry.get( attributeType );
+ Value[] newValues = new Value[ modified.size() ];
+ int increment = 1;
+ int i = 0;
+
+ if ( mod.getAttribute().size() != 0 )
+ {
+ increment = Integer.parseInt( mod.getAttribute().getString() );
+ }
+
+ for ( Value value : modified )
+ {
+ int intValue = Integer.parseInt( value.getNormalized() );
+
+ if ( intValue >= Integer.MAX_VALUE - increment )
+ {
+ throw new IllegalArgumentException( "Increment operation overflow for attribute"
+ + attributeType );
+ }
+
+ newValues[i++] = new Value( Integer.toString( intValue + increment ) );
+ modified.remove( value );
+ }
+
+ modified.add( newValues );
+ }
+
+ break;
default:
throw new IllegalArgumentException( "Unexpected modify operation " + mod.getOperation() );
diff --git a/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java b/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java
index 5dcf74c..c67de8b 100644
--- a/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java
+++ b/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java
@@ -1443,6 +1443,10 @@ public abstract class AbstractBTreePartition extends AbstractPartition implement
modifyReplace( partitionTxn, id, entry, attrMods );
break;
+ case INCREMENT_ATTRIBUTE:
+ modifyIncrement( partitionTxn, id, entry, attrMods );
+ break;
+
default:
throw new LdapException( I18n.err( I18n.ERR_221 ) );
}
@@ -1718,6 +1722,164 @@ public abstract class AbstractBTreePartition extends AbstractPartition implement
/**
+ * Completely replaces the existing set of values for an attribute with the
+ * modified values supplied affecting the appropriate userIndices. The entry
+ * is not persisted: it is only changed in anticipation for a put into the
+ * master table.
+ *
+ * @param partitionTxn The transaction to use
+ * @param id the primary key of the entry
+ * @param entry the entry to alter
+ * @param mods the replacement attribute and values
+ * @throws Exception if index alteration or attribute modification
+ * fails.
+ */
+ @SuppressWarnings("unchecked")
+ private void modifyIncrement( PartitionTxn partitionTxn, String id, Entry entry, Attribute mods )
+ throws LdapException, IndexNotFoundException
+ {
+ if ( entry instanceof ClonedServerEntry )
+ {
+ throw new LdapOtherException( I18n.err( I18n.ERR_215_CANNOT_STORE_CLONED_SERVER_ENTRY ) );
+ }
+
+ String modsOid = schemaManager.getAttributeTypeRegistry().getOidByName( mods.getId() );
+ AttributeType attributeType = mods.getAttributeType();
+
+ // Special case for the ObjectClass index
+ if ( attributeType.equals( objectClassAT ) )
+ {
+ // if the id exists in the index drop all existing attribute
+ // value index entries and add new ones
+ for ( Value value : entry.get( objectClassAT ) )
+ {
+ if ( value.equals( topOCValue ) )
+ {
+ continue;
+ }
+
+ String normalizedOc = objectClassNormalizer.normalize( value.getString() );
+
+ objectClassIdx.drop( partitionTxn, normalizedOc, id );
+ }
+
+ for ( Value value : mods )
+ {
+ if ( value.equals( topOCValue ) )
+ {
+ continue;
+ }
+
+ String normalizedOc = objectClassNormalizer.normalize( value.getString() );
+
+ objectClassIdx.add( partitionTxn, normalizedOc, id );
+ }
+ }
+ else if ( hasUserIndexOn( attributeType ) )
+ {
+ Index<?, String> userIndex = getUserIndex( attributeType );
+
+ // Drop all the previous values
+ Attribute oldAttribute = entry.get( mods.getAttributeType() );
+
+ if ( oldAttribute != null )
+ {
+ for ( Value value : oldAttribute )
+ {
+ String normalized = value.getNormalized();
+ ( ( Index<Object, String> ) userIndex ).drop( partitionTxn, normalized, id );
+ }
+ }
+
+ // And add the new ones
+ for ( Value value : mods )
+ {
+ String normalized = value.getNormalized();
+ ( ( Index ) userIndex ).add( partitionTxn, normalized, id );
+ }
+
+ /*
+ * If we have no new value, we have to drop the AT fro the presence index
+ */
+ if ( mods.size() == 0 )
+ {
+ presenceIdx.drop( partitionTxn, modsOid, id );
+ }
+ }
+ // Special case for the AdministrativeRole index
+ else if ( attributeType.equals( administrativeRoleAT ) )
+ {
+ // Remove the previous values
+ for ( Value value : entry.get( administrativeRoleAT ) )
+ {
+ if ( value.equals( topOCValue ) )
+ {
+ continue;
+ }
+
+ String normalizedOc = objectClassNormalizer.normalize( value.getString() );
+
+ objectClassIdx.drop( partitionTxn, normalizedOc, id );
+ }
+
+ // And add the new ones
+ for ( Value value : mods )
+ {
+ String valueStr = value.getString();
+
+ if ( valueStr.equals( topOCValue ) )
+ {
+ continue;
+ }
+
+ adminRoleIdx.add( partitionTxn, valueStr, id );
+ }
+ }
+
+ String aliasAttributeOid = schemaManager.getAttributeTypeRegistry().getOidByName(
+ SchemaConstants.ALIASED_OBJECT_NAME_AT );
+
+ if ( mods.getAttributeType().equals( aliasedObjectNameAT ) )
+ {
+ dropAliasIndices( partitionTxn, id );
+ }
+
+ // replaces old attributes with new modified ones if they exist
+ Attribute attribute = entry.get( mods.getAttributeType() );
+ Value[] newValues = new Value[ attribute.size() ];
+ int increment = 1;
+ int i = 0;
+
+ if ( mods.size() != 0 )
+ {
+ increment = Integer.parseInt( mods.getString() );
+ }
+
+ for ( Value value : attribute )
+ {
+ int intValue = Integer.parseInt( value.getNormalized() );
+
+ if ( intValue >= Integer.MAX_VALUE - increment )
+ {
+ throw new IllegalArgumentException( "Increment operation overflow for attribute"
+ + attributeType );
+ }
+
+ newValues[i++] = new Value( Integer.toString( intValue + increment ) );
+ attribute.remove( value );
+ }
+
+ attribute.add( newValues );
+
+ if ( modsOid.equals( aliasAttributeOid ) && mods.size() > 0 )
+ {
+ Dn entryDn = getEntryDn( partitionTxn, id );
+ addAliasIndices( partitionTxn, id, entryDn, new Dn( schemaManager, mods.getString() ) );
+ }
+ }
+
+
+ /**
* Completely removes the set of values for an attribute having the values
* supplied while affecting the appropriate userIndices. The entry is not
* persisted: it is only changed in anticipation for a put into the master