diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp index dd86f7da6..328268e3d 100644 --- a/components/discovery/discoverycomponent.cpp +++ b/components/discovery/discoverycomponent.cpp @@ -99,79 +99,18 @@ void DiscoveryComponent::CheckExistingEndpoint(const Endpoint::Ptr& self, const } /** - * Registers handlers for new endpoints. + * Deals with a new endpoint. * * @param endpoint The endpoint. */ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) { - endpoint->OnIdentityChanged.connect(boost::bind(&DiscoveryComponent::NewIdentityHandler, this, _1)); - /* accept discovery::RegisterComponent messages from any endpoint */ endpoint->RegisterPublication("discovery::RegisterComponent"); /* accept discovery::Welcome messages from any endpoint */ endpoint->RegisterPublication("discovery::Welcome"); -} -/** - * Registers message Subscriptions/sources in the specified component information object. - * - * @param neea Event arguments for the endpoint. - * @param info Component information object. - * @return 0 - */ -void DiscoveryComponent::DiscoveryEndpointHandler(const Endpoint::Ptr& endpoint, const ComponentDiscoveryInfo::Ptr& info) const -{ - Endpoint::ConstTopicIterator i; - - for (i = endpoint->BeginSubscriptions(); i != endpoint->EndSubscriptions(); i++) - info->Subscriptions.insert(*i); - - for (i = endpoint->BeginPublications(); i != endpoint->EndPublications(); i++) - info->Publications.insert(*i); -} - -/** - * Retrieves the component information object for the specified component. - * - * @param component The identity of the component. - * @param info Pointer to the information object. - * @returns true if the info object was successfully retrieved, false otherwise. - */ -bool DiscoveryComponent::GetComponentDiscoveryInfo(string component, ComponentDiscoveryInfo::Ptr *info) const -{ - if (component == GetEndpointManager()->GetIdentity()) { - /* Build fake discovery info for ourselves */ - *info = boost::make_shared(); - GetEndpointManager()->ForEachEndpoint(boost::bind(&DiscoveryComponent::DiscoveryEndpointHandler, this, _2, *info)); - - (*info)->LastSeen = 0; - (*info)->Node = GetIcingaApplication()->GetNode(); - (*info)->Service = GetIcingaApplication()->GetService(); - - return true; - } - - map::const_iterator i; - - i = m_Components.find(component); - - if (i == m_Components.end()) - return false; - - *info = i->second; - return true; -} - -/** - * Deals with a new endpoint whose identity has just become known. - * - * @param ea Event arguments for the component. - * @returns 0 - */ -void DiscoveryComponent::NewIdentityHandler(const Endpoint::Ptr& endpoint) -{ string identity = endpoint->GetIdentity(); if (identity == GetEndpointManager()->GetIdentity()) { @@ -231,6 +170,56 @@ void DiscoveryComponent::NewIdentityHandler(const Endpoint::Ptr& endpoint) FinishDiscoverySetup(endpoint); } +/** + * Registers message Subscriptions/sources in the specified component information object. + * + * @param neea Event arguments for the endpoint. + * @param info Component information object. + * @return 0 + */ +void DiscoveryComponent::DiscoveryEndpointHandler(const Endpoint::Ptr& endpoint, const ComponentDiscoveryInfo::Ptr& info) const +{ + Endpoint::ConstTopicIterator i; + + for (i = endpoint->BeginSubscriptions(); i != endpoint->EndSubscriptions(); i++) + info->Subscriptions.insert(*i); + + for (i = endpoint->BeginPublications(); i != endpoint->EndPublications(); i++) + info->Publications.insert(*i); +} + +/** + * Retrieves the component information object for the specified component. + * + * @param component The identity of the component. + * @param info Pointer to the information object. + * @returns true if the info object was successfully retrieved, false otherwise. + */ +bool DiscoveryComponent::GetComponentDiscoveryInfo(string component, ComponentDiscoveryInfo::Ptr *info) const +{ + if (component == GetEndpointManager()->GetIdentity()) { + /* Build fake discovery info for ourselves */ + *info = boost::make_shared(); + GetEndpointManager()->ForEachEndpoint(boost::bind(&DiscoveryComponent::DiscoveryEndpointHandler, this, _2, *info)); + + (*info)->LastSeen = 0; + (*info)->Node = GetIcingaApplication()->GetNode(); + (*info)->Service = GetIcingaApplication()->GetService(); + + return true; + } + + map::const_iterator i; + + i = m_Components.find(component); + + if (i == m_Components.end()) + return false; + + *info = i->second; + return true; +} + /** * Processes discovery::Welcome messages. * diff --git a/components/discovery/discoverycomponent.h b/components/discovery/discoverycomponent.h index 3cb7d8692..3c9bc5fad 100644 --- a/components/discovery/discoverycomponent.h +++ b/components/discovery/discoverycomponent.h @@ -57,7 +57,6 @@ private: Timer::Ptr m_DiscoveryTimer; void NewEndpointHandler(const Endpoint::Ptr& endpoint); - void NewIdentityHandler(const Endpoint::Ptr& endpoint); void NewComponentMessageHandler(const RequestMessage& request); void RegisterComponentMessageHandler(const Endpoint::Ptr& sender, const RequestMessage& request); diff --git a/icinga/endpoint.h b/icinga/endpoint.h index 3b8703620..eaa056dce 100644 --- a/icinga/endpoint.h +++ b/icinga/endpoint.h @@ -79,7 +79,6 @@ public: ConstTopicIterator BeginPublications(void) const; ConstTopicIterator EndPublications(void) const; - boost::signal OnIdentityChanged; boost::signal OnSessionEstablished; private: diff --git a/icinga/endpointmanager.cpp b/icinga/endpointmanager.cpp index fdfdf4497..b8821863b 100644 --- a/icinga/endpointmanager.cpp +++ b/icinga/endpointmanager.cpp @@ -151,9 +151,17 @@ void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint) throw invalid_argument("Identity must be empty."); endpoint->SetEndpointManager(GetSelf()); - m_Endpoints.push_back(endpoint); - OnNewEndpoint(GetSelf(), endpoint); + UnregisterEndpoint(endpoint); + + string identity = endpoint->GetIdentity(); + + if (!identity.empty()) { + m_Endpoints[identity] = endpoint; + OnNewEndpoint(GetSelf(), endpoint); + } else { + m_PendingEndpoints.push_back(endpoint); + } } /** @@ -163,9 +171,13 @@ void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint) */ void EndpointManager::UnregisterEndpoint(Endpoint::Ptr endpoint) { - m_Endpoints.erase( - remove(m_Endpoints.begin(), m_Endpoints.end(), endpoint), - m_Endpoints.end()); + m_PendingEndpoints.erase( + remove(m_PendingEndpoints.begin(), m_PendingEndpoints.end(), endpoint), + m_PendingEndpoints.end()); + + string identity = endpoint->GetIdentity(); + if (!identity.empty()) + m_Endpoints.erase(identity); } /** @@ -203,9 +215,9 @@ void EndpointManager::SendAnycastMessage(Endpoint::Ptr sender, throw invalid_argument("Message is missing the 'method' property."); vector candidates; - for (vector::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) + for (map::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) { - Endpoint::Ptr endpoint = *i; + Endpoint::Ptr endpoint = i->second; if (endpoint->HasSubscription(method)) candidates.push_back(endpoint); } @@ -235,9 +247,10 @@ void EndpointManager::SendMulticastMessage(Endpoint::Ptr sender, if (!message.GetMethod(&method)) throw invalid_argument("Message is missing the 'method' property."); - for (vector::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) + map::iterator i; + for (i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) { - Endpoint::Ptr recipient = *i; + Endpoint::Ptr recipient = i->second; /* don't forward messages back to the sender */ if (sender == recipient) @@ -255,12 +268,12 @@ void EndpointManager::SendMulticastMessage(Endpoint::Ptr sender, */ void EndpointManager::ForEachEndpoint(function callback) { - vector::iterator prev, i; + map::iterator prev, i; for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) { prev = i; i++; - callback(GetSelf(), *prev); + callback(GetSelf(), prev->second); } } @@ -271,13 +284,12 @@ void EndpointManager::ForEachEndpoint(function::const_iterator i; - for (i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) { - if ((*i)->GetIdentity() == identity) - return *i; - } - - return Endpoint::Ptr(); + map::const_iterator i; + i = m_Endpoints.find(identity); + if (i != m_Endpoints.end()) + return i->second; + else + return Endpoint::Ptr(); } void EndpointManager::SendAPIMessage(Endpoint::Ptr sender, diff --git a/icinga/endpointmanager.h b/icinga/endpointmanager.h index d91128315..016c8ca83 100644 --- a/icinga/endpointmanager.h +++ b/icinga/endpointmanager.h @@ -70,7 +70,8 @@ private: shared_ptr m_SSLContext; vector m_Servers; - vector m_Endpoints; + vector m_PendingEndpoints; + map m_Endpoints; /** * Information about a pending API request. diff --git a/icinga/jsonrpcendpoint.cpp b/icinga/jsonrpcendpoint.cpp index 27a8842be..97fc57a5a 100644 --- a/icinga/jsonrpcendpoint.cpp +++ b/icinga/jsonrpcendpoint.cpp @@ -149,7 +149,7 @@ void JsonRpcEndpoint::VerifyCertificateHandler(bool& valid, const shared_ptrRegisterEndpoint(GetSelf()); } } }