operationsbus/matcher.go (63 lines of code) (raw):
package operationsbus
import (
"errors"
"reflect"
)
type EntityFactoryFunc func(string) Entity
// The matcher is utilized in order to keep track of the name and type of each operation. This is required because we only send the OperationRequest through the service bus, but we utilize the name shown in that struct in order to create an instance of the right operation type (e.g. LongRunning) and Run with the correct logic.
type Matcher struct {
Types map[string]reflect.Type
EntityCreators map[string]EntityFactoryFunc
}
func NewMatcher() *Matcher {
return &Matcher{
Types: make(map[string]reflect.Type),
EntityCreators: make(map[string]EntityFactoryFunc),
}
}
// Set adds a key-value pair to the map
// Ex: matcher.Register("LongRunning", &LongRunning{})
func (m *Matcher) Register(key string, value ApiOperation) {
m.Types[key] = reflect.TypeOf(value).Elem()
}
// Set adds a key-value pair to the map
// Ex: matcher.Register("LongRunning", &LongRunning{})
func (m *Matcher) RegisterEntity(key string, value EntityFactoryFunc) {
m.EntityCreators[key] = value
}
// Get retrieves a value from the map by its key
func (m *Matcher) Get(key string) (reflect.Type, bool) {
value, exists := m.Types[key]
return value, exists
}
// This will create an empty instance of the type, with which you can then call op.Init() and initialize any info you need.
func (m *Matcher) CreateOperationInstance(key string) (ApiOperation, error) {
t, exists := m.Types[key]
if !exists {
return nil, errors.New("The ApiOperation doesn't exist in the map: " + key)
}
instance := reflect.New(t).Interface().(ApiOperation)
return instance, nil
}
func (m *Matcher) CreateEntityInstance(key string, lastOperationId string) (Entity, error) {
if lastOperationId == "" {
return nil, errors.New("lastOperationId is empty!")
}
var entity Entity
if f, ok := m.EntityCreators[key]; ok {
entity = f(lastOperationId)
} else {
return nil, errors.New("Something went wrong getting the value of key: " + key)
}
if entity == nil {
return nil, errors.New("Entity was not created successfully!")
}
return entity, nil
}
func (m *Matcher) CreateHookedInstace(key string, hooks []BaseOperationHooksInterface) (*HookedApiOperation, error) {
operation, err := m.CreateOperationInstance(key)
if err != nil {
return nil, err
}
if hooks == nil {
hooks = []BaseOperationHooksInterface{}
}
hOperation := &HookedApiOperation{
Operation: operation,
OperationHooks: hooks,
}
return hOperation, nil
}