001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.server.monitors;
018
019import static org.opends.server.util.ServerConstants.*;
020
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.Set;
024
025import org.forgerock.i18n.slf4j.LocalizedLogger;
026import org.forgerock.opendj.ldap.DN;
027import org.forgerock.opendj.ldap.schema.ObjectClass;
028import org.forgerock.opendj.server.config.server.MonitorProviderCfg;
029import org.opends.server.api.Backend;
030import org.opends.server.api.MonitorData;
031import org.opends.server.api.MonitorProvider;
032import org.opends.server.core.DirectoryServer;
033
034/**
035 * This class implements a monitor provider that will report generic information
036 * for an enabled Directory Server backend, including its backend ID, base DNs,
037 * writability mode, and the number of entries it contains.
038 */
039public class BackendMonitor
040       extends MonitorProvider<MonitorProviderCfg>
041{
042  /** The backend with which this monitor is associated. */
043  private Backend<?> backend;
044
045  /** The name for this monitor. */
046  private String monitorName;
047  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
048
049  /**
050   * Creates a new instance of this backend monitor provider that will work with
051   * the provided backend.  Most of the initialization should be handled in the
052   * {@code initializeMonitorProvider} method.
053   *
054   * @param  backend  The backend with which this monitor is associated.
055   */
056  public BackendMonitor(Backend<?> backend)
057  {
058    this.backend = backend;
059  }
060
061  @Override
062  public void initializeMonitorProvider(MonitorProviderCfg configuration)
063  {
064    monitorName = backend.getBackendID() + " Backend";
065  }
066
067  @Override
068  public String getMonitorInstanceName()
069  {
070    return monitorName;
071  }
072
073  /**
074   * Retrieves the objectclass that should be included in the monitor entry
075   * created from this monitor provider.
076   *
077   * @return  The objectclass that should be included in the monitor entry
078   *          created from this monitor provider.
079   */
080  @Override
081  public ObjectClass getMonitorObjectClass()
082  {
083    return DirectoryServer.getSchema().getObjectClass(OC_MONITOR_BACKEND);
084  }
085
086  @Override
087  public MonitorData getMonitorData()
088  {
089    Set<DN> baseDNs = backend.getBaseDNs();
090
091    MonitorData attrs = new MonitorData(6);
092    attrs.add(ATTR_MONITOR_BACKEND_ID, backend.getBackendID());
093    attrs.add(ATTR_MONITOR_BACKEND_BASE_DN, baseDNs);
094    attrs.add(ATTR_MONITOR_BACKEND_IS_PRIVATE, backend.isPrivateBackend());
095    attrs.add(ATTR_MONITOR_BACKEND_ENTRY_COUNT, backend.getEntryCount());
096    attrs.add(ATTR_MONITOR_BASE_DN_ENTRY_COUNT, getBackendEntryCounts(baseDNs));
097    attrs.add(ATTR_MONITOR_BACKEND_WRITABILITY_MODE, backend.getWritabilityMode());
098    return attrs;
099  }
100
101  private Collection<String> getBackendEntryCounts(Set<DN> baseDNs)
102  {
103    Collection<String> results = new ArrayList<>();
104    if (baseDNs.size() == 1)
105    {
106      // This is done to avoid recalculating the number of entries
107      // using the numSubordinates method in the case where the
108      // backend has a single base DN.
109      results.add(backend.getEntryCount() + " " + baseDNs.iterator().next());
110    }
111    else
112    {
113      for (DN dn : baseDNs)
114      {
115        long entryCount = -1;
116        try
117        {
118          entryCount = backend.getNumberOfEntriesInBaseDN(dn);
119        }
120        catch (Exception ex)
121        {
122          logger.traceException(ex);
123        }
124        results.add(entryCount + " " + dn);
125      }
126    }
127    return results;
128  }
129}