/**
 * @file CosNotifyChannelAdmin.idl
 *
 * @brief Define the CosNotifyChannel module
 *
 * This module is taken from the standard CORBA Notification Service
 * 1.0, as described in:
 *
 * https://www.omg.org/spec/NOT
 *
 * In particular the following two documents were used:
 * formal/2000-06-20
 * formal/01-03-03
 *
 * @author Pradeep Gore <pradeep@cs.wustl.edu>
 */

#ifndef _COS_NOTIFY_CHANNEL_ADMIN_IDL_
#define _COS_NOTIFY_CHANNEL_ADMIN_IDL_

#include "CosNotification.idl"
#include "CosNotifyFilter.idl"
#include "CosNotifyComm.idl"
#include "CosEventChannelAdmin.idl"

#pragma prefix "omg.org"

/**
 * @namespace CosNotifyChannelAdmin
 *
 * @brief Defines the interfaces to connect and manipulate the
 * Notification Service.
 */
module CosNotifyChannelAdmin
{
  /**
   * @exception ConnectionAlreadyActive
   *
   * @brief Exception Raised if an attempt is made to resume a
   * connection that has not been suspended.
   */
  exception ConnectionAlreadyActive {};

  /**
   * @exception ConnectionAlreadyInactive
   *
   * @brief Exception raised if an attempt is made to suspend a
   * connection already suspended.
   */
  exception ConnectionAlreadyInactive {};

  /**
   * @exception NotConnected
   *
   * @brief Exception raised if an attempt is made to suspend or
   *   resume a proxy that has not been connected.
   */
  exception NotConnected {};

  // Forward declarations
  interface ConsumerAdmin;
  interface SupplierAdmin;
  interface EventChannel;
  interface EventChannelFactory;

  /**
   * @enum ProxyType
   *
   * @brief Helper typedef to inspect the types of proxies connected
   *   to an EventChannel
   */
  enum ProxyType {
    /// A push-style proxy that uses the 'any' format
    PUSH_ANY,
    /// A pull-style proxy that uses the 'any' format
    PULL_ANY,
    /// A push-style proxy that uses structured events
    PUSH_STRUCTURED,
    /// A pull-style proxy that uses structured events
    PULL_STRUCTURED,
    /// A push-style proxy that uses event batches
    PUSH_SEQUENCE,
    /// A pull-style proxy that uses event batches
    PULL_SEQUENCE,
    /// A typed, push-style proxy
    PUSH_TYPED,
    /// A typed, pull-style proxy
    PULL_TYPED
  };

  /**
   * @enum ObtainInfoMode
   *
   * @brief Define the modes to fetch subscriptions and publication
   * lists from the Notification Service.
   */
  enum ObtainInfoMode {
    /// Get all the current subscriptions/publications, do not send
    /// updates to the peer
    ALL_NOW_UPDATES_OFF,
    /// Get all the current subscriptions/publications, send updates
    /// to the peer
    ALL_NOW_UPDATES_ON,
    /// Do not get any of the current subscriptions/publications, do
    /// not send updates to the peer either
    NONE_NOW_UPDATES_OFF,
    /// Do not get any of the current subscriptions/publications, but
    /// send updates to the peer
    NONE_NOW_UPDATES_ON
  };

  /**
   * @interface ProxyConsumer
   *
   * @brief Defines the interface shared by all consumer proxies
   *
   * Consumer proxies are used by suppliers to provide events into the
   * Notification Service, this interface captures the shared
   * operations in all those proxies.
   */
  interface ProxyConsumer
    : CosNotification::QoSAdmin
    , CosNotifyFilter::FilterAdmin
  {
    /// The style and event format for this proxy
    readonly attribute ProxyType MyType;

    /// The SupplierAdmin this proxy belongs to
    readonly attribute SupplierAdmin MyAdmin;

    /// Get the list of event types that this proxy could potentially
    /// forward to any consumer connected to the EventChannel
    /**
     * @param mode Describe how the subscriptions should be fetched
     * @return The list of current subscriptions, if requested in the
     * mode argument
     */
    CosNotification::EventTypeSeq obtain_subscription_types(
                                      in ObtainInfoMode mode );

    /// Validate a list of QoS properties for an event
    /**
     * Suppliers can provide events with specific QoS properties, the
     * following operation allows suppliers to verify if a given set
     * of QoS properties would be honored by the proxy.
     *
     * @param required_qos The QoS properties required by the supplier
     * @param available_qos If the QoS properties required are
     *   supported this argument returns any other QoS properties that
     *   the application may set without breaking the proxy
     *   capabilities.
     * @throws CosNotification::UnsupportedQoS if the QoS properties
     *   required cannot be supported. The exception describes the
     *   problems and any legal values in detail.
     */
    void validate_event_qos (
             in CosNotification::QoSProperties required_qos,
             out CosNotification::NamedPropertyRangeSeq available_qos)
      raises (CosNotification::UnsupportedQoS);
  };

