From 95df5cfdba474acb03076953e992b898fbb277a8 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 02 Feb 2009 23:37:54 +0000
Subject: [PATCH] Fix issue 3734 - Make network group policies extensible.

---
 opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java |  508 ++++++++++++++++++-------------------------------------
 1 files changed, 170 insertions(+), 338 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java
index 781574e..5608ad9 100644
--- a/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java
+++ b/opends/src/server/org/opends/server/core/networkgroups/NetworkGroupConfigManager.java
@@ -28,14 +28,11 @@
 
 
 
-import static org.opends.messages.CoreMessages.*;
-import static org.opends.server.loggers.ErrorLogger.logError;
+import static org.opends.messages.ConfigMessages.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
-import java.util.SortedSet;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.opends.messages.Message;
@@ -44,35 +41,40 @@
 import org.opends.server.admin.server.ConfigurationDeleteListener;
 import org.opends.server.admin.server.ServerManagementContext;
 import org.opends.server.admin.std.server.NetworkGroupCfg;
-import org.opends.server.admin.std.server.NetworkGroupCriteriaCfg;
-import
-  org.opends.server.admin.std.server.NetworkGroupRequestFilteringPolicyCfg;
-import org.opends.server.admin.std.server.NetworkGroupResourceLimitsCfg;
 import org.opends.server.admin.std.server.RootCfg;
 import org.opends.server.config.ConfigException;
-import org.opends.server.core.*;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
+import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.InitializationException;
 import org.opends.server.types.ResultCode;
+import org.opends.server.util.StaticUtils;
+
 
 
 /**
- * This class defines a utility that will be used to manage the configuration
- * for the set of network groups defined in the Directory Server.
- * It will perform the necessary initialization of those network groups when
- * the server is first started, and then will manage any changes to them while
- * the server is running.
+ * This class defines a utility that will be used to manage the
+ * configuration for the set of network groups defined in the Directory
+ * Server. It will perform the necessary initialization of those network
+ * groups when the server is first started, and then will manage any
+ * changes to them while the server is running.
  */
