From d576f04e7eb4920c5590fca03599955d2f10aea8 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Fri, 09 Sep 2016 09:45:22 +0000
Subject: [PATCH] OPENDJ-3089 Update SchemaHandler class to behave like SchemaConfigManager
---
opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java | 145 +++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 130 insertions(+), 15 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java b/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java
index 6c03b23..813923e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java
@@ -15,8 +15,10 @@
*/
package org.opends.server.core;
+import static org.opends.server.util.ServerConstants.SCHEMA_PROPERTY_FILENAME;
+import static org.opends.messages.ConfigMessages.WARN_CONFIG_CONFLICTING_DEFINITIONS_IN_SCHEMA_FILE;
+import static org.opends.messages.ConfigMessages.WARN_CONFIG_SCHEMA_CANNOT_PARSE_DEFINITIONS_IN_SCHEMA_FILE;
import static org.opends.messages.SchemaMessages.ERR_SCHEMA_HAS_WARNINGS;
-
import static org.forgerock.util.Utils.*;
import static org.opends.messages.ConfigMessages.*;
import static org.opends.server.util.StaticUtils.*;
@@ -41,8 +43,18 @@
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.Entry;
import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.schema.DITContentRule;
+import org.forgerock.opendj.ldap.schema.DITStructureRule;
+import org.forgerock.opendj.ldap.schema.MatchingRule;
+import org.forgerock.opendj.ldap.schema.MatchingRuleUse;
+import org.forgerock.opendj.ldap.schema.NameForm;
+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.SchemaValidationPolicy;
+import org.forgerock.opendj.ldap.schema.Syntax;
+import org.forgerock.opendj.ldap.schema.AttributeType.Builder;
+import org.forgerock.opendj.ldap.schema.SchemaBuilder.SchemaBuilderHook;
import org.forgerock.opendj.ldif.EntryReader;
import org.forgerock.opendj.ldif.LDIFEntryReader;
import org.forgerock.opendj.server.config.meta.SchemaProviderCfgDefn;
@@ -53,7 +65,6 @@
import org.opends.server.schema.SchemaProvider;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
-import org.opends.server.types.Schema.SchemaUpdater;
import org.opends.server.util.ActivateOnceSDKSchemaIsUsed;
/**
@@ -69,10 +80,12 @@
@ActivateOnceSDKSchemaIsUsed
public final class SchemaHandler
{
- private static final String CORE_SCHEMA_PROVIDER_NAME = "Core Schema";
-
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
+ private static final String CORE_SCHEMA_PROVIDER_NAME = "Core Schema";
+ private static final String CORE_SCHEMA_FILE = "00-core.ldif";
+ private static final String RFC_3112_SCHEMA_FILE = "03-rfc3112.ldif";
+
private ServerContext serverContext;
/**
@@ -122,12 +135,14 @@
// Take providers into account.
loadSchemaFromProviders(serverContext.getRootConfig(), schemaBuilder);
- // Take schema files into account (TODO : or load files using provider mechanism ?)
+ // Take schema files into account
completeSchemaFromFiles(schemaBuilder);
try
{
- // see RemoteSchemaLoader.readSchema()
+ // see RemoteSchemaLoader.readSchema() ==> why ??
+
+ // Add server specific syntaxes and matching rules
AciSyntax.addAciSyntax(schemaBuilder);
SubtreeSpecificationSyntax.addSubtreeSpecificationSyntax(schemaBuilder);
HistoricalCsnOrderingMatchingRuleImpl.addHistoricalCsnOrderingMatchingRule(schemaBuilder);
@@ -306,6 +321,7 @@
{
final LDIFEntryReader reader = new LDIFEntryReader(new FileReader(ldifFile));
reader.setSchema(schema);
+ reader.setSchemaValidationPolicy(SchemaValidationPolicy.ignoreAll());
return reader;
}
catch (Exception e)
@@ -333,7 +349,7 @@
final File schemaDirectory = getSchemaDirectoryPath();
for (String schemaFile : getSchemaFileNames(schemaDirectory))
{
- loadSchemaFile(schemaFile, schemaBuilder, Schema.getDefaultSchema());
+ loadSchemaFile(new File(schemaDirectory, schemaFile), schemaBuilder, Schema.getDefaultSchema());
}
}
@@ -380,6 +396,7 @@
}
catch (Exception e)
{
+ logger.traceException(e);
throw new InitializationException(ERR_CONFIG_SCHEMA_CANNOT_LIST_FILES
.get(schemaDirectory, getExceptionMessage(e)), e);
}
@@ -423,8 +440,8 @@
* Add the schema from the provided schema file to the provided schema
* builder.
*
- * @param schemaFileName
- * The name of the schema file to be loaded
+ * @param schemaFile
+ * the schema file to be loaded
* @param schemaBuilder
* The schema builder in which the contents of the schema file are to
* be loaded.
@@ -433,24 +450,113 @@
* @throws InitializationException
* If a problem occurs while initializing the schema elements.
*/
- private void loadSchemaFile(final String schemaFileName, final SchemaBuilder schemaBuilder, final Schema readSchema)
- throws InitializationException
+ private void loadSchemaFile(final File schemaFile, final SchemaBuilder schemaBuilder, final Schema readSchema)
+ throws InitializationException, ConfigException
{
EntryReader reader = null;
try
{
- File schemaFile = new File(getSchemaDirectoryPath(), schemaFileName);
reader = getLDIFReader(schemaFile, readSchema);
final Entry entry = readSchemaEntry(reader, schemaFile);
- // TODO : there is no more file information attached to schema elements - we should add support for this
- // in order to be able to redirect schema elements in the correct file when doing backups
- schemaBuilder.addSchema(entry, true);
+ boolean failOnError = true;
+ updateSchemaBuilderWithEntry(schemaBuilder, entry, schemaFile.getName(), failOnError);
}
finally {
Utils.closeSilently(reader);
}
}
+ private void updateSchemaBuilderWithEntry(SchemaBuilder schemaBuilder, Entry schemaEntry, String schemaFile,
+ boolean failOnError) throws ConfigException
+ {
+
+ // immediately overwrite these definitions which are already defined in the SDK core schema
+ final boolean overwriteCoreSchemaDefinitions =
+ CORE_SCHEMA_FILE.equals(schemaFile) || RFC_3112_SCHEMA_FILE.equals(schemaFile);
+
+ updateSchemaBuilderWithEntry0(schemaBuilder, schemaEntry, schemaFile, overwriteCoreSchemaDefinitions);
+
+ // check that the update is correct
+ Collection<LocalizableMessage> warnings = schemaBuilder.toSchema().getWarnings();
+ if (!warnings.isEmpty())
+ {
+ if (!overwriteCoreSchemaDefinitions)
+ {
+ // TODO: use correct message = warnings for schema file
+ logger.warn(WARN_CONFIG_CONFLICTING_DEFINITIONS_IN_SCHEMA_FILE, schemaFile, warnings);
+ // try to update again with overwriting
+ updateSchemaBuilderWithEntry0(schemaBuilder, schemaEntry, schemaFile, true);
+ warnings = schemaBuilder.toSchema().getWarnings();
+ if (!warnings.isEmpty())
+ {
+ // TODO: use correct message: warnings for schema file with overwrite=true
+ reportSchemaWarnings(WARN_CONFIG_CONFLICTING_DEFINITIONS_IN_SCHEMA_FILE.get(schemaFile, warnings),
+ failOnError);
+ }
+ }
+ else
+ {
+ // TODO: use correct message: warnings for schema file with overwrite=true
+ reportSchemaWarnings(WARN_CONFIG_CONFLICTING_DEFINITIONS_IN_SCHEMA_FILE.get(schemaFile, warnings), failOnError);
+ }
+ }
+ }
+
+ private void updateSchemaBuilderWithEntry0(final SchemaBuilder schemaBuilder, final Entry schemaEntry,
+ final String schemaFile, final boolean overwrite)
+ {
+ schemaBuilder.addSchema(schemaEntry, overwrite, new SchemaBuilderHook()
+ {
+ @Override
+ public void beforeAddSyntax(Syntax.Builder builder)
+ {
+ builder.removeExtraProperty(SCHEMA_PROPERTY_FILENAME).extraProperties(SCHEMA_PROPERTY_FILENAME, schemaFile);
+ }
+
+ @Override
+ public void beforeAddObjectClass(ObjectClass.Builder builder)
+ {
+ builder.removeExtraProperty(SCHEMA_PROPERTY_FILENAME).extraProperties(SCHEMA_PROPERTY_FILENAME, schemaFile);
+ }
+
+ @Override
+ public void beforeAddNameForm(NameForm.Builder builder)
+ {
+ builder.removeExtraProperty(SCHEMA_PROPERTY_FILENAME).extraProperties(SCHEMA_PROPERTY_FILENAME, schemaFile);
+ }
+
+ @Override
+ public void beforeAddMatchingRuleUse(MatchingRuleUse.Builder builder)
+ {
+ builder.removeExtraProperty(SCHEMA_PROPERTY_FILENAME).extraProperties(SCHEMA_PROPERTY_FILENAME, schemaFile);
+ }
+
+ @Override
+ public void beforeAddMatchingRule(MatchingRule.Builder builder)
+ {
+ builder.removeExtraProperty(SCHEMA_PROPERTY_FILENAME).extraProperties(SCHEMA_PROPERTY_FILENAME, schemaFile);
+ }
+
+ @Override
+ public void beforeAddDitStructureRule(DITStructureRule.Builder builder)
+ {
+ builder.removeExtraProperty(SCHEMA_PROPERTY_FILENAME).extraProperties(SCHEMA_PROPERTY_FILENAME, schemaFile);
+ }
+
+ @Override
+ public void beforeAddDitContentRule(DITContentRule.Builder builder)
+ {
+ builder.removeExtraProperty(SCHEMA_PROPERTY_FILENAME).extraProperties(SCHEMA_PROPERTY_FILENAME, schemaFile);
+ }
+
+ @Override
+ public void beforeAddAttribute(Builder builder)
+ {
+ builder.removeExtraProperty(SCHEMA_PROPERTY_FILENAME).extraProperties(SCHEMA_PROPERTY_FILENAME, schemaFile);
+ }
+ });
+ }
+
private void switchSchema(Schema newSchema) throws DirectoryException
{
rejectSchemaWithWarnings(newSchema);
@@ -468,6 +574,15 @@
}
}
+ private void reportSchemaWarnings(LocalizableMessage message, boolean failOnError) throws ConfigException
+ {
+ if (failOnError)
+ {
+ throw new ConfigException(message);
+ }
+ logger.error(message);
+ }
+
/** A file filter implementation that accepts only LDIF files. */
private static class SchemaFileFilter implements FilenameFilter
{
--
Gitblit v1.10.0