github.com/TIBCOSoftware/flogo-lib@v0.5.9/flogo/support.go (about)

     1  package flogo
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  
     7  	"encoding/json"
     8  	"github.com/TIBCOSoftware/flogo-lib/app"
     9  	"github.com/TIBCOSoftware/flogo-lib/core/action"
    10  	"github.com/TIBCOSoftware/flogo-lib/core/activity"
    11  	"github.com/TIBCOSoftware/flogo-lib/core/data"
    12  	"github.com/TIBCOSoftware/flogo-lib/core/trigger"
    13  	"reflect"
    14  	"strconv"
    15  )
    16  
    17  // toAppConfig converts an App to the core app configuration model
    18  func toAppConfig(a *App) *app.Config {
    19  
    20  	appCfg := &app.Config{}
    21  	appCfg.Name = "app"
    22  	appCfg.Version = "1.0.0"
    23  	appCfg.Properties = a.Properties()
    24  	appCfg.Resources = a.resources
    25  
    26  	var triggerConfigs []*trigger.Config
    27  	for id, trg := range a.Triggers() {
    28  
    29  		triggerConfigs = append(triggerConfigs, toTriggerConfig(strconv.Itoa(id+1), trg))
    30  	}
    31  
    32  	appCfg.Triggers = triggerConfigs
    33  
    34  	return appCfg
    35  }
    36  
    37  // toTriggerConfig converts Trigger to the core Trigger configuration model
    38  func toTriggerConfig(id string, trg *Trigger) *trigger.Config {
    39  
    40  	triggerConfig := &trigger.Config{Id:id, Ref: trg.ref, Settings: trg.Settings()}
    41  
    42  	//todo add output
    43  	//trigger.Config struct { Output   map[string]interface{} `json:"output"` }
    44  
    45  	var handlerConfigs []*trigger.HandlerConfig
    46  	for _, handler := range trg.Handlers() {
    47  		h := &trigger.HandlerConfig{Settings: handler.Settings()}
    48  		//todo add output
    49  		//trigger.HandlerConfig struct { Output   map[string]interface{} `json:"output"` }
    50  
    51  		//todo only handles one action for now
    52  		for _, act := range handler.Actions() {
    53  			h.Action = toActionConfig(act)
    54  			break
    55  		}
    56  
    57  		handlerConfigs = append(handlerConfigs, h)
    58  	}
    59  
    60  	triggerConfig.Handlers = handlerConfigs
    61  	return triggerConfig
    62  }
    63  
    64  // toActionConfig converts Action to the core Action configuration model
    65  func toActionConfig(act *Action) *trigger.ActionConfig {
    66  	actionCfg := &trigger.ActionConfig{}
    67  
    68  	if act.act != nil {
    69  		actionCfg.Act = act.act
    70  		return actionCfg
    71  	}
    72  
    73  	actionCfg.Ref = act.ref
    74  
    75  	//todo handle error
    76  	jsonData, _ := json.Marshal(act.Settings())
    77  	actionCfg.Data = jsonData
    78  
    79  	mappings := &data.IOMappings{}
    80  
    81  	if len(act.inputMappings) > 0 {
    82  		mappings.Input, _ = toMappingDefs(act.inputMappings)
    83  	}
    84  	if len(act.outputMappings) > 0 {
    85  		mappings.Output, _ = toMappingDefs(act.outputMappings)
    86  	}
    87  	actionCfg.Mappings = mappings
    88  
    89  	return actionCfg
    90  }
    91  
    92  func toMappingDefs(mappings []string) ([]*data.MappingDef, error) {
    93  
    94  	var mappingDefs []*data.MappingDef
    95  	for _, strMapping := range mappings {
    96  
    97  		idx := strings.Index(strMapping, "=")
    98  		lhs := strings.TrimSpace(strMapping[:idx])
    99  		rhs := strings.TrimSpace(strMapping[idx+1:])
   100  
   101  		mType, mValue := getMappingValue(rhs)
   102  		mappingDef := &data.MappingDef{Type: mType, MapTo: lhs, Value: mValue}
   103  		mappingDefs = append(mappingDefs, mappingDef)
   104  	}
   105  	return mappingDefs, nil
   106  }
   107  
   108  func getMappingValue(strValue string) (data.MappingType, interface{}) {
   109  
   110  	//todo add support for other mapping types
   111  	return data.MtExpression, strValue
   112  }
   113  
   114  // ProxyAction
   115  
   116  type proxyAction struct {
   117  	handlerFunc HandlerFunc
   118  	metadata    *action.Metadata
   119  }
   120  
   121  func NewProxyAction(f HandlerFunc) action.Action {
   122  	return &proxyAction{
   123  		handlerFunc: f,
   124  		metadata:    &action.Metadata{Async: false},
   125  	}
   126  }
   127  
   128  // Metadata get the Action's metadata
   129  func (a *proxyAction) Metadata() *action.Metadata {
   130  	return a.metadata
   131  }
   132  
   133  // IOMetadata get the Action's IO metadata
   134  func (a *proxyAction) IOMetadata() *data.IOMetadata {
   135  	return nil
   136  }
   137  
   138  // Run implementation of action.SyncAction.Run
   139  func (a *proxyAction) Run(ctx context.Context, inputs map[string]*data.Attribute) (map[string]*data.Attribute, error) {
   140  	return a.handlerFunc(ctx, inputs)
   141  }
   142  
   143  // EvalActivity evaluates the specified activity using the provided inputs
   144  func EvalActivity(act activity.Activity, inputs map[string]interface{}) (map[string]*data.Attribute, error) {
   145  
   146  	if act.Metadata() == nil {
   147  		//try loading activity with metadata
   148  		value := reflect.ValueOf(act)
   149  		value = value.Elem()
   150  		ref := value.Type().PkgPath()
   151  
   152  		act = activity.Get(ref)
   153  	}
   154  
   155  	if act.Metadata() == nil {
   156  		//return error
   157  	}
   158  
   159  	ac := &activityContext{inputScope: data.NewFixedScope(act.Metadata().Input),
   160  		outputScope: data.NewFixedScope(act.Metadata().Output)}
   161  
   162  	for key, value := range inputs {
   163  		ac.inputScope.SetAttrValue(key, value)
   164  	}
   165  
   166  	_, evalErr := act.Eval(ac)
   167  
   168  	if evalErr != nil {
   169  		return nil, evalErr
   170  	}
   171  
   172  	return ac.outputScope.GetAttrs(), nil
   173  }
   174  
   175  /////////////////////////////////////////
   176  // activity.Context Implementation
   177  
   178  type activityContext struct {
   179  	inputScope  *data.FixedScope
   180  	outputScope *data.FixedScope
   181  }
   182  
   183  func (aCtx *activityContext) ActivityHost() activity.Host {
   184  	return aCtx
   185  }
   186  
   187  func (aCtx *activityContext) Name() string {
   188  	return ""
   189  }
   190  
   191  func (aCtx *activityContext) GetSetting(setting string) (value interface{}, exists bool) {
   192  	return nil, false
   193  }
   194  
   195  func (aCtx *activityContext) GetInitValue(key string) (value interface{}, exists bool) {
   196  	return nil, false
   197  }
   198  
   199  // GetInput implements activity.Context.GetInput
   200  func (aCtx *activityContext) GetInput(name string) interface{} {
   201  
   202  	val, found := aCtx.inputScope.GetAttr(name)
   203  	if found {
   204  		return val.Value()
   205  	}
   206  
   207  	return nil
   208  }
   209  
   210  // GetOutput implements activity.Context.GetOutput
   211  func (aCtx *activityContext) GetOutput(name string) interface{} {
   212  
   213  	val, found := aCtx.outputScope.GetAttr(name)
   214  	if found {
   215  		return val.Value()
   216  	}
   217  
   218  	return nil
   219  }
   220  
   221  // SetOutput implements activity.Context.SetOutput
   222  func (aCtx *activityContext) SetOutput(name string, value interface{}) {
   223  	aCtx.outputScope.SetAttrValue(name, value)
   224  }
   225  
   226  func (aCtx *activityContext) GetSharedData() map[string]interface{} {
   227  	return nil
   228  }
   229  
   230  //Deprecated
   231  func (aCtx *activityContext) TaskName() string {
   232  	//ignore
   233  	return ""
   234  }
   235  
   236  //Deprecated
   237  func (aCtx *activityContext) FlowDetails() activity.FlowDetails {
   238  	//ignore
   239  	return nil
   240  }
   241  
   242  /////////////////////////////////////////
   243  // activity.Host Implementation
   244  
   245  func (aCtx *activityContext) ID() string {
   246  	//ignore
   247  	return ""
   248  }
   249  
   250  func (aCtx *activityContext) IOMetadata() *data.IOMetadata {
   251  	return nil
   252  }
   253  
   254  func (aCtx *activityContext) Reply(replyData map[string]*data.Attribute, err error) {
   255  	// ignore
   256  }
   257  
   258  func (aCtx *activityContext) Return(returnData map[string]*data.Attribute, err error) {
   259  	//ignore
   260  }
   261  
   262  func (aCtx *activityContext) WorkingData() data.Scope {
   263  	return nil
   264  }
   265  
   266  func (aCtx *activityContext) GetResolver() data.Resolver {
   267  	return data.GetBasicResolver()
   268  }