/**
  * File: GroupMembershipNamingService.idl
  * Content: CORBA specification of the service to handle the Group Membership
  * Author: LuisM Pena
  * Date: 3nd December 2000
  * Version: 0.30.00
  * Last changes:
  *
  **/

#ifndef GROUP_MEMBERSHIP_NAMING_SERVICE
#define GROUP_MEMBERSHIP_NAMING_SERVICE

#include "GroupMembershipService.idl"
#include "DomainExceptions.idl"

module sensei
{

  module middleware
  {

    module gmns
    {

      //bringing some declarations into scope ...
      typedef sensei::middleware::gms::GroupHandler	GroupHandler;
      typedef sensei::middleware::gms::GroupMember 	GroupMember;

      /***********************************************************************/
      /************************* EXCEPTIONS **********************************/
      /***********************************************************************/

      /**
        * Exception thrown after an invalid group handler input
        **/
      exception InvalidGroupHandlerException{};

      /**
        * Exception thrown after an invalid group handler factory input
        **/
      exception InvalidGroupHandlerFactoryException{};

      /**
        * Exception thrown by the GroupHandlerFactory or its creator
        **/
      exception GroupHandlerFactoryException{};

      /***********************************************************************/
      /************************* GROUP HANDLER FACTORY ***********************/
      /***********************************************************************/

      /**
        * Interface to create GroupHandlers
        **/
      interface GroupHandlerFactory
      {
        /**
          * Creates a new handler.
          **/
        GroupHandler create() raises (GroupHandlerFactoryException);
      };

      /***********************************************************************/
      /************************* GROUP HANDLER FACTORY CREATOR ***************/
      /***********************************************************************/

      /**
        * ValueType that creates GroupHandlerFactories on
        * demand. This is not a remote object, the intention is to
        * create the GroupHandler in the local memory belonging to the
        * group member, and therefore avoid new points of failure.
        * If the GroupHandler would be created directly by any of the
        * membership services, the failure of the service would suppose
        * the failure of the associated GroupMember
        **/
      valuetype GroupHandlerFactoryCreator
      {
        /**
          * Creates a new handler factory for the given member
          **/
        GroupHandlerFactory create(in GroupMember member) raises (GroupHandlerFactoryException);
      };

      /***********************************************************************/
      /************************* GROUP MEMBERSHIP BASIC SERVICE **************/
      /***********************************************************************/

      /**
        * this interface allows the creation of new groups and the
        * extension of those groups by adding new members.
        * This service works on GroupMember basis: the service user wanting
        * to join a group must suply a member of that group
        **/
      interface GroupMembershipBasicService
      {
        /**
          * Creates a GroupHandlerFactoryCreator
          **/
        GroupHandlerFactoryCreator getFactoryCreator();

        /**
          * Creates a new group.
          * @param factory A factory creating GroupHandlers on demand
          **/
        GroupHandler createGroup(in GroupHandlerFactory theFactory)
            raises (InvalidGroupHandlerFactoryException, GroupHandlerFactoryException);

        /**
          * Extends a group with an additional member
          * @param group a valid handler on a existing group.
          * @returns the group handler created, which can be nil if the member
          *    could not join the group because was considered faulty or because
          *    the groupHandler used is not valid or has been expulsed from the group
          **/
        GroupHandler joinGroup(in GroupHandler group, in GroupHandlerFactory theFactory)
            raises (	InvalidGroupHandlerException,
                      InvalidGroupHandlerFactoryException,
                      GroupHandlerFactoryException);
      };


      /***********************************************************************/
      /************************* REPLICATED SERVER ***************************/
      /***********************************************************************/

      /**
       * To be registered in the GroupMembershipNamingService, a client must
       * supply a GroupHandlerFactory, to create the GroupHandler to be used
       * to access the group, and a reference to be supplied to clients
       * accessing the service, unless clients must no access its reference
       */
      interface ReplicatedServer
      {
      };

      typedef sequence<ReplicatedServer> ReplicatedServersList;

      /***********************************************************************/
      /************************* GROUP MEMBERSHIP NAMING SERVICE *************/
      /***********************************************************************/

      /**
        * The Group Member Naming Service is a naming service for reliable
        * Group Members. It allows to join groups just by specifying the
        * group name. This service will locate other members in the group,
        * or will just create the group.
        * This service is not compatible with the GroupMembershipBasicService,
        * members added to groups using that service are unknown on this
        * Naming Service.
        **/
      interface GroupMembershipNamingService
      {
        /**
          * Creates a GroupHandlerFactoryCreator
          **/
        GroupHandlerFactoryCreator getFactoryCreator();

        /**
          * Finds a group with the name specified and includes the member with the given name
          * The reference can be null if the member is no accesible to clients
          * @returns the group handler created, or null if this member has been considered by
          *  the group.
          * @exception MemberStateException if the member defining the service cannot contact
          *  other members and decide surely about the joining
          **/
        GroupHandler findAndJoinGroup(in string groupName, in GroupHandlerFactory theFactory,
            in string memberName, in ReplicatedServer clientsReference)
          raises (	sensei::middleware::domains::MemberStateException,
                    InvalidGroupHandlerFactoryException,
                    GroupHandlerFactoryException);

        /**
          * Leaves a group. This method is not needed to be called, as the service can
          * discover by itself that a member has left the group, but it can speed up
          * other member's joining.
          **/
        void leaveGroup(in string groupName, in GroupHandler member);

        /**
          * Returns the know references to a group, which can be still not valid. The list
          * is empty if there are no servers in the group or the group does not exist
          **/
        ReplicatedServersList getGroup(in string groupName) raises (sensei::middleware::domains::MemberStateException);

        /**
          * Returns a specific reference of a member in the group. If
          * the group does not exist or it contains no such a member, null is returned
          **/
        ReplicatedServer getGroupServer(in string groupName, in string memberName)
          raises(sensei::middleware::domains::MemberStateException);

        /**
          * Returns a reference to a member in the group, warrantied to be valid. Note that it can
          * get invalidated before the client received it.
          **/
        ReplicatedServer getValidGroupServer(in string groupName)
          raises(sensei::middleware::domains::MemberStateException);
      };
    };
  };
};

#endif