  /**
   * @interface ProxySupplier
   *
   * @brief Defines the interface shared by all supplier proxies
   *
   * Supplier proxies are used by consumers to communicate with the
   * Notification Service, this interface captures the shared
   * operations in all those proxies.
   */
  interface ProxySupplier
    : CosNotification::QoSAdmin
    , CosNotifyFilter::FilterAdmin
  {
    /// The style and event format for this proxy
    readonly attribute ProxyType MyType;

    /// The ConsumerAdmin this proxy belongs to
    readonly attribute ConsumerAdmin MyAdmin;

    /// Get and set the mapping filter used to change the priority
    /// property for this proxy.
    /**
     * The filter is initialized to the nil reference
     */
    attribute CosNotifyFilter::MappingFilter priority_filter;

    /// Get and set the mapping filter used to change the lifetime
    /// property for this proxy.
    /**
     * The filter is initialized to the nil reference
     */
    attribute CosNotifyFilter::MappingFilter lifetime_filter;

    /// Get the list of event types that this proxy could potentially
    /// forward to its connected supplier
    /**
     * @param mode Describe how the publications should be fetched
     * @return The list of current subscriptions, if requested in the
     * mode argument
     */
    CosNotification::EventTypeSeq obtain_offered_types(
                                      in ObtainInfoMode mode );

    /// Validate a list of QoS properties for an event
    /**
     * Applications send events with specific QoS properties, the
     * following operation allows consumers to verify if a given set
     * of QoS properties would be honored by the proxy.
     *
     * @param required_qos The QoS properties required by the supplier
     * @param available_qos If the QoS properties required are
     *   supported this argument returns any other QoS properties that
     *   the application may set without breaking the proxy
     *   capabilities.
     * @throws CosNotification::UnsupportedQoS if the QoS properties
     *   required cannot be supported. The exception describes the
     *   problems and any legal values in detail.
     */
    void validate_event_qos (
             in CosNotification::QoSProperties required_qos,
             out CosNotification::NamedPropertyRangeSeq available_qos)
      raises (CosNotification::UnsupportedQoS);
  };

