mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Nicolas Capponi
12.07.2016 383ff591182ce9730728c938d9b86e95f86ad676
OPENDJ-3089 Update SchemaLoader and RemoteSchemaLoader to use SchemaHandler and SDK Schema

Also update ConfigReader, ConfigFromFile and ConfigFromConnection classes
to use SDK schema
6 files modified
237 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromConnection.java 21 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromFile.java 7 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigReader.java 10 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java 76 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/SchemaLoader.java 119 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java 4 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromConnection.java
@@ -50,6 +50,7 @@
import org.forgerock.opendj.ldap.LdapException;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldif.ConnectionEntryReader;
import org.forgerock.opendj.server.config.client.AdministrationConnectorCfgClient;
import org.forgerock.opendj.server.config.client.BackendCfgClient;
@@ -311,12 +312,12 @@
    {
      try
      {
        readSchema(connWrapper);
        if (getSchema() != null)
        Schema schema = readSchema(connWrapper);
        if (schema != null)
        {
          // Update the schema: so that when we call the server code the
          // latest schema read on the server we are managing is used.
          DirectoryServer.setSchema(getSchema());
          DirectoryServer.setSchema(schema);
        }
      }
      catch (OpenDsException oe)
@@ -629,20 +630,12 @@
   * @throws OpenDsException
   *           if an error occurs reading the schema.
   */
  private void readSchema(ConnectionWrapper connWrapper) throws OpenDsException
  private Schema readSchema(ConnectionWrapper connWrapper) throws OpenDsException
  {
    try
    {
      if (isLocal)
      {
        super.readSchema();
      }
      else
      {
        RemoteSchemaLoader loader = new RemoteSchemaLoader();
        loader.readSchema(connWrapper);
        schema = loader.getSchema();
      }
      schema = isLocal ? super.readSchema() : new RemoteSchemaLoader().readSchema(connWrapper);
      return schema;
    }
    catch (LdapException e)
    {
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromFile.java
@@ -34,6 +34,7 @@
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.server.config.server.AdministrationConnectorCfg;
import org.forgerock.opendj.server.config.server.BackendCfg;
import org.forgerock.opendj.server.config.server.BackendIndexCfg;
@@ -132,12 +133,12 @@
    {
      try
      {
        readSchema();
        if (getSchema() != null)
        Schema schema = readSchema();
        if (schema != null)
        {
          // Update the schema: so that when we call the server code the
          // latest schema read on the server we are managing is used.
          DirectoryServer.setSchema(getSchema());
          DirectoryServer.setSchema(schema);
        }
      }
      catch (final OpenDsException oe)
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigReader.java
@@ -31,6 +31,7 @@
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.server.config.meta.AdministrationConnectorCfgDefn;
import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor;
@@ -42,7 +43,6 @@
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.OpenDsException;
import org.opends.server.types.Schema;
/**
 * An abstract class providing some common interface for the class that read
@@ -251,18 +251,20 @@
  /**
   * Reads the schema from the files.
   *
   * @return the schema
   * @throws ConfigException if an error occurs reading the schema.
   * @throws InitializationException if an error occurs initializing
   * configuration to read schema.
   * @throws DirectoryException if there is an error registering the minimal
   * objectclasses.
   */
  protected void readSchema() throws ConfigException, InitializationException,
  protected Schema readSchema() throws ConfigException, InitializationException,
  DirectoryException
  {
    SchemaLoader loader = new SchemaLoader();
    loader.readSchema();
    schema = loader.getSchema();
    schema = loader.readSchema();
    return schema;
  }
  /**
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java
@@ -21,11 +21,8 @@
import static org.forgerock.opendj.ldap.schema.CoreSchema.*;
import static org.forgerock.opendj.ldap.schema.Schema.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.config.ConfigConstants.ATTR_ATTRIBUTE_TYPES;
import static org.opends.server.config.ConfigConstants.ATTR_LDAP_SYNTAXES;
import static org.opends.server.schema.SchemaConstants.*;
import java.util.Arrays;
import java.util.Iterator;
import org.forgerock.opendj.config.server.ConfigException;
@@ -37,20 +34,15 @@
import org.forgerock.opendj.ldap.LdapException;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.forgerock.opendj.ldap.schema.MatchingRuleImpl;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.schema.SchemaBuilder;
import org.opends.admin.ads.util.ConnectionWrapper;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ServerContext;
import org.opends.server.replication.plugin.HistoricalCsnOrderingMatchingRuleImpl;
import org.opends.server.schema.AciSyntax;
import org.opends.server.schema.SubtreeSpecificationSyntax;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.Schema;
import org.opends.server.types.Schema.SchemaUpdater;
/** Class used to retrieve the schema from the schema files. */
public class RemoteSchemaLoader extends SchemaLoader
@@ -70,10 +62,11 @@
  }
  /**
   * Reads the schema.
   * Reads and returns the schema.
   *
   * @param connWrapper
   *          the connection to be used to load the schema.
   * @return the schema
   * @throws LdapException
   *           if an error occurs reading the schema.
   * @throws DirectoryException
@@ -83,70 +76,43 @@
   * @throws ConfigException
   *           if an error occurs loading the configuration required to use the schema classes.
   */
  public void readSchema(ConnectionWrapper connWrapper) throws LdapException, DirectoryException,
  public Schema readSchema(ConnectionWrapper connWrapper) throws LdapException, DirectoryException,
      InitializationException, ConfigException
  {
    schema = getBaseSchema();
    Schema baseSchema = getBaseSchema();
    SchemaBuilder schemaBuilder = new SchemaBuilder(baseSchema);
    // Add missing matching rules and attribute syntaxes to base schema to allow read of remote server schema
    // (see OPENDJ-1122 for more details)
    addMissingSyntaxesToBaseSchema(new AciSyntax(), new SubtreeSpecificationSyntax());
    addMissingMatchingRuleToBaseSchema("1.3.6.1.4.1.26027.1.4.4", "historicalCsnOrderingMatch",
    AciSyntax.addAciSyntax(schemaBuilder);
    SubtreeSpecificationSyntax.addSubtreeSpecificationSyntax(schemaBuilder);
    addMatchingRuleIfMissing(schemaBuilder, baseSchema, "1.3.6.1.4.1.26027.1.4.4", "historicalCsnOrderingMatch",
        "1.3.6.1.4.1.1466.115.121.1.40", new HistoricalCsnOrderingMatchingRuleImpl());
    // Add remote schema entry
    final SearchRequest request = newSearchRequest(
        DN.valueOf(DN_DEFAULT_SCHEMA_ROOT), BASE_OBJECT, Filter.alwaysTrue(),
        ATTR_LDAP_SYNTAXES, ATTR_ATTRIBUTE_TYPES, ATTR_OBJECTCLASSES);
    final SearchResultEntry entry = connWrapper.getConnection().searchSingleEntry(request);
    removeNonOpenDjOrOpenDsSyntaxes(entry);
    schema.updateSchema(new SchemaUpdater()
    {
      @Override
      public org.forgerock.opendj.ldap.schema.Schema update(SchemaBuilder builder)
      {
        builder.addSchema(entry, true);
        return builder.toSchema();
      }
    });
    schemaBuilder.addSchema(entry, true);
    return buildSchema(schemaBuilder);
  }
  private void addMissingSyntaxesToBaseSchema(final AttributeSyntax<?>... syntaxes)
      throws DirectoryException, InitializationException, ConfigException
  private void addMatchingRuleIfMissing(SchemaBuilder schemaBuilder, Schema baseSchema, final String oid,
      final String name, final String syntaxOID, final MatchingRuleImpl impl) throws InitializationException,
      ConfigException, DirectoryException
  {
    for (AttributeSyntax<?> syntax : syntaxes)
    if (!baseSchema.hasMatchingRule(name))
    {
      final ServerContext serverContext = DirectoryServer.getInstance().getServerContext();
      final org.forgerock.opendj.ldap.schema.Schema schemaNG = serverContext.getSchemaNG();
      if (!schemaNG.hasSyntax(syntax.getOID()))
      {
        syntax.initializeSyntax(null, serverContext);
      }
      schema.registerSyntax(syntax.getSDKSyntax(schemaNG), true);
    }
  }
  private void addMissingMatchingRuleToBaseSchema(final String oid, final String name, final String syntaxOID,
      final MatchingRuleImpl impl)
      throws InitializationException, ConfigException, DirectoryException
  {
    final org.forgerock.opendj.ldap.schema.Schema schemaNG = schema.getSchemaNG();
    final MatchingRule matchingRule;
    if (schemaNG.hasMatchingRule(name))
    {
      matchingRule = schemaNG.getMatchingRule(name);
    }
    else
    {
      matchingRule = new SchemaBuilder(schemaNG)
          .buildMatchingRule(oid)
      schemaBuilder.buildMatchingRule(oid)
            .names(name)
            .syntaxOID(syntaxOID)
            .implementation(impl)
          .addToSchema()
          .toSchema()
          .getMatchingRule(oid);
        .addToSchema();
    }
    schema.registerMatchingRules(Arrays.asList(matchingRule), true);
  }
  private void removeNonOpenDjOrOpenDsSyntaxes(final SearchResultEntry entry) throws DirectoryException
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/SchemaLoader.java
@@ -16,11 +16,12 @@
 */
package org.opends.guitools.controlpanel.util;
import static org.opends.messages.SchemaMessages.ERR_SCHEMA_HAS_WARNINGS;
import static org.opends.messages.ConfigMessages.*;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -31,17 +32,17 @@
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.forgerock.opendj.ldap.schema.ObjectClass;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.schema.SchemaBuilder;
import org.forgerock.opendj.ldap.schema.Syntax;
import org.forgerock.util.Utils;
import org.opends.server.config.ConfigConstants;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SchemaConfigManager;
import org.opends.server.core.SchemaHandler;
import org.opends.server.core.ServerContext;
import org.opends.server.schema.SchemaConstants;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.Schema;
import com.forgerock.opendj.util.OperatingSystem;
/** Class used to retrieve the schema from the schema files. */
public class SchemaLoader
@@ -63,13 +64,16 @@
  /** List of attribute syntaxes to keep in the schema. */
  protected final List<Syntax> syntaxesToKeep = new ArrayList<>();
  private final ServerContext serverContext;
  /** Constructor. */
  public SchemaLoader()
  {
    Schema sc = DirectoryServer.getSchema();
    serverContext = DirectoryServer.getInstance().getServerContext();
    Schema schema = serverContext.getSchemaHandler().getSchema();
    for (String name : OBJECTCLASS_TO_KEEP)
    {
      ObjectClass oc = sc.getObjectClass(name);
      ObjectClass oc = schema.getObjectClass(name);
      if (!oc.isPlaceHolder())
      {
        objectclassesToKeep.add(oc);
@@ -77,23 +81,19 @@
    }
    for (String name : ATTRIBUTES_TO_KEEP)
    {
      if (sc.hasAttributeType(name))
      if (schema.hasAttributeType(name))
      {
        attributesToKeep.add(sc.getAttributeType(name));
        attributesToKeep.add(schema.getAttributeType(name));
      }
    }
    matchingRulesToKeep.addAll(sc.getMatchingRules());
    syntaxesToKeep.addAll(sc.getSyntaxes());
  }
  private static String getSchemaDirectoryPath()
  {
    File schemaDir = DirectoryServer.getEnvironmentConfig().getSchemaDirectory();
    return schemaDir != null ? schemaDir.getAbsolutePath() : null;
    matchingRulesToKeep.addAll(schema.getMatchingRules());
    syntaxesToKeep.addAll(schema.getSyntaxes());
  }
  /**
   * Reads the schema.
   * Reads and returns the schema.
   *
   * @return the schema
   *
   * @throws ConfigException
   *           if an error occurs reading the schema.
@@ -102,44 +102,41 @@
   * @throws DirectoryException
   *           if there is an error registering the minimal objectclasses.
   */
  public void readSchema() throws DirectoryException, ConfigException, InitializationException
  public Schema readSchema() throws DirectoryException, ConfigException, InitializationException
  {
    schema = getBaseSchema();
    SchemaHandler schemaHandler = serverContext.getSchemaHandler();
    final File schemaDir = schemaHandler.getSchemaDirectoryPath();
    final List<String> fileNames = getSchemaFileNames(schemaDir);
    List<String> fileNames;
    String schemaDirPath = getSchemaDirectoryPath();
    // build the schema from schema files
    Schema baseSchema = getBaseSchema();
    SchemaBuilder schemaBuilder = new SchemaBuilder(baseSchema);
    for (String schemaFile : fileNames)
    {
      schemaHandler.loadSchemaFileIntoSchemaBuilder(new File(schemaDir, schemaFile), schemaBuilder, baseSchema);
    }
    return buildSchema(schemaBuilder);
  }
  Schema buildSchema(SchemaBuilder schemaBuilder) throws InitializationException
  {
    schema = schemaBuilder.toSchema();
    Collection<LocalizableMessage> warnings = schema.getWarnings();
    if (!warnings.isEmpty())
    {
      throw new InitializationException(
          ERR_SCHEMA_HAS_WARNINGS.get(warnings.size(), Utils.joinAsString("; ", warnings)));
    }
    return schema;
  }
  private List<String> getSchemaFileNames(final File schemaDir)
      throws InitializationException
  {
    final List<String> fileNames;
    try
    {
      // Load install directory schema
      File schemaDir = new File(schemaDirPath);
      if (schemaDirPath == null || !schemaDir.exists())
      {
        LocalizableMessage message = ERR_CONFIG_SCHEMA_NO_SCHEMA_DIR.get(schemaDirPath);
        throw new InitializationException(message);
      }
      else if (!schemaDir.isDirectory())
      {
        LocalizableMessage message = ERR_CONFIG_SCHEMA_DIR_NOT_DIRECTORY.get(schemaDirPath);
        throw new InitializationException(message);
      }
      FileFilter ldifFilesFilter = new FileFilter()
      {
        @Override
        public boolean accept(File f)
        {
          if (f != null)
          {
            if (f.isDirectory())
            {
              return true;
            }
            return OperatingSystem.isWindows() ? f.getName().toLowerCase().endsWith(".ldif")
                                               : f.getName().endsWith(".ldif");
          }
          return false;
        }
      };
      File[] schemaFiles = schemaDir.listFiles(ldifFilesFilter);
      File[] schemaFiles = schemaDir.listFiles(new SchemaHandler.SchemaFileFilter());
      fileNames = new ArrayList<>(schemaFiles.length);
      for (File f : schemaFiles)
      {
@@ -148,24 +145,12 @@
          fileNames.add(f.getName());
        }
      }
      Collections.sort(fileNames);
    }
    catch (InitializationException ie)
    {
      throw ie;
      return fileNames;
    }
    catch (Exception e)
    {
      throw new InitializationException(ERR_CONFIG_SCHEMA_CANNOT_LIST_FILES.get(schemaDirPath, e.getMessage()), e);
    }
    // Iterate through the schema files and read them as an LDIF file containing a single entry.
    // Then get the attributeTypes and objectClasses attributes from that entry
    // and parse them to initialize the server schema.
    for (String schemaFile : fileNames)
    {
      SchemaConfigManager.loadSchemaFile(schema, schemaFile);
      throw new InitializationException(ERR_CONFIG_SCHEMA_CANNOT_LIST_FILES.get(schemaDir, e.getMessage()), e);
    }
  }
@@ -198,7 +183,7 @@
      {
        builder.buildObjectClass(oc).addToSchemaOverwrite();
      }
      return new Schema(builder.toSchema());
      return builder.toSchema();
    }
    catch (LocalizedIllegalArgumentException e)
    {
opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java
@@ -89,6 +89,7 @@
import org.opends.server.util.SchemaUtils;
import org.opends.server.util.StaticUtils;
import com.forgerock.opendj.util.OperatingSystem;
import com.sun.corba.se.spi.ior.WriteContents;
/**
@@ -1012,7 +1013,8 @@
    @Override
    public boolean accept(File directory, String filename)
    {
      return filename.endsWith(LDIF_SUFFIX);
      return OperatingSystem.isWindows() ?
          filename.toLowerCase().endsWith(LDIF_SUFFIX) : filename.endsWith(LDIF_SUFFIX);
    }
  }