001    /*
002     * Copyright 2009-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.logs;
022    
023    
024    
025    import java.util.Collections;
026    import java.util.LinkedList;
027    import java.util.List;
028    import java.util.StringTokenizer;
029    
030    import com.unboundid.ldap.sdk.ResultCode;
031    import com.unboundid.ldap.sdk.unboundidds.controls.AssuredReplicationLocalLevel;
032    import com.unboundid.ldap.sdk.unboundidds.controls.
033                AssuredReplicationRemoteLevel;
034    import com.unboundid.util.NotExtensible;
035    import com.unboundid.util.NotMutable;
036    import com.unboundid.util.ThreadSafety;
037    import com.unboundid.util.ThreadSafetyLevel;
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 provides a data structure that holds information about a log
049     * message that may appear in the Directory Server access log about the result
050     * of a delete operation processed by the Directory Server.
051     */
052    @NotExtensible()
053    @NotMutable()
054    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
055    public class DeleteResultAccessLogMessage
056           extends DeleteRequestAccessLogMessage
057           implements OperationResultAccessLogMessage
058    {
059      /**
060       * The serial version UID for this serializable class.
061       */
062      private static final long serialVersionUID = -4379716182028950134L;
063    
064    
065    
066      // The assured replication level to use for local servers.
067      private final AssuredReplicationLocalLevel assuredReplicationLocalLevel;
068    
069      // The assured replication level to use for remote servers.
070      private final AssuredReplicationRemoteLevel assuredReplicationRemoteLevel;
071    
072      //  Indicates whether the delete operation targeted a soft-deleted entry.
073      private final Boolean changeToSoftDeletedEntry;
074    
075      // Indicates whether the response was known to be delayed by replication
076      // assurance processing.
077      private final Boolean responseDelayedByAssurance;
078    
079      // Indicates whether the any uncached data was accessed in the course of
080      // processing this operation.
081      private final Boolean uncachedDataAccessed;
082    
083      // The processing time for the operation.
084      private final Double processingTime;
085    
086      // The queue time for the operation.
087      private final Double queueTime;
088    
089      // The port of the backend server to which the request has been forwarded.
090      private final Integer targetPort;
091    
092      // The list of privileges required for processing the operation that the
093      // requester did not have.
094      private final List<String> missingPrivileges;
095    
096      // The list of privileges used during the course of processing the operation
097      // before an alternate authorization identity was assigned.
098      private final List<String> preAuthZUsedPrivileges;
099    
100      // The list of referral URLs for the operation.
101      private final List<String> referralURLs;
102    
103      // The list of response control OIDs for the operation.
104      private final List<String> responseControlOIDs;
105    
106      // The list of servers accessed while processing the operation.
107      private final List<String> serversAccessed;
108    
109      // The list of privileges used during the course of processing the operation.
110      private final List<String> usedPrivileges;
111    
112      // The assured replication timeout, in milliseconds.
113      private final Long assuredReplicationTimeoutMillis;
114    
115      // The number of intermediate response messages returned to the client.
116      private final Long intermediateResponsesReturned;
117    
118      // The result code for the operation.
119      private final ResultCode resultCode;
120    
121      // Additional information about the operation result.
122      private final String additionalInformation;
123    
124      // The alternate authorization DN for the operation.
125      private final String authzDN;
126    
127      // The diagnostic message for the operation.
128      private final String diagnosticMessage;
129    
130      // The intermediate client result for the operation.
131      private final String intermediateClientResult;
132    
133      // The matched DN for the operation.
134      private final String matchedDN;
135    
136      // The replication change ID for the operation.
137      private final String replicationChangeID;
138    
139      // The DN of the soft-deleted entry that was created as a result of a soft
140      // delete operation rather than a hard delete.
141      private final String softDeletedEntryDN;
142    
143      // The address of the backend server to which the request has been forwarded.
144      private final String targetHost;
145    
146      // The protocol used to forward the request to the backend server.
147      private final String targetProtocol;
148    
149    
150    
151      /**
152       * Creates a new delete result access log message from the provided message
153       * string.
154       *
155       * @param  s  The string to be parsed as a delete result access log message.
156       *
157       * @throws  LogException  If the provided string cannot be parsed as a valid
158       *                        log message.
159       */
160      public DeleteResultAccessLogMessage(final String s)
161             throws LogException
162      {
163        this(new LogMessage(s));
164      }
165    
166    
167    
168      /**
169       * Creates a new delete result access log message from the provided log
170       * message.
171       *
172       * @param  m  The log message to be parsed as a delete result access log
173       *            message.
174       */
175      public DeleteResultAccessLogMessage(final LogMessage m)
176      {
177        super(m);
178    
179        diagnosticMessage        = getNamedValue("message");
180        additionalInformation    = getNamedValue("additionalInfo");
181        matchedDN                = getNamedValue("matchedDN");
182        processingTime           = getNamedValueAsDouble("etime");
183        queueTime                = getNamedValueAsDouble("qtime");
184        intermediateClientResult = getNamedValue("from");
185        authzDN                  = getNamedValue("authzDN");
186        replicationChangeID      = getNamedValue("replicationChangeID");
187        softDeletedEntryDN       = getNamedValue("softDeleteEntryDN");
188        targetHost               = getNamedValue("targetHost");
189        targetPort               = getNamedValueAsInteger("targetPort");
190        targetProtocol           = getNamedValue("targetProtocol");
191    
192        changeToSoftDeletedEntry =
193             getNamedValueAsBoolean("changeToSoftDeletedEntry");
194        intermediateResponsesReturned =
195             getNamedValueAsLong("intermediateResponsesReturned");
196    
197        final Integer rcInteger = getNamedValueAsInteger("resultCode");
198        if (rcInteger == null)
199        {
200          resultCode = null;
201        }
202        else
203        {
204          resultCode = ResultCode.valueOf(rcInteger);
205        }
206    
207        final String refStr = getNamedValue("referralURLs");
208        if ((refStr == null) || (refStr.length() == 0))
209        {
210          referralURLs = Collections.emptyList();
211        }
212        else
213        {
214          final LinkedList<String> refs = new LinkedList<String>();
215          int startPos = 0;
216          while (true)
217          {
218            final int commaPos = refStr.indexOf(",ldap", startPos);
219            if (commaPos < 0)
220            {
221              refs.add(refStr.substring(startPos));
222              break;
223            }
224            else
225            {
226              refs.add(refStr.substring(startPos, commaPos));
227              startPos = commaPos+1;
228            }
229          }
230          referralURLs = Collections.unmodifiableList(refs);
231        }
232    
233        final String controlStr = getNamedValue("responseControls");
234        if (controlStr == null)
235        {
236          responseControlOIDs = Collections.emptyList();
237        }
238        else
239        {
240          final LinkedList<String> controlList = new LinkedList<String>();
241          final StringTokenizer t = new StringTokenizer(controlStr, ",");
242          while (t.hasMoreTokens())
243          {
244            controlList.add(t.nextToken());
245          }
246          responseControlOIDs = Collections.unmodifiableList(controlList);
247        }
248    
249        final String serversAccessedStr = getNamedValue("serversAccessed");
250        if ((serversAccessedStr == null) || (serversAccessedStr.length() == 0))
251        {
252          serversAccessed = Collections.emptyList();
253        }
254        else
255        {
256          final LinkedList<String> servers = new LinkedList<String>();
257          final StringTokenizer tokenizer =
258               new StringTokenizer(serversAccessedStr, ",");
259          while (tokenizer.hasMoreTokens())
260          {
261            servers.add(tokenizer.nextToken());
262          }
263          serversAccessed = Collections.unmodifiableList(servers);
264        }
265    
266        uncachedDataAccessed = getNamedValueAsBoolean("uncachedDataAccessed");
267    
268    
269        final String localLevelStr = getNamedValue("localAssuranceLevel");
270        if (localLevelStr == null)
271        {
272          assuredReplicationLocalLevel = null;
273        }
274        else
275        {
276          assuredReplicationLocalLevel =
277               AssuredReplicationLocalLevel.valueOf(localLevelStr);
278        }
279    
280        final String remoteLevelStr = getNamedValue("remoteAssuranceLevel");
281        if (remoteLevelStr == null)
282        {
283          assuredReplicationRemoteLevel = null;
284        }
285        else
286        {
287          assuredReplicationRemoteLevel =
288               AssuredReplicationRemoteLevel.valueOf(remoteLevelStr);
289        }
290    
291        assuredReplicationTimeoutMillis =
292             getNamedValueAsLong("assuranceTimeoutMillis");
293        responseDelayedByAssurance =
294             getNamedValueAsBoolean("responseDelayedByAssurance");
295    
296        final String usedPrivilegesStr = getNamedValue("usedPrivileges");
297        if ((usedPrivilegesStr == null) || (usedPrivilegesStr.length() == 0))
298        {
299          usedPrivileges = Collections.emptyList();
300        }
301        else
302        {
303          final LinkedList<String> privileges = new LinkedList<String>();
304          final StringTokenizer tokenizer =
305               new StringTokenizer(usedPrivilegesStr, ",");
306          while (tokenizer.hasMoreTokens())
307          {
308            privileges.add(tokenizer.nextToken());
309          }
310          usedPrivileges = Collections.unmodifiableList(privileges);
311        }
312    
313        final String preAuthZUsedPrivilegesStr =
314             getNamedValue("preAuthZUsedPrivileges");
315        if ((preAuthZUsedPrivilegesStr == null) ||
316            (preAuthZUsedPrivilegesStr.length() == 0))
317        {
318          preAuthZUsedPrivileges = Collections.emptyList();
319        }
320        else
321        {
322          final LinkedList<String> privileges = new LinkedList<String>();
323          final StringTokenizer tokenizer =
324               new StringTokenizer(preAuthZUsedPrivilegesStr, ",");
325          while (tokenizer.hasMoreTokens())
326          {
327            privileges.add(tokenizer.nextToken());
328          }
329          preAuthZUsedPrivileges = Collections.unmodifiableList(privileges);
330        }
331    
332        final String missingPrivilegesStr = getNamedValue("missingPrivileges");
333        if ((missingPrivilegesStr == null) || (missingPrivilegesStr.length() == 0))
334        {
335          missingPrivileges = Collections.emptyList();
336        }
337        else
338        {
339          final LinkedList<String> privileges = new LinkedList<String>();
340          final StringTokenizer tokenizer =
341               new StringTokenizer(missingPrivilegesStr, ",");
342          while (tokenizer.hasMoreTokens())
343          {
344            privileges.add(tokenizer.nextToken());
345          }
346          missingPrivileges = Collections.unmodifiableList(privileges);
347        }
348      }
349    
350    
351    
352      /**
353       * Retrieves the result code for the operation.
354       *
355       * @return  The result code for the operation, or {@code null} if it is not
356       *          included in the log message.
357       */
358      public ResultCode getResultCode()
359      {
360        return resultCode;
361      }
362    
363    
364    
365      /**
366       * Retrieves the diagnostic message for the operation.
367       *
368       * @return  The diagnostic message for the operation, or {@code null} if it is
369       *          not included in the log message.
370       */
371      public String getDiagnosticMessage()
372      {
373        return diagnosticMessage;
374      }
375    
376    
377    
378      /**
379       * Retrieves a message with additional information about the result of the
380       * operation.
381       *
382       * @return  A message with additional information about the result of the
383       *          operation, or {@code null} if it is not included in the log
384       *          message.
385       */
386      public String getAdditionalInformation()
387      {
388        return additionalInformation;
389      }
390    
391    
392    
393      /**
394       * Retrieves the matched DN for the operation.
395       *
396       * @return  The matched DN for the operation, or {@code null} if it is not
397       *          included in the log message.
398       */
399      public String getMatchedDN()
400      {
401        return matchedDN;
402      }
403    
404    
405    
406      /**
407       * Retrieves the list of referral URLs for the operation.
408       *
409       * @return  The list of referral URLs for the operation, or an empty list if
410       *          it is not included in the log message.
411       */
412      public List<String> getReferralURLs()
413      {
414        return referralURLs;
415      }
416    
417    
418    
419      /**
420       * Retrieves the number of intermediate response messages returned in the
421       * course of processing the operation.
422       *
423       * @return  The number of intermediate response messages returned to the
424       *          client in the course of processing the operation, or {@code null}
425       *          if it is not included in the log message.
426       */
427      public Long getIntermediateResponsesReturned()
428      {
429        return intermediateResponsesReturned;
430      }
431    
432    
433    
434      /**
435       * Retrieves the length of time in milliseconds required to process the
436       * operation.
437       *
438       * @return  The length of time in milliseconds required to process the
439       *          operation, or {@code null} if it is not included in the log
440       *          message.
441       */
442      public Double getProcessingTimeMillis()
443      {
444        return processingTime;
445      }
446    
447    
448    
449      /**
450       * Retrieves the length of time in milliseconds the operation was required to
451       * wait on the work queue.
452       *
453       * @return  The length of time in milliseconds the operation was required to
454       *          wait on the work queue, or {@code null} if it is not included in
455       *          the log message.
456       */
457      public Double getQueueTimeMillis()
458      {
459        return queueTime;
460      }
461    
462    
463    
464      /**
465       * Retrieves the OIDs of any response controls contained in the log message.
466       *
467       * @return  The OIDs of any response controls contained in the log message, or
468       *          an empty list if it is not included in the log message.
469       */
470      public List<String> getResponseControlOIDs()
471      {
472        return responseControlOIDs;
473      }
474    
475    
476    
477      /**
478       * Retrieves a list of the additional servers that were accessed in the course
479       * of processing the operation.  For example, if the access log message is
480       * from a Directory Proxy Server instance, then this may contain a list of the
481       * backend servers used to process the operation.
482       *
483       * @return  A list of the additional servers that were accessed in the course
484       *          of processing the operation, or an empty list if it is not
485       *          included in the log message.
486       */
487      public List<String> getServersAccessed()
488      {
489        return serversAccessed;
490      }
491    
492    
493    
494      /**
495       * Indicates whether the server accessed any uncached data in the course of
496       * processing the operation.
497       *
498       * @return  {@code true} if the server was known to access uncached data in
499       *          the course of processing the operation, {@code false} if the
500       *          server was known not to access uncached data, or {@code null} if
501       *          it is not included in the log message (and the server likely did
502       *          not access uncached data).
503       */
504      public Boolean getUncachedDataAccessed()
505      {
506        return uncachedDataAccessed;
507      }
508    
509    
510    
511      /**
512       * Retrieves the content of the intermediate client result for the
513       * operation.
514       *
515       * @return  The content of the intermediate client result for the operation,
516       *          or {@code null} if it is not included in the log message.
517       */
518      public String getIntermediateClientResult()
519      {
520        return intermediateClientResult;
521      }
522    
523    
524    
525      /**
526       * Retrieves the alternate authorization DN for the operation.
527       *
528       * @return  The alternate authorization DN for the operation, or {@code null}
529       *          if it is not included in the log message.
530       */
531      public String getAlternateAuthorizationDN()
532      {
533        return authzDN;
534      }
535    
536    
537    
538      /**
539       * Retrieves the replication change ID for the operation, if available.
540       *
541       * @return  The replication change ID for the operation, or {@code null} if it
542       *          is not included in the log message.
543       */
544      public String getReplicationChangeID()
545      {
546        return replicationChangeID;
547      }
548    
549    
550    
551      /**
552       * Retrieves the DN of the soft-deleted entry that was created as a result of
553       * this operation, if it was a soft delete rather than a normal hard delete.
554       *
555       * @return  The DN of the soft-deleted entry that was created as a result of
556       *          this operation, or {@code null} if it is not included in the log
557       *          message (e.g., because the operation was a hard delete rather than
558       *          a soft delete).
559       */
560      public String getSoftDeletedEntryDN()
561      {
562        return softDeletedEntryDN;
563      }
564    
565    
566    
567      /**
568       * Indicates whether the delete operation targeted a soft-deleted entry.
569       *
570       * @return  {@code true} if the delete operation was known to target a
571       *          soft-deleted entry, {@code false} if it was known to target a
572       *          non-soft-deleted entry, or {@code null} if it is not included in
573       *          the log message (and likely did not target a soft-deleted entry).
574       */
575      public Boolean getChangeToSoftDeletedEntry()
576      {
577        return changeToSoftDeletedEntry;
578      }
579    
580    
581    
582      /**
583       * Retrieves the address of the backend server to which the request has been
584       * forwarded.
585       *
586       * @return  The address of the backend server to which the request has been
587       *          forwarded, or {@code null} if it is not included in the log
588       *          message.
589       */
590      public String getTargetHost()
591      {
592        return targetHost;
593      }
594    
595    
596    
597      /**
598       * Retrieves the port of the backend server to which the request has been
599       * forwarded.
600       *
601       * @return  The port of the backend server to which the request has been
602       *          forwarded, or {@code null} if it is not included in the log
603       *          message.
604       */
605      public Integer getTargetPort()
606      {
607        return targetPort;
608      }
609    
610    
611    
612      /**
613       * Retrieves the protocol used to forward the request to the backend server.
614       *
615       * @return  The protocol used to forward the request to the backend server, or
616       *          {@code null} if it is not included in the log message.
617       */
618      public String getTargetProtocol()
619      {
620        return targetProtocol;
621      }
622    
623    
624    
625      /**
626       * Retrieves the local level that will be used for assured replication
627       * processing, if available.
628       *
629       * @return  The local level that will be used for assured replication
630       *          processing, or {@code null} if this is not included in the log
631       *          message (e.g., because assured replication will not be performed
632       *          for the operation).
633       */
634      public AssuredReplicationLocalLevel getAssuredReplicationLocalLevel()
635      {
636        return assuredReplicationLocalLevel;
637      }
638    
639    
640    
641      /**
642       * Retrieves the remote level that will be used for assured replication
643       * processing, if available.
644       *
645       * @return  The remote level that will be used for assured replication
646       *          processing, or {@code null} if this is not included in the log
647       *          message (e.g., because assured replication will not be performed
648       *          for the operation).
649       */
650      public AssuredReplicationRemoteLevel getAssuredReplicationRemoteLevel()
651      {
652        return assuredReplicationRemoteLevel;
653      }
654    
655    
656    
657      /**
658       * Retrieves the maximum length of time in milliseconds that the server will
659       * delay the response to the client while waiting for the replication
660       * assurance requirement to be satisfied.
661       *
662       * @return  The maximum length of time in milliseconds that the server will
663       *          delay the response to the client while waiting for the replication
664       *          assurance requirement to be satisfied, or {@code null} if this is
665       *          not included in the log message (e.g., because assured replication
666       *          will not be performed for the operation).
667       */
668      public Long getAssuredReplicationTimeoutMillis()
669      {
670        return assuredReplicationTimeoutMillis;
671      }
672    
673    
674    
675      /**
676       * Indicates whether the operation response to the client will be delayed
677       * until replication assurance has been satisfied or the timeout has occurred.
678       *
679       * @return  {@code true} if the operation response to the client will be
680       *          delayed until replication assurance has been satisfied,
681       *          {@code false} if the response will not be delayed by assurance
682       *          processing, or {@code null} if this was not included in the
683       *          log message (e.g., because assured replication will not be
684       *          performed for the operation)
685       */
686      public Boolean getResponseDelayedByAssurance()
687      {
688        return responseDelayedByAssurance;
689      }
690    
691    
692    
693      /**
694       * Retrieves the names of any privileges used during the course of processing
695       * the operation.
696       *
697       * @return  The names of any privileges used during the course of processing
698       *          the operation, or an empty list if no privileges were used or this
699       *          is not included in the log message.
700       */
701      public List<String> getUsedPrivileges()
702      {
703        return usedPrivileges;
704      }
705    
706    
707    
708      /**
709       * Retrieves the names of any privileges used during the course of processing
710       * the operation before an alternate authorization identity was assigned.
711       *
712       * @return  The names of any privileges used during the course of processing
713       *          the operation before an alternate authorization identity was
714       *          assigned, or an empty list if no privileges were used or this is
715       *          not included in the log message.
716       */
717      public List<String> getPreAuthorizationUsedPrivileges()
718      {
719        return preAuthZUsedPrivileges;
720      }
721    
722    
723    
724      /**
725       * Retrieves the names of any privileges that would have been required for
726       * processing the operation but that the requester did not have.
727       *
728       * @return  The names of any privileges that would have been required for
729       *          processing the operation but that the requester did not have, or
730       *          an empty list if there were no missing privileges or this is not
731       *          included in the log message.
732       */
733      public List<String> getMissingPrivileges()
734      {
735        return missingPrivileges;
736      }
737    
738    
739    
740      /**
741       * {@inheritDoc}
742       */
743      @Override()
744      public AccessLogMessageType getMessageType()
745      {
746        return AccessLogMessageType.RESULT;
747      }
748    }