From 58efebb846e1048cfadbdabee0071aeffca46aa5 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan Date: Wed, 17 Apr 2024 10:47:21 -0400 Subject: [PATCH] Replace ULIDs by 16 byte ids and recommend UUID v7 The early version of the spec was written before UUID v7 existed and ULID was chosen as a ID type that is suited to be used as a primary key in databases. Since than UUID v7 was standardized and aims to serve the exact same niche. ## Proposal Replace instance_id definition to be an arbitrary sequence of 16 bytes. Both ULID and any version of UUID may be used as the value. We also recommend to use UUID v7 for the value. This is a breaking change in the spec. We recommend opamp-go implementation to implement the change in backward compatible way, supporting both old and new instance_uid formats for a period of time. Since `bytes` and `string` are compatible in the Protobuf wire encoding it is possible to use the new Protobuf declarations to receive messages encoded using the old Protobuf declarations - string's UTF8 bytes will simply populate the bytes of the new field. Receivers can simply probe for the length of the received bytes field and if it is 26 treat it as ULID in canonical format, if it is 16 bytes treat it as opaque id in new format, otherwise consider it invalid. I will also post a PR in opamp-go that implements the above behavior. --- proto/opamp.proto | 9 +++++---- specification.md | 16 ++++++++-------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/proto/opamp.proto b/proto/opamp.proto index a1e77e1..e78b35e 100644 --- a/proto/opamp.proto +++ b/proto/opamp.proto @@ -25,8 +25,8 @@ option go_package = "github.com/open-telemetry/opamp-go/protobufs"; message AgentToServer { // Globally unique identifier of the running instance of the Agent. SHOULD remain // unchanged for the lifetime of the Agent process. - // Recommended format: https://github.com/ulid/spec - string instance_uid = 1; + // MUST be 16 bytes long and SHOULD be generated using the UUID v7 spec. + bytes instance_uid = 1; // The sequence number is incremented by 1 for every AgentToServer sent // by the Agent. This allows the Server to detect that it missed a message when @@ -148,7 +148,7 @@ message CertificateRequest { message ServerToAgent { // Agent instance uid. MUST match the instance_uid field in AgentToServer message. // Used for multiplexing messages from/to multiple agents using one message stream. - string instance_uid = 1; + bytes instance_uid = 1; // error_response is set if the Server wants to indicate that something went wrong // during processing of an AgentToServer message. If error_response is set then @@ -804,7 +804,8 @@ enum PackageStatusEnum { message AgentIdentification { // When new_instance_uid is set, Agent MUST update instance_uid // to the value provided and use it for all further communication. - string new_instance_uid = 1; + // MUST be 16 bytes long and SHOULD be generated using the UUID v7 spec. + bytes new_instance_uid = 1; } ///////////////////////////////////////////////////////////////////////////////////// diff --git a/specification.md b/specification.md index 63aab57..7d9c4d2 100644 --- a/specification.md +++ b/specification.md @@ -479,7 +479,7 @@ document are specified in ```protobuf message AgentToServer { - string instance_uid = 1; + bytes instance_uid = 1; uint64 sequence_num = 2; AgentDescription agent_description = 3; uint64 capabilities = 4; @@ -504,9 +504,9 @@ The instance_uid field is a globally unique identifier of the running instance of the Agent. The Agent SHOULD self-generate this identifier and make the best effort to avoid creating an identifier that may conflict with identifiers created by other Agents. The instance_uid SHOULD remain unchanged for the -lifetime of the Agent process. The instance_uid MUST be a -[ULID](https://github.com/ulid/spec) formatted as a 26 character string in canonical -representation. +lifetime of the Agent process. The instance_uid MUST be +16 bytes long and SHOULD be generated using the +[UUID v7 spec](https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-14.html#name-uuid-version-7). In case the Agent wants to use an identifier generated by the Server, the field SHOULD be set with a temporary value and RequestInstanceUid flag MUST be set. @@ -704,7 +704,7 @@ The ServerToAgent message has the following structure: ```protobuf message ServerToAgent { - string instance_uid = 1; + bytes instance_uid = 1; ServerErrorResponse error_response = 2; AgentRemoteConfig remote_config = 3; ConnectionSettingsOffers connection_settings = 4; // Status: [Beta] @@ -826,12 +826,12 @@ enum ServerCapabilities { Properties related to identification of the Agent, which can be overridden by the Server if needed. When new_instance_uid is set, Agent MUST update instance_uid to the value provided and use it for all further communication. The new_instance_uid MUST -be a [ULID](https://github.com/ulid/spec) formatted as a 26 character string in canonical -representation. +be 16 bytes long and SHOULD be generated using the +[UUID v7 spec](https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-14.html#name-uuid-version-7). ```protobuf message AgentIdentification { - string new_instance_uid = 1; + bytes new_instance_uid = 1; } ```