This is an automated email from the ASF dual-hosted git repository. hanahmily pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb-client-proto.git
commit 164447d7385441da4c0c7087b5faa4ff15c299a7 Author: Gao Hongtao <[email protected]> AuthorDate: Thu Dec 18 15:15:43 2025 +0000 Add proto files for Banyandb API including common, database, measure, model, property, stream, and trace definitions --- proto/banyandb/v1/banyandb-common.proto | 182 ++++++++ proto/banyandb/v1/banyandb-database.proto | 742 ++++++++++++++++++++++++++++++ proto/banyandb/v1/banyandb-measure.proto | 219 +++++++++ proto/banyandb/v1/banyandb-model.proto | 198 ++++++++ proto/banyandb/v1/banyandb-property.proto | 112 +++++ proto/banyandb/v1/banyandb-stream.proto | 130 ++++++ proto/banyandb/v1/banyandb-trace.proto | 122 +++++ 7 files changed, 1705 insertions(+) diff --git a/proto/banyandb/v1/banyandb-common.proto b/proto/banyandb/v1/banyandb-common.proto new file mode 100644 index 0000000..d4ace04 --- /dev/null +++ b/proto/banyandb/v1/banyandb-common.proto @@ -0,0 +1,182 @@ +// Licensed to Apache Software Foundation (ASF) under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Apache Software Foundation (ASF) licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +syntax = "proto3"; + +option java_package = "org.apache.skywalking.banyandb.common.v1"; + +package banyandb.common.v1; + +import "google/protobuf/timestamp.proto"; +import "validate/validate.proto"; + +enum Catalog { + CATALOG_UNSPECIFIED = 0; + CATALOG_STREAM = 1; + CATALOG_MEASURE = 2; + CATALOG_PROPERTY = 3; + CATALOG_TRACE = 4; +} + +// Metadata is for multi-tenant, multi-model use +message Metadata { + // group contains a set of options, like retention policy, max + string group = 1; + // name of the entity + string name = 2; + // id is the unique identifier of the entity + // if id is not set, the system will generate a unique id + uint32 id = 3; + // readonly. create_revision is the revision of last creation on this key. + int64 create_revision = 4; + // readonly. mod_revision is the revision of last modification on this key. + int64 mod_revision = 5; +} + +// IntervalRule is a structured duration +message IntervalRule { + enum Unit { + UNIT_UNSPECIFIED = 0; + UNIT_HOUR = 1; + UNIT_DAY = 2; + } + // unit can only be UNIT_HOUR or UNIT_DAY + Unit unit = 1 [(validate.rules).enum.defined_only = true]; + uint32 num = 2 [(validate.rules).uint32.gt = 0]; +} + +message LifecycleStage { + // The stage name (e.g., "warm", "cold"). + // This should be a non-empty string. + string name = 1 [(validate.rules).string.min_len = 1]; + + // Number of shards allocated for this stage. + // Must be greater than zero. + uint32 shard_num = 2 [(validate.rules).uint32.gt = 0]; + + // Defines the interval for data segmentation in this stage. + // This is a required field and uses the IntervalRule structure. + IntervalRule segment_interval = 3 [(validate.rules).message.required = true]; + + // Specifies the time-to-live for data in this stage before moving to the next. + // This is also a required field using the IntervalRule structure. + IntervalRule ttl = 4 [(validate.rules).message.required = true]; + + // Node selector specifying target nodes for this stage. + // Optional; if provided, it must be a non-empty string. + string node_selector = 5 [(validate.rules).string.min_len = 1]; + + // Indicates whether segments that are no longer live should be closed. + bool close = 6; + + // replicas is the number of replicas for this stage. + // This is an optional field and defaults to 0. + // A value of 0 means no replicas, while a value of 1 means one primary shard and one replica. + // Higher values indicate more replicas. + uint32 replicas = 7; +} + +message ResourceOpts { + // shard_num is the number of shards + uint32 shard_num = 1 [(validate.rules).uint32.gt = 0]; + // segment_interval indicates the length of a segment + IntervalRule segment_interval = 2; + // ttl indicates time to live, how long the data will be cached + IntervalRule ttl = 3; + // stages defines the ordered lifecycle stages. Data progresses through these stages sequentially. + repeated LifecycleStage stages = 4; + // default_stages is the name of the default stage + repeated string default_stages = 5; + // replicas is the number of replicas. This is used to ensure high availability and fault tolerance. + // This is an optional field and defaults to 0. + // A value of 0 means no replicas, while a value of 1 means one primary shard and one replica. + // Higher values indicate more replicas. + uint32 replicas = 6; +} + +// Group is an internal object for Group management +message Group { + // metadata define the group's identity + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // catalog denotes which type of data the group contains + common.v1.Catalog catalog = 2; + // resourceOpts indicates the structure of the underlying kv storage + ResourceOpts resource_opts = 3; + // updated_at indicates when resources of the group are updated + google.protobuf.Timestamp updated_at = 4; +} + +// APIVersion is the version of the API +message APIVersion { + // version is the version of the API + string version = 1; + // revision is the commit hash of the API + string revision = 2; +} + +// GetAPIVersionRequest is the request for GetAPIVersion +message GetAPIVersionRequest { + // empty +} + +// GetAPIVersionResponse is the response for GetAPIVersion +message GetAPIVersionResponse { + // version is the version of the API + APIVersion version = 1; +} + +// Service is the service for the API +service Service { + // GetAPIVersion returns the version of the API + rpc GetAPIVersion(GetAPIVersionRequest) returns (GetAPIVersionResponse); +} + +// Trace is the top level message of a trace. +message Trace { + // trace_id is the unique identifier of the trace. + string trace_id = 1; + // spans is a list of spans in the trace. + repeated Span spans = 2; + // error indicates whether the trace is an error trace. + bool error = 3; +} + +// Span is the basic unit of a trace. +message Span { + // start_time is the start time of the span. + google.protobuf.Timestamp start_time = 1; + // end_time is the end time of the span. + google.protobuf.Timestamp end_time = 2; + // error indicates whether the span is an error span. + bool error = 3; + // tags is a list of tags of the span. + repeated Tag tags = 4; + // message is the message generated by the span. + string message = 5; + // children is a list of child spans of the span. + repeated Span children = 6; + // duration is the duration of the span. + int64 duration = 7; +} + +// Tag is the key-value pair of a span. +message Tag { + // key is the key of the tag. + string key = 1; + // value is the value of the tag. + string value = 2; +} diff --git a/proto/banyandb/v1/banyandb-database.proto b/proto/banyandb/v1/banyandb-database.proto new file mode 100644 index 0000000..bd8242a --- /dev/null +++ b/proto/banyandb/v1/banyandb-database.proto @@ -0,0 +1,742 @@ +// Licensed to Apache Software Foundation (ASF) under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Apache Software Foundation (ASF) licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +syntax = "proto3"; + +option java_package = "org.apache.skywalking.banyandb.database.v1"; + +package banyandb.database.v1; + +import "google/protobuf/timestamp.proto"; +import "validate/validate.proto"; +import "banyandb/v1/banyandb-common.proto"; +import "banyandb/v1/banyandb-model.proto"; + +enum TagType { + TAG_TYPE_UNSPECIFIED = 0; + TAG_TYPE_STRING = 1; + TAG_TYPE_INT = 2; + TAG_TYPE_STRING_ARRAY = 3; + TAG_TYPE_INT_ARRAY = 4; + TAG_TYPE_DATA_BINARY = 5; + TAG_TYPE_TIMESTAMP = 6; +} + +message TagFamilySpec { + string name = 1 [(validate.rules).string.min_len = 1]; + // tags defines accepted tags + repeated TagSpec tags = 2 [(validate.rules).repeated.min_items = 1]; +} + +message TagSpec { + string name = 1 [(validate.rules).string.min_len = 1]; + TagType type = 2 [(validate.rules).enum.defined_only = true]; +} + +// Stream intends to store streaming data, for example, traces or logs +message Stream { + // metadata is the identity of a trace series + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // tag_families + repeated TagFamilySpec tag_families = 2 [(validate.rules).repeated.min_items = 1]; + // entity indicates how to generate a series and shard a stream + Entity entity = 3 [(validate.rules).message.required = true]; + // updated_at indicates when the stream is updated + google.protobuf.Timestamp updated_at = 4; +} + +message Entity { + repeated string tag_names = 1 [(validate.rules).repeated.min_items = 1]; +} + +message ShardingKey { + repeated string tag_names = 1 [(validate.rules).repeated.min_items = 1]; +} + +enum FieldType { + FIELD_TYPE_UNSPECIFIED = 0; + FIELD_TYPE_STRING = 1; + FIELD_TYPE_INT = 2; + FIELD_TYPE_DATA_BINARY = 3; + FIELD_TYPE_FLOAT = 4; +} + +enum EncodingMethod { + ENCODING_METHOD_UNSPECIFIED = 0; + ENCODING_METHOD_GORILLA = 1; +} + +enum CompressionMethod { + COMPRESSION_METHOD_UNSPECIFIED = 0; + COMPRESSION_METHOD_ZSTD = 1; +} + +// FieldSpec is the specification of field +message FieldSpec { + // name is the identity of a field + string name = 1 [(validate.rules).string.min_len = 1]; + // field_type denotes the type of field value + FieldType field_type = 2 [(validate.rules).enum.defined_only = true]; + // encoding_method indicates how to encode data during writing + EncodingMethod encoding_method = 3 [(validate.rules).enum.defined_only = true]; + // compression_method indicates how to compress data during writing + CompressionMethod compression_method = 4 [(validate.rules).enum.defined_only = true]; +} + +// Measure intends to store data point +message Measure { + // metadata is the identity of a measure + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // tag_families are for filter measures + repeated TagFamilySpec tag_families = 2 [(validate.rules).repeated.min_items = 1]; + // fields denote measure values + repeated FieldSpec fields = 3; + // entity indicates which tags will be to generate a series and shard a measure + Entity entity = 4 [(validate.rules).message.required = true]; + // interval indicates how frequently to send a data point + // valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h", "d". + string interval = 5; + // updated_at indicates when the measure is updated + google.protobuf.Timestamp updated_at = 6; + // index_mode specifies whether the data should be stored exclusively in the index, + // meaning it will not be stored in the data storage system. + bool index_mode = 7; + // sharding_key determines the distribution of TopN-related data. + ShardingKey sharding_key = 8; +} + +// TopNAggregation generates offline TopN statistics for a measure's TopN approximation +message TopNAggregation { + // metadata is the identity of an aggregation + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // source_measure denotes the data source of this aggregation + common.v1.Metadata source_measure = 2 [(validate.rules).message.required = true]; + // field_name is the name of field used for ranking + string field_name = 3 [(validate.rules).string.min_len = 1]; + // field_value_sort indicates how to sort fields + // ASC: bottomN + // DESC: topN + // UNSPECIFIED: topN + bottomN + // todo validate plugin exist bug https://github.com/bufbuild/protoc-gen-validate/issues/672 + model.v1.Sort field_value_sort = 4; + // group_by_tag_names groups data points into statistical counters + repeated string group_by_tag_names = 5; + // criteria select partial data points from measure + model.v1.Criteria criteria = 6; + // counters_number sets the number of counters to be tracked. The default value is 1000 + int32 counters_number = 7; + // lru_size defines how much entry is allowed to be maintained in the memory + int32 lru_size = 8; + // updated_at indicates when the measure is updated + google.protobuf.Timestamp updated_at = 9; +} + +// IndexRule defines how to generate indices based on tags and the index type +// IndexRule should bind to a subject through an IndexRuleBinding to generate proper indices. +message IndexRule { + // metadata define the rule's identity + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // tags are the combination that refers to an indexed object + // If the elements in tags are more than 1, the object will generate a multi-tag index + // Caveat: All tags in a multi-tag MUST have an identical IndexType + repeated string tags = 2 [(validate.rules).repeated.min_items = 1]; + // Type determine the index structure under the hood + enum Type { + TYPE_UNSPECIFIED = 0; + TYPE_INVERTED = 1; + TYPE_SKIPPING = 2; + // TYPE_TREE is a tree index, which is used for storing hierarchical data. + TYPE_TREE = 3; + } + // type is the IndexType of this IndexObject. + Type type = 3 [(validate.rules).enum.defined_only = true]; + // updated_at indicates when the IndexRule is updated + google.protobuf.Timestamp updated_at = 4; + + // analyzer analyzes tag value to support the full-text searching for TYPE_INVERTED indices. + // available analyzers are: + // - "standard" provides grammar based tokenization + // - "simple" breaks text into tokens at any non-letter character, + // such as numbers, spaces, hyphens and apostrophes, discards non-letter characters, + // and changes uppercase to lowercase. + // - "keyword" is a “noop” analyzer which returns the entire input string as a single token. + // - "url" breaks test into tokens at any non-letter and non-digit character. + string analyzer = 5; + // no_sort indicates whether the index is not for sorting. + bool no_sort = 6; +} + +// Subject defines which stream or measure would generate indices +message Subject { + // catalog is where the subject belongs to + // todo validate plugin exist bug https://github.com/bufbuild/protoc-gen-validate/issues/672 + common.v1.Catalog catalog = 1; + // name refers to a stream or measure in a particular catalog + string name = 2 [(validate.rules).string.min_len = 1]; +} + +// IndexRuleBinding is a bridge to connect severalIndexRules to a subject +// This binding is valid between begin_at_nanoseconds and expire_at_nanoseconds, that provides flexible strategies +// to control how to generate time series indices. +message IndexRuleBinding { + // metadata is the identity of this binding + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // rules refers to the IndexRule + repeated string rules = 2 [(validate.rules).repeated.min_items = 1]; + // subject indicates the subject of binding action + Subject subject = 3 [(validate.rules).message.required = true]; + // begin_at_nanoseconds is the timestamp, after which the binding will be active + google.protobuf.Timestamp begin_at = 4 [(validate.rules).timestamp.required = true]; + // expire_at_nanoseconds it the timestamp, after which the binding will be inactive + // expire_at_nanoseconds must be larger than begin_at_nanoseconds + google.protobuf.Timestamp expire_at = 5 [(validate.rules).timestamp.required = true]; + // updated_at indicates when the IndexRuleBinding is updated + google.protobuf.Timestamp updated_at = 6; +} + +// Property stores the user defined data +message Property { + // metadata is the identity of a property + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // tag stores the content of a property + repeated TagSpec tags = 2 [(validate.rules).repeated.min_items = 1]; + // updated_at indicates when the property is updated + google.protobuf.Timestamp updated_at = 6; +} + +// TraceTagSpec defines the specification of a tag in a trace. +message TraceTagSpec { + // name is the name of the tag. + string name = 1 [(validate.rules).string.min_len = 1]; + // type is the type of the tag. + TagType type = 2 [(validate.rules).enum.defined_only = true]; +} + +// Trace defines a tracing-specific storage resource. +// It is suitable for storing traces and spans. +// The name of a Trace is a logical namespace within a group, +// while the group of a Trace corresponds to a physical directory. +message Trace { + // metadata is the identity of the trace resource. + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // tags are the specification of tags. + repeated TraceTagSpec tags = 2 [(validate.rules).repeated.min_items = 1]; + // trace_id_tag_name is the name of the tag that stores the trace ID. + string trace_id_tag_name = 3 [(validate.rules).string.min_len = 1]; + // timestamp_tag_name is the name of the tag that stores the timestamp. + string timestamp_tag_name = 4 [(validate.rules).string.min_len = 1]; + // updated_at indicates when the trace resource is updated. + google.protobuf.Timestamp updated_at = 5; + // span_id_tag_name is the name of the tag that stores the span ID. + string span_id_tag_name = 6 [(validate.rules).string.min_len = 1]; +} + +message StreamRegistryServiceCreateRequest { + banyandb.database.v1.Stream stream = 1; +} + +message StreamRegistryServiceCreateResponse { + int64 mod_revision = 1; +} + +message StreamRegistryServiceUpdateRequest { + banyandb.database.v1.Stream stream = 1; +} + +message StreamRegistryServiceUpdateResponse { + int64 mod_revision = 1; +} + +message StreamRegistryServiceDeleteRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message StreamRegistryServiceDeleteResponse { + bool deleted = 1; +} + +message StreamRegistryServiceGetRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message StreamRegistryServiceGetResponse { + banyandb.database.v1.Stream stream = 1; +} + +message StreamRegistryServiceExistRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message StreamRegistryServiceExistResponse { + bool has_group = 1; + bool has_stream = 2; +} + +message StreamRegistryServiceListRequest { + string group = 1; +} + +message StreamRegistryServiceListResponse { + repeated banyandb.database.v1.Stream stream = 1; +} + +service StreamRegistryService { + rpc Create(StreamRegistryServiceCreateRequest) returns (StreamRegistryServiceCreateResponse); + rpc Update(StreamRegistryServiceUpdateRequest) returns (StreamRegistryServiceUpdateResponse); + rpc Delete(StreamRegistryServiceDeleteRequest) returns (StreamRegistryServiceDeleteResponse); + + rpc Get(StreamRegistryServiceGetRequest) returns (StreamRegistryServiceGetResponse); + + rpc List(StreamRegistryServiceListRequest) returns (StreamRegistryServiceListResponse); + + // Exist doesn't expose an HTTP endpoint. Please use HEAD method to touch Get instead + rpc Exist(StreamRegistryServiceExistRequest) returns (StreamRegistryServiceExistResponse); +} + +message IndexRuleBindingRegistryServiceCreateRequest { + banyandb.database.v1.IndexRuleBinding index_rule_binding = 1; +} + +message IndexRuleBindingRegistryServiceCreateResponse {} + +message IndexRuleBindingRegistryServiceUpdateRequest { + banyandb.database.v1.IndexRuleBinding index_rule_binding = 1; +} + +message IndexRuleBindingRegistryServiceUpdateResponse {} + +message IndexRuleBindingRegistryServiceDeleteRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message IndexRuleBindingRegistryServiceDeleteResponse { + bool deleted = 1; +} + +message IndexRuleBindingRegistryServiceGetRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message IndexRuleBindingRegistryServiceGetResponse { + banyandb.database.v1.IndexRuleBinding index_rule_binding = 1; +} + +message IndexRuleBindingRegistryServiceListRequest { + string group = 1; +} + +message IndexRuleBindingRegistryServiceListResponse { + repeated banyandb.database.v1.IndexRuleBinding index_rule_binding = 1; +} + +message IndexRuleBindingRegistryServiceExistRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message IndexRuleBindingRegistryServiceExistResponse { + bool has_group = 1; + bool has_index_rule_binding = 2; +} + +service IndexRuleBindingRegistryService { + rpc Create(IndexRuleBindingRegistryServiceCreateRequest) returns (IndexRuleBindingRegistryServiceCreateResponse); + rpc Update(IndexRuleBindingRegistryServiceUpdateRequest) returns (IndexRuleBindingRegistryServiceUpdateResponse); + rpc Delete(IndexRuleBindingRegistryServiceDeleteRequest) returns (IndexRuleBindingRegistryServiceDeleteResponse); + + rpc Get(IndexRuleBindingRegistryServiceGetRequest) returns (IndexRuleBindingRegistryServiceGetResponse); + + rpc List(IndexRuleBindingRegistryServiceListRequest) returns (IndexRuleBindingRegistryServiceListResponse); + + // Exist doesn't expose an HTTP endpoint. Please use HEAD method to touch Get instead + rpc Exist(IndexRuleBindingRegistryServiceExistRequest) returns (IndexRuleBindingRegistryServiceExistResponse); +} + +message IndexRuleRegistryServiceCreateRequest { + banyandb.database.v1.IndexRule index_rule = 1; +} + +message IndexRuleRegistryServiceCreateResponse {} + +message IndexRuleRegistryServiceUpdateRequest { + banyandb.database.v1.IndexRule index_rule = 1; +} + +message IndexRuleRegistryServiceUpdateResponse {} + +message IndexRuleRegistryServiceDeleteRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message IndexRuleRegistryServiceDeleteResponse { + bool deleted = 1; +} + +message IndexRuleRegistryServiceGetRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message IndexRuleRegistryServiceGetResponse { + banyandb.database.v1.IndexRule index_rule = 1; +} + +message IndexRuleRegistryServiceListRequest { + string group = 1; +} + +message IndexRuleRegistryServiceListResponse { + repeated banyandb.database.v1.IndexRule index_rule = 1; +} + +message IndexRuleRegistryServiceExistRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message IndexRuleRegistryServiceExistResponse { + bool has_group = 1; + bool has_index_rule = 2; +} + +service IndexRuleRegistryService { + rpc Create(IndexRuleRegistryServiceCreateRequest) returns (IndexRuleRegistryServiceCreateResponse); + rpc Update(IndexRuleRegistryServiceUpdateRequest) returns (IndexRuleRegistryServiceUpdateResponse); + rpc Delete(IndexRuleRegistryServiceDeleteRequest) returns (IndexRuleRegistryServiceDeleteResponse); + + rpc Get(IndexRuleRegistryServiceGetRequest) returns (IndexRuleRegistryServiceGetResponse); + + rpc List(IndexRuleRegistryServiceListRequest) returns (IndexRuleRegistryServiceListResponse); + + // Exist doesn't expose an HTTP endpoint. Please use HEAD method to touch Get instead + rpc Exist(IndexRuleRegistryServiceExistRequest) returns (IndexRuleRegistryServiceExistResponse); +} + +message MeasureRegistryServiceCreateRequest { + banyandb.database.v1.Measure measure = 1; +} + +message MeasureRegistryServiceCreateResponse { + int64 mod_revision = 1; +} + +message MeasureRegistryServiceUpdateRequest { + banyandb.database.v1.Measure measure = 1; +} + +message MeasureRegistryServiceUpdateResponse { + int64 mod_revision = 1; +} + +message MeasureRegistryServiceDeleteRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message MeasureRegistryServiceDeleteResponse { + bool deleted = 1; +} + +message MeasureRegistryServiceGetRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message MeasureRegistryServiceGetResponse { + banyandb.database.v1.Measure measure = 1; +} + +message MeasureRegistryServiceListRequest { + string group = 1; +} + +message MeasureRegistryServiceListResponse { + repeated banyandb.database.v1.Measure measure = 1; +} + +message MeasureRegistryServiceExistRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message MeasureRegistryServiceExistResponse { + bool has_group = 1; + bool has_measure = 2; +} + +service MeasureRegistryService { + rpc Create(MeasureRegistryServiceCreateRequest) returns (MeasureRegistryServiceCreateResponse); + rpc Update(MeasureRegistryServiceUpdateRequest) returns (MeasureRegistryServiceUpdateResponse); + rpc Delete(MeasureRegistryServiceDeleteRequest) returns (MeasureRegistryServiceDeleteResponse); + + rpc Get(MeasureRegistryServiceGetRequest) returns (MeasureRegistryServiceGetResponse); + + rpc List(MeasureRegistryServiceListRequest) returns (MeasureRegistryServiceListResponse); + + // Exist doesn't expose an HTTP endpoint. Please use HEAD method to touch Get instead + rpc Exist(MeasureRegistryServiceExistRequest) returns (MeasureRegistryServiceExistResponse); +} + +message GroupRegistryServiceCreateRequest { + banyandb.common.v1.Group group = 1; +} + +message GroupRegistryServiceCreateResponse {} + +message GroupRegistryServiceUpdateRequest { + banyandb.common.v1.Group group = 1; +} + +message GroupRegistryServiceUpdateResponse {} + +message GroupRegistryServiceDeleteRequest { + string group = 1; +} + +message GroupRegistryServiceDeleteResponse { + bool deleted = 1; +} + +message GroupRegistryServiceGetRequest { + string group = 1; +} + +message GroupRegistryServiceGetResponse { + banyandb.common.v1.Group group = 1; +} + +message GroupRegistryServiceListRequest {} + +message GroupRegistryServiceListResponse { + repeated banyandb.common.v1.Group group = 1; +} + +message GroupRegistryServiceExistRequest { + string group = 1; +} + +message GroupRegistryServiceExistResponse { + bool has_group = 1; +} + +service GroupRegistryService { + rpc Create(GroupRegistryServiceCreateRequest) returns (GroupRegistryServiceCreateResponse); + rpc Update(GroupRegistryServiceUpdateRequest) returns (GroupRegistryServiceUpdateResponse); + rpc Delete(GroupRegistryServiceDeleteRequest) returns (GroupRegistryServiceDeleteResponse); + + rpc Get(GroupRegistryServiceGetRequest) returns (GroupRegistryServiceGetResponse); + + rpc List(GroupRegistryServiceListRequest) returns (GroupRegistryServiceListResponse); + + // Exist doesn't expose an HTTP endpoint. Please use HEAD method to touch Get instead + rpc Exist(GroupRegistryServiceExistRequest) returns (GroupRegistryServiceExistResponse); +} + +message TopNAggregationRegistryServiceCreateRequest { + banyandb.database.v1.TopNAggregation top_n_aggregation = 1; +} + +message TopNAggregationRegistryServiceCreateResponse {} + +message TopNAggregationRegistryServiceUpdateRequest { + banyandb.database.v1.TopNAggregation top_n_aggregation = 1; +} + +message TopNAggregationRegistryServiceUpdateResponse {} + +message TopNAggregationRegistryServiceDeleteRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message TopNAggregationRegistryServiceDeleteResponse { + bool deleted = 1; +} + +message TopNAggregationRegistryServiceGetRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message TopNAggregationRegistryServiceGetResponse { + banyandb.database.v1.TopNAggregation top_n_aggregation = 1; +} + +message TopNAggregationRegistryServiceListRequest { + string group = 1; +} + +message TopNAggregationRegistryServiceListResponse { + repeated banyandb.database.v1.TopNAggregation top_n_aggregation = 1; +} + +message TopNAggregationRegistryServiceExistRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message TopNAggregationRegistryServiceExistResponse { + bool has_group = 1; + bool has_top_n_aggregation = 2; +} + +service TopNAggregationRegistryService { + rpc Create(TopNAggregationRegistryServiceCreateRequest) returns (TopNAggregationRegistryServiceCreateResponse); + rpc Update(TopNAggregationRegistryServiceUpdateRequest) returns (TopNAggregationRegistryServiceUpdateResponse); + rpc Delete(TopNAggregationRegistryServiceDeleteRequest) returns (TopNAggregationRegistryServiceDeleteResponse); + rpc Get(TopNAggregationRegistryServiceGetRequest) returns (TopNAggregationRegistryServiceGetResponse); + rpc List(TopNAggregationRegistryServiceListRequest) returns (TopNAggregationRegistryServiceListResponse); + // Exist doesn't expose an HTTP endpoint. Please use HEAD method to touch Get instead + rpc Exist(TopNAggregationRegistryServiceExistRequest) returns (TopNAggregationRegistryServiceExistResponse); +} + +message SnapshotRequest { + message Group { + common.v1.Catalog catalog = 1; + string group = 2; + } + repeated Group groups = 1; +} + +message Snapshot { + common.v1.Catalog catalog = 1; + string name = 2; + string error = 3; +} + +message SnapshotResponse { + repeated Snapshot snapshots = 1; +} + +service SnapshotService { + rpc Snapshot(SnapshotRequest) returns (SnapshotResponse); +} + +message PropertyRegistryServiceCreateRequest { + banyandb.database.v1.Property property = 1; +} + +message PropertyRegistryServiceCreateResponse { + int64 mod_revision = 1; +} + +message PropertyRegistryServiceUpdateRequest { + banyandb.database.v1.Property property = 1; +} + +message PropertyRegistryServiceUpdateResponse { + int64 mod_revision = 1; +} + +message PropertyRegistryServiceDeleteRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message PropertyRegistryServiceDeleteResponse { + bool deleted = 1; +} + +message PropertyRegistryServiceGetRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message PropertyRegistryServiceGetResponse { + banyandb.database.v1.Property property = 1; +} + +message PropertyRegistryServiceListRequest { + string group = 1; +} + +message PropertyRegistryServiceListResponse { + repeated banyandb.database.v1.Property properties = 1; +} + +message PropertyRegistryServiceExistRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message PropertyRegistryServiceExistResponse { + bool has_group = 1; + bool has_property = 2; +} + +service PropertyRegistryService { + rpc Create(PropertyRegistryServiceCreateRequest) returns (PropertyRegistryServiceCreateResponse); + rpc Update(PropertyRegistryServiceUpdateRequest) returns (PropertyRegistryServiceUpdateResponse); + rpc Delete(PropertyRegistryServiceDeleteRequest) returns (PropertyRegistryServiceDeleteResponse); + + rpc Get(PropertyRegistryServiceGetRequest) returns (PropertyRegistryServiceGetResponse); + + rpc List(PropertyRegistryServiceListRequest) returns (PropertyRegistryServiceListResponse); + + // Exist doesn't expose an HTTP endpoint. Please use HEAD method to touch Get instead + rpc Exist(PropertyRegistryServiceExistRequest) returns (PropertyRegistryServiceExistResponse); +} + +message TraceRegistryServiceCreateRequest { + banyandb.database.v1.Trace trace = 1; +} + +message TraceRegistryServiceCreateResponse { + int64 mod_revision = 1; +} + +message TraceRegistryServiceUpdateRequest { + banyandb.database.v1.Trace trace = 1; +} + +message TraceRegistryServiceUpdateResponse { + int64 mod_revision = 1; +} + +message TraceRegistryServiceDeleteRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message TraceRegistryServiceDeleteResponse { + bool deleted = 1; +} + +message TraceRegistryServiceGetRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message TraceRegistryServiceGetResponse { + banyandb.database.v1.Trace trace = 1; +} + +message TraceRegistryServiceExistRequest { + banyandb.common.v1.Metadata metadata = 1; +} + +message TraceRegistryServiceExistResponse { + bool has_group = 1; + bool has_trace = 2; +} + +message TraceRegistryServiceListRequest { + string group = 1; +} + +message TraceRegistryServiceListResponse { + repeated banyandb.database.v1.Trace trace = 1; +} + +service TraceRegistryService { + rpc Create(TraceRegistryServiceCreateRequest) returns (TraceRegistryServiceCreateResponse); + rpc Update(TraceRegistryServiceUpdateRequest) returns (TraceRegistryServiceUpdateResponse); + rpc Delete(TraceRegistryServiceDeleteRequest) returns (TraceRegistryServiceDeleteResponse); + + rpc Get(TraceRegistryServiceGetRequest) returns (TraceRegistryServiceGetResponse); + + rpc List(TraceRegistryServiceListRequest) returns (TraceRegistryServiceListResponse); + + // Exist doesn't expose an HTTP endpoint. Please use HEAD method to touch Get instead + rpc Exist(TraceRegistryServiceExistRequest) returns (TraceRegistryServiceExistResponse); +} diff --git a/proto/banyandb/v1/banyandb-measure.proto b/proto/banyandb/v1/banyandb-measure.proto new file mode 100644 index 0000000..f8c4f91 --- /dev/null +++ b/proto/banyandb/v1/banyandb-measure.proto @@ -0,0 +1,219 @@ +// Licensed to Apache Software Foundation (ASF) under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Apache Software Foundation (ASF) licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +syntax = "proto3"; + +option java_package = "org.apache.skywalking.banyandb.measure.v1"; + +package banyandb.measure.v1; + +import "google/protobuf/timestamp.proto"; +import "validate/validate.proto"; +import "banyandb/v1/banyandb-common.proto"; +import "banyandb/v1/banyandb-model.proto"; + +// DataPoint is stored in Measures +message DataPoint { + // timestamp is in the timeunit of milliseconds. + google.protobuf.Timestamp timestamp = 1; + // tag_families contains tags selected in the projection + repeated model.v1.TagFamily tag_families = 2; + message Field { + string name = 1; + model.v1.FieldValue value = 2; + } + // fields contains fields selected in the projection + repeated Field fields = 3; + // sid is the series id of the data point + uint64 sid = 4; + // version is the version of the data point in a series + // sid, timestamp and version are used to identify a data point + int64 version = 5; +} + +// QueryResponse is the response for a query to the Query module. +message QueryResponse { + // data_points are the actual data returned + repeated DataPoint data_points = 1; + // trace contains the trace information of the query when trace is enabled + common.v1.Trace trace = 2; +} + +// QueryRequest is the request contract for query. +message QueryRequest { + // groups indicate where the data points are stored. + repeated string groups = 1 [(validate.rules).repeated.min_items = 1]; + // name is the identity of a measure. + string name = 2 [(validate.rules).string.min_len = 1]; + // time_range is a range query with begin/end time of entities in the timeunit of milliseconds. + model.v1.TimeRange time_range = 3 [(validate.rules).message.required = true]; + // tag_families are indexed. + model.v1.Criteria criteria = 4; + // tag_projection can be used to select tags of the data points in the response + model.v1.TagProjection tag_projection = 5; + message FieldProjection { + repeated string names = 1; + } + // field_projection can be used to select fields of the data points in the response + FieldProjection field_projection = 6; + message GroupBy { + // tag_projection must be a subset of the tag_projection of QueryRequest + model.v1.TagProjection tag_projection = 1; + // field_name must be one of fields indicated by field_projection + string field_name = 2; + } + // group_by groups data points based on their field value for a specific tag and use field_name as the projection name + GroupBy group_by = 7; + message Aggregation { + model.v1.AggregationFunction function = 1; + // field_name must be one of files indicated by the field_projection + string field_name = 2; + } + // agg aggregates data points based on a field + Aggregation agg = 8; + message Top { + // number set the how many items should be returned + int32 number = 1; + // field_name must be one of files indicated by the field_projection + string field_name = 2; + // field_value_sort indicates how to sort fields + // ASC: bottomN + // DESC: topN + // UNSPECIFIED: topN + model.v1.Sort field_value_sort = 3; + } + // top limits the result based on a particular field. + // If order_by is specified, top sorts the dataset based on order_by's output + Top top = 9; + // offset is used to support pagination, together with the following limit. + // If top is specified, offset processes the dataset based on top's output + uint32 offset = 10; + // limit is used to impose a boundary on the number of records being returned. + // If top is specified, limit processes the dataset based on top's output + uint32 limit = 11; + // order_by is given to specify the sort for a tag. + model.v1.QueryOrder order_by = 12; + // trace is used to enable trace for the query + bool trace = 13; + // stages is used to specify the stage of the data points in the lifecycle + repeated string stages = 14; + // rewriteAggTopNResult will rewrite agg result to raw data + bool rewrite_agg_top_n_result = 15; +} + + + +service MeasureService { + rpc Query(QueryRequest) returns (QueryResponse); + rpc Write(stream WriteRequest) returns (stream WriteResponse); + rpc TopN(TopNRequest) returns (TopNResponse); +} + +// TopNList contains a series of topN items +message TopNList { + // timestamp is in the timeunit of milliseconds. + google.protobuf.Timestamp timestamp = 1; + message Item { + repeated model.v1.Tag entity = 1; + model.v1.FieldValue value = 2; + } + // items contains top-n items in a list + repeated Item items = 2; +} + +// TopNResponse is the response for a query to the Query module. +message TopNResponse { + // lists contain a series topN lists ranked by timestamp + // if agg_func in query request is specified, lists' size should be one. + repeated TopNList lists = 1; + // trace contains the trace information of the query when trace is enabled + common.v1.Trace trace = 2; +} + +// TopNRequest is the request contract for query. +message TopNRequest { + // groups indicate where the data points are stored. + repeated string groups = 1 [(validate.rules).repeated.min_items = 1]; + // name is the identity of a measure. + string name = 2 [(validate.rules).string.min_len = 1]; + // time_range is a range query with begin/end time of entities in the timeunit of milliseconds. + model.v1.TimeRange time_range = 3 [(validate.rules).message.required = true]; + // top_n set the how many items should be returned in each list. + int32 top_n = 4 [(validate.rules).int32.gt = 0]; + // agg aggregates lists grouped by field names in the time_range + model.v1.AggregationFunction agg = 5; + // criteria select counters. Only equals are acceptable. + repeated model.v1.Condition conditions = 6; + // field_value_sort indicates how to sort fields + model.v1.Sort field_value_sort = 7; + // trace is used to enable trace for the query + bool trace = 8; + // stages is used to specify the stage of the data points in the lifecycle + repeated string stages = 9; +} + +// TagFamilySpec defines the specification of a tag family. +message TagFamilySpec { + // name of the tag family + string name = 1; + // names of tags in the tag family + repeated string tag_names = 2; +} + +// DataPointSpec defines the specification of a data point. +message DataPointSpec { + // the tag family specification + repeated TagFamilySpec tag_family_spec = 1; + // the field names + repeated string field_names = 2; +} + +// DataPointValue is the data point for writing. It only contains values. +message DataPointValue { + // timestamp is in the timeunit of milliseconds. + google.protobuf.Timestamp timestamp = 1 [(validate.rules).timestamp.required = true]; + // the order of tag_families' items match DataPointSpec + repeated model.v1.TagFamilyForWrite tag_families = 2 [(validate.rules).repeated.min_items = 1]; + // the order of fields match DataPointSpec + repeated model.v1.FieldValue fields = 3; + // the version of the data point + int64 version = 4; +} + +// WriteRequest is the request contract for write +message WriteRequest { + // the metadata is required only for the first request of gRPC stream. + common.v1.Metadata metadata = 1; + // the data_point is required. + DataPointValue data_point = 2 [(validate.rules).message.required = true]; + // the message_id is required. + uint64 message_id = 3 [(validate.rules).uint64.gt = 0]; + // the data point specification. + // If this is not set with the indicated metadata, use the schema definition. + // If this is not set, use the existing spec declaration from previous requests in the current gRPC stream. + DataPointSpec data_point_spec = 4; +} + +// WriteResponse is the response contract for write +message WriteResponse { + // the message_id from request. + uint64 message_id = 1 [(validate.rules).uint64.gt = 0]; + // status indicates the request processing result + string status = 2; + // the metadata from request when request fails + common.v1.Metadata metadata = 3; +} diff --git a/proto/banyandb/v1/banyandb-model.proto b/proto/banyandb/v1/banyandb-model.proto new file mode 100644 index 0000000..e6066fc --- /dev/null +++ b/proto/banyandb/v1/banyandb-model.proto @@ -0,0 +1,198 @@ +// Licensed to Apache Software Foundation (ASF) under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Apache Software Foundation (ASF) licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +syntax = "proto3"; + +option java_package = "org.apache.skywalking.banyandb.model.v1"; + +package banyandb.model.v1; + +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; + +message Str { + string value = 1; +} + +message Int { + int64 value = 1; +} + +message Float { + double value = 1; +} + +message StrArray { + repeated string value = 1; +} + +message IntArray { + repeated int64 value = 1; +} + +message TagValue { + oneof value { + google.protobuf.NullValue null = 1; + Str str = 2; + StrArray str_array = 3; + Int int = 4; + IntArray int_array = 5; + bytes binary_data = 6; + google.protobuf.Timestamp timestamp = 7; + } +} + +message TagFamilyForWrite { + repeated TagValue tags = 1; +} + +message FieldValue { + oneof value { + google.protobuf.NullValue null = 1; + model.v1.Str str = 2; + model.v1.Int int = 3; + bytes binary_data = 4; + model.v1.Float float = 5; + } +} + +enum AggregationFunction { + AGGREGATION_FUNCTION_UNSPECIFIED = 0; + AGGREGATION_FUNCTION_MEAN = 1; + AGGREGATION_FUNCTION_MAX = 2; + AGGREGATION_FUNCTION_MIN = 3; + AGGREGATION_FUNCTION_COUNT = 4; + AGGREGATION_FUNCTION_SUM = 5; +} + +// Pair is the building block of a record which is equivalent to a key-value pair. +// In the context of Trace, it could be metadata of a trace such as service_name, service_instance, etc. +// Besides, other tags are organized in key-value pair in the underlying storage layer. +// One should notice that the values can be a multi-value. +message Tag { + string key = 1; + TagValue value = 2; +} + +message TagFamily { + string name = 1; + repeated Tag tags = 2; +} + +// Condition consists of the query condition with a single binary operator to be imposed +// For 1:1 BinaryOp, values in condition must be an array with length = 1, +// while for 1:N BinaryOp, values can be an array with length >= 1. +message Condition { + // BinaryOp specifies the operation imposed to the given query condition + // For EQ, NE, LT, GT, LE and GE, only one operand should be given, i.e. one-to-one relationship. + // HAVING and NOT_HAVING allow multi-value to be the operand such as array/vector, i.e. one-to-many relationship. + // For example, "keyA" contains "valueA" **and** "valueB" + // MATCH performances a full-text search if the tag is analyzed. + // The string value applies to the same analyzer as the tag, but string array value does not. + // Each item in a string array is seen as a token instead of a query expression. + enum BinaryOp { + BINARY_OP_UNSPECIFIED = 0; + BINARY_OP_EQ = 1; + BINARY_OP_NE = 2; + BINARY_OP_LT = 3; + BINARY_OP_GT = 4; + BINARY_OP_LE = 5; + BINARY_OP_GE = 6; + BINARY_OP_HAVING = 7; + BINARY_OP_NOT_HAVING = 8; + BINARY_OP_IN = 9; + BINARY_OP_NOT_IN = 10; + BINARY_OP_MATCH = 11; + } + string name = 1; + BinaryOp op = 2; + TagValue value = 3; + message MatchOption { + string analyzer = 1; + enum Operator { + OPERATOR_UNSPECIFIED = 0; + OPERATOR_AND = 1; + OPERATOR_OR = 2; + } + Operator operator = 2; + } + MatchOption match_option = 4; +} + +// tag_families are indexed. +message Criteria { + oneof exp { + LogicalExpression le = 1; + Condition condition = 2; + } +} + +// LogicalExpression supports logical operation +message LogicalExpression { + enum LogicalOp { + LOGICAL_OP_UNSPECIFIED = 0; + LOGICAL_OP_AND = 1; + LOGICAL_OP_OR = 2; + } + // op is a logical operation + LogicalOp op = 1; + Criteria left = 2; + Criteria right = 3; +} + +enum Sort { + SORT_UNSPECIFIED = 0; + SORT_DESC = 1; + SORT_ASC = 2; +} + +// QueryOrder means a Sort operation to be done for a given index rule. +// The index_rule_name refers to the name of a index rule bound to the subject. +message QueryOrder { + string index_rule_name = 1; + Sort sort = 2; +} + +// TagProjection is used to select the names of keys to be returned. +message TagProjection { + message TagFamily { + string name = 1; + repeated string tags = 2; + } + repeated TagFamily tag_families = 1; +} + +// TimeRange is a range query for uint64, +// the range here follows left-inclusive and right-exclusive rule, i.e. [begin, end) if both edges exist +message TimeRange { + google.protobuf.Timestamp begin = 1; + google.protobuf.Timestamp end = 2; +} + +// Status is the response status for write +enum Status { + STATUS_UNSPECIFIED = 0; + STATUS_SUCCEED = 1; + STATUS_INVALID_TIMESTAMP = 2; + STATUS_NOT_FOUND = 3; + STATUS_EXPIRED_SCHEMA = 4; + STATUS_INTERNAL_ERROR = 5; + STATUS_DISK_FULL = 6; + STATUS_VERSION_UNSUPPORTED = 7; // Client version not supported + STATUS_VERSION_DEPRECATED = 8; // Client version deprecated but still supported + STATUS_METADATA_REQUIRED = 9; // Metadata is required for the first request +} diff --git a/proto/banyandb/v1/banyandb-property.proto b/proto/banyandb/v1/banyandb-property.proto new file mode 100644 index 0000000..b602ef5 --- /dev/null +++ b/proto/banyandb/v1/banyandb-property.proto @@ -0,0 +1,112 @@ +// Licensed to Apache Software Foundation (ASF) under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Apache Software Foundation (ASF) licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +syntax = "proto3"; + +option java_package = "org.apache.skywalking.banyandb.property.v1"; + +package banyandb.property.v1; + +import "google/protobuf/timestamp.proto"; +import "validate/validate.proto"; +import "banyandb/v1/banyandb-common.proto"; +import "banyandb/v1/banyandb-model.proto"; + +// Property stores the user defined data +message Property { + // metadata is the identity of a property + common.v1.Metadata metadata = 1 [(validate.rules).message.required = true]; + // id is the identity of a property + string id = 2 [(validate.rules).string.min_len = 1]; + // tag stores the content of a property + repeated model.v1.Tag tags = 3 [(validate.rules).repeated.min_items = 1]; + // updated_at indicates when the property is updated + google.protobuf.Timestamp updated_at = 4; +} + +message ApplyRequest { + banyandb.property.v1.Property property = 1 [(validate.rules).message.required = true]; + enum Strategy { + STRATEGY_UNSPECIFIED = 0; + STRATEGY_MERGE = 1; + STRATEGY_REPLACE = 2; + } + // strategy indicates how to update a property. It defaults to STRATEGY_MERGE + Strategy strategy = 2; +} + +message ApplyResponse { + // created indicates whether the property existed. + // True: the property is absent. False: the property existed. + bool created = 1; + uint32 tags_num = 2; +} + +message DeleteRequest { + // groups indicate where the data points are stored. + string group = 1 [(validate.rules).string.min_len = 1]; + // name is the identity of a property. + string name = 2 [(validate.rules).string.min_len = 1]; + // id is the identity of item in the property. + string id = 3; +} + +message DeleteResponse { + bool deleted = 1; +} + +message QueryOrder { + // tag_name is the name of the tag to be ordered. + string tag_name = 1; + // order_by is given to specify the sort for a tag. + model.v1.Sort sort = 12; +} + +// QueryRequest is the request contract for query. +message QueryRequest { + // groups indicate where the data points are stored. + repeated string groups = 1 [(validate.rules).repeated.min_items = 1]; + // name is created when it receives the first property + string name = 2; + // ids is the identities of properties + repeated string ids = 3; + // criteria is used to filter properties based on tags + model.v1.Criteria criteria = 4; + // tag_projection can be used to select tags of the data points in the response + repeated string tag_projection = 5; + uint32 limit = 6; + // trace is used to enable trace for the query + bool trace = 7; + // order_by is given to specify the sort for a tag. + QueryOrder order_by = 8; +} + +// QueryResponse is the response for a query to the Query module. +message QueryResponse { + // properties are the actual data returned + repeated banyandb.property.v1.Property properties = 1; + // trace contains the trace information of the query when trace is enabled + common.v1.Trace trace = 2; +} + +service PropertyService { + // Apply creates a property if it's absent, or update a existed one based on a strategy. + rpc Apply(ApplyRequest) returns (ApplyResponse); + rpc Delete(DeleteRequest) returns (DeleteResponse); + + rpc Query(QueryRequest) returns (QueryResponse); +} diff --git a/proto/banyandb/v1/banyandb-stream.proto b/proto/banyandb/v1/banyandb-stream.proto new file mode 100644 index 0000000..642b189 --- /dev/null +++ b/proto/banyandb/v1/banyandb-stream.proto @@ -0,0 +1,130 @@ +// Licensed to Apache Software Foundation (ASF) under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Apache Software Foundation (ASF) licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +syntax = "proto3"; + +option java_package = "org.apache.skywalking.banyandb.stream.v1"; + +package banyandb.stream.v1; + +import "google/protobuf/timestamp.proto"; +import "validate/validate.proto"; +import "banyandb/v1/banyandb-common.proto"; +import "banyandb/v1/banyandb-model.proto"; + +// Element represents +// (stream context) a Span defined in Google Dapper paper or equivalently a Segment in Skywalking. +// (Log context) a log +message Element { + // element_id could be span_id of a Span or segment_id of a Segment in the context of stream + string element_id = 1; + // timestamp represents a millisecond + // 1) either the start time of a Span/Segment, + // 2) or the timestamp of a log + google.protobuf.Timestamp timestamp = 2; + // fields contains all indexed Field. Some typical names, + // - stream_id + // - duration + // - service_name + // - service_instance_id + // - end_time_milliseconds + repeated model.v1.TagFamily tag_families = 3; +} + +// QueryResponse is the response for a query to the Query module. +message QueryResponse { + // elements are the actual data returned + repeated Element elements = 1; + // trace contains the trace information of the query when trace is enabled + common.v1.Trace trace = 2; +} + +// QueryRequest is the request contract for query. +message QueryRequest { + // groups indicate where the elements are stored. + repeated string groups = 1 [(validate.rules).repeated.min_items = 1]; + // name is the identity of a stream. + string name = 2 [(validate.rules).string.min_len = 1]; + // time_range is a range query with begin/end time of entities in the timeunit of milliseconds. + // In the context of stream, it represents the range of the `startTime` for spans/segments, + // while in the context of Log, it means the range of the timestamp(s) for logs. + // it is always recommended to specify time range for performance reason + model.v1.TimeRange time_range = 3; + // offset is used to support pagination, together with the following limit + uint32 offset = 4; + // limit is used to impose a boundary on the number of records being returned + uint32 limit = 5; + // order_by is given to specify the sort for a field. So far, only fields in the type of Integer are supported + model.v1.QueryOrder order_by = 6; + // tag_families are indexed. + model.v1.Criteria criteria = 7; + // projection can be used to select the key names of the element in the response + model.v1.TagProjection projection = 8 [(validate.rules).message.required = true]; + // trace is used to enable trace for the query + bool trace = 9; + // stage is used to specify the stage of the query in the lifecycle + repeated string stages = 10; +} + + + +service StreamService { + rpc Query(QueryRequest) returns (QueryResponse); + rpc Write(stream WriteRequest) returns (stream WriteResponse); + +} + +// TagFamilySpec defines the specification of a tag family. +message TagFamilySpec { + // name of the tag family + string name = 1; + // names of tags in the tag family + repeated string tag_names = 2; +} + +message ElementValue { + // element_id could be span_id of a Span or segment_id of a Segment in the context of stream + string element_id = 1; + // timestamp is in the timeunit of milliseconds. It represents + // 1) either the start time of a Span/Segment, + // 2) or the timestamp of a log + google.protobuf.Timestamp timestamp = 2; + // the order of tag_families' items match TagFamilySpec + repeated model.v1.TagFamilyForWrite tag_families = 3; +} + +message WriteRequest { + // the metadata is required only for the first request of gRPC stream. + common.v1.Metadata metadata = 1; + // the element is required. + ElementValue element = 2 [(validate.rules).message.required = true]; + // the message_id is required. + uint64 message_id = 3 [(validate.rules).uint64.gt = 0]; + // the tag family specification. + // If this is not set with the indicated metadata, use the schema definition. + // If this is not set, use the existing spec declaration from previous requests in the current gRPC stream. + repeated TagFamilySpec tag_family_spec = 4; +} + +message WriteResponse { + // the message_id from request. + uint64 message_id = 1 [(validate.rules).uint64.gt = 0]; + // status indicates the request processing result + string status = 2; + // the metadata from request when request fails + common.v1.Metadata metadata = 3; +} diff --git a/proto/banyandb/v1/banyandb-trace.proto b/proto/banyandb/v1/banyandb-trace.proto new file mode 100644 index 0000000..b822b59 --- /dev/null +++ b/proto/banyandb/v1/banyandb-trace.proto @@ -0,0 +1,122 @@ +// Licensed to Apache Software Foundation (ASF) under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Apache Software Foundation (ASF) licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +syntax = "proto3"; + +option java_package = "org.apache.skywalking.banyandb.trace.v1"; + +package banyandb.trace.v1; + +import "validate/validate.proto"; +import "banyandb/v1/banyandb-common.proto"; +import "banyandb/v1/banyandb-model.proto"; + +// Span is a single operation within a trace. +message Span { + // tags are the indexed tags of the span. + repeated model.v1.Tag tags = 1; + // span is the raw span data. + bytes span = 2; + // span_id is the unique identifier of the span. + string span_id = 3; +} + +// InternalTrace is the trace that is used for internal use. +message InternalTrace { + // spans are the spans that belong to this trace. + repeated Span spans = 1; + // trace_id is the unique identifier of the trace. + string trace_id = 2; + // key is used for sorting. + int64 key = 3; +} + +// Trace contains all spans that belong to a single trace ID. +message Trace { + // spans is the list of spans that belong to this trace. + repeated Span spans = 1; + // trace_id is the unique identifier of the trace. + string trace_id = 2; +} + +// QueryResponse is the response of a query. +message QueryResponse { + // traces is a list of traces that match the query, with spans grouped by trace ID. + repeated Trace traces = 1; + // trace_query_result contains the trace of the query execution if tracing is enabled. + common.v1.Trace trace_query_result = 2; +} + +// InternalQueryResponse is the response of an internal query. +message InternalQueryResponse { + // internal_traces is a list of internal traces that match the query. + repeated InternalTrace internal_traces = 1; + // trace_query_result contains the trace of the query execution if tracing is enabled. + common.v1.Trace trace_query_result = 2; +} + +// QueryRequest is the request contract for query. +message QueryRequest { + // groups indicates the physical data location. + repeated string groups = 1 [(validate.rules).repeated.min_items = 1]; + // name is the identity of a trace. + string name = 2 [(validate.rules).string.min_len = 1]; + // time_range is a range query with begin/end time of entities in the timeunit of milliseconds. + // In the context of trace, it represents the range of the `startTime` for spans/segments, + // it is always recommended to specify time range for performance reason + model.v1.TimeRange time_range = 3; + // offset is used to support pagination, together with the following limit + uint32 offset = 4; + // limit is used to impose a boundary on the number of spans being returned + uint32 limit = 5; + // order_by is given to specify the sort for a tag. So far, only tags in the type of Integer are supported + model.v1.QueryOrder order_by = 6; + // criteria is the filter criteria. + model.v1.Criteria criteria = 7; + // projection can be used to select the names of the tags in the response + repeated string tag_projection = 8; + // trace is used to enable trace for the query + bool trace = 9; + // stage is used to specify the stage of the query in the lifecycle + repeated string stages = 10; +} + + + +service TraceService { + rpc Query(QueryRequest) returns (QueryResponse); + rpc Write(stream WriteRequest) returns (stream WriteResponse); + +} + +message TagSpec { + repeated string tag_names = 1; +} + +message WriteRequest { + common.v1.Metadata metadata = 1; + repeated model.v1.TagValue tags = 2 [(validate.rules).repeated.min_items = 1]; + bytes span = 3; + uint64 version = 4 [(validate.rules).uint64.gt = 0]; + TagSpec tag_spec = 5; +} + +message WriteResponse { + common.v1.Metadata metadata = 1; + uint64 version = 2; + string status = 3; +}
