001    /*
002     * Copyright 2008-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2015 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.ldap.sdk.unboundidds.monitors;
022    
023    
024    
025    import java.util.Collections;
026    import java.util.List;
027    import java.util.LinkedHashMap;
028    import java.util.Map;
029    
030    import com.unboundid.ldap.sdk.Entry;
031    import com.unboundid.util.DebugType;
032    import com.unboundid.util.NotMutable;
033    import com.unboundid.util.ThreadSafety;
034    import com.unboundid.util.ThreadSafetyLevel;
035    
036    import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
037    import static com.unboundid.util.Debug.*;
038    
039    
040    
041    /**
042     * <BLOCKQUOTE>
043     *   <B>NOTE:</B>  This class is part of the Commercial Edition of the UnboundID
044     *   LDAP SDK for Java.  It is not available for use in applications that
045     *   include only the Standard Edition of the LDAP SDK, and is not supported for
046     *   use in conjunction with non-UnboundID products.
047     * </BLOCKQUOTE>
048     * This class defines a monitor entry that provides general information about a
049     * Directory Server backend.  Information that may be available in a backend
050     * monitor entry includes:
051     * <UL>
052     *   <LI>The backend ID for the backend.</LI>
053     *   <LI>The set of base DNs for the backend.</LI>
054     *   <LI>The total number of entries in the backend.</LI>
055     *   <LI>The number of entries in the backend per base DN.</LI>
056     *   <LI>The writability mode for the backend, which indicates whether it will
057     *       accept write operations.</LI>
058     *   <LI>An indication about whether the backend is public (intended to hold
059     *       user data) or private (intended to hold operational data).</LI>
060     * </UL>
061     * The set of backend monitor entries published by the directory server can be
062     * obtained using the {@link MonitorManager#getBackendMonitorEntries} method.
063     * Specific methods are available for accessing the associated monitor data
064     * (e.g., {@link BackendMonitorEntry#getBackendID} to retrieve the backend ID),
065     * and there are also methods for accessing this information in a generic manner
066     * (e.g., {@link BackendMonitorEntry#getMonitorAttributes} to retrieve all of
067     * the monitor attributes).  See the {@link MonitorManager} class documentation
068     * for an example that demonstrates the use of the generic API for accessing
069     * monitor data.
070     */
071    @NotMutable()
072    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
073    public final class BackendMonitorEntry
074           extends MonitorEntry
075    {
076      /**
077       * The structural object class used in backend monitor entries.
078       */
079      static final String BACKEND_MONITOR_OC = "ds-backend-monitor-entry";
080    
081    
082    
083      /**
084       * The name of the attribute that contains the backend ID.
085       */
086      private static final String ATTR_BACKEND_ID = "ds-backend-id";
087    
088    
089    
090      /**
091       * The name of the attribute that specifies the base DN(s) for the backend.
092       */
093      private static final String ATTR_BASE_DN = "ds-backend-base-dn";
094    
095    
096    
097      /**
098       * The name of the attribute that specifies the number of entries per base DN
099       * in the backend.
100       */
101      private static final String ATTR_ENTRIES_PER_BASE_DN =
102           "ds-base-dn-entry-count";
103    
104    
105    
106      /**
107       * The name of the attribute that indicates whether the backend is a private
108       * backend.
109       */
110      private static final String ATTR_IS_PRIVATE = "ds-backend-is-private";
111    
112    
113    
114      /**
115       * The name of the attribute that holds the number of soft deletes processed
116       * since the backend was initialized.
117       */
118      private static final String ATTR_SOFT_DELETE_COUNT =
119           "ds-soft-delete-operations-count";
120    
121    
122    
123      /**
124       * The name of the attribute that specifies the total number of entries in the
125       * backend.
126       */
127      private static final String ATTR_TOTAL_ENTRIES = "ds-backend-entry-count";
128    
129    
130    
131      /**
132       * The name of the attribute that holds the number of undeletes  processed
133       * since the backend was initialized.
134       */
135      private static final String ATTR_UNDELETE_COUNT =
136           "ds-undelete-operations-count";
137    
138    
139    
140      /**
141       * The name of the attribute that specifies the writability mode for the
142       * backend.
143       */
144      private static final String ATTR_WRITABILITY_MODE =
145           "ds-backend-writability-mode";
146    
147    
148    
149      /**
150       * The serial version UID for this serializable class.
151       */
152      private static final long serialVersionUID = -4256944695436807547L;
153    
154    
155    
156      // Indicates whether the backend is a private backend.
157      private final Boolean isPrivate;
158    
159      // The base DNs for the backend.
160      private final List<String> baseDNs;
161    
162      // The number of soft delete operations processed since the backend was
163      // started.
164      private final Long softDeleteCount;
165    
166      // The total number of entries in the backend.
167      private final Long totalEntries;
168    
169      // The number of undelete operations processed since the backend was started.
170      private final Long undeleteCount;
171    
172      // The number of entries per base DN in the backend.
173      private final Map<String,Long> entriesPerBaseDN;
174    
175      // The backend ID for the backend.
176      private final String backendID;
177    
178      // The writability mode for the backend.
179      private final String writabilityMode;
180    
181    
182    
183      /**
184       * Creates a new backend monitor entry from the provided entry.
185       *
186       * @param  entry  The entry to be parsed as a backend monitor entry.  It must
187       *                not be {@code null}.
188       */
189      public BackendMonitorEntry(final Entry entry)
190      {
191        super(entry);
192    
193        backendID       = getString(ATTR_BACKEND_ID);
194        baseDNs         = getStrings(ATTR_BASE_DN);
195        isPrivate       = getBoolean(ATTR_IS_PRIVATE);
196        softDeleteCount = getLong(ATTR_SOFT_DELETE_COUNT);
197        totalEntries    = getLong(ATTR_TOTAL_ENTRIES);
198        undeleteCount   = getLong(ATTR_UNDELETE_COUNT);
199        writabilityMode = getString(ATTR_WRITABILITY_MODE);
200    
201        final List<String> entriesPerBase = getStrings(ATTR_ENTRIES_PER_BASE_DN);
202        final LinkedHashMap<String,Long> countMap =
203             new LinkedHashMap<String,Long>(entriesPerBase.size());
204        for (final String s : entriesPerBase)
205        {
206          try
207          {
208            final int spacePos = s.indexOf(' ');
209            final Long l = Long.parseLong(s.substring(0, spacePos));
210            final String dn = s.substring(spacePos+1).trim();
211            countMap.put(dn, l);
212          }
213          catch (Exception e)
214          {
215            debugException(e);
216    
217            if (debugEnabled(DebugType.MONITOR))
218            {
219              debugMonitor(entry,
220                           "Cannot parse value '" + s + "' for attribute " +
221                                ATTR_ENTRIES_PER_BASE_DN);
222            }
223          }
224        }
225    
226        entriesPerBaseDN = Collections.unmodifiableMap(countMap);
227      }
228    
229    
230    
231      /**
232       * Retrieves the backend ID for the associated backend.
233       *
234       * @return  The backend ID for the associated backend, or {@code null} if it
235       *          was not included in the monitor entry.
236       */
237      public String getBackendID()
238      {
239        return backendID;
240      }
241    
242    
243    
244      /**
245       * Retrieves the base DNs for the associated backend.
246       *
247       * @return  The base DNs for the associated backend, or an empty list if it
248       *          was not included in the monitor entry.
249       */
250      public List<String> getBaseDNs()
251      {
252        return baseDNs;
253      }
254    
255    
256    
257      /**
258       * Indicates whether the associated backend is a private backend.
259       *
260       * @return  {@code Boolean.TRUE} if the backend is a private backend,
261       *          {@code Boolean.FALSE} if it is not a private backend, or
262       *          {@code null} if it was not included in the monitor entry.
263       */
264      public Boolean isPrivate()
265      {
266        return isPrivate;
267      }
268    
269    
270    
271      /**
272       * Retrieves the writability mode for the associated backend.
273       *
274       * @return  The writability mode for the associated backend, or {@code null}
275       *          if it was not included in the monitor entry.
276       */
277      public String getWritabilityMode()
278      {
279        return writabilityMode;
280      }
281    
282    
283    
284      /**
285       * Retrieves the total number of entries in the associated backend.
286       *
287       * @return  The total number of entries in the associated backend, or
288       *          {@code null} if it was not included in the monitor entry.
289       */
290      public Long getTotalEntries()
291      {
292        return totalEntries;
293      }
294    
295    
296    
297      /**
298       * Retrieves a count of the number of entries per base DN in the associated
299       * backend.
300       *
301       * @return  A count of the number of entries per base DN in the associated
302       *          backend, or an empty map if it was not included in the monitor
303       *          entry.
304       */
305      public Map<String,Long> getEntriesPerBaseDN()
306      {
307        return entriesPerBaseDN;
308      }
309    
310    
311    
312      /**
313       * Retrieves the number of soft delete operations processed in the backend
314       * since the backend was started.
315       *
316       * @return  The number of soft delete operations processed in the backend
317       *          since the backend was started, or {@code null} if it was not
318       *          included in the monitor entry.
319       */
320      public Long getSoftDeleteCount()
321      {
322        return softDeleteCount;
323      }
324    
325    
326    
327      /**
328       * Retrieves the number of undelete operations processed in the backend since
329       * the backend was started.
330       *
331       * @return  The number of undelete operations processed in the backend since
332       *          the backend was started, or {@code null} if it was not included in
333       *          the monitor entry.
334       */
335      public Long getUndeleteCount()
336      {
337        return undeleteCount;
338      }
339    
340    
341    
342      /**
343       * {@inheritDoc}
344       */
345      @Override()
346      public String getMonitorDisplayName()
347      {
348        return INFO_BACKEND_MONITOR_DISPNAME.get();
349      }
350    
351    
352    
353      /**
354       * {@inheritDoc}
355       */
356      @Override()
357      public String getMonitorDescription()
358      {
359        return INFO_BACKEND_MONITOR_DESC.get();
360      }
361    
362    
363    
364      /**
365       * {@inheritDoc}
366       */
367      @Override()
368      public Map<String,MonitorAttribute> getMonitorAttributes()
369      {
370        final LinkedHashMap<String,MonitorAttribute> attrs =
371             new LinkedHashMap<String,MonitorAttribute>();
372    
373        if (backendID != null)
374        {
375          addMonitorAttribute(attrs,
376               ATTR_BACKEND_ID,
377               INFO_BACKEND_DISPNAME_BACKEND_ID.get(),
378               INFO_BACKEND_DESC_BACKEND_ID.get(),
379               backendID);
380        }
381    
382        if (! baseDNs.isEmpty())
383        {
384          addMonitorAttribute(attrs,
385               ATTR_BASE_DN,
386               INFO_BACKEND_DISPNAME_BASE_DN.get(),
387               INFO_BACKEND_DESC_BASE_DN.get(),
388               baseDNs);
389        }
390    
391        if (totalEntries != null)
392        {
393          addMonitorAttribute(attrs,
394               ATTR_TOTAL_ENTRIES,
395               INFO_BACKEND_DISPNAME_TOTAL_ENTRIES.get(),
396               INFO_BACKEND_DESC_TOTAL_ENTRIES.get(),
397               totalEntries);
398        }
399    
400        for (final String baseDN : entriesPerBaseDN.keySet())
401        {
402          final Long count = entriesPerBaseDN.get(baseDN);
403          addMonitorAttribute(attrs,
404                              ATTR_ENTRIES_PER_BASE_DN + '-' + baseDN,
405                              INFO_BACKEND_DISPNAME_ENTRY_COUNT.get(baseDN),
406                              INFO_BACKEND_DESC_ENTRY_COUNT.get(baseDN),
407                              count);
408    
409        }
410    
411        if (softDeleteCount != null)
412        {
413          addMonitorAttribute(attrs,
414               ATTR_SOFT_DELETE_COUNT,
415               INFO_BACKEND_DISPNAME_SOFT_DELETE_COUNT.get(),
416               INFO_BACKEND_DESC_SOFT_DELETE_COUNT.get(),
417               softDeleteCount);
418        }
419    
420        if (undeleteCount != null)
421        {
422          addMonitorAttribute(attrs,
423               ATTR_UNDELETE_COUNT,
424               INFO_BACKEND_DISPNAME_UNDELETE_COUNT.get(),
425               INFO_BACKEND_DESC_UNDELETE_COUNT.get(),
426               undeleteCount);
427        }
428    
429        if (writabilityMode != null)
430        {
431          addMonitorAttribute(attrs,
432               ATTR_WRITABILITY_MODE,
433               INFO_BACKEND_DISPNAME_WRITABILITY_MODE.get(),
434               INFO_BACKEND_DESC_WRITABILITY_MODE.get(),
435               writabilityMode);
436        }
437    
438        if (isPrivate != null)
439        {
440          addMonitorAttribute(attrs,
441               ATTR_IS_PRIVATE,
442               INFO_BACKEND_DISPNAME_IS_PRIVATE.get(),
443               INFO_BACKEND_DESC_IS_PRIVATE.get(),
444               isPrivate);
445        }
446    
447        return Collections.unmodifiableMap(attrs);
448      }
449    }