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

Nicolas Capponi
12.54.2016 5ee33e1763d2574f769a8a278806e882694feb00
OPENDJ-3089 Update AddSchemaFileTask class to replace server Schema usage by SchemaHandler

- remove all references to SchemaConfigManager and server Schema
- use SchemaHandler class as an entry point for all schema related
operations
3 files modified
187 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java 122 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/tasks/AddSchemaFileTask.java 63 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/task.properties 2 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java
@@ -17,8 +17,6 @@
import static org.opends.messages.ConfigMessages.ERR_CONFIG_SCHEMA_DIR_NOT_DIRECTORY;
import static org.opends.messages.ConfigMessages.ERR_CONFIG_SCHEMA_NO_SCHEMA_DIR;
import static org.forgerock.opendj.ldap.schema.CoreSchema.*;
import static org.opends.messages.SchemaMessages.NOTE_SCHEMA_IMPORT_FAILED;
import static org.opends.server.util.SchemaUtils.getElementSchemaFile;
import static org.forgerock.util.Utils.closeSilently;
@@ -51,13 +49,17 @@
import org.opends.server.schema.SubtreeSpecificationSyntax;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.adapter.server3x.Converters;
import org.forgerock.opendj.config.ClassPropertyDefinition;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.Entry;
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.ConflictingSchemaElementException;
import org.forgerock.opendj.ldap.schema.CoreSchema;
import org.forgerock.opendj.ldap.schema.DITContentRule;
import org.forgerock.opendj.ldap.schema.DITStructureRule;
import org.forgerock.opendj.ldap.schema.MatchingRule;
@@ -81,11 +83,14 @@
import org.opends.server.types.Attribute;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.Modification;
import org.opends.server.types.SchemaWriter;
import org.opends.server.util.ActivateOnceSDKSchemaIsUsed;
import org.opends.server.util.SchemaUtils;
import org.opends.server.util.StaticUtils;
import com.sun.corba.se.spi.ior.WriteContents;
/**
 * Responsible for loading the server schema.
 * <p>
@@ -107,8 +112,13 @@
  private static final String CONFIG_SCHEMA_ELEMENTS_FILE = "02-config.ldif";
  private static final String CORE_SCHEMA_ELEMENTS_FILE = "00-core.ldif";
  private static final AttributeType attributeTypesType = getAttributeTypesAttributeType();
  private static final AttributeType objectClassesType = getObjectClassesAttributeType();
  private static final AttributeType attributeTypesType = CoreSchema.getAttributeTypesAttributeType();
  private static final AttributeType objectClassesType = CoreSchema.getObjectClassesAttributeType();
  private static final AttributeType ditStructureRulesType = CoreSchema.getDITStructureRulesAttributeType();
  private static final AttributeType ditContentRulesType = CoreSchema.getDITContentRulesAttributeType();
  private static final AttributeType ldapSyntaxesType = CoreSchema.getLDAPSyntaxesAttributeType();
  private static final AttributeType matchingRuleUsesType = CoreSchema.getMatchingRuleUseAttributeType();
  private static final AttributeType nameFormsType = CoreSchema.getNameFormsAttributeType();
  private ServerContext serverContext;
@@ -335,6 +345,29 @@
  }
  /**
   * Replaces the schema with the provided schema and update the concatened schema files.
   *
   * @param newSchema
   *            The new schema to use
   * @throws DirectoryException
   *            If an error occurs during update of schema or schema files
   */
  public void updateSchemaAndConcatenatedSchemaFiles(Schema newSchema) throws DirectoryException
  {
    exclusiveLock.lock();
    try
    {
      switchSchema(newSchema);
      SchemaWriter.writeConcatenatedSchema();
      youngestModificationTime = System.currentTimeMillis();
    }
    finally
    {
      exclusiveLock.unlock();
    }
  }
  /**
   * Updates the schema option  if the new value differs from the old value.
   *
   * @param <T> the schema option's type
@@ -657,7 +690,7 @@
    for (String schemaFile : schemaFileNames)
    {
      loadSchemaFile(new File(schemaDirectory, schemaFile), schemaBuilder, Schema.getDefaultSchema());
      loadSchemaFile(new File(schemaDirectory, schemaFile), schemaBuilder, Schema.getDefaultSchema(), false);
    }
  }
@@ -749,6 +782,75 @@
  }
  /**
   * Loads the contents of the provided schema file into the provided schema builder.
   *
   * @param schemaFile
   *            The schema file to load.
   * @param schemaBuilder
   *            The schema builder to update.
   * @param readSchema
   *            The schema used to read the schema file.
   * @throws InitializationException
   *            If a problem occurs when reading the schema file.
   * @throws ConfigException
   *            If a problem occurs when updating the schema builder.
   */
  public void loadSchemaFileIntoSchemaBuilder(final File schemaFile, final SchemaBuilder schemaBuilder,
      final Schema readSchema) throws InitializationException, ConfigException
  {
    loadSchemaFile(schemaFile, schemaBuilder, readSchema, true);
  }
  /**
   * Loads the contents of the provided schema file into the provided schema builder and returns the list
   * of modifications.
   *
   * @param schemaFile
   *          The schema file to load.
   * @param schemaBuilder
   *            The schema builder to update.
   * @param readSchema
   *            The schema used to read the schema file.
   * @return A list of the modifications that could be performed in order to obtain the contents of
   *         the file.
   * @throws ConfigException
   *           If a configuration problem causes the schema element initialization to fail.
   * @throws InitializationException
   *           If a problem occurs while initializing the schema elements that is not related to the
   *           server configuration.
   */
  public List<Modification> loadSchemaFileIntoSchemaBuilderAndReturnModifications(final File schemaFile,
      final SchemaBuilder schemaBuilder, final Schema readSchema) throws InitializationException, ConfigException
  {
    final Entry entry = loadSchemaFile(schemaFile, schemaBuilder, readSchema, true);
    if (entry != null)
    {
      return createAddModifications(entry,
          ldapSyntaxesType,
          attributeTypesType,
          objectClassesType,
          nameFormsType,
          ditContentRulesType,
          ditStructureRulesType,
          matchingRuleUsesType);
    }
    return Collections.emptyList();
  }
  private List<Modification> createAddModifications(Entry entry, AttributeType... attrTypes)
  {
    List<Modification> mods = new ArrayList<>(entry.getAttributeCount());
    for (AttributeType attrType : attrTypes)
    {
      for (org.forgerock.opendj.ldap.Attribute a : entry.getAllAttributes(AttributeDescription.create(attrType)))
      {
        mods.add(new Modification(ModificationType.ADD, Converters.toAttribute(a)));
      }
    }
    return mods;
  }
  /**
   * Add the schema from the provided schema file to the provided schema
   * builder.
   *
@@ -759,10 +861,16 @@
   *          be loaded.
   * @param readSchema
   *          The schema used to read the file.
   * @param failOnError
   *          Indicates whether an exception must be thrown if an error occurs
   * @return the schema entry that has been read from the schema file
   * @throws InitializationException
   *           If a problem occurs while initializing the schema elements.
   * @throws ConfigException
   *           If a problem occurs when updating the schema builder.
   */
  private void loadSchemaFile(final File schemaFile, final SchemaBuilder schemaBuilder, final Schema readSchema)
  private Entry loadSchemaFile(final File schemaFile, final SchemaBuilder schemaBuilder, final Schema readSchema,
      boolean failOnError)
         throws InitializationException, ConfigException
  {
    EntryReader reader = null;
@@ -772,9 +880,9 @@
      final Entry entry = readSchemaEntry(reader, schemaFile);
      if (entry != null)
      {
        boolean failOnError = true;
        updateSchemaBuilderWithEntry(schemaBuilder, entry, schemaFile.getName(), failOnError);
      }
      return entry;
    }
    finally {
      Utils.closeSilently(reader);
opendj-server-legacy/src/main/java/org/opends/server/tasks/AddSchemaFileTask.java
@@ -27,13 +27,16 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.schema.SchemaBuilder;
import org.forgerock.opendj.server.config.server.SynchronizationProviderCfg;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.SynchronizationProvider;
import org.opends.server.backends.task.Task;
import org.opends.server.backends.task.TaskState;
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.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.DirectoryException;
@@ -43,8 +46,6 @@
import org.opends.server.types.Modification;
import org.opends.server.types.Operation;
import org.opends.server.types.Privilege;
import org.opends.server.types.Schema;
import org.opends.server.types.SchemaWriter;
import org.opends.server.util.SchemaUtils;
import static org.opends.messages.TaskMessages.*;
@@ -89,7 +90,8 @@
    // Get the attribute that specifies which schema file(s) to add.
    Entry taskEntry = getTaskEntry();
    AttributeType attrType = DirectoryServer.getSchema().getAttributeType(ATTR_TASK_ADDSCHEMAFILE_FILENAME);
    ServerContext serverContext = getServerContext();
    AttributeType attrType = serverContext.getSchema().getAttributeType(ATTR_TASK_ADDSCHEMAFILE_FILENAME);
    List<Attribute> attrList = taskEntry.getAllAttributes(attrType);
    if (attrList.isEmpty())
    {
@@ -100,7 +102,7 @@
    // Get the name(s) of the schema files to add and make sure they exist in
    // the schema directory.
    String schemaInstanceDirectory = DirectoryServer.getEnvironmentConfig().getSchemaDirectory().getPath();
    File schemaInstanceDirectory = getSchemaDirectory();
    filesToAdd = new TreeSet<>();
    for (Attribute a : attrList)
    {
@@ -133,17 +135,20 @@
      }
    }
    // Create a new dummy schema and make sure that we can add the contents of
    // all the schema files into it.  Even though this duplicates work we'll
    // have to do later, it will be good to do it now as well so we can reject
    // Make sure that we can add the contents of all the schema files into the schema.
    // Even though this duplicates work we'll have to do later,
    // it will be good to do it now as well so we can reject
    // the entry immediately which will fail the attempt by the client to add it
    // to the server, rather than having to check its status after the fact.
    Schema schema = DirectoryServer.getSchema().duplicate();
    final SchemaHandler schemaHandler = serverContext.getSchemaHandler();
    final Schema currentSchema = schemaHandler.getSchema();
    final SchemaBuilder schemaBuilder = new SchemaBuilder(currentSchema);
    for (String schemaFile : filesToAdd)
    {
      try
      {
        SchemaConfigManager.loadSchemaFile(schema, schemaFile);
        File file = new File(schemaInstanceDirectory, schemaFile);
        schemaHandler.loadSchemaFileIntoSchemaBuilder(file, schemaBuilder, currentSchema);
      }
      catch (ConfigException | InitializationException e)
      {
@@ -155,6 +160,19 @@
    }
  }
  private File getSchemaDirectory() throws DirectoryException
  {
    try
    {
      return getServerContext().getSchemaHandler().getSchemaDirectoryPath();
    }
    catch (InitializationException e)
    {
      logger.traceException(e);
      throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,  e.getMessageObject());
    }
  }
  @Override
  protected TaskState runTask()
  {
@@ -170,12 +188,16 @@
    try
    {
      LinkedList<Modification> mods = new LinkedList<>();
      Schema schema = DirectoryServer.getSchema().duplicate();
      final SchemaHandler schemaHandler = getServerContext().getSchemaHandler();
      final Schema currentSchema = schemaHandler.getSchema();
      final SchemaBuilder schemaBuilder = new SchemaBuilder(currentSchema);
      for (String schemaFile : filesToAdd)
      {
        try
        {
          List<Modification> modList = SchemaConfigManager.loadSchemaFileReturnModifications(schema, schemaFile);
          File file = new File(getSchemaDirectory(), schemaFile);
          List<Modification> modList =
              schemaHandler.loadSchemaFileIntoSchemaBuilderAndReturnModifications(file, schemaBuilder, currentSchema);
          for (Modification m : modList)
          {
            Attribute a = m.getAttribute();
@@ -188,7 +210,7 @@
            mods.add(new Modification(m.getModificationType(), builder.toAttribute()));
          }
        }
        catch (ConfigException | InitializationException e)
        catch (DirectoryException | ConfigException | InitializationException e)
        {
          logger.traceException(e);
          logger.error(ERR_TASK_ADDSCHEMAFILE_ERROR_LOADING_SCHEMA_FILE, schemaFile, e.getMessage());
@@ -214,11 +236,20 @@
          }
        }
        SchemaWriter.writeConcatenatedSchema();
        final Schema newSchema = schemaBuilder.toSchema();
        try
        {
          schemaHandler.updateSchemaAndConcatenatedSchemaFiles(newSchema);
        }
        catch (DirectoryException e)
        {
          // This is very unlikely to happen because each schema file was previously loaded without error
          logger.traceException(e);
          logger.error(ERR_TASK_ADDSCHEMAFILE_SCHEMA_VALIDATION_ERROR, e.getMessage());
          return TaskState.STOPPED_BY_ERROR;
        }
      }
      schema.setYoungestModificationTime(System.currentTimeMillis());
      DirectoryServer.setSchema(schema);
      return TaskState.COMPLETED_SUCCESSFULLY;
    }
    finally
opendj-server-legacy/src/messages/org/opends/messages/task.properties
@@ -193,3 +193,5 @@
  does not appear to be a replication server
ERR_TASK_RESET_CHANGE_NUMBER_INVALID_114=Invalid change number (%d) specified, it must be greater than zero
ERR_TASK_RESET_CHANGE_NUMBER_FAILED_115=Unable to reset the change number index: %s
ERR_TASK_ADDSCHEMAFILE_SCHEMA_VALIDATION_ERROR_116=An error occurred while attempting to \
 validate the schema after changes made by the add schema file task: %s