banyand/metadata/schema/schema.go (211 lines of code) (raw):

// 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. // Package schema implements CRUD schema. package schema import ( "context" "io" "github.com/pkg/errors" "google.golang.org/protobuf/proto" commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1" databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1" propertyv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/property/v1" ) var errUnsupportedEntityType = errors.New("unsupported entity type") // Kind is the type of a resource. type Kind int // EventHandler allows receiving and handling the resource change events. type EventHandler interface { OnAddOrUpdate(Metadata) OnDelete(Metadata) } // KindMask tends to check whether an event is valid. const ( KindGroup Kind = 1 << iota KindStream KindMeasure KindIndexRuleBinding KindIndexRule KindTopNAggregation KindProperty KindNode KindShard KindMask = KindGroup | KindStream | KindMeasure | KindIndexRuleBinding | KindIndexRule | KindTopNAggregation | KindProperty | KindNode | KindShard ) // ListOpt contains options to list resources. type ListOpt struct { Group string } // Registry allowing depositing resources. type Registry interface { io.Closer Stream IndexRule IndexRuleBinding Measure Group TopNAggregation Property Node Shard RegisterHandler(Kind, EventHandler) } // TypeMeta defines the identity and type of an Event. type TypeMeta struct { Name string Group string Kind Kind } // Metadata wrap dedicated serialized resource and its TypeMeta. type Metadata struct { Spec Spec TypeMeta } // Spec is a placeholder of a serialized resource. type Spec interface{} // Unmarshal encode bytes to proto.Message. func (tm TypeMeta) Unmarshal(data []byte) (m proto.Message, err error) { switch tm.Kind { case KindGroup: m = &commonv1.Group{} case KindStream: m = &databasev1.Stream{} case KindMeasure: m = &databasev1.Measure{} case KindIndexRuleBinding: m = &databasev1.IndexRuleBinding{} case KindIndexRule: m = &databasev1.IndexRule{} case KindProperty: m = &propertyv1.Property{} case KindTopNAggregation: m = &databasev1.TopNAggregation{} case KindNode: m = &databasev1.Node{} case KindShard: m = &databasev1.Shard{} default: return nil, errUnsupportedEntityType } err = proto.Unmarshal(data, m) return } func (m Metadata) key() (string, error) { switch m.Kind { case KindGroup: return formatGroupKey(m.Name), nil case KindMeasure: return formatMeasureKey(&commonv1.Metadata{ Group: m.Group, Name: m.Name, }), nil case KindStream: return formatStreamKey(&commonv1.Metadata{ Group: m.Group, Name: m.Name, }), nil case KindIndexRule: return formatIndexRuleKey(&commonv1.Metadata{ Group: m.Group, Name: m.Name, }), nil case KindIndexRuleBinding: return formatIndexRuleBindingKey(&commonv1.Metadata{ Group: m.Group, Name: m.Name, }), nil case KindProperty: return formatPropertyKey(&commonv1.Metadata{ Group: m.Group, Name: m.Name, }), nil case KindTopNAggregation: return formatTopNAggregationKey(&commonv1.Metadata{ Group: m.Group, Name: m.Name, }), nil case KindNode: r, err := strToRole(m.Group) if err != nil { return "", err } return formatNodeKey(r, m.Name), nil case KindShard: return formatShardKey(&commonv1.Metadata{ Group: m.Group, Name: m.Name, }), nil default: return "", errUnsupportedEntityType } } func (m Metadata) equal(other proto.Message) bool { if other == nil { return false } if checker, ok := checkerMap[m.Kind]; ok { return checker(m.Spec.(proto.Message), other) } return false } // Stream allows CRUD stream schemas in a group. type Stream interface { GetStream(ctx context.Context, metadata *commonv1.Metadata) (*databasev1.Stream, error) ListStream(ctx context.Context, opt ListOpt) ([]*databasev1.Stream, error) CreateStream(ctx context.Context, stream *databasev1.Stream) error UpdateStream(ctx context.Context, stream *databasev1.Stream) error DeleteStream(ctx context.Context, metadata *commonv1.Metadata) (bool, error) } // IndexRule allows CRUD index rule schemas in a group. type IndexRule interface { GetIndexRule(ctx context.Context, metadata *commonv1.Metadata) (*databasev1.IndexRule, error) ListIndexRule(ctx context.Context, opt ListOpt) ([]*databasev1.IndexRule, error) CreateIndexRule(ctx context.Context, indexRule *databasev1.IndexRule) error UpdateIndexRule(ctx context.Context, indexRule *databasev1.IndexRule) error DeleteIndexRule(ctx context.Context, metadata *commonv1.Metadata) (bool, error) } // IndexRuleBinding allows CRUD index rule binding schemas in a group. type IndexRuleBinding interface { GetIndexRuleBinding(ctx context.Context, metadata *commonv1.Metadata) (*databasev1.IndexRuleBinding, error) ListIndexRuleBinding(ctx context.Context, opt ListOpt) ([]*databasev1.IndexRuleBinding, error) CreateIndexRuleBinding(ctx context.Context, indexRuleBinding *databasev1.IndexRuleBinding) error UpdateIndexRuleBinding(ctx context.Context, indexRuleBinding *databasev1.IndexRuleBinding) error DeleteIndexRuleBinding(ctx context.Context, metadata *commonv1.Metadata) (bool, error) } // Measure allows CRUD measure schemas in a group. type Measure interface { GetMeasure(ctx context.Context, metadata *commonv1.Metadata) (*databasev1.Measure, error) ListMeasure(ctx context.Context, opt ListOpt) ([]*databasev1.Measure, error) CreateMeasure(ctx context.Context, measure *databasev1.Measure) error UpdateMeasure(ctx context.Context, measure *databasev1.Measure) error DeleteMeasure(ctx context.Context, metadata *commonv1.Metadata) (bool, error) TopNAggregations(ctx context.Context, metadata *commonv1.Metadata) ([]*databasev1.TopNAggregation, error) } // Group allows CRUD groups which is namespaces of resources. type Group interface { GetGroup(ctx context.Context, group string) (*commonv1.Group, error) ListGroup(ctx context.Context) ([]*commonv1.Group, error) // DeleteGroup delete all items belonging to the group DeleteGroup(ctx context.Context, group string) (bool, error) CreateGroup(ctx context.Context, group *commonv1.Group) error UpdateGroup(ctx context.Context, group *commonv1.Group) error } // TopNAggregation allows CRUD top-n aggregation schemas in a group. type TopNAggregation interface { GetTopNAggregation(ctx context.Context, metadata *commonv1.Metadata) (*databasev1.TopNAggregation, error) ListTopNAggregation(ctx context.Context, opt ListOpt) ([]*databasev1.TopNAggregation, error) CreateTopNAggregation(ctx context.Context, measure *databasev1.TopNAggregation) error UpdateTopNAggregation(ctx context.Context, measure *databasev1.TopNAggregation) error DeleteTopNAggregation(ctx context.Context, metadata *commonv1.Metadata) (bool, error) } // Property allows CRUD properties or tags in group. type Property interface { GetProperty(ctx context.Context, metadata *propertyv1.Metadata, tags []string) (*propertyv1.Property, error) ListProperty(ctx context.Context, container *commonv1.Metadata, ids []string, tags []string) ([]*propertyv1.Property, error) ApplyProperty(ctx context.Context, property *propertyv1.Property, strategy propertyv1.ApplyRequest_Strategy) (bool, uint32, error) DeleteProperty(ctx context.Context, metadata *propertyv1.Metadata, tags []string) (bool, uint32, error) } // Role is the role of node. type Role string const ( // RoleMeta is the role of meta node. RoleMeta = "meta" // RoleData is the role of data node. RoleData = "data" // RoleQuery is the role of query node. RoleQuery = "query" // RoleLiaison is the role of liaison node. RoleLiaison = "liaison" ) func strToRole(role string) (Role, error) { switch role { case RoleMeta, RoleData, RoleQuery, RoleLiaison: return Role(role), nil default: return "", errors.New("invalid role") } } // Node allows CRUD node schemas in a group. type Node interface { ListNode(ctx context.Context, role Role) ([]*databasev1.Node, error) } // Shard allows CRUD shard schemas in a group. type Shard interface { CreateOrUpdateShard(ctx context.Context, shard *databasev1.Shard) error ListShard(ctx context.Context, opt ListOpt) ([]*databasev1.Shard, error) }