NDS.Live Registry Module
1.简介
NDS.Live是分布式生态系统,要求客户端(如路上的车辆)能够直接访问特定的服务端点。服务端点由网络节点表示。注册表是NDS.Live的网关。注册表接收、存储和分发有关服务节点的元数据的网络节点。在客户端连接到任何特定服务之前,注册表能提供一些信息。服务节点通过注册宣布其操作就绪情况,连接成本和优先级值。客户端使用注册表来发现能够为特定于应用程序的需求提供数据的网络服务节点。注册表还能够考虑客户机经济方面的问题,并在带宽受限的环境中优先考虑请求。
注册表表示网络节点,根注册表可以将客户端指向其他注册表;单个注册表可以跨多个NDS映射表,这些映射由NDS系统token标识。这意味着属于不同NDS映射的服务节点可以在相同的注册表中注册。
下图显示了注册表如何充当网络节点和客户端之间的代理。
Service Metadata(服务元数据)
注册的每个服务都需要提供元数据,以便客户端可以连接到该服务。在服务节点的地址旁边,注册表提供连接和使用数据所需的信息,包括有关所使用的协议和NDS.Live的模块。
模块内容
Registry模块包含下列文件:
常量
const ModuleName NAME = "REGISTRY"; //模块名称
const ModuleVersion VERSION = "2023.06"; //模块版本
const ModuleService REGISTRY_SERVICE = "registry.services.NdsRegistry"; //注册该模块服务的模块服务标识符
2.Registry Filestore
注册表信息可以存储在SQLite数据库文件中, 注册表列出了所有相关节点,包括可用的第二层注册表。
注册表文件存储的文件名始终是registry.ndslive且均为小写字母,包括文件结尾。
规则
- 存储注册表信息的SQLite数据库的文件名只能使用小写字母,包括文件扩展名。包含扩展名的文件名应为registry.ndslive
- 如果RegistryNodeTable表中字段NodeType设置为SERVICE,ServiceInformation字段填写相应的服务信息。RegistryDefinition字段应为NULL
- |如果RegistryNodeTable表中字段NodeType设置为REGISTRY,即字段RegistryDefinition应填写相应的注册信息。ServiceInformation应为NULL
SQL Database RegistryStore
/**存储注册表信息的SQL数据库。* /
sql_database RegistryStore
{
RegistryNodeTable nodeTable;
}
SQL Table RegistryNodeTable
/**注册节点表,提供注册节点信息。* /
sql_table RegistryNodeTable
{
NdsSystemToken systemId sql "NOT NULL"; /** 网络节点所使用的NDS系统标识符 */
NdsNodeToken nodeToken sql "NOT NULL"; /** 网络节点标识符. */
NdsNodeLegalInfo legalInfo sql "NOT NULL"; /** 网络节点的合法信息. */
NodeType type sql "NOT NULL"; /** 网络节点的功能角色. */
ConnectionCosts connectionCosts sql "NOT NULL"; /** 一般成本值,可由客户端解释. */
SpatialExtent spatialCoverage sql "NOT NULL"; /** 网络节点的地理覆盖范围. */
ProtocolType protocolType sql "NOT NULL"; /** 节点接口协议,客户端可以使用该协议进行通信. */
string protocolDetailsUri sql "NOT NULL"; /** URI获取有关所使用协议的更多信息. */
string nodeName sql "NOT NULL"; /** 网络节点的名称. */
string hostName sql "NOT NULL"; /** 网络节点的主机名或IP地址. */
uint16 port sql "NOT NULL"; /** 网络节点在指定名称的主机上运行时使用的端口. */
ServiceInformation serviceInformation sql "NULL"; /** 服务器信息. */
ModuleDefinition registryDefinition sql "NULL"; /** 已注册的第二级注册表的模块信息. */
sql "primary key (systemId, nodeToken)";
};
3.Registry Node
这个包定义了描述和搜索服务节点所必需的注册表服务。注册表节点通过NdsNodeToken和NdsSystemToken的组合来唯一标识。
3.1子类型
Subtype ServicePriority
/** 定义服务的全局优先级。数值越高优先级越高。客户机使用该组合的值,以决定是否连接到特定的服务节点*/
subtype uint8 ServicePriority;
Subtype ConnectionCosts
/** 定义连接到特定服务节点的成本。成本可以是实际成本,比如数据传输成本,但主要是人为的。应用程序可以从提供相同数据的不同节点中进行选择它将产生的成本。*/
subtype uint16 ConnectionCosts;
3.2注册信息
注册信息包括可能的语义节点类型和特定服务类型的基本枚举,以及远程过程调用(RPC)和发布-订阅(PubSub)系统的协议类型。与ServiceInformation.moduleDefinition结合使用。此信息使客户端能够确定使用哪些结构与特定服务进行交互。
Enumeration NodeType
/** 网络节点类型. */
enum uint8 NodeType
{
REGISTRY = 0,/** 网络节点提供注册接口. */
SERVICE = 1,/** 网络节点提供基于模块的服务. */
TOPIC_SERVER = 3/** 网络节点是一个发布-订阅代理 */
};
Subtype ProtocolType
/** 底层服务或发布-订阅实现的协议类型. */
subtype uint8 ProtocolType;
const ProtocolType REST = 0; /** 服务使用HTTPS的安全REST实现. */
const ProtocolType GRPC = 1; /** 服务使用gRPC. */
const ProtocolType MQTT = 2; /**服务使用MQTT代理. */
const ProtocolType REST_OPENAPI30 = 3/*服务使用HTTPS的安全REST实现,并提供有关的附加信息传输层使用OpenAPI 3.0*/
const ProtocolType SOME_IP = 5;/**服务使用SOME/IP实现. */
const ProtocolType REST_UNSECURE = 6; /**服务使用不安全的REST实现. */
const ProtocolType REST_OPENAPI30_UNSECURE = 7;//该服务使用不安全的REST实现,并使用OpenAPI 3.0提供关于传输层的附加信息
const ProtocolType FILE_SQLITE3 = 8; //数据存储在SQLITE(文件格式3)文件中
3.3节点信息对象
网络节点定义在节点信息对象中,节点信息对象存储在节点列表中。每个节点信息对象标识由网络节点提供的特定服务,包括物理和语义属性。节点中定义connectionCosts(连接成本)、spatialCoverage(地理覆盖)和ServiceInformation.servicePriority(优先级值),这些服务节点属性影响到潜在客户端连接服务节点的决策。
规则
- 如果将ProtocolType设置为REST_OPENAPI30,则protocolDetailsUri将指向JSON表示的OpenAPI定义文件的节点,例如openapi.json。
**Structure NodeList **
/** 节点信息对象列表 */
struct NodeList
{
varuint numNodes; /** ' nodes '数组中对象的计数. */
NodeInformation nodes[numNodes]; /** 唯一节点信息对象的数组。. */
};
Structure NodeInformation
/** 节点信息对象的定义. */
struct NodeInformation
{
NdsSystemToken systemId; //网络节点使用的NDS映射标识符。
NdsNodeToken nodeToken; /**网络节点标识符。* /
NdsNodeLegalInfo legalInfo; /**网络节点的合法信息。* /
NodeType type; /**网络节点的功能角色。* /
ConnectionCosts connectionCosts; /**一般成本值,可由客户端解释。* /
SpatialExtent spatialCoverage; /**网络节点的地理覆盖。* /
ProtocolType protocolType; /**节点接口协议,客户端可以使用该协议进行通信。* /
string protocolDetailsUri; /** URI获取有关所使用协议的更多信息。* /
string nodeName; /**网络节点的任意名称。* /
string hostName; /**网络节点的主机名或IP地址。在文件存储的情况下,相对文件名。* /
uint16 port; /**网络节点在指定名称的主机上运行的端口。* /
ServiceInformation serviceInformation if type == NodeType.SERVICE; //service 信息
ModuleDefinition registryDefinition if type == NodeType.REGISTRY; /**已注册的第二层注册表的模块信息。* /
};
Service Information
NodeType.SERVICE网络节点。ServiceInformation结构定义所提供的服务。节点提供服务接口,这需要额外的限定条件。serviceMetadata字段包含可以用相应模块解析器解析的外部元数据(在ExternData包装器中定义)。
Structure ServiceInformation
/** 定义所提供的服务. */
struct ServiceInformation
{
ModuleDefinition moduleDefinition; /**服务的模块定义* /
ModuleService moduleService; /**服务的模块服务标识符。* /
ServicePriority servicePriority; /**优先级提示,可用于注册表或客户端控制网络使用。* /
optional ExternData serviceMetadata; //服务的元数据。如果没有填充服务元数据,则需要直接从中检索详细信息该服务。
align(8):
extern serviceCertificationMetadata; /**服务的认证元数据。* /
};
3.4节点搜索过滤和服务信息过滤
节点搜索过滤器和服务信息过滤器是针对网络节点的搜索过滤器,客户端填充搜索过滤器并将其传递给注册表,注册表搜索与过滤器匹配的网络节点并返回一个NodeList。一个节点过滤器仅对一个模块有效。如果一个节点数据层来自多个模块后续调用可能返回同一个网络节点,这取决于客户端实现智能查找并组合服务节点以获得最佳查询策略。
规则
- 如果每个过滤字段都匹配NodeInformation中的对应字段,NodeSearchFilter和ServiceInformationFilter只匹配节点信息对象
**Structure NodeSearchFilter **
/** 节点搜索过滤. */
struct NodeSearchFilter
{
NdsSystemToken systemId; /**令牌,用于标识应该由所需节点服务的映射。* /
NodeType nodeType; /**需要的节点类型。* /
ServiceInformationFilter serviceInfoFilter if nodeType == NodeType.SERVICE; /**可选的服务信息过滤器,用于附加特定于服务的标准。* /
};
**Structure ServiceInformationFilter **
/**服务信息过滤。* /
struct ServiceInformationFilter
{
ModuleDefinition moduleDefinition; /**期望的服务模块。* /
ModuleService moduleService; /**需要的服务标识符。* /
ServicePriority minServicePriority; /**期望的最低服务优先级。价值是包容性的。* /
ServicePriority maxServicePriority; /**期望的最大服务优先级。价值是包容性的。* /
};
4.注册服务
此包定义访问注册表节点必须的注册节点。
4.1NDS注册服务
NDS注册表服务的单个实例跨一个或多个NDS映射表,这些映射表由NdsSystemToken标识。提供属于相同NDS映射表的数据的网络节点由相同的NdsSystemToken关联。属于不同NDS映射表的服务节点可以在同一个NDS注册表中注册,如果 NodeInformation.type设置为NodeType.REGISTRY,一个NDS注册表中的服务可能引用其他NDS注册表的实例。
unregisterNode函数的NdsNodeToken参数必须是之前通过registerNode函数提供用于注册节点的值,就是注册节点和反注册节点函数要相对应。
规则
- 使用getAllNodes和getAllNodesAllSystems获取注册表中的条目:注册表不应在getAllNodes和getAllNodesAllSystems中包含自身。
- 注册表应该保留对特定NodeInformation结构的引用,直到使用该结构的确切NdsNodeToken调用unregisterNode。
- 如果使用已经注册的NdsNodeToken调用registerNode方法,注册表将更新节点的信息
- 元数据方法getRegistryModuleDefinition应该由所有注册服务实现
- 元数据方法getRegistryServiceCapabilities应该由所有注册服务实现
- getAllNodesAllSystems方法应由所有注册表服务实现
NdsRegistry 服务
//NDS.live注册表服务,充当一个获取有关可用服务和其他注册表信息的网关。' NdsRegistry '的单个实例在一个或多个NDS地图上运行。
service NdsRegistry
{
ModuleDefinition getRegistryModuleDefinition(Empty);/**注册表服务本身的模块定义。**/
RegistryServiceCapabilitiesResponse getRegistryServiceCapabilities(Empty);/**注册服务实现方法的元数据。* /
NodeList getAllNodesAllSystems(Empty);/**请求所有系统的所有可用节点。* /
NodeList getAllNodes(NdsSystemToken);/**请求完整NDS地图的所有可用网络节点。* /
NodeList searchNodes(NodeSearchFilter);/**请求特定过滤器的所有可用网络节点。* /
Empty registerNode(NodeInformation);/**注册一个新的网络节点。* /
Empty unregisterNode(NdsNodeToken);/**从系统中移除节点。* /
};
**RegistryServiceCapabilitiesResponse **
/**包装注册表功能,以便直接在服务接口中使用。* /
struct RegistryServiceCapabilitiesResponse
{
RegistryServiceCapabilities capabilities;/**定义注册表服务实现的方法。* /
};
RegistryServiceCapabilities
/**可以通过注册服务实现的方法。* /
bitmask uint16 RegistryServiceCapabilities
{
GET_ALL_NODES,/**如果' getAllNodes'方法被实现时设置* /
SEARCH_NODES,/**如果' getAllNodes'方法被实现时设置* /
REGISTER_NODE,/**如果' registerNode'方法被实现时设置* /
UNREGISTER_NODE/**如果' unregisterNode'方法被实现时设置* /
};
RegistryTopics
/**发布-订阅注册表服务主题。* /
pubsub RegistryTopics
{
pubsub("nds/registry/update/system") NdsSystemToken ndsSystemToken; //每当注册中心更新已发布的NDS系统令牌的更改/添加/删除节点信息时,就发布。
pubsub("nds/registry/update/tier2registry") Empty empty; /**当二级注册表被更改/添加/删除时发布。* /
};