}
/**
- * 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<ComponentDiscoveryInfo>();
- GetEndpointManager()->ForEachEndpoint(boost::bind(&DiscoveryComponent::DiscoveryEndpointHandler, this, _2, *info));
-
- (*info)->LastSeen = 0;
- (*info)->Node = GetIcingaApplication()->GetNode();
- (*info)->Service = GetIcingaApplication()->GetService();
-
- return true;
- }
- map<string, ComponentDiscoveryInfo::Ptr>::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()) {
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<ComponentDiscoveryInfo>();
+ GetEndpointManager()->ForEachEndpoint(boost::bind(&DiscoveryComponent::DiscoveryEndpointHandler, this, _2, *info));
+
+ (*info)->LastSeen = 0;
+ (*info)->Node = GetIcingaApplication()->GetNode();
+ (*info)->Service = GetIcingaApplication()->GetService();
+
+ return true;
+ }
+
+ map<string, ComponentDiscoveryInfo::Ptr>::const_iterator i;
+
+ i = m_Components.find(component);
+
+ if (i == m_Components.end())
+ return false;
+
+ *info = i->second;
+ return true;
+}
+
/**
* Processes discovery::Welcome messages.
*
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);
+ }
}
/**
*/
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);
}
/**
throw invalid_argument("Message is missing the 'method' property.");
vector<Endpoint::Ptr> candidates;
- for (vector<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
+ for (map<string, Endpoint::Ptr>::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);
}
if (!message.GetMethod(&method))
throw invalid_argument("Message is missing the 'method' property.");
- for (vector<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
+ map<string, Endpoint::Ptr>::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)
*/
void EndpointManager::ForEachEndpoint(function<void (const EndpointManager::Ptr&, const Endpoint::Ptr&)> callback)
{
- vector<Endpoint::Ptr>::iterator prev, i;
+ map<string, Endpoint::Ptr>::iterator prev, i;
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) {
prev = i;
i++;
- callback(GetSelf(), *prev);
+ callback(GetSelf(), prev->second);
}
}
*/
Endpoint::Ptr EndpointManager::GetEndpointByIdentity(string identity) const
{
- vector<Endpoint::Ptr>::const_iterator i;
- for (i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) {
- if ((*i)->GetIdentity() == identity)
- return *i;
- }
-
- return Endpoint::Ptr();
+ map<string, Endpoint::Ptr>::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,