-public class NetworkGroupConfigManager
-       implements ConfigurationChangeListener<NetworkGroupCfg>,
-                  ConfigurationAddListener<NetworkGroupCfg>,
-                  ConfigurationDeleteListener<NetworkGroupCfg>
+public class NetworkGroupConfigManager implements
+    ConfigurationChangeListener<NetworkGroupCfg>,
+    ConfigurationAddListener<NetworkGroupCfg>,
+    ConfigurationDeleteListener<NetworkGroupCfg>
 
 {
+  /**
+   * The tracer object for the debug logger.
+   */
+  private static final DebugTracer TRACER = getTracer();
+
   // A mapping between the DNs of the config entries and the associated
   // network groups.
-  private ConcurrentHashMap<DN, NetworkGroup> networkGroups;
+  private final ConcurrentHashMap<DN, NetworkGroup> networkGroups;
 
 
 
@@ -87,175 +89,52 @@
 
 
   /**
-   * Initializes all network groups currently defined in the Directory
-   * Server configuration.  This should only be called at Directory Server
-   * startup.
-   *
-   * @throws  ConfigException  If a configuration problem causes the network
-   *                           group initialization process to fail.
-   */
-  public void initializeNetworkGroups()
-      throws ConfigException
-  {
-    // Get the root configuration object.
-    ServerManagementContext managementContext =
-         ServerManagementContext.getInstance();
-    RootCfg rootConfiguration =
-         managementContext.getRootConfiguration();
-
-
-    // Register as an add and delete listener with the root configuration so we
-    // can be notified if any network group entries are added or removed.
-    rootConfiguration.addNetworkGroupAddListener(this);
-    rootConfiguration.addNetworkGroupDeleteListener(this);
-
-
-    //Initialize the existing network groups.
-    for (String networkGroupName : rootConfiguration.listNetworkGroups())
-    {
-      NetworkGroupCfg networkGroupConfiguration =
-           rootConfiguration.getNetworkGroup(networkGroupName);
-      networkGroupConfiguration.addChangeListener(this);
-
-      if (networkGroupConfiguration.isEnabled())
-      {
-        try
-        {
-          createAndRegisterNetworkGroup(networkGroupConfiguration);
-        }
-        catch (DirectoryException de)
-        {
-          throw new ConfigException(de.getMessageObject());
-        }
-      }
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean isConfigurationAddAcceptable(
-      NetworkGroupCfg configuration,
-      List<Message>   unacceptableReasons)
-  {
-    // Nothing to check.
-    return true;
-  }
-
-
-
-  /**
    * {@inheritDoc}
    */
   public ConfigChangeResult applyConfigurationAdd(
       NetworkGroupCfg configuration)
   {
-    ResultCode    resultCode          = ResultCode.SUCCESS;
-    boolean       adminActionRequired = false;
-    List<Message> messages            = new ArrayList<Message>();
+    ResultCode resultCode = ResultCode.SUCCESS;
+    boolean adminActionRequired = false;
+    List<Message> messages = new ArrayList<Message>();
 
+    // Register to be notified of changes to the new network group.
     configuration.addChangeListener(this);
 
-    // If the new network group is enabled then create it and register it.
+    // If the new network group is enabled then create it and register
+    // it.
     if (configuration.isEnabled())
     {
       try
       {
-        createAndRegisterNetworkGroup(configuration);
+        NetworkGroup networkGroup =
+            NetworkGroup.createUserNetworkGroup(configuration);
+        networkGroups.put(configuration.dn(), networkGroup);
       }
-      catch (DirectoryException de)
+      catch (InitializationException e)
       {
-        if (resultCode == ResultCode.SUCCESS)
+        if (debugEnabled())
         {
-          resultCode = DirectoryServer.getServerErrorResultCode();
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
         }
 
-        messages.add(de.getMessageObject());
+        messages.add(e.getMessageObject());
+        resultCode = DirectoryServer.getServerErrorResultCode();
       }
-
-    }
-
-    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean isConfigurationDeleteAcceptable(
-      NetworkGroupCfg configuration,
-      List<Message>   unacceptableReasons)
-  {
-    return true;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public ConfigChangeResult applyConfigurationDelete(
-      NetworkGroupCfg configuration)
-  {
-    ResultCode    resultCode          = ResultCode.SUCCESS;
-    boolean       adminActionRequired = false;
-    List<Message> messages            = new ArrayList<Message>();
-
-
-    NetworkGroup networkGroup = networkGroups.remove(configuration.dn());
-    if (networkGroup != null)
-    {
-      networkGroup.deregister();
-      networkGroup.finalizeNetworkGroup();
-    }
-
-    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean isConfigurationChangeAcceptable(
-      NetworkGroupCfg configuration,
-      List<Message>   unacceptableReasons)
-  {
-    // If the network group is disabled then there is nothing to check.
-    if (! configuration.isEnabled())
-    {
-      return true;
-    }
-
-    // Check that all the workflows in the network group have a
-    // different base DN.
-
-    boolean result = true;
-    Set<String> allBaseDNs = new HashSet<String>();
-    for (String workflowId : configuration.getWorkflow())
-    {
-      WorkflowImpl workflow =
-        (WorkflowImpl) WorkflowImpl.getWorkflow(workflowId);
-      String baseDN = workflow.getBaseDN().toNormalizedString();
-      if (allBaseDNs.contains(baseDN))
+      catch (ConfigException e)
       {
-        // This baseDN is duplicated
-        Message message = ERR_WORKFLOW_BASE_DN_DUPLICATED_IN_NG.get(
-          baseDN, configuration.getNetworkGroupId());
-        unacceptableReasons.add(message);
-        result = false;
-        break;
-      }
-      else
-      {
-        allBaseDNs.add(baseDN);
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        }
+
+        messages.add(e.getMessageObject());
+        resultCode = DirectoryServer.getServerErrorResultCode();
       }
     }
 
-    return result;
+    return new ConfigChangeResult(resultCode, adminActionRequired,
+        messages);
   }
 
 
@@ -266,215 +145,168 @@
   public ConfigChangeResult applyConfigurationChange(
       NetworkGroupCfg configuration)
   {
-    ResultCode    resultCode          = ResultCode.SUCCESS;
-    boolean       adminActionRequired = false;
-    List<Message> messages            = new ArrayList<Message>();
+    ResultCode resultCode = ResultCode.SUCCESS;
+    boolean adminActionRequired = false;
+    List<Message> messages = new ArrayList<Message>();
 
-    ConfigChangeResult configChangeResult =
-      new ConfigChangeResult(resultCode, adminActionRequired, messages);
+    // Enable / disable the network group as required.
+    NetworkGroup networkGroup = networkGroups.get(configuration.dn());
 
-    // Get the existing network group if it's already enabled.
-    NetworkGroup existingNetworkGroup = networkGroups.get(configuration.dn());
-
-    // If the new configuration has the network group disabled, then disable
-    // it if it is enabled, or do nothing if it's already disabled.
-    if (! configuration.isEnabled())
+    if (networkGroup != null && !configuration.isEnabled())
     {
-      if (existingNetworkGroup != null)
-      {
-        networkGroups.remove(configuration.dn());
-        existingNetworkGroup.deregister();
-        existingNetworkGroup.finalizeNetworkGroup();
-      }
-
-      return configChangeResult;
+      // The network group has been disabled.
+      networkGroups.remove(configuration.dn());
+      networkGroup.finalizeNetworkGroup();
     }
-
-    // If the network group is disabled then create it and register it.
-    if (existingNetworkGroup == null)
+    else if (networkGroup == null && configuration.isEnabled())
     {
+      // The network group has been enabled.
       try
       {
-        createAndRegisterNetworkGroup(configuration);
+        networkGroup =
+            NetworkGroup.createUserNetworkGroup(configuration);
+        networkGroups.put(configuration.dn(), networkGroup);
       }
-      catch (DirectoryException de)
+      catch (InitializationException e)
       {
-        if (resultCode == ResultCode.SUCCESS)
+        if (debugEnabled())
         {
-          resultCode = DirectoryServer.getServerErrorResultCode();
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
         }
 
-        messages.add(de.getMessageObject());
+        messages.add(e.getMessageObject());
+        resultCode = DirectoryServer.getServerErrorResultCode();
       }
-    } else {
-      // The network group is already defined
-      // Simply update the properties
-      existingNetworkGroup.setNetworkGroupPriority(configuration.getPriority());
-
-      // Check for workflows currently registered in the network group
-      // but that must be removed
-      SortedSet<String> configWorkflows = configuration.getWorkflow();
-      for (String id : existingNetworkGroup.getRegisteredWorkflows()) {
-        if (!configWorkflows.contains(id)) {
-          existingNetworkGroup.deregisterWorkflow(id);
+      catch (ConfigException e)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
         }
+
+        messages.add(e.getMessageObject());
+        resultCode = DirectoryServer.getServerErrorResultCode();
       }
-
-      // Check for newly defined workflows
-      List<String> ngWorkflows = existingNetworkGroup.getRegisteredWorkflows();
-      for (String id : configuration.getWorkflow()) {
-        if (! ngWorkflows.contains(id)) {
-          WorkflowImpl workflowImpl =
-                  (WorkflowImpl) WorkflowImpl.getWorkflow(id);
-          try {
-            existingNetworkGroup.registerWorkflow(workflowImpl);
-          } catch (DirectoryException de) {
-            if (resultCode == ResultCode.SUCCESS)
-            {
-              resultCode = de.getResultCode();
-            }
-            messages.add(de.getMessageObject());
-          }
-        }
-      }
-
-      // Update the client connection affinity policy.
-      existingNetworkGroup.setAffinityPolicy(
-        ClientConnectionAffinityPolicy.toClientConnectionAffinityPolicy(
-          configuration.getAffinityPolicy()));
-
-      // Update the client connection affinity timeout
-      existingNetworkGroup.setAffinityTimeout(
-        configuration.getAffinityTimeout());
     }
 
-    configChangeResult =
-      new ConfigChangeResult(resultCode, adminActionRequired, messages);
-
-    return configChangeResult;
+    return new ConfigChangeResult(resultCode, adminActionRequired,
+        messages);
   }
 
 
+
   /**
-   * Creates and registers a network group.
-   *
-   * @param networkGroupCfg  the network group configuration
-   *
-   * @throws DirectoryException If a problem occurs while trying to
-   *                            register a network group.
+   * {@inheritDoc}
    */
-  private void createAndRegisterNetworkGroup(
-      NetworkGroupCfg networkGroupCfg
-      ) throws DirectoryException
+  public ConfigChangeResult applyConfigurationDelete(
+      NetworkGroupCfg configuration)
   {
-    // create the network group
-    String networkGroupId = networkGroupCfg.getNetworkGroupId();
-    NetworkGroup networkGroup = new NetworkGroup(networkGroupId);
+    ResultCode resultCode = ResultCode.SUCCESS;
+    boolean adminActionRequired = false;
+    List<Message> messages = new ArrayList<Message>();
 
-    // register the workflows with the network group
-    for (String workflowID: networkGroupCfg.getWorkflow())
+    NetworkGroup networkGroup =
+        networkGroups.remove(configuration.dn());
+    if (networkGroup != null)
     {
-      WorkflowImpl workflowImpl =
-        (WorkflowImpl) WorkflowImpl.getWorkflow(workflowID);
-      if (workflowImpl == null)
+      networkGroup.finalizeNetworkGroup();
+    }
+
+    return new ConfigChangeResult(resultCode, adminActionRequired,
+        messages);
+  }
+
+
+
+  /**
+   * Initializes all network groups currently defined in the Directory
+   * Server configuration. This should only be called at Directory
+   * Server startup.
+   *
+   * @throws ConfigException
+   *           If a critical configuration problem prevents the network
+   *           group initialization from succeeding.
+   * @throws InitializationException
+   *           If a problem occurs while initializing the network groups
+   *           that is not related to the server configuration.
+   */
+  public void initializeNetworkGroups() throws ConfigException,
+      InitializationException
+  {
+    // Get the root configuration object.
+    ServerManagementContext managementContext =
+        ServerManagementContext.getInstance();
+    RootCfg rootConfiguration =
+        managementContext.getRootConfiguration();
+
+    // Register as an add and delete listener with the root
+    // configuration so we can be notified if any network group entries
+    // are added or removed.
+    rootConfiguration.addNetworkGroupAddListener(this);
+    rootConfiguration.addNetworkGroupDeleteListener(this);
+
+    // Initialize the existing network groups.
+    for (String networkGroupName : rootConfiguration
+        .listNetworkGroups())
+    {
+      NetworkGroupCfg configuration =
+          rootConfiguration.getNetworkGroup(networkGroupName);
+      configuration.addChangeListener(this);
+
+      List<Message> unacceptableReasons = new ArrayList<Message>();
+      if (!NetworkGroup.isConfigurationAcceptable(configuration,
+          unacceptableReasons))
       {
-        // The workflow does not exist, log an error message
-        // and skip the workflow
-        Message message = INFO_ERR_WORKFLOW_DOES_NOT_EXIST.get(
-          workflowID, networkGroupId);
-        logError(message);
+        Message message =
+            ERR_CONFIG_NETWORK_GROUP_CONFIG_NOT_ACCEPTABLE.get(String
+                .valueOf(configuration.dn()), StaticUtils.listToString(
+                unacceptableReasons, ". "));
+        throw new InitializationException(message);
       }
-      else
+
+      if (configuration.isEnabled())
       {
-        networkGroup.registerWorkflow(workflowImpl);
+        NetworkGroup networkGroup =
+            NetworkGroup.createUserNetworkGroup(configuration);
+        networkGroups.put(configuration.dn(), networkGroup);
       }
     }
+  }
 
-    // register the root DSE workflow with the network group
-    WorkflowImpl rootDSEworkflow =
-      (WorkflowImpl) WorkflowImpl.getWorkflow("__root.dse__#");
-    networkGroup.registerWorkflow(rootDSEworkflow);
 
-    // finally register the network group with the server
-    networkGroups.put(networkGroupCfg.dn(), networkGroup);
-    networkGroup.register();
-    // Set the priority
-    networkGroup.setNetworkGroupPriority(networkGroupCfg.getPriority());
 
-    // Set the criteria
-    NetworkGroupCriteriaCfg criteriaCfg;
-    NetworkGroupCriteria criteria;
-    try {
-      criteriaCfg = networkGroupCfg.getNetworkGroupCriteria();
-    } catch (ConfigException ce) {
-      criteriaCfg = null;
-    }
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isConfigurationAddAcceptable(
+      NetworkGroupCfg configuration, List<Message> unacceptableReasons)
+  {
+    return NetworkGroup.isConfigurationAcceptable(configuration,
+        unacceptableReasons);
+  }
 
-    criteria = new NetworkGroupCriteria(criteriaCfg);
-    networkGroup.setCriteria(criteria);
 
-    // Add a config listener on the criteria
-    try {
-      networkGroupCfg.addNetworkGroupCriteriaAddListener(criteria);
-      networkGroupCfg.addNetworkGroupCriteriaDeleteListener(criteria);
-    } catch (ConfigException ex) {
-      throw new DirectoryException(ResultCode.UNDEFINED,
-            ex.getMessageObject());
-    }
 
-    // Set the resource limits
-    NetworkGroupResourceLimitsCfg limitsCfg;
-    ResourceLimits limits;
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isConfigurationChangeAcceptable(
+      NetworkGroupCfg configuration, List<Message> unacceptableReasons)
+  {
+    return NetworkGroup.isConfigurationAcceptable(configuration,
+        unacceptableReasons);
+  }
 
-    try {
-      limitsCfg = networkGroupCfg.getNetworkGroupResourceLimits();
-    } catch (ConfigException ex) {
-      limitsCfg = null;
-    }
-    limits = new ResourceLimits(limitsCfg);
-    networkGroup.setResourceLimits(limits);
 
-    // Add a config listener on the resource limits
-    try {
-      networkGroupCfg.addNetworkGroupResourceLimitsAddListener(limits);
-      networkGroupCfg.addNetworkGroupResourceLimitsDeleteListener(limits);
-    } catch (ConfigException ex) {
-      throw new DirectoryException(ResultCode.UNDEFINED,
-              ex.getMessageObject());
-    }
 
-    // Set the request filtering policy
-    NetworkGroupRequestFilteringPolicyCfg policyCfg;
-    RequestFilteringPolicy policy;
-    try {
-      policyCfg = networkGroupCfg.getNetworkGroupRequestFilteringPolicy();
-    } catch (ConfigException ex) {
-      policyCfg = null;
-    }
-    policy = new RequestFilteringPolicy(policyCfg);
-    networkGroup.setRequestFilteringPolicy(policy);
-
-    // Add a config listener on the request filtering policy
-    try {
-      networkGroupCfg.addNetworkGroupRequestFilteringPolicyAddListener
-              (policy);
-      networkGroupCfg.addNetworkGroupRequestFilteringPolicyDeleteListener(
-              policy);
-    } catch (ConfigException ex) {
-      throw new DirectoryException(ResultCode.UNDEFINED,
-              ex.getMessageObject());
-    }
-
-    // Set the client connection affinity policy.
-    ClientConnectionAffinityPolicy affinityPolicy =
-      ClientConnectionAffinityPolicy.toClientConnectionAffinityPolicy(
-        networkGroupCfg.getAffinityPolicy());
-    networkGroup.setAffinityPolicy(affinityPolicy);
-
-    // Set the client connection affinity timeout
-    long affinityTimeout = networkGroupCfg.getAffinityTimeout();
-    networkGroup.setAffinityTimeout(affinityTimeout);
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isConfigurationDeleteAcceptable(
+      NetworkGroupCfg configuration, List<Message> unacceptableReasons)
+  {
+    // Always ok.
+    return true;
   }
 
 }
-

--
Gitblit v1.10.0