001/*
002 * Copyright 2009-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2009-2020 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2015-2020 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.sdk.unboundidds.logs;
037
038
039
040import java.util.Collections;
041import java.util.LinkedList;
042import java.util.List;
043import java.util.StringTokenizer;
044
045import com.unboundid.ldap.sdk.ResultCode;
046import com.unboundid.util.NotMutable;
047import com.unboundid.util.ThreadSafety;
048import com.unboundid.util.ThreadSafetyLevel;
049
050
051
052/**
053 * This class provides a data structure that holds information about a log
054 * message that may appear in the Directory Server access log about the result
055 * of a compare operation processed by the Directory Server.
056 * <BR>
057 * <BLOCKQUOTE>
058 *   <B>NOTE:</B>  This class, and other classes within the
059 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
060 *   supported for use against Ping Identity, UnboundID, and
061 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
062 *   for proprietary functionality or for external specifications that are not
063 *   considered stable or mature enough to be guaranteed to work in an
064 *   interoperable way with other types of LDAP servers.
065 * </BLOCKQUOTE>
066 */
067@NotMutable()
068@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
069public final class CompareResultAccessLogMessage
070       extends CompareRequestAccessLogMessage
071       implements OperationResultAccessLogMessage
072{
073  /**
074   * The serial version UID for this serializable class.
075   */
076  private static final long serialVersionUID = -1198844903765372824L;
077
078
079
080  // Indicates whether the any uncached data was accessed in the course of
081  // processing this operation.
082  private final Boolean uncachedDataAccessed;
083
084  // The processing time for the operation.
085  private final Double processingTime;
086
087  // The queue time for the operation.
088  private final Double queueTime;
089
090  // The list of privileges required for processing the operation that the
091  // requester did not have.
092  private final List<String> missingPrivileges;
093
094  // The list of privileges used during the course of processing the operation
095  // before an alternate authorization identity was assigned.
096  private final List<String> preAuthZUsedPrivileges;
097
098  // The list of referral URLs for the operation.
099  private final List<String> referralURLs;
100
101  // The list of response control OIDs for the operation.
102  private final List<String> responseControlOIDs;
103
104  // The list of servers accessed while processing the operation.
105  private final List<String> serversAccessed;
106
107  // The list of privileges used during the course of processing the operation.
108  private final List<String> usedPrivileges;
109
110  // The number of intermediate response messages returned to the client.
111  private final Long intermediateResponsesReturned;
112
113  // The result code for the operation.
114  private final ResultCode resultCode;
115
116  // Additional information about the operation result.
117  private final String additionalInformation;
118
119  // The alternate authorization DN for the operation.
120  private final String authzDN;
121
122  // The diagnostic message for the operation.
123  private final String diagnosticMessage;
124
125  // The intermediate client result for the operation.
126  private final String intermediateClientResult;
127
128  // The matched DN for the operation.
129  private final String matchedDN;
130
131  // The port of the backend server to which the request has been forwarded.
132  private final Integer targetPort;
133
134  // The address of the backend server to which the request has been forwarded.
135  private final String targetHost;
136
137  // The protocol used to forward the request to the backend server.
138  private final String targetProtocol;
139
140
141
142  /**
143   * Creates a new compare result access log message from the provided message
144   * string.
145   *
146   * @param  s  The string to be parsed as a compare result access log message.
147   *
148   * @throws  LogException  If the provided string cannot be parsed as a valid
149   *                        log message.
150   */
151  public CompareResultAccessLogMessage(final String s)
152         throws LogException
153  {
154    this(new LogMessage(s));
155  }
156
157
158
159  /**
160   * Creates a new compare result access log message from the provided log
161   * message.
162   *
163   * @param  m  The log message to be parsed as a compare result access log
164   *            message.
165   */
166  public CompareResultAccessLogMessage(final LogMessage m)
167  {
168    super(m);
169
170    diagnosticMessage        = getNamedValue("message");
171    additionalInformation    = getNamedValue("additionalInfo");
172    matchedDN                = getNamedValue("matchedDN");
173    processingTime           = getNamedValueAsDouble("etime");
174    queueTime                = getNamedValueAsDouble("qtime");
175    intermediateClientResult = getNamedValue("from");
176    authzDN                  = getNamedValue("authzDN");
177    targetHost               = getNamedValue("targetHost");
178    targetPort               = getNamedValueAsInteger("targetPort");
179    targetProtocol           = getNamedValue("targetProtocol");
180
181    intermediateResponsesReturned =
182         getNamedValueAsLong("intermediateResponsesReturned");
183
184    final Integer rcInteger = getNamedValueAsInteger("resultCode");
185    if (rcInteger == null)
186    {
187      resultCode = null;
188    }
189    else
190    {
191      resultCode = ResultCode.valueOf(rcInteger);
192    }
193
194    final String refStr = getNamedValue("referralURLs");
195    if ((refStr == null) || refStr.isEmpty())
196    {
197      referralURLs = Collections.emptyList();
198    }
199    else
200    {
201      final LinkedList<String> refs = new LinkedList<>();
202      int startPos = 0;
203      while (true)
204      {
205        final int commaPos = refStr.indexOf(",ldap", startPos);
206        if (commaPos < 0)
207        {
208          refs.add(refStr.substring(startPos));
209          break;
210        }
211        else
212        {
213          refs.add(refStr.substring(startPos, commaPos));
214          startPos = commaPos+1;
215        }
216      }
217      referralURLs = Collections.unmodifiableList(refs);
218    }
219
220    final String controlStr = getNamedValue("responseControls");
221    if (controlStr == null)
222    {
223      responseControlOIDs = Collections.emptyList();
224    }
225    else
226    {
227      final LinkedList<String> controlList = new LinkedList<>();
228      final StringTokenizer t = new StringTokenizer(controlStr, ",");
229      while (t.hasMoreTokens())
230      {
231        controlList.add(t.nextToken());
232      }
233      responseControlOIDs = Collections.unmodifiableList(controlList);
234    }
235
236    final String serversAccessedStr = getNamedValue("serversAccessed");
237    if ((serversAccessedStr == null) || serversAccessedStr.isEmpty())
238    {
239      serversAccessed = Collections.emptyList();
240    }
241    else
242    {
243      final LinkedList<String> servers = new LinkedList<>();
244      final StringTokenizer tokenizer =
245           new StringTokenizer(serversAccessedStr, ",");
246      while (tokenizer.hasMoreTokens())
247      {
248        servers.add(tokenizer.nextToken());
249      }
250      serversAccessed = Collections.unmodifiableList(servers);
251    }
252
253    uncachedDataAccessed = getNamedValueAsBoolean("uncachedDataAccessed");
254
255    final String usedPrivilegesStr = getNamedValue("usedPrivileges");
256    if ((usedPrivilegesStr == null) || usedPrivilegesStr.isEmpty())
257    {
258      usedPrivileges = Collections.emptyList();
259    }
260    else
261    {
262      final LinkedList<String> privileges = new LinkedList<>();
263      final StringTokenizer tokenizer =
264           new StringTokenizer(usedPrivilegesStr, ",");
265      while (tokenizer.hasMoreTokens())
266      {
267        privileges.add(tokenizer.nextToken());
268      }
269      usedPrivileges = Collections.unmodifiableList(privileges);
270    }
271
272    final String preAuthZUsedPrivilegesStr =
273         getNamedValue("preAuthZUsedPrivileges");
274    if ((preAuthZUsedPrivilegesStr == null) ||
275        preAuthZUsedPrivilegesStr.isEmpty())
276    {
277      preAuthZUsedPrivileges = Collections.emptyList();
278    }
279    else
280    {
281      final LinkedList<String> privileges = new LinkedList<>();
282      final StringTokenizer tokenizer =
283           new StringTokenizer(preAuthZUsedPrivilegesStr, ",");
284      while (tokenizer.hasMoreTokens())
285      {
286        privileges.add(tokenizer.nextToken());
287      }
288      preAuthZUsedPrivileges = Collections.unmodifiableList(privileges);
289    }
290
291    final String missingPrivilegesStr = getNamedValue("missingPrivileges");
292    if ((missingPrivilegesStr == null) || missingPrivilegesStr.isEmpty())
293    {
294      missingPrivileges = Collections.emptyList();
295    }
296    else
297    {
298      final LinkedList<String> privileges = new LinkedList<>();
299      final StringTokenizer tokenizer =
300           new StringTokenizer(missingPrivilegesStr, ",");
301      while (tokenizer.hasMoreTokens())
302      {
303        privileges.add(tokenizer.nextToken());
304      }
305      missingPrivileges = Collections.unmodifiableList(privileges);
306    }
307  }
308
309
310
311  /**
312   * Retrieves the result code for the operation.
313   *
314   * @return  The result code for the operation, or {@code null} if it is not
315   *          included in the log message.
316   */
317  @Override()
318  public ResultCode getResultCode()
319  {
320    return resultCode;
321  }
322
323
324
325  /**
326   * Retrieves the diagnostic message for the operation.
327   *
328   * @return  The diagnostic message for the operation, or {@code null} if it is
329   *          not included in the log message.
330   */
331  @Override()
332  public String getDiagnosticMessage()
333  {
334    return diagnosticMessage;
335  }
336
337
338
339  /**
340   * Retrieves a message with additional information about the result of the
341   * operation.
342   *
343   * @return  A message with additional information about the result of the
344   *          operation, or {@code null} if it is not included in the log
345   *          message.
346   */
347  @Override()
348  public String getAdditionalInformation()
349  {
350    return additionalInformation;
351  }
352
353
354
355  /**
356   * Retrieves the matched DN for the operation.
357   *
358   * @return  The matched DN for the operation, or {@code null} if it is not
359   *          included in the log message.
360   */
361  @Override()
362  public String getMatchedDN()
363  {
364    return matchedDN;
365  }
366
367
368
369  /**
370   * Retrieves the list of referral URLs for the operation.
371   *
372   * @return  The list of referral URLs for the operation, or an empty list if
373   *          it is not included in the log message.
374   */
375  @Override()
376  public List<String> getReferralURLs()
377  {
378    return referralURLs;
379  }
380
381
382
383  /**
384   * Retrieves the number of intermediate response messages returned in the
385   * course of processing the operation.
386   *
387   * @return  The number of intermediate response messages returned to the
388   *          client in the course of processing the operation, or {@code null}
389   *          if it is not included in the log message.
390   */
391  @Override()
392  public Long getIntermediateResponsesReturned()
393  {
394    return intermediateResponsesReturned;
395  }
396
397
398
399  /**
400   * Retrieves the length of time in milliseconds required to process the
401   * operation.
402   *
403   * @return  The length of time in milliseconds required to process the
404   *          operation, or {@code null} if it is not included in the log
405   *          message.
406   */
407  @Override()
408  public Double getProcessingTimeMillis()
409  {
410    return processingTime;
411  }
412
413
414
415  /**
416   * Retrieves the length of time in milliseconds the operation was required to
417   * wait on the work queue.
418   *
419   * @return  The length of time in milliseconds the operation was required to
420   *          wait on the work queue, or {@code null} if it is not included in
421   *          the log message.
422   */
423  @Override()
424  public Double getQueueTimeMillis()
425  {
426    return queueTime;
427  }
428
429
430
431  /**
432   * Retrieves the OIDs of any response controls contained in the log message.
433   *
434   * @return  The OIDs of any response controls contained in the log message, or
435   *          an empty list if it is not included in the log message.
436   */
437  @Override()
438  public List<String> getResponseControlOIDs()
439  {
440    return responseControlOIDs;
441  }
442
443
444
445  /**
446   * Retrieves a list of the additional servers that were accessed in the course
447   * of processing the operation.  For example, if the access log message is
448   * from a Directory Proxy Server instance, then this may contain a list of the
449   * backend servers used to process the operation.
450   *
451   * @return  A list of the additional servers that were accessed in the course
452   *          of processing the operation, or an empty list if it is not
453   *          included in the log message.
454   */
455  @Override()
456  public List<String> getServersAccessed()
457  {
458    return serversAccessed;
459  }
460
461
462
463  /**
464   * Indicates whether the server accessed any uncached data in the course of
465   * processing the operation.
466   *
467   * @return  {@code true} if the server was known to access uncached data in
468   *          the course of processing the operation, {@code false} if the
469   *          server was known not to access uncached data, or {@code null} if
470   *          it is not included in the log message (and the server likely did
471   *          not access uncached data).
472   */
473  public Boolean getUncachedDataAccessed()
474  {
475    return uncachedDataAccessed;
476  }
477
478
479
480  /**
481   * Retrieves the content of the intermediate client result for the
482   * operation.
483   *
484   * @return  The content of the intermediate client result for the operation,
485   *          or {@code null} if it is not included in the log message.
486   */
487  @Override()
488  public String getIntermediateClientResult()
489  {
490    return intermediateClientResult;
491  }
492
493
494
495  /**
496   * Retrieves the alternate authorization DN for the operation.
497   *
498   * @return  The alternate authorization DN for the operation, or {@code null}
499   *          if it is not included in the log message.
500   */
501  public String getAlternateAuthorizationDN()
502  {
503    return authzDN;
504  }
505
506
507
508  /**
509   * Retrieves the address of the backend server to which the request has been
510   * forwarded.
511   *
512   * @return  The address of the backend server to which the request has been
513   *          forwarded, or {@code null} if it is not included in the log
514   *          message.
515   */
516  public String getTargetHost()
517  {
518    return targetHost;
519  }
520
521
522
523  /**
524   * Retrieves the port of the backend server to which the request has been
525   * forwarded.
526   *
527   * @return  The port of the backend server to which the request has been
528   *          forwarded, or {@code null} if it is not included in the log
529   *          message.
530   */
531  public Integer getTargetPort()
532  {
533    return targetPort;
534  }
535
536
537
538  /**
539   * Retrieves the protocol used to forward the request to the backend server.
540   *
541   * @return  The protocol used to forward the request to the backend server, or
542   *          {@code null} if it is not included in the log message.
543   */
544  public String getTargetProtocol()
545  {
546    return targetProtocol;
547  }
548
549
550
551  /**
552   * Retrieves the names of any privileges used during the course of processing
553   * the operation.
554   *
555   * @return  The names of any privileges used during the course of processing
556   *          the operation, or an empty list if no privileges were used or this
557   *          is not included in the log message.
558   */
559  public List<String> getUsedPrivileges()
560  {
561    return usedPrivileges;
562  }
563
564
565
566  /**
567   * Retrieves the names of any privileges used during the course of processing
568   * the operation before an alternate authorization identity was assigned.
569   *
570   * @return  The names of any privileges used during the course of processing
571   *          the operation before an alternate authorization identity was
572   *          assigned, or an empty list if no privileges were used or this is
573   *          not included in the log message.
574   */
575  public List<String> getPreAuthorizationUsedPrivileges()
576  {
577    return preAuthZUsedPrivileges;
578  }
579
580
581
582  /**
583   * Retrieves the names of any privileges that would have been required for
584   * processing the operation but that the requester did not have.
585   *
586   * @return  The names of any privileges that would have been required for
587   *          processing the operation but that the requester did not have, or
588   *          an empty list if there were no missing privileges or this is not
589   *          included in the log message.
590   */
591  public List<String> getMissingPrivileges()
592  {
593    return missingPrivileges;
594  }
595
596
597
598  /**
599   * {@inheritDoc}
600   */
601  @Override()
602  public AccessLogMessageType getMessageType()
603  {
604    return AccessLogMessageType.RESULT;
605  }
606}