001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.core;
028    
029    
030    
031    import java.util.ArrayList;
032    import java.util.List;
033    import java.util.concurrent.ConcurrentHashMap;
034    
035    import org.opends.messages.Message;
036    import org.opends.server.admin.server.ConfigurationAddListener;
037    import org.opends.server.admin.server.ConfigurationChangeListener;
038    import org.opends.server.admin.server.ConfigurationDeleteListener;
039    import org.opends.server.admin.server.ServerManagementContext;
040    import org.opends.server.admin.std.server.NetworkGroupCfg;
041    import org.opends.server.admin.std.server.RootCfg;
042    import org.opends.server.config.ConfigException;
043    import org.opends.server.types.ConfigChangeResult;
044    import org.opends.server.types.DN;
045    import org.opends.server.types.DirectoryException;
046    import org.opends.server.types.ResultCode;
047    
048    
049    /**
050     * This class defines a utility that will be used to manage the configuration
051     * for the set of network groups defined in the Directory Server.
052     * It will perform the necessary initialization of those network groups when
053     * the server is first started, and then will manage any changes to them while
054     * the server is running.
055     */
056    public class NetworkGroupConfigManager
057           implements ConfigurationChangeListener<NetworkGroupCfg>,
058                      ConfigurationAddListener<NetworkGroupCfg>,
059                      ConfigurationDeleteListener<NetworkGroupCfg>
060    
061    {
062      // A mapping between the DNs of the config entries and the associated
063      // network groups.
064      private ConcurrentHashMap<DN, NetworkGroup> networkGroups;
065    
066    
067    
068      /**
069       * Creates a new instance of this network group config manager.
070       */
071      public NetworkGroupConfigManager()
072      {
073        networkGroups = new ConcurrentHashMap<DN, NetworkGroup>();
074      }
075    
076    
077    
078      /**
079       * Initializes all network groups currently defined in the Directory
080       * Server configuration.  This should only be called at Directory Server
081       * startup.
082       *
083       * @throws  ConfigException  If a configuration problem causes the network
084       *                           group initialization process to fail.
085       */
086      public void initializeNetworkGroups()
087          throws ConfigException
088      {
089        // Get the root configuration object.
090        ServerManagementContext managementContext =
091             ServerManagementContext.getInstance();
092        RootCfg rootConfiguration =
093             managementContext.getRootConfiguration();
094    
095    
096        // Register as an add and delete listener with the root configuration so we
097        // can be notified if any network group entries are added or removed.
098        rootConfiguration.addNetworkGroupAddListener(this);
099        rootConfiguration.addNetworkGroupDeleteListener(this);
100    
101    
102        //Initialize the existing network groups.
103        for (String networkGroupName : rootConfiguration.listNetworkGroups())
104        {
105          NetworkGroupCfg networkGroupConfiguration =
106               rootConfiguration.getNetworkGroup(networkGroupName);
107          networkGroupConfiguration.addChangeListener(this);
108    
109          if (networkGroupConfiguration.isEnabled())
110          {
111            try
112            {
113              createAndRegisterNetworkGroup(networkGroupConfiguration);
114            }
115            catch (DirectoryException de)
116            {
117              throw new ConfigException(de.getMessageObject());
118            }
119          }
120        }
121      }
122    
123    
124    
125      /**
126       * {@inheritDoc}
127       */
128      public boolean isConfigurationAddAcceptable(
129          NetworkGroupCfg configuration,
130          List<Message>   unacceptableReasons)
131      {
132        // Nothing to check.
133        return true;
134      }
135    
136    
137    
138      /**
139       * {@inheritDoc}
140       */
141      public ConfigChangeResult applyConfigurationAdd(
142          NetworkGroupCfg configuration)
143      {
144        ResultCode         resultCode          = ResultCode.SUCCESS;
145        boolean            adminActionRequired = false;
146        ArrayList<Message> messages            = new ArrayList<Message>();
147    
148        configuration.addChangeListener(this);
149    
150        // If the new network group is enabled then create it and register it.
151        if (configuration.isEnabled())
152        {
153          try
154          {
155            createAndRegisterNetworkGroup(configuration);
156          }
157          catch (DirectoryException de)
158          {
159            if (resultCode == ResultCode.SUCCESS)
160            {
161              resultCode = DirectoryServer.getServerErrorResultCode();
162            }
163    
164            messages.add(de.getMessageObject());
165          }
166    
167        }
168    
169        return new ConfigChangeResult(resultCode, adminActionRequired, messages);
170      }
171    
172    
173    
174      /**
175       * {@inheritDoc}
176       */
177      public boolean isConfigurationDeleteAcceptable(
178          NetworkGroupCfg configuration,
179          List<Message>   unacceptableReasons)
180      {
181        return true;
182      }
183    
184    
185    
186      /**
187       * {@inheritDoc}
188       */
189      public ConfigChangeResult applyConfigurationDelete(
190          NetworkGroupCfg configuration)
191      {
192        ResultCode         resultCode          = ResultCode.SUCCESS;
193        boolean            adminActionRequired = false;
194        ArrayList<Message> messages            = new ArrayList<Message>();
195    
196    
197        NetworkGroup networkGroup = networkGroups.remove(configuration.dn());
198        if (networkGroup != null)
199        {
200          networkGroup.deregister();
201          networkGroup.finalizeNetworkGroup();
202        }
203    
204        return new ConfigChangeResult(resultCode, adminActionRequired, messages);
205      }
206    
207    
208    
209      /**
210       * {@inheritDoc}
211       */
212      public boolean isConfigurationChangeAcceptable(
213          NetworkGroupCfg configuration,
214          List<Message>   unacceptableReasons)
215      {
216        // Nothing to check.
217        return true;
218      }
219    
220    
221    
222      /**
223       * {@inheritDoc}
224       */
225      public ConfigChangeResult applyConfigurationChange(
226          NetworkGroupCfg configuration)
227      {
228        ResultCode         resultCode          = ResultCode.SUCCESS;
229        boolean            adminActionRequired = false;
230        ArrayList<Message> messages            = new ArrayList<Message>();
231    
232        ConfigChangeResult configChangeResult =
233          new ConfigChangeResult(resultCode, adminActionRequired, messages);
234    
235    
236        // Get the existing network group if it's already enabled.
237        NetworkGroup existingNetworkGroup = networkGroups.get(configuration.dn());
238    
239        // If the new configuration has the network group disabled, then disable
240        // it if it is enabled, or do nothing if it's already disabled.
241        if (! configuration.isEnabled())
242        {
243          if (existingNetworkGroup != null)
244          {
245            networkGroups.remove(configuration.dn());
246            existingNetworkGroup.deregister();
247            existingNetworkGroup.finalizeNetworkGroup();
248          }
249    
250          return configChangeResult;
251        }
252    
253        // If the network group is disabled then create it and register it.
254        if (existingNetworkGroup == null)
255        {
256          try
257          {
258            createAndRegisterNetworkGroup(configuration);
259          }
260          catch (DirectoryException de)
261          {
262            if (resultCode == ResultCode.SUCCESS)
263            {
264              resultCode = DirectoryServer.getServerErrorResultCode();
265            }
266    
267            messages.add(de.getMessageObject());
268          }
269        }
270    
271        return configChangeResult;
272      }
273    
274    
275      /**
276       * Creates and registers a network group.
277       *
278       * @param networkGroupCfg  the network group configuration
279       *
280       * @throws DirectoryException If a problem occurs while trying to
281       *                            register a network group.
282       */
283      private void createAndRegisterNetworkGroup(
284          NetworkGroupCfg networkGroupCfg
285          ) throws DirectoryException
286      {
287        // create the network group
288        String networkGroupId = networkGroupCfg.getNetworkGroupId();
289        NetworkGroup networkGroup = new NetworkGroup(networkGroupId);
290    
291        // register the workflows with the network group
292        for (String workflowID: networkGroupCfg.getWorkflow())
293        {
294          WorkflowImpl workflowImpl =
295            (WorkflowImpl) WorkflowImpl.getWorkflow(workflowID);
296          networkGroup.registerWorkflow(workflowImpl);
297        }
298    
299        // finally register the network group with the server
300        networkGroups.put(networkGroupCfg.dn(), networkGroup);
301        networkGroup.register();
302      }
303    
304    }
305