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 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.core;
028    import org.opends.messages.Message;
029    
030    
031    
032    import java.lang.reflect.Method;
033    import java.util.ArrayList;
034    import java.util.List;
035    
036    import org.opends.server.admin.ClassPropertyDefinition;
037    import org.opends.server.admin.server.ConfigurationChangeListener;
038    import org.opends.server.admin.std.meta.WorkQueueCfgDefn;
039    import org.opends.server.admin.std.server.WorkQueueCfg;
040    import org.opends.server.admin.std.server.RootCfg;
041    import org.opends.server.admin.server.ServerManagementContext;
042    import org.opends.server.api.WorkQueue;
043    import org.opends.server.config.ConfigException;
044    import org.opends.server.types.ConfigChangeResult;
045    import org.opends.server.types.InitializationException;
046    import org.opends.server.types.ResultCode;
047    
048    import static org.opends.messages.ConfigMessages.*;
049    
050    import static org.opends.server.util.StaticUtils.*;
051    
052    
053    
054    /**
055     * This class defines a utility that will be used to manage the Directory Server
056     * work queue.
057     */
058    public class WorkQueueConfigManager
059           implements ConfigurationChangeListener<WorkQueueCfg>
060    {
061      /**
062       * Creates a new instance of this work queue config manager.
063       */
064      public WorkQueueConfigManager()
065      {
066        // No implementation is required.
067      }
068    
069    
070    
071      /**
072       * Initializes the Directory Server's work queue.  This should only be called
073       * at server startup.
074       *
075       * @return  WorkQueue  The initialized work queue that should be used by the
076       *                     server.
077       *
078       * @throws  ConfigException  If a configuration problem causes the work queue
079       *                           initialization process to fail.
080       *
081       * @throws  InitializationException  If a problem occurs while initializing
082       *                                   the work queue that is not related to the
083       *                                   server configuration.
084       */
085      public WorkQueue initializeWorkQueue()
086             throws ConfigException, InitializationException
087      {
088        // Get the root configuration object.
089        ServerManagementContext managementContext =
090             ServerManagementContext.getInstance();
091        RootCfg rootConfiguration =
092             managementContext.getRootConfiguration();
093    
094    
095        // Get the work queue configuration and register with it as a change
096        // listener.
097        WorkQueueCfg workQueueConfig = rootConfiguration.getWorkQueue();
098        workQueueConfig.addChangeListener(this);
099    
100    
101        // Get the work queue class, and load and instantiate an instance of it
102        // using that configuration.
103        WorkQueueCfgDefn definition = WorkQueueCfgDefn.getInstance();
104        ClassPropertyDefinition propertyDefinition =
105             definition.getJavaClassPropertyDefinition();
106        Class<? extends WorkQueue> workQueueClass =
107             propertyDefinition.loadClass(workQueueConfig.getJavaClass(),
108                                          WorkQueue.class);
109    
110        try
111        {
112          WorkQueue workQueue = workQueueClass.newInstance();
113    
114          Method method = workQueue.getClass().getMethod("initializeWorkQueue",
115              workQueueConfig.configurationClass());
116          method.invoke(workQueue, workQueueConfig);
117    
118          return workQueue;
119        }
120        catch (Exception e)
121        {
122          Message message = ERR_CONFIG_WORK_QUEUE_INITIALIZATION_FAILED.
123              get(workQueueConfig.getJavaClass(),
124                  String.valueOf(workQueueConfig.dn()),
125                  stackTraceToSingleLineString(e));
126          throw new InitializationException(message, e);
127        }
128      }
129    
130    
131    
132      /**
133       * {@inheritDoc}
134       */
135      public boolean isConfigurationChangeAcceptable(WorkQueueCfg configuration,
136                          List<Message> unacceptableReasons)
137      {
138        // Changes to the work queue configuration will always be acceptable to this
139        // generic implementation.
140        return true;
141      }
142    
143    
144    
145      /**
146       * {@inheritDoc}
147       */
148      public ConfigChangeResult applyConfigurationChange(WorkQueueCfg configuration)
149      {
150        ResultCode        resultCode          = ResultCode.SUCCESS;
151        boolean           adminActionRequired = false;
152        ArrayList<Message> messages            = new ArrayList<Message>();
153    
154    
155        // If the work queue class has been changed, then we should warn the user
156        // that it won't take effect until the server is restarted.
157        WorkQueue workQueue = DirectoryServer.getWorkQueue();
158        String workQueueClass = configuration.getJavaClass();
159        if (! workQueueClass.equals(workQueue.getClass().getName()))
160        {
161    
162          messages.add(INFO_CONFIG_WORK_QUEUE_CLASS_CHANGE_REQUIRES_RESTART.get(
163                  workQueue.getClass().getName(),
164                  workQueueClass));
165    
166          adminActionRequired = true;
167        }
168    
169    
170        return new ConfigChangeResult(resultCode, adminActionRequired, messages);
171      }
172    }
173