Savarese Software Research Corporation
registry/service.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2009 Savarese Software Research Corporation
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     https://www.savarese.com/software/ApacheLicense-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00022 #ifndef __SSRC_WSPR_REGISTRY_SERVICE_H
00023 #define __SSRC_WSPR_REGISTRY_SERVICE_H
00024 
00025 #include <ssrc/wispers/index/IndexService.h>
00026 
00027 __BEGIN_NS_SSRC_WSPR_REGISTRY
00028 
00029 using NS_SSRC_SPREAD::MembershipInfo;
00030 using namespace NS_SSRC_WSPR_INDEX;
00031 
00032 // TODO: move this into utility package or into ssrcspread
00033 int group_index(const NS_SSRC_SPREAD::GroupList & groups,
00034                 const string & group);
00035 
00039 class Registry :
00040   public IndexService<service_map, IndexScheme,
00041                       NS_SSRC_WISP_PROTOCOL::GroupMembershipEnable>
00042 {
00043   friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>;
00044   typedef IndexService<service_map, IndexScheme, GroupMembership> super;
00045 
00046   WISP_IMPORT(NS_SSRC_WSPR_REGISTRY, MessageReregister);
00047   WISP_IMPORT(NS_SSRC_WSPR_REGISTRY, CallReregister);
00048 
00049   bool _is_leader;
00050   string _leader_name;
00051 
00052   void request_registrations(const string & registry,
00053                              const bool self_discard = true);
00054 
00055   void process_request(const MessageRegister & msg, const MessageInfo &) {
00056     register_service(msg.service_name, msg.service_types.begin(),
00057                      msg.service_types.end());
00058   }
00059   void process_request(const MessageReregister & msg, const MessageInfo &) {
00060     reregister_service(msg.service_name, msg.service_types.begin(),
00061                        msg.service_types.end());
00062   }
00063 
00064   void process_request(const MessageUnregister & msg, const MessageInfo &){
00065     unregister_service(msg.service_name, msg.service_types.begin(),
00066                        msg.service_types.end());
00067   }
00068 
00069   void process_request(const MessageQueryByName & msg,
00070                        const MessageInfo & msginfo)
00071   {
00072     if(is_leader() || group_index(msginfo.groups, name()) >= 0)
00073       process_query<ByName, CallQueryResult>(msg, msginfo);
00074   }
00075 
00076   void process_request(const MessageQueryByType & msg,
00077                        const MessageInfo & msginfo)
00078   {
00079     if(is_leader() || group_index(msginfo.groups, name()) >= 0)
00080       process_query<ByType, CallQueryResult>(msg, msginfo);
00081   }
00082 
00083   void process_request(const MessageQueryAll & msg,
00084                        const MessageInfo & msginfo)
00085   {
00086     if(is_leader() || group_index(msginfo.groups, name()) >= 0) {
00087       _caller.reply<CallQueryResult>(Message::FIFOSelfDiscard, msginfo.sender(),
00088                                      msginfo.token(), _index);
00089     }
00090   }
00091 
00092   virtual void process_membership_message(const MessageInfo & msginfo,
00093                                           const MembershipInfo & meminfo);
00094 
00095   virtual void transition(State state);
00096 
00097 public:
00098 
00102   explicit Registry(super::caller_type & caller) :
00103     super(caller), _is_leader(false), _leader_name()
00104   {
00105     add_service_type(protocol::service_type_registry());
00106 
00107     WISP_SERVICE_REQUEST(MessageRegister);
00108     WISP_SERVICE_REQUEST(MessageReregister);
00109     WISP_SERVICE_REQUEST(MessageUnregister);
00110     WISP_SERVICE_REQUEST(MessageQueryByName);
00111     WISP_SERVICE_REQUEST(MessageQueryByType);
00112     WISP_SERVICE_REQUEST(MessageQueryAll);
00113   }
00114 
00115   virtual ~Registry() { }
00116 
00120   bool is_leader() {
00121     return _is_leader;
00122   }
00123 
00127   string leader_name() {
00128     return _leader_name;
00129   }
00130 
00134   void service_join(const string & service_name) {
00135     if(count<ByName>(service_name) == 0)
00136       insert<ByName>(RegistryEntry(service_name,
00137                                    protocol::service_type_unknown()));
00138   }
00139 
00143   void service_leave(const string & service_name) {
00144     erase<ByName>(service_name);
00145   }
00146 
00150   template<typename InputIterator>
00151   void register_service(const string & service_name,
00152                         InputIterator service_type,
00153                         const InputIterator & end_of_range)
00154   {
00155     while(service_type != end_of_range) {
00156       insert<ByName>(RegistryEntry(service_name, *service_type));
00157       ++service_type;
00158     }
00159 
00160     // Remove unknown type.
00161     index_by_composite & index = get_index<ByComposite>();
00162     index_by_composite::iterator it =
00163       index.find(boost::make_tuple(service_name,
00164                                    protocol::service_type_unknown()));
00165 
00166     if(it != index.end())
00167       index.erase(it);
00168   }
00169 
00173   template<typename InputIterator>
00174   void reregister_service(const string & service_name,
00175                           InputIterator service_type,
00176                           const InputIterator & end_of_range)
00177   {
00178     get_index<ByName>().erase(service_name);
00179     register_service(service_name, service_type, end_of_range);
00180   }
00181 
00185   template<typename InputIterator>
00186   void unregister_service(const string & service_name,
00187                           InputIterator service_type,
00188                           const InputIterator & end_of_range)
00189   {
00190     index_by_composite & index = get_index<ByComposite>();
00191     index_by_composite::iterator it;
00192 
00193     while(service_type != end_of_range) {
00194       it = index.find(boost::make_tuple(service_name, *service_type));
00195       if(it != index.end())
00196         index.erase(it);
00197       ++service_type;
00198     }
00199 
00200     // Add unknown type entry if every service_name entry has been removed.
00201     if(count<ByName>(service_name) == 0)
00202       insert<ByName>(RegistryEntry(service_name,
00203                                    protocol::service_type_unknown()));
00204   }
00205 
00206 };
00207 
00208 __END_NS_SSRC_WSPR_REGISTRY
00209 
00210 #endif

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.