/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * Listener.java
 * $Id: Listener.java,v 1.5 2006/11/08 20:55:16 harpreet Exp $
 * $Date: 2006/11/08 20:55:16 $
 * $Revision: 1.5 $
 */

package com.sun.enterprise.admin.monitor.callflow;

/**
 * This interface exposes the call flow Listener API.
 *
 * This interface is implemented by listeners that are registered with the
 * call flow agent, in order to receive the call flow trap point notifications.
 *
 * Note 1: There are no ordering guaratees for the various notifications.
 *
 * Note 2: A listener implementation must be stateless. This is allow the
 * listener to be accessed concurrently by multiple threads, and yet avoid
 * synchronization overhead associated with protected access to shared state,
 * in a multi-threaded environment.
 *
 * Note 3: It is also imperative that the listener implementation is
 * light-weight, and avoids time consuming operations such as disk access,
 * logging, synchronization locks, et cetera. This will ensure that the
 * listener does not negatively impact the performance of the
 * application thread.
 *
 * @author Ram Jeyaraman
 * @date October 11, 2005
 */
public interface Listener {

    /**
     * This notification indicates that a request is being started.
     *
     * Allowed request types are:
     *
     * 1. Remote HTTP Web request.
     * 2. Remote EJB request.
     * 3. MDB request.
     * 4. Timer EJB.
     *
     * @param requestType Type of the request.
     *
     * @param callerIPAddress Client host IP address of caller.
     */
    public void requestStart(
            final String requestId,  final RequestType requestType,
            final String callerIPAddress, final String remoteUser);

    /**
     * This notification indicates that a request is about to complete.
     */
    public void requestEnd(final String requestId);

    /**
     * This notification indicates that an EJB method is about to be invoked.
     *
     * This parameters provide information such as method name, component
     * name, component type, application name, module name, caller principal.
     */
    public void ejbMethodStart(
            final String requestId, final String methodName,
            final String applicationName, final String moduleName,
            final String componentName, final ComponentType componentType,
            final String callerPrincipal, final String transactionId);

    /**
     * This notification indicates that an EJB method has completed. The
     * parameters provide information on the outcome of the invocation
     * such as exception, if any.
     */
    public void ejbMethodEnd(final String requestId, final Throwable exception);

    /**
     * This notification indicates that a web method is about to be invoked.
     *
     * This parameters provide information such as method name, component
     * name, component type, application name, module name, caller principal,
     * and caller IP address.
     */
    public void webMethodStart(
            final String requestId, final String methodName,
            final String applicationName, final String moduleName,
            final String componentName, final ComponentType componentType,
            final String callerPrincipal);

    /**
     * This notification indicates that a web method has completed. The
     * parameters provide information on the outcome of the invocation
     * such as exception, if any.
     */
    public void webMethodEnd(final String requestId, final Throwable exception);

    /**
     * This notification indicates that an EntityManager method is about to be invoked.
     *
     * This parameters provide information such as method name, component
     * name, component type, application name, module name, caller principal.
     */
    public void entityManagerMethodStart(
            final String requestId, final EntityManagerMethod entityManagerMethod,
            final String applicationName, final String moduleName,
            final String componentName, final ComponentType componentType,
            final String callerPrincipal);

    /**
     * This notification indicates that an EntityManager method has completed.
     */
    public void entityManagerMethodEnd(String requestId);

    /**
     * This notification indicates that an EntityManager Query method is about to be invoked.
     *
     * This parameters provide information such as method name, component
     * name, component type, application name, module name, caller principal.
     */
    public void entityManagerQueryStart(
            final String requestId, final EntityManagerQueryMethod queryMethod,
            final String applicationName, final String moduleName,
            final String componentName, final ComponentType componentType,
            final String callerPrincipal);

    /**
     * This notification indicates that an EntityManager Query method has completed.
     */
    public void entityManagerQueryEnd(final String requestId);

}
