/**
   * Calls buildAuditEvent() and invokes the request to the audit path.
   *
   * @param connectionFactory factory used to make crest call to audit service.
   */
  public final Promise<ResourceResponse, ResourceException> log(
      ConfigAuditState configAuditState,
      Request request,
      Context context,
      ConnectionFactory connectionFactory) {
    try {

      JsonValue before = configAuditState.getBefore();
      JsonValue after = configAuditState.getAfter();

      // Get authenticationId from security context, if it exists.
      String authenticationId =
          (context.containsContext(SecurityContext.class))
              ? context.asContext(SecurityContext.class).getAuthenticationId()
              : null;

      // Build the event utilizing the config builder.
      AuditEvent auditEvent =
          ConfigAuditEventBuilder.configEvent()
              .resourceOperationFromRequest(request)
              .authenticationFromSecurityContext(context)
              .runAs(authenticationId)
              .transactionIdFromRootContext(context)
              .revision(configAuditState.getRevision())
              .timestamp(System.currentTimeMillis())
              .eventName(CONFIG_AUDIT_EVENT_NAME)
              .before(null != before ? before.toString() : "")
              .after(null != after ? after.toString() : "")
              .changedFields(getChangedFields(before, after))
              .toEvent();

      return connectionFactory
          .getConnection()
          .create(context, Requests.newCreateRequest(AUDIT_CONFIG_REST_PATH, auditEvent.getValue()))
          .asPromise();
    } catch (ResourceException e) {
      LOGGER.error("had trouble logging audit event for config changes.", e);
      return e.asPromise();
    } catch (Exception e) {
      LOGGER.error("had trouble logging audit event for config changes.", e);
      return new InternalServerErrorException(e.getMessage(), e).asPromise();
    }
  }