/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.knox.gateway.audit.api;

import java.util.concurrent.Callable;

/**
 * Manipulates the audit context associated with the current thread.
 */
public interface AuditService {

  /**
   * Creates and attaches an "empty" audit context.
   *
   * @return A new, empty, attached audit context.  Will never be null.
   */
  AuditContext createContext();

  /**
   * Retrieves the current attached audit context, if any.
   *
   * @return The current attached audit context if any.  May be null.
   */
  AuditContext getContext();

  /**
   * Attaches the provided audit context to the current thread.
   * Providing a null value will have no effect and the currently attached context if any will remain.
   *
   * @param context The audit context to attach to the current thread.  May be null.
   */
  void attachContext( AuditContext context );

  /**
   * Detaches the current audit context, if any, from the current thread.
   * This will typically be used when an audit context needs to be propagated between threads.
   *
   * @return The now detached audit context, if any.  May be null.
   */
  AuditContext detachContext();

  /**
   * Retrieves an auditor configured with the the provided component and service names.  Will never be null.
   *
   * @param auditorName The name of auditor. Can be used to separate audit events to different destinations. For example security audit, operations audit, etc
   * @param componentName The name of component that will be placed used in every audit event generated by {@link Auditor Auditor} instance
   * @param serviceName The name of service that will be placed used in every audit event generated by {@link Auditor Auditor} instance
   * @return Auditor configured with the component and service names. Will never be null.
   */
  Auditor getAuditor( String auditorName, String componentName, String serviceName );

  /**
   * Executes the callable within the provided audit context.
   * The provided context is attached and detached around the invocation of the callable.
   *
   * @param <T> Type of callable
   * @param context The context to establish around the invocation of the callable.  May not be null.
   * @param callable The callable to invoke after establishing the correlation context.  May not be null.
   * @return The result of the callable's call method.
   * @throws Exception Thrown if thrown by the callable's call method.
   */
  <T> T execute( AuditContext context, Callable<T> callable ) throws Exception;

}