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