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