Web Wispers 1.2.2 C++ Unit Test Coverage
Current view: top level - ssrc/wispers/registry - service.h (source / functions) Hit Total Coverage
Test: Web Wispers 1.2.2 C++ Unit Tests Lines: 69 69 100.0 %
Date: 2012-04-09 Functions: 17 18 94.4 %
Branches: 61 138 44.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright 2006-2009 Savarese Software Research Corporation
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at
       7                 :            :  *
       8                 :            :  *     https://www.savarese.com/software/ApacheLicense-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : /**
      18                 :            :  * @file
      19                 :            :  * This header defines the Registry class.
      20                 :            :  */
      21                 :            : 
      22                 :            : #ifndef __SSRC_WSPR_REGISTRY_SERVICE_H
      23                 :            : #define __SSRC_WSPR_REGISTRY_SERVICE_H
      24                 :            : 
      25                 :            : #include <ssrc/wispers/index/IndexService.h>
      26                 :            : 
      27                 :            : __BEGIN_NS_SSRC_WSPR_REGISTRY
      28                 :            : 
      29                 :            : using NS_SSRC_SPREAD::MembershipInfo;
      30                 :            : using namespace NS_SSRC_WSPR_INDEX;
      31                 :            : 
      32                 :            : // TODO: move this into utility package or into ssrcspread
      33                 :            : int group_index(const NS_SSRC_SPREAD::GroupList & groups,
      34                 :            :                 const string & group);
      35                 :            : 
      36                 :            : /**
      37                 :            :  *
      38                 :            :  */
      39                 :            : class Registry :
      40                 :            :   public IndexService<service_map, IndexScheme,
      41                 :            :                       NS_SSRC_WISP_PROTOCOL::GroupMembershipEnable>
      42                 :            : {
      43                 :            :   friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>;
      44                 :            :   typedef IndexService<service_map, IndexScheme, GroupMembership> super;
      45                 :            : 
      46                 :            :   WISP_IMPORT(NS_SSRC_WSPR_REGISTRY, MessageReregister);
      47                 :            :   WISP_IMPORT(NS_SSRC_WSPR_REGISTRY, CallReregister);
      48                 :            : 
      49                 :            :   bool _is_leader;
      50                 :            :   string _leader_name;
      51                 :            : 
      52                 :            :   void request_registrations(const string & registry,
      53                 :            :                              const bool self_discard = true);
      54                 :            : 
      55                 :          1 :   void process_request(const MessageRegister & msg, const MessageInfo &) {
      56                 :          1 :     register_service(msg.service_name, msg.service_types.begin(),
      57                 :          2 :                      msg.service_types.end());
      58                 :          1 :   }
      59                 :          2 :   void process_request(const MessageReregister & msg, const MessageInfo &) {
      60                 :          2 :     reregister_service(msg.service_name, msg.service_types.begin(),
      61                 :          4 :                        msg.service_types.end());
      62                 :          2 :   }
      63                 :            : 
      64                 :          1 :   void process_request(const MessageUnregister & msg, const MessageInfo &){
      65                 :          1 :     unregister_service(msg.service_name, msg.service_types.begin(),
      66                 :          2 :                        msg.service_types.end());
      67                 :          1 :   }
      68                 :            : 
      69                 :          3 :   void process_request(const MessageQueryByName & msg,
      70                 :            :                        const MessageInfo & msginfo)
      71                 :            :   {
      72   [ -  +  #  #  :          3 :     if(is_leader() || group_index(msginfo.groups, name()) >= 0)
          #  #  #  #  -  
             +  +  -  #  
                      # ]
      73                 :          3 :       process_query<ByName, CallQueryResult>(msg, msginfo);
      74                 :          3 :   }
      75                 :            : 
      76                 :          1 :   void process_request(const MessageQueryByType & msg,
      77                 :            :                        const MessageInfo & msginfo)
      78                 :            :   {
      79   [ -  +  #  #  :          1 :     if(is_leader() || group_index(msginfo.groups, name()) >= 0)
          #  #  #  #  -  
             +  +  -  #  
                      # ]
      80                 :          1 :       process_query<ByType, CallQueryResult>(msg, msginfo);
      81                 :          1 :   }
      82                 :            : 
      83                 :          1 :   void process_request(const MessageQueryAll & msg,
      84                 :            :                        const MessageInfo & msginfo)
      85                 :            :   {
      86   [ -  +  #  #  :          1 :     if(is_leader() || group_index(msginfo.groups, name()) >= 0) {
          #  #  #  #  -  
             +  +  -  #  
                      # ]
      87                 :          1 :       _caller.reply<CallQueryResult>(Message::FIFOSelfDiscard, msginfo.sender(),
      88                 :          2 :                                      msginfo.token(), _index);
      89                 :            :     }
      90                 :          1 :   }
      91                 :            : 
      92                 :            :   virtual void process_membership_message(const MessageInfo & msginfo,
      93                 :            :                                           const MembershipInfo & meminfo);
      94                 :            : 
      95                 :            :   virtual void transition(State state);
      96                 :            : 
      97                 :            : public:
      98                 :            : 
      99                 :            :   /**
     100                 :            :    *
     101                 :            :    */
     102                 :          6 :   explicit Registry(super::caller_type & caller) :
     103         [ +  - ]:          6 :     super(caller), _is_leader(false), _leader_name()
     104                 :            :   {
     105   [ +  -  +  -  :          6 :     add_service_type(protocol::service_type_registry());
                   +  - ]
     106                 :            : 
     107         [ +  - ]:          6 :     WISP_SERVICE_REQUEST(MessageRegister);
     108         [ +  - ]:          6 :     WISP_SERVICE_REQUEST(MessageReregister);
     109         [ +  - ]:          6 :     WISP_SERVICE_REQUEST(MessageUnregister);
     110         [ +  - ]:          6 :     WISP_SERVICE_REQUEST(MessageQueryByName);
     111         [ +  - ]:          6 :     WISP_SERVICE_REQUEST(MessageQueryByType);
     112         [ +  - ]:          6 :     WISP_SERVICE_REQUEST(MessageQueryAll);
     113                 :          6 :   }
     114                 :            : 
     115   [ +  -  -  + ]:          6 :   virtual ~Registry() { }
     116                 :            : 
     117                 :            :   /**
     118                 :            :    *
     119                 :            :    */
     120                 :          6 :   bool is_leader() {
     121                 :          6 :     return _is_leader;
     122                 :            :   }
     123                 :            : 
     124                 :            :   /**
     125                 :            :    *
     126                 :            :    */
     127                 :            :   string leader_name() {
     128                 :            :     return _leader_name;
     129                 :            :   }
     130                 :            : 
     131                 :            :   /**
     132                 :            :    *
     133                 :            :    */
     134                 :          5 :   void service_join(const string & service_name) {
     135         [ +  + ]:          5 :     if(count<ByName>(service_name) == 0)
     136                 :            :       insert<ByName>(RegistryEntry(service_name,
     137   [ +  -  +  -  :          4 :                                    protocol::service_type_unknown()));
                   +  - ]
     138                 :          5 :   }
     139                 :            : 
     140                 :            :   /**
     141                 :            :    *
     142                 :            :    */
     143                 :          2 :   void service_leave(const string & service_name) {
     144                 :          2 :     erase<ByName>(service_name);
     145                 :          2 :   }
     146                 :            : 
     147                 :            :   /**
     148                 :            :    *
     149                 :            :    */
     150                 :            :   template<typename InputIterator>
     151                 :          5 :   void register_service(const string & service_name,
     152                 :            :                         InputIterator service_type,
     153                 :            :                         const InputIterator & end_of_range)
     154                 :            :   {
     155   [ +  +  +  +  :         21 :     while(service_type != end_of_range) {
                   +  + ]
     156   [ +  -  +  -  :         11 :       insert<ByName>(RegistryEntry(service_name, *service_type));
                   +  - ]
     157                 :         11 :       ++service_type;
     158                 :            :     }
     159                 :            : 
     160                 :            :     // Remove unknown type.
     161                 :          5 :     index_by_composite & index = get_index<ByComposite>();
     162                 :            :     index_by_composite::iterator it =
     163                 :            :       index.find(boost::make_tuple(service_name,
     164   [ +  -  +  -  :          5 :                                    protocol::service_type_unknown()));
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     165                 :            : 
     166   [ -  +  -  +  :          5 :     if(it != index.end())
                   +  + ]
     167                 :          1 :       index.erase(it);
     168                 :          5 :   }
     169                 :            : 
     170                 :            :   /**
     171                 :            :    *
     172                 :            :    */
     173                 :            :   template<typename InputIterator>
     174                 :          2 :   void reregister_service(const string & service_name,
     175                 :            :                           InputIterator service_type,
     176                 :            :                           const InputIterator & end_of_range)
     177                 :            :   {
     178                 :          2 :     get_index<ByName>().erase(service_name);
     179                 :          2 :     register_service(service_name, service_type, end_of_range);
     180                 :          2 :   }
     181                 :            : 
     182                 :            :   /**
     183                 :            :    *
     184                 :            :    */
     185                 :            :   template<typename InputIterator>
     186                 :          2 :   void unregister_service(const string & service_name,
     187                 :            :                           InputIterator service_type,
     188                 :            :                           const InputIterator & end_of_range)
     189                 :            :   {
     190                 :          2 :     index_by_composite & index = get_index<ByComposite>();
     191                 :          2 :     index_by_composite::iterator it;
     192                 :            : 
     193   [ +  +  +  + ]:          7 :     while(service_type != end_of_range) {
     194   [ +  -  +  - ]:          3 :       it = index.find(boost::make_tuple(service_name, *service_type));
     195   [ +  -  +  - ]:          3 :       if(it != index.end())
     196                 :          3 :         index.erase(it);
     197                 :          3 :       ++service_type;
     198                 :            :     }
     199                 :            : 
     200                 :            :     // Add unknown type entry if every service_name entry has been removed.
     201   [ -  +  +  - ]:          2 :     if(count<ByName>(service_name) == 0)
     202   [ #  #  #  #  :          1 :       insert<ByName>(RegistryEntry(service_name,
          #  #  +  -  +  
                -  +  - ]
     203                 :            :                                    protocol::service_type_unknown()));
     204                 :          2 :   }
     205                 :            : 
     206                 :            : };
     207                 :            : 
     208                 :            : __END_NS_SSRC_WSPR_REGISTRY
     209                 :            : 
     210                 :            : #endif