server/pubsub/struct.go (88 lines of code) (raw):

/* * Licensed to the 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. * The 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 pubsub import ( "encoding/json" "errors" "strings" "github.com/apache/servicecomb-kie/pkg/common" "github.com/apache/servicecomb-kie/pkg/stringutil" "github.com/apache/servicecomb-kie/pkg/util" ) // const const ( ActionPut = "put" ActionDelete = "del" ) // KVChangeEvent is event between kie nodes, and broadcast by serf type KVChangeEvent struct { Key string Action string //include: put,delete Labels map[string]string DomainID string Project string } func (e *KVChangeEvent) String() string { return strings.Join([]string{e.Key, e.Action, stringutil.FormatMap(e.Labels), e.DomainID, e.Project}, ";;") } // NewKVChangeEvent create a struct base on event payload func NewKVChangeEvent(payload []byte) (*KVChangeEvent, error) { ke := &KVChangeEvent{} err := json.Unmarshal(payload, ke) return ke, err } // Topic can be subscribe type Topic struct { Labels map[string]string `json:"-"` LabelsFormat string `json:"labels,omitempty"` DomainID string `json:"domainID,omitempty"` Project string `json:"project,omitempty"` MatchType string `json:"match,omitempty"` } func (t *Topic) Encode() (string, error) { t.LabelsFormat = stringutil.FormatMap(t.Labels) b, err := json.Marshal(t) if err != nil { return "", err } return string(b), nil } // ParseTopic parse topic string to topic struct func ParseTopic(s string) (*Topic, error) { t := &Topic{ Labels: make(map[string]string), } err := json.Unmarshal([]byte(s), t) if err != nil { return nil, err } if t.LabelsFormat == stringutil.LabelNone { return t, nil } ls := strings.Split(t.LabelsFormat, "::") if len(ls) != 0 { for _, l := range ls { s := strings.Split(l, "=") if len(s) != 2 { return nil, errors.New("invalid label:" + l) } t.Labels[s[0]] = s[1] } } return t, err } // Match compare event with topic // If the match type is set to exact in long pulling request, only update request with exactly // the same label of pulling request will match the request and will trigger an immediate return. // // If the match type is not set, it will be matched when pulling request labels is equal to // update request labels or a subset of it. func (t *Topic) Match(event *KVChangeEvent) bool { match := false if t.MatchType == common.PatternExact { if !util.IsEquivalentLabel(t.Labels, event.Labels) { return false } } if len(t.Labels) == 0 { return true } for k, v := range t.Labels { if event.Labels[k] != v { return false } match = true } return match } // Observer represents a client polling request type Observer struct { UUID string Event chan *KVChangeEvent }