Service Discovery

The RTC Toolkit introduces a basic service discovery mechanism that allows lookup and retrieval of service endpoints by name. It uses a ServiceRegistryAdapter to retrieve the service information.

The discovery mechanism makes use of the Client-Side Discovery Pattern where a client retrieves endpoints of required services by querying a central service registry (a database).

The service registry has two implementations:

  • The default is a Consul-based service registry which requires Nomad and Consul services, and Nomad jobs to include services information for the RTC components.

  • Alternatively, a file-based service registry can be used for development purpose. Its storage back-end in a single, shared, YAML file using the CII config-ng format.

Note

The Consul-based mechanism shall be the default and used in operations. Therefore the optional -s or --sde command line argument of components and tools is not needed when running the system with this default configuration.

Service endpoints are represented in URI format and retrieved using the elt::mal::Uri class, which is aliased as ServiceEndpoint. The Service Discovery create the appropiate adapter as indicated by the URI (See the examples below).

Supported Service Queries

Currently the following service queries are supported:

Service Query

Format

Description

GetPersistentRepoEndpoint

elt::mal::Uri

Service endpoint of the Persistent Configuration Repository.

GetRuntimeRepoEndpoint

elt::mal::Uri

Service endpoint of the Runtime Configuration Repository.

GetOldbEndpoint

elt::mal::Uri

Service endpoint of the Online Database.

GetReqRepEndpoint

elt::mal::Uri

CII MAL request/reply endpoint of an RTC Component.

GetPubSubEndpoint

elt::mal::Uri

CII MAL publish/subscribe endpoint of an RTC Component.

For supported URI schemes of GetPersistentRepoEndpoint refer to section Service Discovery Endpoint.

For supported URI schemes of GetRuntimeRepoEndpoint refer to section Data Access.

For supported URI schemes of GetOldbEndpoint refer to section Data Access.

Service Discovery API

The service discovery interface rtctk::componentFramework::ServiceDiscovery provides the following methods:

std::vector<std::string> ListComponents();
ServiceEndpoint GetOldbEndpoint ();
ServiceEndpoint GetRuntimeRepoEndpoint ();
ServiceEndpoint GetPersistentRepoEndpoint ();
ServiceEndpoint GetReqRepEndpoint (const std::string& component_name = "",
const std::string& service_type = ServiceRegistryIf::COMPONENT_TYPE, const bool health_check = true);
ServiceEndpoint GetPubSubEndpoint (const std::string& component_name = "",
const std::string& service_type = ServiceRegistryIf::COMPONENT_TYPE, const bool health_check = true);

When a component name is not given, the component name given at construction time of Service Discovery is used. The optional health_check flag is used to indicate whether to check the health of the component, i.e., if the process is already/still running before returning the endpoint (the default is to perform the check) The ListComponents function returns all known components.

Example Code

Use of the consul adapter to access the Service Discovery (to be used for production):

#include <rtctk/componentFramework/serviceDiscovery.hpp>

using rtctk::componentFramework::ServiceDiscovery;

void service_discovery() {
    ServiceDiscovery service_discovery(elt::mal::Uri{"consul://127.0.0.1:8500"}, "my_component");
    elt::mal::Uri oldb_uri = service_discovery.GetOldbEndpoint();
    DoSomethingWithOldb(oldb_uri);
    elt::mal::Uri some_component_reqrep_uri = GetReqRepEndpoint("some_component");
}

Use of the file adapter to access the Service Discovery (to be used just for testing or similar):

#include <rtctk/componentFramework/serviceDiscovery.hpp>

using rtctk::componentFramework::ServiceDiscovery;

void service_discovery() {
    ServiceDiscovery service_discovery(elt::mal::Uri{"file:///path/to/file.yaml"}, "my_component");
    elt::mal::Uri oldb_uri = service_discovery.GetOldbEndpoint();
    DoSomethingWithOldb(oldb_uri);
    elt::mal::Uri some_component_reqrep_uri = GetReqRepEndpoint("some_component");
}

Limitations and Known Issues

  • Currently it is not foreseen that developers define custom service types in the service registry. Users are only supposed to re-use the available service types e.g. to add endpoints to nomad job files (or use the rtctkDeploymentGen tool) for new components, add to the YAML file or to adjust the endpoints of existing components.