ext/datasource/property.go (48 lines of code) (raw):

// Copyright 1999-2020 Alibaba Group Holding Ltd. // // Licensed 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 datasource import ( "reflect" "github.com/alibaba/sentinel-golang/logging" "github.com/pkg/errors" ) // PropertyConverter func is to convert source message bytes to the specific property. // the first return value: is the real property; // the second return value: return nil if succeed to convert src, if not return the detailed error when convert src. // if src is nil or len(src)==0, the return value is (nil,nil) type PropertyConverter func(src []byte) (interface{}, error) // PropertyUpdater func is to update the specific properties to downstream. // return nil if succeed to update, if not, return the error. type PropertyUpdater func(data interface{}) error type PropertyHandler interface { // check whether the current src is consistent with last update property isPropertyConsistent(src interface{}) bool // handle the current property Handle(src []byte) error } // DefaultPropertyHandler encapsulate the Converter and updater of property. // One DefaultPropertyHandler instance is to handle one property type. // DefaultPropertyHandler should check whether current property is consistent with last update property // converter convert the message to the specific property // updater update the specific property to downstream. type DefaultPropertyHandler struct { lastUpdateProperty interface{} converter PropertyConverter updater PropertyUpdater } func (h *DefaultPropertyHandler) isPropertyConsistent(src interface{}) bool { isConsistent := reflect.DeepEqual(src, h.lastUpdateProperty) if isConsistent { return true } else { h.lastUpdateProperty = src return false } } func (h *DefaultPropertyHandler) Handle(src []byte) error { defer func() { if err := recover(); err != nil { logging.Error(errors.Errorf("%+v", err), "Unexpected panic in DefaultPropertyHandler.Handle()") } }() // convert to target property realProperty, err := h.converter(src) if err != nil { return err } isConsistent := h.isPropertyConsistent(realProperty) if isConsistent { return nil } return h.updater(realProperty) } func NewDefaultPropertyHandler(converter PropertyConverter, updater PropertyUpdater) *DefaultPropertyHandler { return &DefaultPropertyHandler{ converter: converter, updater: updater, } }