Browse Source

fix: Adding baseRuntime eval calls

Matthias Ladkau 3 years ago
parent
commit
9e5fab12eb
3 changed files with 126 additions and 115 deletions
  1. 0 1
      interpreter/provider.go
  2. 6 1
      interpreter/rt_identifier.go
  3. 120 113
      interpreter/rt_sink.go

+ 0 - 1
interpreter/provider.go

@@ -9,7 +9,6 @@
  */
 
 // TODO:
-// Document event processing with sinks
 // Context supporting final and exception handling
 // Inline escaping in strings "bla {1+1} bla"
 

+ 6 - 1
interpreter/rt_identifier.go

@@ -39,7 +39,12 @@ func identifierRuntimeInst(erp *ECALRuntimeProvider, node *parser.ASTNode) parse
 Eval evaluate this runtime component.
 */
 func (rt *identifierRuntime) Eval(vs parser.Scope, is map[string]interface{}) (interface{}, error) {
-	return rt.resolveValue(vs, is, rt.node)
+	var res interface{}
+	_, err := rt.baseRuntime.Eval(vs, is)
+	if err == nil {
+		res, err = rt.resolveValue(vs, is, rt.node)
+	}
+	return res, err
 }
 
 /*

+ 120 - 113
interpreter/rt_sink.go

@@ -86,144 +86,147 @@ func (rt *sinkRuntime) Eval(vs parser.Scope, is map[string]interface{}) (interfa
 	var stateMatch map[string]interface{}
 	var priority int
 	var statements *parser.ASTNode
-	var err error
 
-	// Create default scope
+	_, err := rt.baseRuntime.Eval(vs, is)
 
-	scopeMatch = []string{}
+	if err == nil {
+		// Create default scope
+
+		scopeMatch = []string{}
 
-	// Get the name of the sink
+		// Get the name of the sink
 
-	name := rt.node.Children[0].Token.Val
+		name := rt.node.Children[0].Token.Val
 
-	// Create helper function
+		// Create helper function
 
-	makeStringList := func(child *parser.ASTNode) ([]string, error) {
-		var ret []string
+		makeStringList := func(child *parser.ASTNode) ([]string, error) {
+			var ret []string
 
-		val, err := child.Runtime.Eval(vs, is)
+			val, err := child.Runtime.Eval(vs, is)
 
-		if err == nil {
-			for _, v := range val.([]interface{}) {
-				ret = append(ret, fmt.Sprint(v))
+			if err == nil {
+				for _, v := range val.([]interface{}) {
+					ret = append(ret, fmt.Sprint(v))
+				}
 			}
-		}
 
-		return ret, err
-	}
+			return ret, err
+		}
 
-	// Collect values from children
+		// Collect values from children
 
-	for _, child := range rt.node.Children[1:] {
+		for _, child := range rt.node.Children[1:] {
 
-		switch child.Name {
+			switch child.Name {
 
-		case parser.NodeKINDMATCH:
-			kindMatch, err = makeStringList(child)
-			break
+			case parser.NodeKINDMATCH:
+				kindMatch, err = makeStringList(child)
+				break
 
-		case parser.NodeSCOPEMATCH:
-			scopeMatch, err = makeStringList(child)
-			break
+			case parser.NodeSCOPEMATCH:
+				scopeMatch, err = makeStringList(child)
+				break
 
-		case parser.NodeSTATEMATCH:
-			var val interface{}
-			stateMatch = make(map[string]interface{})
+			case parser.NodeSTATEMATCH:
+				var val interface{}
+				stateMatch = make(map[string]interface{})
 
-			if val, err = child.Runtime.Eval(vs, is); err == nil {
-				for k, v := range val.(map[interface{}]interface{}) {
-					stateMatch[fmt.Sprint(k)] = v
+				if val, err = child.Runtime.Eval(vs, is); err == nil {
+					for k, v := range val.(map[interface{}]interface{}) {
+						stateMatch[fmt.Sprint(k)] = v
+					}
 				}
-			}
-			break
+				break
 
-		case parser.NodePRIORITY:
-			var val interface{}
+			case parser.NodePRIORITY:
+				var val interface{}
 
-			if val, err = child.Runtime.Eval(vs, is); err == nil {
-				priority = int(math.Floor(val.(float64)))
-			}
-			break
+				if val, err = child.Runtime.Eval(vs, is); err == nil {
+					priority = int(math.Floor(val.(float64)))
+				}
+				break
 
-		case parser.NodeSUPPRESSES:
-			suppresses, err = makeStringList(child)
-			break
+			case parser.NodeSUPPRESSES:
+				suppresses, err = makeStringList(child)
+				break
 
-		case parser.NodeSTATEMENTS:
-			statements = child
-			break
-		}
+			case parser.NodeSTATEMENTS:
+				statements = child
+				break
+			}
 
-		if err != nil {
-			break
+			if err != nil {
+				break
+			}
 		}
-	}
 
-	if err == nil && statements != nil {
-		var desc string
+		if err == nil && statements != nil {
+			var desc string
 
-		sinkName := fmt.Sprint(name)
+			sinkName := fmt.Sprint(name)
 
-		if len(rt.node.Meta) > 0 &&
-			(rt.node.Meta[0].Type() == parser.MetaDataPreComment ||
-				rt.node.Meta[0].Type() == parser.MetaDataPostComment) {
-			desc = strings.TrimSpace(rt.node.Meta[0].Value())
-		}
+			if len(rt.node.Meta) > 0 &&
+				(rt.node.Meta[0].Type() == parser.MetaDataPreComment ||
+					rt.node.Meta[0].Type() == parser.MetaDataPostComment) {
+				desc = strings.TrimSpace(rt.node.Meta[0].Value())
+			}
 
-		rule := &engine.Rule{
-			Name:            sinkName,   // Name
-			Desc:            desc,       // Description
-			KindMatch:       kindMatch,  // Kind match
-			ScopeMatch:      scopeMatch, // Match on event cascade scope
-			StateMatch:      stateMatch, // No state match
-			Priority:        priority,   // Priority of the rule
-			SuppressionList: suppresses, // List of suppressed rules by this rule
-			Action: func(p engine.Processor, m engine.Monitor, e *engine.Event) error { // Action of the rule
+			rule := &engine.Rule{
+				Name:            sinkName,   // Name
+				Desc:            desc,       // Description
+				KindMatch:       kindMatch,  // Kind match
+				ScopeMatch:      scopeMatch, // Match on event cascade scope
+				StateMatch:      stateMatch, // No state match
+				Priority:        priority,   // Priority of the rule
+				SuppressionList: suppresses, // List of suppressed rules by this rule
+				Action: func(p engine.Processor, m engine.Monitor, e *engine.Event) error { // Action of the rule
 
-				// Create a new root variable scope
+					// Create a new root variable scope
 
-				sinkVS := scope.NewScope(fmt.Sprintf("sink: %v", sinkName))
+					sinkVS := scope.NewScope(fmt.Sprintf("sink: %v", sinkName))
 
-				// Create a new instance state with the monitor - everything called
-				// by the rule will have access to the current monitor.
+					// Create a new instance state with the monitor - everything called
+					// by the rule will have access to the current monitor.
 
-				sinkIs := map[string]interface{}{
-					"monitor": m,
-				}
+					sinkIs := map[string]interface{}{
+						"monitor": m,
+					}
 
-				err = sinkVS.SetValue("event", map[interface{}]interface{}{
-					"name":  e.Name(),
-					"kind":  strings.Join(e.Kind(), engine.RuleKindSeparator),
-					"state": e.State(),
-				})
+					err = sinkVS.SetValue("event", map[interface{}]interface{}{
+						"name":  e.Name(),
+						"kind":  strings.Join(e.Kind(), engine.RuleKindSeparator),
+						"state": e.State(),
+					})
 
-				if err == nil {
-					scope.SetParentOfScope(sinkVS, vs)
+					if err == nil {
+						scope.SetParentOfScope(sinkVS, vs)
 
-					if _, err = statements.Runtime.Eval(sinkVS, sinkIs); err != nil {
+						if _, err = statements.Runtime.Eval(sinkVS, sinkIs); err != nil {
 
-						if sre, ok := err.(*SinkRuntimeError); ok {
-							sre.environment = sinkVS
+							if sre, ok := err.(*SinkRuntimeError); ok {
+								sre.environment = sinkVS
 
-						} else {
+							} else {
 
-							// Provide additional information for unexpected errors
+								// Provide additional information for unexpected errors
 
-							err = &SinkRuntimeError{
-								err.(*util.RuntimeError),
-								sinkVS,
-								nil,
+								err = &SinkRuntimeError{
+									err.(*util.RuntimeError),
+									sinkVS,
+									nil,
+								}
 							}
 						}
 					}
-				}
 
-				return err
-			},
-		}
+					return err
+				},
+			}
 
-		if err = rt.erp.Processor.AddRule(rule); err != nil {
-			err = rt.erp.NewRuntimeError(util.ErrInvalidState, err.Error(), rt.node)
+			if err = rt.erp.Processor.AddRule(rule); err != nil {
+				err = rt.erp.NewRuntimeError(util.ErrInvalidState, err.Error(), rt.node)
+			}
 		}
 	}
 
@@ -254,34 +257,38 @@ type sinkDetailRuntime struct {
 Eval evaluate this runtime component.
 */
 func (rt *sinkDetailRuntime) Eval(vs parser.Scope, is map[string]interface{}) (interface{}, error) {
+	var ret interface{}
 
-	ret, err := rt.node.Children[0].Runtime.Eval(vs, is)
+	_, err := rt.baseRuntime.Eval(vs, is)
 
 	if err == nil {
 
-		// Check value is of expected type
+		if ret, err = rt.node.Children[0].Runtime.Eval(vs, is); err == nil {
 
-		if rt.valType == "list" {
-			if _, ok := ret.([]interface{}); !ok {
-				return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
-					fmt.Sprintf("Expected a list as value"),
-					rt.node)
-			}
+			// Check value is of expected type
 
-		} else if rt.valType == "map" {
+			if rt.valType == "list" {
+				if _, ok := ret.([]interface{}); !ok {
+					return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
+						fmt.Sprintf("Expected a list as value"),
+						rt.node)
+				}
 
-			if _, ok := ret.(map[interface{}]interface{}); !ok {
-				return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
-					fmt.Sprintf("Expected a map as value"),
-					rt.node)
-			}
+			} else if rt.valType == "map" {
 
-		} else if rt.valType == "int" {
+				if _, ok := ret.(map[interface{}]interface{}); !ok {
+					return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
+						fmt.Sprintf("Expected a map as value"),
+						rt.node)
+				}
 
-			if _, ok := ret.(float64); !ok {
-				return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
-					fmt.Sprintf("Expected a number as value"),
-					rt.node)
+			} else if rt.valType == "int" {
+
+				if _, ok := ret.(float64); !ok {
+					return nil, rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
+						fmt.Sprintf("Expected a number as value"),
+						rt.node)
+				}
 			}
 		}
 	}