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 legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2008 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.core;
028import java.util.List;
029
030import org.forgerock.i18n.LocalizableMessage;
031import org.opends.server.admin.ClassPropertyDefinition;
032import org.opends.server.admin.server.ConfigurationChangeListener;
033import org.opends.server.admin.server.ServerManagementContext;
034import org.opends.server.admin.std.meta.WorkQueueCfgDefn;
035import org.opends.server.admin.std.server.RootCfg;
036import org.opends.server.admin.std.server.WorkQueueCfg;
037import org.opends.server.api.WorkQueue;
038import org.forgerock.opendj.config.server.ConfigException;
039import org.forgerock.opendj.config.server.ConfigChangeResult;
040import org.opends.server.types.InitializationException;
041
042import static org.opends.messages.ConfigMessages.*;
043import static org.opends.server.util.StaticUtils.*;
044
045/**
046 * This class defines a utility that will be used to manage the Directory Server
047 * work queue.
048 */
049public class WorkQueueConfigManager
050       implements ConfigurationChangeListener<WorkQueueCfg>
051{
052  private final ServerContext serverContext;
053
054  /**
055   * Creates a new instance of this work queue config manager.
056   *
057   * @param serverContext
058   *            The server context.
059   */
060  public WorkQueueConfigManager(ServerContext serverContext)
061  {
062    this.serverContext = serverContext;
063  }
064
065
066  /**
067   * Initializes the Directory Server's work queue.  This should only be called
068   * at server startup.
069   *
070   * @return  WorkQueue  The initialized work queue that should be used by the
071   *                     server.
072   *
073   * @throws  ConfigException  If a configuration problem causes the work queue
074   *                           initialization process to fail.
075   *
076   * @throws  InitializationException  If a problem occurs while initializing
077   *                                   the work queue that is not related to the
078   *                                   server configuration.
079   */
080  public WorkQueue initializeWorkQueue()
081         throws ConfigException, InitializationException
082  {
083    // Get the root configuration object.
084    ServerManagementContext managementContext =
085         ServerManagementContext.getInstance();
086    RootCfg rootConfiguration =
087         managementContext.getRootConfiguration();
088
089
090    // Get the work queue configuration and register with it as a change
091    // listener.
092    WorkQueueCfg workQueueConfig = rootConfiguration.getWorkQueue();
093    workQueueConfig.addChangeListener(this);
094
095
096    // Get the work queue class, and load and instantiate an instance of it
097    // using that configuration.
098    WorkQueueCfgDefn definition = WorkQueueCfgDefn.getInstance();
099    ClassPropertyDefinition propertyDefinition =
100         definition.getJavaClassPropertyDefinition();
101    Class<? extends WorkQueue> workQueueClass =
102         propertyDefinition.loadClass(workQueueConfig.getJavaClass(),
103                                      WorkQueue.class);
104
105    try
106    {
107      WorkQueue workQueue = workQueueClass.newInstance();
108
109      workQueue.initializeWorkQueue(workQueueConfig);
110
111      return workQueue;
112    }
113    catch (Exception e)
114    {
115      LocalizableMessage message = ERR_CONFIG_WORK_QUEUE_INITIALIZATION_FAILED.
116          get(workQueueConfig.getJavaClass(), workQueueConfig.dn(), stackTraceToSingleLineString(e));
117      throw new InitializationException(message, e);
118    }
119  }
120
121
122
123  /** {@inheritDoc} */
124  @Override
125  public boolean isConfigurationChangeAcceptable(WorkQueueCfg configuration,
126                      List<LocalizableMessage> unacceptableReasons)
127  {
128    // Changes to the work queue configuration will always be acceptable to this
129    // generic implementation.
130    return true;
131  }
132
133
134
135  /** {@inheritDoc} */
136  @Override
137  public ConfigChangeResult applyConfigurationChange(WorkQueueCfg configuration)
138  {
139    final ConfigChangeResult ccr = new ConfigChangeResult();
140
141    // If the work queue class has been changed, then we should warn the user
142    // that it won't take effect until the server is restarted.
143    WorkQueue workQueue = DirectoryServer.getWorkQueue();
144    String workQueueClass = configuration.getJavaClass();
145    if (! workQueueClass.equals(workQueue.getClass().getName()))
146    {
147      ccr.addMessage(INFO_CONFIG_WORK_QUEUE_CLASS_CHANGE_REQUIRES_RESTART.get(
148              workQueue.getClass().getName(), workQueueClass));
149      ccr.setAdminActionRequired(true);
150    }
151    return ccr;
152  }
153}