opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -446,9 +446,6 @@ private List<SynchronizationProvider<SynchronizationProviderCfg>> synchronizationProviders; /** The set of virtual attributes defined in the server. */ private List<VirtualAttributeRule> virtualAttributes; /** * The set of backend initialization listeners registered with the Directory * Server. @@ -918,8 +915,6 @@ directoryServer.supportedFeatures = new TreeSet<String>(); directoryServer.supportedLDAPVersions = new ConcurrentHashMap<Integer,List<ConnectionHandler>>(); directoryServer.virtualAttributes = new CopyOnWriteArrayList<VirtualAttributeRule>(); directoryServer.connectionHandlers = new CopyOnWriteArrayList<ConnectionHandler>(); directoryServer.identityMappers = @@ -4394,9 +4389,9 @@ * @return The set of virtual attribute rules registered with the Directory * Server. */ public static List<VirtualAttributeRule> getVirtualAttributes() public static Collection<VirtualAttributeRule> getVirtualAttributes() { return directoryServer.virtualAttributes; return directoryServer.virtualAttributeConfigManager.getVirtualAttributes(); } @@ -4417,7 +4412,7 @@ List<VirtualAttributeRule> ruleList = new LinkedList<VirtualAttributeRule>(); for (VirtualAttributeRule rule : directoryServer.virtualAttributes) for (VirtualAttributeRule rule : getVirtualAttributes()) { if (rule.appliesToEntry(entry)) { @@ -4428,68 +4423,24 @@ return ruleList; } /** * Registers the provided virtual attribute rule with the Directory Server. * * @param rule The virtual attribute rule to be registered. */ public static void registerVirtualAttribute(VirtualAttributeRule rule) public static void registerVirtualAttribute(final VirtualAttributeRule rule) { synchronized (directoryServer.virtualAttributes) { directoryServer.virtualAttributes.add(rule); } getInstance().virtualAttributeConfigManager.register(rule); } /** * Deregisters the provided virtual attribute rule with the Directory Server. * * @param rule The virutal attribute rule to be deregistered. * @param rule The virtual attribute rule to be deregistered. */ public static void deregisterVirtualAttribute(VirtualAttributeRule rule) { synchronized (directoryServer.virtualAttributes) { directoryServer.virtualAttributes.remove(rule); } } /** * Replaces the specified virtual attribute rule in the set of virtual * attributes registered with the Directory Server. If the old rule cannot * be found in the list, then the set of registered virtual attributes is not * updated. * * @param oldRule The existing rule that should be replaced with the new * rule. * @param newRule The new rule that should be used in place of the existing * rule. * * @return {@code true} if the old rule was found and replaced with the new * version, or {@code false} if it was not. */ public static boolean replaceVirtualAttribute(VirtualAttributeRule oldRule, VirtualAttributeRule newRule) { synchronized (directoryServer.virtualAttributes) { int pos = directoryServer.virtualAttributes.indexOf(oldRule); if (pos >= 0) { directoryServer.virtualAttributes.set(pos, newRule); return true; } else { return false; } } getInstance().virtualAttributeConfigManager.deregister(rule); } opends/src/server/org/opends/server/core/VirtualAttributeConfigManager.java
@@ -27,7 +27,6 @@ */ package org.opends.server.core; import java.lang.reflect.Method; import java.util.*; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; @@ -104,8 +103,7 @@ // Get the root configuration object. ServerManagementContext managementContext = ServerManagementContext.getInstance(); RootCfg rootConfiguration = managementContext.getRootConfiguration(); RootCfg rootConfiguration = managementContext.getRootConfiguration(); // Register as an add and delete listener with the root configuration so we @@ -162,7 +160,6 @@ VirtualAttributeRule rule = createRule(cfg, provider, filters); rules.put(cfg.dn(), rule); DirectoryServer.registerVirtualAttribute(rule); } catch (InitializationException ie) { @@ -185,10 +182,7 @@ cfg.getConflictBehavior()); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isConfigurationAddAcceptable( VirtualAttributeCfg configuration, @@ -242,11 +236,7 @@ return filters; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationAdd( VirtualAttributeCfg configuration) @@ -296,17 +286,12 @@ { VirtualAttributeRule rule = createRule(configuration, provider, filters); rules.put(configuration.dn(), rule); DirectoryServer.registerVirtualAttribute(rule); } return new ConfigChangeResult(resultCode, adminActionRequired, messages); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isConfigurationDeleteAcceptable( VirtualAttributeCfg configuration, @@ -316,11 +301,7 @@ return true; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationDelete( VirtualAttributeCfg configuration) @@ -332,18 +313,13 @@ VirtualAttributeRule rule = rules.remove(configuration.dn()); if (rule != null) { DirectoryServer.deregisterVirtualAttribute(rule); rule.getProvider().finalizeVirtualAttributeProvider(); } return new ConfigChangeResult(resultCode, adminActionRequired, messages); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public boolean isConfigurationChangeAcceptable( VirtualAttributeCfg configuration, @@ -384,11 +360,7 @@ return true; } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override public ConfigChangeResult applyConfigurationChange( VirtualAttributeCfg configuration) @@ -409,7 +381,6 @@ if (existingRule != null) { rules.remove(configuration.dn()); DirectoryServer.deregisterVirtualAttribute(existingRule); existingRule.getProvider().finalizeVirtualAttributeProvider(); } @@ -450,15 +421,9 @@ if (resultCode == ResultCode.SUCCESS) { VirtualAttributeRule rule = createRule(configuration, provider, filters); rules.put(configuration.dn(), rule); if (existingRule == null) if (existingRule != null) { DirectoryServer.registerVirtualAttribute(rule); } else { DirectoryServer.replaceVirtualAttribute(existingRule, rule); existingRule.getProvider().finalizeVirtualAttributeProvider(); } } @@ -474,7 +439,7 @@ * * @param className The fully-qualified name of the certificate mapper * class to load, instantiate, and initialize. * @param configuration The configuration to use to initialize the * @param cfg The configuration to use to initialize the * virtual attribute provider. It must not be * {@code null}. * @param initialize Indicates whether the virtual attribute provider @@ -485,8 +450,9 @@ * @throws InitializationException If a problem occurred while attempting to * initialize the certificate mapper. */ @SuppressWarnings({ "rawtypes", "unchecked" }) private VirtualAttributeProvider<? extends VirtualAttributeCfg> loadProvider(String className, VirtualAttributeCfg configuration, loadProvider(String className, VirtualAttributeCfg cfg, boolean initialize) throws InitializationException { @@ -499,31 +465,20 @@ Class<? extends VirtualAttributeProvider> providerClass = propertyDefinition.loadClass(className, VirtualAttributeProvider.class); VirtualAttributeProvider<? extends VirtualAttributeCfg> provider = providerClass.newInstance(); VirtualAttributeProvider provider = providerClass.newInstance(); if (initialize) { Method method = provider.getClass().getMethod( "initializeVirtualAttributeProvider", configuration.configurationClass()); method.invoke(provider, configuration); provider.initializeVirtualAttributeProvider(cfg); } else { Method method = provider.getClass().getMethod("isConfigurationAcceptable", VirtualAttributeCfg.class, List.class); List<Message> unacceptableReasons = new ArrayList<Message>(); Boolean acceptable = (Boolean) method.invoke(provider, configuration, unacceptableReasons); if (! acceptable) if (!provider.isConfigurationAcceptable(cfg, unacceptableReasons)) { String reasons = collectionToString(unacceptableReasons, ". "); Message message = ERR_CONFIG_VATTR_CONFIG_NOT_ACCEPTABLE.get( String.valueOf(configuration.dn()), reasons); String.valueOf(cfg.dn()), reasons); throw new InitializationException(message); } } @@ -533,9 +488,55 @@ catch (Exception e) { Message message = ERR_CONFIG_VATTR_INITIALIZATION_FAILED. get(className, String.valueOf(configuration.dn()), get(className, String.valueOf(cfg.dn()), stackTraceToSingleLineString(e)); throw new InitializationException(message, e); } } /** * Retrieves the collection of registered virtual attribute rules. * * @return The collection of registered virtual attribute rules. */ public Collection<VirtualAttributeRule> getVirtualAttributes() { return this.rules.values(); } /** * Registers the provided virtual attribute rule. * * @param rule * The virtual attribute rule to be registered. */ public void register(VirtualAttributeRule rule) { rules.put(getDummyDN(rule), rule); } /** * Deregisters the provided virtual attribute rule. * * @param rule * The virtual attribute rule to be deregistered. */ public void deregister(VirtualAttributeRule rule) { rules.remove(getDummyDN(rule)); } private DN getDummyDN(VirtualAttributeRule rule) { try { String name = rule.getAttributeType().getNameOrOID(); return DN.decode("cn=" + name + ",cn=Virtual Attributes,cn=config"); } catch (DirectoryException e) { // should never happen throw new RuntimeException(e); } } } opends/src/server/org/opends/server/replication/server/ReplicationServer.java
@@ -32,13 +32,13 @@ import java.net.*; import java.util.*; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicReference; import org.opends.messages.Category; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.messages.Severity; import org.opends.server.admin.server.ConfigurationChangeListener; import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn; import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn.*; import org.opends.server.admin.std.server.ReplicationServerCfg; import org.opends.server.admin.std.server.UserDefinedVirtualAttributeCfg; @@ -111,10 +111,11 @@ */ private static final DebugTracer TRACER = getTracer(); private static String externalChangeLogWorkflowID = private static String eclWorkflowID = "External Changelog Workflow ID"; private ECLWorkflowElement eclwe; private WorkflowImpl externalChangeLogWorkflowImpl = null; private AtomicReference<WorkflowImpl> eclWorkflowImpl = new AtomicReference<WorkflowImpl>(); /** * This is required for unit testing, so that we can keep track of all the @@ -428,7 +429,7 @@ // Creates the ECL workflow elem so that DS (LDAPReplicationDomain) // can know me and really enableECL. if (WorkflowImpl.getWorkflow(externalChangeLogWorkflowID) != null) if (WorkflowImpl.getWorkflow(eclWorkflowID) != null) { // Already done. Nothing to do return; @@ -461,54 +462,54 @@ */ public void enableECL() throws DirectoryException { if (externalChangeLogWorkflowImpl!=null) if (eclWorkflowImpl.get() != null) { // do nothing if ECL is already enabled // ECL is already enabled, do nothing return; } // Create the workflow for the base DN and register the workflow with // the server. externalChangeLogWorkflowImpl = new WorkflowImpl( externalChangeLogWorkflowID, DN.decode(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT), eclwe.getWorkflowElementID(), eclwe); externalChangeLogWorkflowImpl.register(); // Create the workflow for the base DN // and register the workflow with the server. final DN dn = DN.decode(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT); final WorkflowImpl workflowImpl = new WorkflowImpl(eclWorkflowID, dn, eclwe.getWorkflowElementID(), eclwe); if (!eclWorkflowImpl.compareAndSet(null, workflowImpl)) { // ECL is being enabled, do nothing return; } NetworkGroup defaultNetworkGroup = NetworkGroup.getDefaultNetworkGroup(); defaultNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl); workflowImpl.register(); // FIXME:ECL should the ECL Workflow be registered in adminNetworkGroup? NetworkGroup adminNetworkGroup = NetworkGroup.getAdminNetworkGroup(); adminNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl); NetworkGroup.getDefaultNetworkGroup().registerWorkflow(workflowImpl); // FIXME:ECL should the ECL Workflow be registered in internalNetworkGroup? NetworkGroup internalNetworkGroup = NetworkGroup.getInternalNetworkGroup(); internalNetworkGroup.registerWorkflow(externalChangeLogWorkflowImpl); // FIXME:ECL should the ECL Workflow be registered in admin and internal // network groups? NetworkGroup.getAdminNetworkGroup().registerWorkflow(workflowImpl); NetworkGroup.getInternalNetworkGroup().registerWorkflow(workflowImpl); enableECLVirtualAttr("lastexternalchangelogcookie", new LastCookieVirtualProvider()); enableECLVirtualAttr("firstchangenumber", new FirstChangeNumberVirtualAttributeProvider()); enableECLVirtualAttr("lastchangenumber", new LastChangeNumberVirtualAttributeProvider()); enableECLVirtualAttr("changelog", new ChangelogBaseDNVirtualAttributeProvider()); DirectoryServer.registerVirtualAttribute(buildVirtualAttributeRule( "lastexternalchangelogcookie", new LastCookieVirtualProvider())); DirectoryServer.registerVirtualAttribute(buildVirtualAttributeRule( "firstchangenumber", new FirstChangeNumberVirtualAttributeProvider())); DirectoryServer.registerVirtualAttribute(buildVirtualAttributeRule( "lastchangenumber", new LastChangeNumberVirtualAttributeProvider())); DirectoryServer.registerVirtualAttribute(buildVirtualAttributeRule( "changelog", new ChangelogBaseDNVirtualAttributeProvider())); } private static void enableECLVirtualAttr(String attrName, private static VirtualAttributeRule buildVirtualAttributeRule(String attrName, VirtualAttributeProvider<UserDefinedVirtualAttributeCfg> provider) throws DirectoryException throws DirectoryException { Set<DN> baseDNs = new HashSet<DN>(0); Set<DN> groupDNs = new HashSet<DN>(0); Set<SearchFilter> filters = new HashSet<SearchFilter>(0); VirtualAttributeCfgDefn.ConflictBehavior conflictBehavior = ConflictBehavior.VIRTUAL_OVERRIDES_REAL; ConflictBehavior conflictBehavior = ConflictBehavior.VIRTUAL_OVERRIDES_REAL; try { Set<DN> baseDNs = Collections.singleton(DN.decode("")); Set<DN> groupDNs = Collections.emptySet(); Set<SearchFilter> filters = Collections.singleton( SearchFilter.createFilterFromString("(objectclass=*)")); // To avoid the configuration in cn=config just // create a rule and register it into the DirectoryServer @@ -517,17 +518,9 @@ AttributeType attributeType = DirectoryServer.getAttributeType( attrName, false); SearchFilter filter = SearchFilter.createFilterFromString("objectclass=*"); filters.add(filter); baseDNs.add(DN.decode("")); VirtualAttributeRule rule = new VirtualAttributeRule(attributeType, provider, baseDNs, SearchScope.BASE_OBJECT, groupDNs, filters, conflictBehavior); DirectoryServer.registerVirtualAttribute(rule); return new VirtualAttributeRule(attributeType, provider, baseDNs, SearchScope.BASE_OBJECT, groupDNs, filters, conflictBehavior); } catch (Exception e) { @@ -539,25 +532,35 @@ private void shutdownECL() { WorkflowImpl eclwf = (WorkflowImpl) WorkflowImpl .getWorkflow(externalChangeLogWorkflowID); WorkflowImpl eclwf = (WorkflowImpl) WorkflowImpl.getWorkflow(eclWorkflowID); // do it only if not already done by another RS (unit test case) // if (DirectoryServer.getWorkflowElement(externalChangeLogWorkflowID) if (eclwf != null) { // FIXME:ECL should the ECL Workflow be registered in // internalNetworkGroup? NetworkGroup internalNetworkGroup = NetworkGroup .getInternalNetworkGroup(); internalNetworkGroup.deregisterWorkflow(externalChangeLogWorkflowID); // FIXME:ECL should the ECL Workflow be registered in admin and internal // network groups? NetworkGroup.getInternalNetworkGroup().deregisterWorkflow(eclWorkflowID); NetworkGroup.getAdminNetworkGroup().deregisterWorkflow(eclWorkflowID); // FIXME:ECL should the ECL Workflow be registered in adminNetworkGroup? NetworkGroup adminNetworkGroup = NetworkGroup.getAdminNetworkGroup(); adminNetworkGroup.deregisterWorkflow(externalChangeLogWorkflowID); NetworkGroup.getDefaultNetworkGroup().deregisterWorkflow(eclWorkflowID); NetworkGroup defaultNetworkGroup = NetworkGroup.getDefaultNetworkGroup(); defaultNetworkGroup.deregisterWorkflow(externalChangeLogWorkflowID); try { DirectoryServer.deregisterVirtualAttribute(buildVirtualAttributeRule( "lastexternalchangelogcookie", new LastCookieVirtualProvider())); DirectoryServer.deregisterVirtualAttribute(buildVirtualAttributeRule( "firstchangenumber", new FirstChangeNumberVirtualAttributeProvider())); DirectoryServer.deregisterVirtualAttribute(buildVirtualAttributeRule( "lastchangenumber", new LastChangeNumberVirtualAttributeProvider())); DirectoryServer.deregisterVirtualAttribute(buildVirtualAttributeRule( "changelog", new ChangelogBaseDNVirtualAttributeProvider())); } catch (DirectoryException e) { // Should never happen throw new RuntimeException(e); } eclwf.deregister(); eclwf.finalizeWorkflow();