  /**
   * @interface ProxyPushConsumer
   *
   * @brief Defines the interface provided for push-style suppliers
   *   using the 'any' event format.
   */
  interface ProxyPushConsumer
    : ProxyConsumer
    , CosNotifyComm::PushConsumer
  {
    /// Connect a supplier to the proxy
    /**
     * Suppliers cannot push events into a ProxyPushConsumer until
     * this method is invoked.
     *
     * @param push_supplier the callback object used to inform the
     *   application if the event channel is destroyed.  If the
     *   argument is nil no destroy notification is provided.
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_any_push_supplier (
             in CosEventComm::PushSupplier push_supplier)
      raises(CosEventChannelAdmin::AlreadyConnected);
  };

  /**
   * @interface StructuredProxyPushConsumer
   *
   * @brief Defines the interface provided for push-style suppliers
   *   using the 'structured' event format.
   */
  interface StructuredProxyPushConsumer
    : ProxyConsumer
    , CosNotifyComm::StructuredPushConsumer
  {
    /// Connect a supplier to the proxy
    /**
     * Suppliers cannot push events into a ProxyPushConsumer until
     * this method is invoked.
     *
     * @param push_supplier the callback object used to inform the
     *   application if the event channel is destroyed.  If the
     *   argument is nil no destroy notification is provided.
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_structured_push_supplier (
             in CosNotifyComm::StructuredPushSupplier push_supplier)
      raises(CosEventChannelAdmin::AlreadyConnected);
  };

  /**
   * @interface SequenceProxyPushConsumer
   *
   * @brief Defines the interface provided for push-style suppliers
   *   using the 'batched' event format.
   */
  interface SequenceProxyPushConsumer
    : ProxyConsumer
    , CosNotifyComm::SequencePushConsumer
  {
    /// Connect a supplier to the proxy
    /**
     * Suppliers cannot push events into a ProxyPushConsumer until
     * this method is invoked.
     *
     * @param push_supplier the callback object used to inform the
     *   application if the event channel is destroyed.  If the
     *   argument is nil no destroy notification is provided.
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_sequence_push_supplier (
             in CosNotifyComm::SequencePushSupplier push_supplier)
      raises(CosEventChannelAdmin::AlreadyConnected);
  };

#ifdef TAO_HAS_NOTIFY_PULL_INTERFACES

  /**
   * @interface ProxyPullSupplier
   *
   * @brief Defines the interface provided for pull-style consumers
   *   using the 'any' event format.
   */
  interface ProxyPullSupplier
    : ProxySupplier
    , CosNotifyComm::PullSupplier
  {
    /// Connect a consumer to the proxy
    /**
     * The consumer cannot pull events until this operation is invoked.
     *
     * @param pull_consumer the callback object used to inform the
     *   application if the event channel is destroyed.  If the
     *   argument is nil no destroy notification is provided.
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_any_pull_consumer (
             in CosEventComm::PullConsumer pull_consumer)
      raises(CosEventChannelAdmin::AlreadyConnected);
  };

  /**
   * @interface StructuredProxyPullSupplier
   *
   * @brief Defines the interface provided for pull-style consumers
   *   using the 'structured' event format.
   */
  interface StructuredProxyPullSupplier
    : ProxySupplier
    , CosNotifyComm::StructuredPullSupplier
  {
    /// Connect a consumer to the proxy
    /**
     * The consumer cannot pull events until this operation is invoked.
     *
     * @param pull_consumer the callback object used to inform the
     *   application if the event channel is destroyed.  If the
     *   argument is nil no destroy notification is provided.
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_structured_pull_consumer (
             in CosNotifyComm::StructuredPullConsumer pull_consumer)
      raises(CosEventChannelAdmin::AlreadyConnected);
  };

  /**
   * @interface SequenceProxyPullSupplier
   *
   * @brief Defines the interface provided for pull-style consumer
   *   using the 'batched' event format.
   */
  interface SequenceProxyPullSupplier
    : ProxySupplier
    , CosNotifyComm::SequencePullSupplier
  {
    /// Connect a consumer to the proxy
    /**
     * The consumer cannot pull events until this operation is invoked.
     *
     * @param pull_consumer the callback object used to inform the
     *   application if the event channel is destroyed.  If the
     *   argument is nil no destroy notification is provided.
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_sequence_pull_consumer (
             in CosNotifyComm::SequencePullConsumer pull_consumer)
      raises(CosEventChannelAdmin::AlreadyConnected);
  };

  /**
   * @interface ProxyPullConsumer
   *
   * @brief Defines the interface provided for pull-style suppliers
   *   using the 'any' event format.
   */
  interface ProxyPullConsumer
    : ProxyConsumer
    , CosNotifyComm::PullConsumer
  {
    /// Connect a supplier to the proxy
    /**
     * The event channel will not pull events from the supplier until
     * this operation is invoked.
     *
     * @param pull_supplier the callback object used to inform the
     *   application if the event channel is destroyed.
     * @throws CORBA::BAD_PARAM if the pull_supplier argument is nil
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_any_pull_supplier (
             in CosEventComm::PullSupplier pull_supplier)
      raises(CosEventChannelAdmin::AlreadyConnected,
             CosEventChannelAdmin::TypeError );

    /// Suspend the connection, the event channel will stop pulling
    /// events.
    /**
     * @throws ConnectionAlreadyInactive if the method is invoked
     *   while the connection is suspended
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void suspend_connection()
      raises(ConnectionAlreadyInactive, NotConnected);

    /// Resume the connection, the event channel will start pulling
    /// events one more.
    /**
     * @throws ConnectionAlreadyActive if the method is invoked
     *   while the connection is active
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void resume_connection()
      raises(ConnectionAlreadyActive, NotConnected);
  };

  /**
   * @interface StructuredProxyPullConsumer
   *
   * @brief Defines the interface provided for pull-style suppliers
   *   using the 'structured' event format.
   */
  interface StructuredProxyPullConsumer
    : ProxyConsumer
    , CosNotifyComm::StructuredPullConsumer
  {
    /// Connect a supplier to the proxy
    /**
     * The event channel will not pull events from the supplier until
     * this operation is invoked.
     *
     * @param pull_supplier the callback object used to inform the
     *   application if the event channel is destroyed.
     * @throws CORBA::BAD_PARAM if the pull_supplier argument is nil
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_structured_pull_supplier (
             in CosNotifyComm::StructuredPullSupplier pull_supplier)
      raises(CosEventChannelAdmin::AlreadyConnected,
             CosEventChannelAdmin::TypeError );

    /// Suspend the connection, the event channel will stop pulling
    /// events.
    /**
     * @throws ConnectionAlreadyInactive if the method is invoked
     *   while the connection is suspended
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void suspend_connection()
      raises(ConnectionAlreadyInactive, NotConnected);

    /// Resume the connection, the event channel will start pulling
    /// events one more.
    /**
     * @throws ConnectionAlreadyActive if the method is invoked
     *   while the connection is active
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void resume_connection()
      raises(ConnectionAlreadyActive, NotConnected);
  };

  /**
   * @interface SequenceProxyPullConsumer
   *
   * @brief Defines the interface provided for pull-style suppliers
   *   using the 'batched' event format.
   */
  interface SequenceProxyPullConsumer
    : ProxyConsumer
    , CosNotifyComm::SequencePullConsumer
  {
    /// Connect a supplier to the proxy
    /**
     * The event channel will not pull events from the supplier until
     * this operation is invoked.
     *
     * @param pull_supplier the callback object used to inform the
     *   application if the event channel is destroyed.
     * @throws CORBA::BAD_PARAM if the pull_supplier argument is nil
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_sequence_pull_supplier (
             in CosNotifyComm::SequencePullSupplier pull_supplier)
      raises(CosEventChannelAdmin::AlreadyConnected,
             CosEventChannelAdmin::TypeError );

    /// Suspend the connection, the event channel will stop pulling
    /// events.
    /**
     * @throws ConnectionAlreadyInactive if the method is invoked
     *   while the connection is suspended
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void suspend_connection()
      raises(ConnectionAlreadyInactive, NotConnected);

    /// Resume the connection, the event channel will start pulling
    /// events one more.
    /**
     * @throws ConnectionAlreadyActive if the method is invoked
     *   while the connection is active
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void resume_connection()
      raises(ConnectionAlreadyActive, NotConnected);
  };
#endif /* TAO_HAS_NOTIFY_PULL_INTERFACES */

  /**
   * @interface ProxyPushSupplier
   *
   * @brief Defines the interface provided for push-style consumers
   *   using the 'any' event format.
   */
  interface ProxyPushSupplier
    : ProxySupplier
    , CosNotifyComm::PushSupplier
  {
    /// Connect a consumer to the proxy
    /**
     * The event channel will not push events to the consumer until
     * this operation is invoked.
     *
     * @param push_consumer the callback object used to push events to
     *   the application and inform if the event channel is destroyed
     * @throws CORBA::BAD_PARAM if the push_consumer argument is nil
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_any_push_consumer (
             in CosEventComm::PushConsumer push_consumer)
      raises(CosEventChannelAdmin::AlreadyConnected,
             CosEventChannelAdmin::TypeError );

    /// Suspend the connection, the event channel will stop pushing
    /// events to the consumer.
    /**
     * @throws ConnectionAlreadyInactive if the method is invoked
     *   while the connection is suspended
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void suspend_connection()
      raises(ConnectionAlreadyInactive, NotConnected);

    /// Resume the connection, the event channel will start pushing
    /// events to the consumer once more
    /**
     * @throws ConnectionAlreadyActive if the method is invoked
     *   while the connection is active
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void resume_connection()
      raises(ConnectionAlreadyActive, NotConnected);
  };

  /**
   * @interface StructuredProxyPushSupplier
   *
   * @brief Defines the interface provided for push-style consumers
   *   using the 'structured' event format.
   */
  interface StructuredProxyPushSupplier
    : ProxySupplier
    , CosNotifyComm::StructuredPushSupplier
  {
    /// Connect a consumer to the proxy
    /**
     * The event channel will not push events to the consumer until
     * this operation is invoked.
     *
     * @param push_consumer the callback object used to push events to
     *   the application and inform if the event channel is destroyed
     * @throws CORBA::BAD_PARAM if the push_consumer argument is nil
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_structured_push_consumer (
             in CosNotifyComm::StructuredPushConsumer push_consumer)
      raises(CosEventChannelAdmin::AlreadyConnected,
             CosEventChannelAdmin::TypeError );

    /// Suspend the connection, the event channel will stop pushing
    /// events to the consumer.
    /**
     * @throws ConnectionAlreadyInactive if the method is invoked
     *   while the connection is suspended
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void suspend_connection()
      raises(ConnectionAlreadyInactive, NotConnected);

    /// Resume the connection, the event channel will start pushing
    /// events to the consumer once more
    /**
     * @throws ConnectionAlreadyActive if the method is invoked
     *   while the connection is active
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void resume_connection()
      raises(ConnectionAlreadyActive, NotConnected);
  };

  /**
   * @interface SequenceProxyPushSupplier
   *
   * @brief Defines the interface provided for push-style consumers
   *   using the 'batched' event format.
   */
  interface SequenceProxyPushSupplier
    : ProxySupplier
    , CosNotifyComm::SequencePushSupplier
  {
    /// Connect a consumer to the proxy
    /**
     * The event channel will not push events to the consumer until
     * this operation is invoked.
     *
     * @param push_consumer the callback object used to push events to
     *   the application and inform if the event channel is destroyed
     * @throws CORBA::BAD_PARAM if the push_consumer argument is nil
     * @throws CosEventChannelAdmin::AlreadyConnected if the proxy is
     *   already connected, i.e. if this operation is invoked more than
     *   one time.
     */
    void connect_sequence_push_consumer (
             in CosNotifyComm::SequencePushConsumer push_consumer)
      raises(CosEventChannelAdmin::AlreadyConnected,
             CosEventChannelAdmin::TypeError );

    /// Suspend the connection, the event channel will stop pushing
    /// events to the consumer.
    /**
     * @throws ConnectionAlreadyInactive if the method is invoked
     *   while the connection is suspended
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void suspend_connection()
      raises(ConnectionAlreadyInactive, NotConnected);

    /// Resume the connection, the event channel will start pushing
    /// events to the consumer once more
    /**
     * @throws ConnectionAlreadyActive if the method is invoked
     *   while the connection is active
     * @throws NotConnected if the method is invoked before the
     *   supplier connects
     */
    void resume_connection()
      raises(ConnectionAlreadyActive, NotConnected);
  };

  /// Each proxy is assigned a unique ID by its proxy admin
  typedef long ProxyID;
  /// Helper type to query or fetch multiple IDs simulatenously
  typedef sequence <ProxyID> ProxyIDSeq;

  /**
   * @enum ClientType
   *
   * @brief Helper type used to fetch proxies
   */
  enum ClientType {
    /// The proxy uses the 'any' event format
    ANY_EVENT,
    /// The proxy uses the 'structured' event format
    STRUCTURED_EVENT,
    /// The proxy uses the 'sequence' (or batch) event format
    SEQUENCE_EVENT
  };

  /**
   * @enum InterFilterGroupOperator
   *
   * @brief Define how multiple Filters are considered in a proxy
   *   admin
   */
  enum InterFilterGroupOperator {
    AND_OP,
    OR_OP
  };

  /// Each proxy admin is assigned a unique number by its EventChannel
  typedef long AdminID;
  /// List of Admin IDs
  typedef sequence<AdminID> AdminIDSeq;

  /**
   * @exception AdminNotFound
   *
   * @brief Exception raised if a lookup for a specific Admin ID
   *   fails.
   */
  exception AdminNotFound {};

  /**
   * @exception ProxyNotFound
   *
   * @brief Exception raised if a lookup for a specific Proxy ID
   *   fails.
   */
  exception ProxyNotFound {};

  /**
   * @struct AdminLimit
   *
   * @brief Helper structure to represent a violation of the limits in
   *   a proxy admin.
   */
  struct AdminLimit {
    CosNotification::PropertyName name;
    CosNotification::PropertyValue value;
  };

  /**
   * @exception AdminLimitExceeded
   *
   * @brief Exception raised if a limit in a proxy admin is breached
   */
  exception AdminLimitExceeded {
    /// The limit that caused the problem.
    AdminLimit admin_property_err;
  };

  /**
   * @interface ConsumerAdmin
   *
   * @brief Interface used to control and obtain the proxies used by
   *   consumers.
   */
  interface ConsumerAdmin
    : CosNotification::QoSAdmin
    , CosNotifyComm::NotifySubscribe
    , CosNotifyFilter::FilterAdmin
    , CosEventChannelAdmin::ConsumerAdmin
  {
    /// The ID assigned to this admin by its event channel
    readonly attribute AdminID MyID;

    /// The event channel this admin belongs to
    readonly attribute EventChannel MyChannel;

    /// How are multiple filters interpreted
    readonly attribute InterFilterGroupOperator MyOperator;

    /// A special mapping filter to change the priority property of
    /// events
    attribute CosNotifyFilter::MappingFilter priority_filter;

    /// A special mapping filter to change the lifetime property of
    /// events
    attribute CosNotifyFilter::MappingFilter lifetime_filter;

    /// Get the complete list of pull proxy suppliers
    readonly attribute ProxyIDSeq pull_suppliers;

    /// Get the complete list of push proxy suppliers
    readonly attribute ProxyIDSeq push_suppliers;

    /// Get an specific ProxySupplier
    /**
     * @param proxy_id The proxy ID that will be retrieved
     * @throws ProxyNotFound if the proxy_id is not found in this
     *   ConsumerAdmin
     */
    ProxySupplier get_proxy_supplier (in ProxyID proxy_id)
      raises (ProxyNotFound );

    /// Create a new pull-style proxy supplier
    /**
     * @param ctype The event format that the ProxySupplier should
     *   support
     * @param proxy_id The ID assigned to the new proxy supplier
     * @return The new ProxySupplier
     * @throws AdminLimitExceeded if a limit in this admin is reached,
     *   such as the maximum number of proxies.
     */
    ProxySupplier obtain_notification_pull_supplier (in ClientType ctype,
                                                     out ProxyID proxy_id)
      raises ( AdminLimitExceeded );

    /// Create a new push-style proxy supplier
    /**
     * @param ctype The event format that the ProxySupplier should
     *   support
     * @param proxy_id The ID assigned to the new proxy supplier
     * @return The new ProxySupplier
     * @throws AdminLimitExceeded if a limit in this admin is reached,
     *   such as the maximum number of proxies.
     */
    ProxySupplier obtain_notification_push_supplier (in ClientType ctype,
                                                     out ProxyID proxy_id)
      raises ( AdminLimitExceeded );

    /// Destroy the Admin
    void destroy();
  };

  /**
   * @interface SupplierAdmin
   *
   * @brief Interface used to control and obtain the proxies used by
   *   suppliers.
   */
  interface SupplierAdmin
    : CosNotification::QoSAdmin
    , CosNotifyComm::NotifyPublish
    , CosNotifyFilter::FilterAdmin
    , CosEventChannelAdmin::SupplierAdmin
  {
    /// The ID assigned to this admin by its event channel
    readonly attribute AdminID MyID;

    /// The event channel this admin belongs to
    readonly attribute EventChannel MyChannel;

    /// How are multiple filters interpreted
    readonly attribute InterFilterGroupOperator MyOperator;

    /// Get the complete list of pull proxy consumers
    readonly attribute ProxyIDSeq pull_consumers;

    /// Get the complete list of push proxy consumers
    readonly attribute ProxyIDSeq push_consumers;

    /// Get an specific ProxyConsumer
    /**
     * @param proxy_id The proxy ID that will be retrieved
     * @throws ProxyNotFound if the proxy_id is not found in this
     *   SupplierAdmin
     */
    ProxyConsumer get_proxy_consumer (in ProxyID proxy_id )
      raises ( ProxyNotFound );

    /// Create a new pull-style proxy consumer
    /**
     * @param ctype The event format that the ProxyConsumer should
     *   support
     * @param proxy_id The ID assigned to the new proxy consumer
     * @return The new ProxyConsumer
     * @throws AdminLimitExceeded if a limit in this admin is reached,
     *   such as the maximum number of proxies.
     */
    ProxyConsumer obtain_notification_pull_consumer (in ClientType ctype,
                                                     out ProxyID proxy_id)
      raises ( AdminLimitExceeded );

    /// Create a new push-style proxy consumer
    /**
     * @param ctype The event format that the ProxyConsumer should
     *   support
     * @param proxy_id The ID assigned to the new proxy consumer
     * @return The new ProxySupplier
     * @throws AdminLimitExceeded if a limit in this admin is reached,
     *   such as the maximum number of proxies.
     */
    ProxyConsumer obtain_notification_push_consumer (in ClientType ctype,
                                                     out ProxyID proxy_id)
      raises ( AdminLimitExceeded );

    /// Destroy the Admin
    void destroy();
  };

  /**
   * @interface EventChannel
   *
   * @brief Defines the interface to control an use an event channel
   */
  interface EventChannel
    : CosNotification::QoSAdmin
    , CosNotification::AdminPropertiesAdmin
    , CosEventChannelAdmin::EventChannel
  {
    /// The factory this event channel belongs to
    readonly attribute EventChannelFactory MyFactory;

    /// The default consumer admin
    readonly attribute ConsumerAdmin default_consumer_admin;

    /// The default supplier admin
    readonly attribute SupplierAdmin default_supplier_admin;

    /// The default filter factory for this event channel
    readonly attribute CosNotifyFilter::FilterFactory default_filter_factory;

    /// Create a new consumer admin
    /**
     * @param op Defines how multiple filters would be interpreted in
     *   the new consumer admin
     * @param id Returns the ID assigned to the new consumer admin
     * @return The new consumer admin
     */
    ConsumerAdmin new_for_consumers(in InterFilterGroupOperator op,
                                    out AdminID id );

    /// Create a new supplier admin
    /**
     * @param op Defines how multiple filters would be interpreted in
     *   the new supplier admin
     * @param id Returns the ID assigned to the new supplier admin
     * @return The new supplier admin
     */
    SupplierAdmin new_for_suppliers(in InterFilterGroupOperator op,
                                    out AdminID id );

    /// Fetch an specific consumer admin based on its ID
    /**
     * @param id The id of the consumer that should be returned
     * @return The consumer admin assigned the given ID
     * @throws AdminNotFound if there is no consumer admin with the ID
     *   provided
     */
    ConsumerAdmin get_consumeradmin ( in AdminID id )
      raises (AdminNotFound);

    /// Fetch an specific supplier admin based on its ID
    /**
     * @param id The id of the supplier that should be returned
     * @return The supplier admin assigned the given ID
     * @throws AdminNotFound if there is no supplier admin with the ID
     *   provided
     */
    SupplierAdmin get_supplieradmin ( in AdminID id )
      raises (AdminNotFound);

    /// Get the IDs of all the consumer admins
    AdminIDSeq get_all_consumeradmins();

    /// Get the IDs of all the supplier admins
    AdminIDSeq get_all_supplieradmins();
  };

  /// Each event channel is assigned a unique ID by its factory
  typedef long ChannelID;

  /// Helper type used to return the complete list of event channel
  /// IDs
  typedef sequence<ChannelID> ChannelIDSeq;

  /**
   * @exception ChannelNotFound
   *
   * @brief Exception raised if an specific ChannelID is not found.
   */
  exception ChannelNotFound {};

  /**
   * @interface EventChannelFactory
   *
   * @brief Defines the interface used to build event channels
   */
  interface EventChannelFactory {
    /// Create a new event channel
    /**
     * @param initial_qos Configure the initial QoS properties of the
     *   new EventChannel
     * @param initial_admin Configure the initial Admin properties of
     *   the new EventChannel
     * @param id Returns the ID assigned to the new EventChannel
     * @return The new event channel
     * @throws CosNotification::UnsupportedQoS if the requested QoS
     *   properties cannot be satisfied or are invalid
     * @throws CosNotification::UnsupportedAdmin if the requested
     *   admin properties cannot be satisfied or are invalid
     */
    EventChannel create_channel (in CosNotification::QoSProperties initial_qos,
                                 in CosNotification::AdminProperties initial_admin,
                                 out ChannelID id)
      raises(CosNotification::UnsupportedQoS,
             CosNotification::UnsupportedAdmin );

    /// Get the complete list of event channels in this factory
    ChannelIDSeq get_all_channels();

    /// Get an event channel given its ID
    /**
     * @param id The ID of the event channel the application wants
     * @return The event channel
     * @throws ChannelNotFound if the give ID is unknown on this
     *   factory
     */
    EventChannel get_event_channel ( in ChannelID id )
      raises (ChannelNotFound);
  };
};

#pragma prefix ""

#endif /* _COS_NOTIFY_CHANNEL_ADMIN_IDL_ */
