| | |
| | | |
| | | |
| | | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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); |
| | | } |
| | | |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
| | | |