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 }