Use a map (rather than a vector) for endpoints where we know the identity.

This commit is contained in:
Gunnar Beutner 2012-06-20 15:22:39 +02:00
parent 468a0ad5b2
commit 77029763cf
6 changed files with 84 additions and 84 deletions

View File

@ -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. * @param endpoint The endpoint.
*/ */
void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint)
{ {
endpoint->OnIdentityChanged.connect(boost::bind(&DiscoveryComponent::NewIdentityHandler, this, _1));
/* accept discovery::RegisterComponent messages from any endpoint */ /* accept discovery::RegisterComponent messages from any endpoint */
endpoint->RegisterPublication("discovery::RegisterComponent"); endpoint->RegisterPublication("discovery::RegisterComponent");
/* accept discovery::Welcome messages from any endpoint */ /* accept discovery::Welcome messages from any endpoint */
endpoint->RegisterPublication("discovery::Welcome"); 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(); string identity = endpoint->GetIdentity();
if (identity == GetEndpointManager()->GetIdentity()) { if (identity == GetEndpointManager()->GetIdentity()) {
@ -231,6 +170,56 @@ void DiscoveryComponent::NewIdentityHandler(const Endpoint::Ptr& endpoint)
FinishDiscoverySetup(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<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. * Processes discovery::Welcome messages.
* *

View File

@ -57,7 +57,6 @@ private:
Timer::Ptr m_DiscoveryTimer; Timer::Ptr m_DiscoveryTimer;
void NewEndpointHandler(const Endpoint::Ptr& endpoint); void NewEndpointHandler(const Endpoint::Ptr& endpoint);
void NewIdentityHandler(const Endpoint::Ptr& endpoint);
void NewComponentMessageHandler(const RequestMessage& request); void NewComponentMessageHandler(const RequestMessage& request);
void RegisterComponentMessageHandler(const Endpoint::Ptr& sender, const RequestMessage& request); void RegisterComponentMessageHandler(const Endpoint::Ptr& sender, const RequestMessage& request);

View File

@ -79,7 +79,6 @@ public:
ConstTopicIterator BeginPublications(void) const; ConstTopicIterator BeginPublications(void) const;
ConstTopicIterator EndPublications(void) const; ConstTopicIterator EndPublications(void) const;
boost::signal<void (const Endpoint::Ptr&)> OnIdentityChanged;
boost::signal<void (const Endpoint::Ptr&)> OnSessionEstablished; boost::signal<void (const Endpoint::Ptr&)> OnSessionEstablished;
private: private:

View File

@ -151,9 +151,17 @@ void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint)
throw invalid_argument("Identity must be empty."); throw invalid_argument("Identity must be empty.");
endpoint->SetEndpointManager(GetSelf()); endpoint->SetEndpointManager(GetSelf());
m_Endpoints.push_back(endpoint);
UnregisterEndpoint(endpoint);
string identity = endpoint->GetIdentity();
if (!identity.empty()) {
m_Endpoints[identity] = endpoint;
OnNewEndpoint(GetSelf(), 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) void EndpointManager::UnregisterEndpoint(Endpoint::Ptr endpoint)
{ {
m_Endpoints.erase( m_PendingEndpoints.erase(
remove(m_Endpoints.begin(), m_Endpoints.end(), endpoint), remove(m_PendingEndpoints.begin(), m_PendingEndpoints.end(), endpoint),
m_Endpoints.end()); 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."); throw invalid_argument("Message is missing the 'method' property.");
vector<Endpoint::Ptr> candidates; 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)) if (endpoint->HasSubscription(method))
candidates.push_back(endpoint); candidates.push_back(endpoint);
} }
@ -235,9 +247,10 @@ void EndpointManager::SendMulticastMessage(Endpoint::Ptr sender,
if (!message.GetMethod(&method)) if (!message.GetMethod(&method))
throw invalid_argument("Message is missing the 'method' property."); 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 */ /* don't forward messages back to the sender */
if (sender == recipient) if (sender == recipient)
@ -255,12 +268,12 @@ void EndpointManager::SendMulticastMessage(Endpoint::Ptr sender,
*/ */
void EndpointManager::ForEachEndpoint(function<void (const EndpointManager::Ptr&, const Endpoint::Ptr&)> callback) 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(); ) { for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) {
prev = i; prev = i;
i++; i++;
callback(GetSelf(), *prev); callback(GetSelf(), prev->second);
} }
} }
@ -271,12 +284,11 @@ void EndpointManager::ForEachEndpoint(function<void (const EndpointManager::Ptr&
*/ */
Endpoint::Ptr EndpointManager::GetEndpointByIdentity(string identity) const Endpoint::Ptr EndpointManager::GetEndpointByIdentity(string identity) const
{ {
vector<Endpoint::Ptr>::const_iterator i; map<string, Endpoint::Ptr>::const_iterator i;
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) { i = m_Endpoints.find(identity);
if ((*i)->GetIdentity() == identity) if (i != m_Endpoints.end())
return *i; return i->second;
} else
return Endpoint::Ptr(); return Endpoint::Ptr();
} }

View File

@ -70,7 +70,8 @@ private:
shared_ptr<SSL_CTX> m_SSLContext; shared_ptr<SSL_CTX> m_SSLContext;
vector<JsonRpcServer::Ptr> m_Servers; vector<JsonRpcServer::Ptr> m_Servers;
vector<Endpoint::Ptr> m_Endpoints; vector<Endpoint::Ptr> m_PendingEndpoints;
map<string, Endpoint::Ptr> m_Endpoints;
/** /**
* Information about a pending API request. * Information about a pending API request.

View File

@ -149,7 +149,7 @@ void JsonRpcEndpoint::VerifyCertificateHandler(bool& valid, const shared_ptr<X50
if (GetIdentity().empty() && !identity.empty()) { if (GetIdentity().empty() && !identity.empty()) {
m_Identity = identity; m_Identity = identity;
OnIdentityChanged(GetSelf()); GetEndpointManager()->RegisterEndpoint(GetSelf());
} }
} }
} }