diff --git a/controllers/v1/evalHandler.go b/controllers/v1/evalHandler.go index 6f87d1c..fcaaf40 100644 --- a/controllers/v1/evalHandler.go +++ b/controllers/v1/evalHandler.go @@ -56,9 +56,6 @@ func EvalHandler() gin.HandlerFunc { if err != nil { log.Errorf("Erro on load: %v", err) c.String(http.StatusInternalServerError, "Error on load knowledgeBase and/or version") - // w.WriteHeader(http.StatusservicesUnavailable) - // encoder := json.NewEncoder(w) - // encoder.Encode(err) loadMutex.Unlock() return } @@ -90,6 +87,7 @@ func EvalHandler() gin.HandlerFunc { result, err := services.EvalService.Eval(ctx, knowledgeBase) if err != nil { + log.Errorf("Error on eval: %v", err) c.Status(http.StatusInternalServerError) fmt.Fprint(c.Writer, "Error on eval") @@ -99,7 +97,13 @@ func EvalHandler() gin.HandlerFunc { log.Debug("Context:\n\t", ctx.GetEntries(), "\n\n") log.Debug("Features:\n\t", result.GetFeatures(), "\n\n") - c.JSON(http.StatusOK, result.GetFeatures()) + responseCode := http.StatusOK + + if result.Has("requiredParamErrors") { + responseCode = http.StatusBadRequest + } + + c.JSON(responseCode, result.GetFeatures()) } } diff --git a/services/rulles.go b/services/rulles.go index 7e96fec..d8efe9a 100644 --- a/services/rulles.go +++ b/services/rulles.go @@ -155,6 +155,10 @@ func (s Eval) Eval(ctx *types.Context, knowledgeBase *ast.KnowledgeBase) (result result.Put("errors", ctx.GetMap("errors").GetEntries()) } + if ctx.Has("requiredParamErrors") && len(ctx.GetMap("requiredParamErrors").GetEntries()) > 0 { + result.Put("requiredParamErrors", ctx.GetMap("requiredParamErrors").GetEntries()) + } + log.Debug("Context:\n\t", ctx.GetEntries(), "\n\n") log.Debug("Features:\n\t", result.GetFeatures(), "\n\n") diff --git a/types/context.go b/types/context.go index 0fce2dc..9e4e18b 100644 --- a/types/context.go +++ b/types/context.go @@ -25,9 +25,11 @@ type RemoteLoadeds map[string]RemoteLoaded // Context its used to store parameters and temporary variables during rule assertions type Context struct { TypedMap - RemoteLoadeds RemoteLoadeds + RemoteLoadeds RemoteLoadeds + RequiredParams []string Resolver Loader + RequiredConfigured bool } // Resolver ... @@ -68,13 +70,48 @@ func NewContext() *Context { // NewContextFromMap method create a new Context from map func NewContextFromMap(values map[string]interface{}) *Context { instance := &Context{ - TypedMap: *NewTypedMapFromMap(values), - RemoteLoadeds: make(map[string]RemoteLoaded), + TypedMap: *NewTypedMapFromMap(values), + RemoteLoadeds: make(map[string]RemoteLoaded), + RequiredParams: []string{}, } instance.Getter = interface{}(instance).(Getter) return instance } +// RegistryRequiredParams ... +func (c *Context) RegistryRequiredParams(params ...string) { + + for _, param := range params { + if c.isRemoteLoaded(param) { + continue + } + c.RequiredParams = append(c.RequiredParams, param) + if !c.Has(param) { + c.addError("requiredParamErrors", param, fmt.Errorf("parameter %s is required", param)) + } + + } +} + +func (c *Context) addError(key, param string, err interface{}) { + if !c.Has(key) { + c.Put(key, NewTypedMap()) + } + + switch r := err.(type) { + case *log.Entry: + c.GetMap(key).AddItem(param, r.Message) + case log.Entry: + c.GetMap(key).AddItem(param, r.Message) + case string: + c.GetMap(key).AddItem(param, r) + case error: + c.GetMap(key).AddItem(param, r.Error()) + default: + c.GetMap(key).AddItem(param, fmt.Sprintf("%v", r)) + } +} + // RegistryRemoteLoadedWithFrom ... func (c *Context) RegistryRemoteLoadedWithFrom(param string, resolver string, from string) { if from == "" { @@ -104,21 +141,7 @@ func (c *Context) loadImpl(param string) interface{} { if r == nil { return } - if !c.Has("errors") { - c.Put("errors", NewTypedMap()) - } - switch r := r.(type) { - case *log.Entry: - c.GetMap("errors").AddItem(param, r.Message) - case log.Entry: - c.GetMap("errors").AddItem(param, r.Message) - case string: - c.GetMap("errors").AddItem(param, r) - case error: - c.GetMap("errors").AddItem(param, r.Error()) - default: - c.GetMap("errors").AddItem(param, fmt.Sprintf("%v", r)) - } + c.addError("errors", param, r) }() remote, ok := c.RemoteLoadeds[param] if !ok { @@ -225,3 +248,13 @@ func (c *Context) resolveImpl(resolver string, param string) interface{} { return output.Context[param] } + +// SetRequiredConfigured ... +func (c *Context) SetRequiredConfigured() { + c.RequiredConfigured = true +} + +// IsReady ... +func (c *Context) IsReady() bool { + return c.RequiredConfigured && !c.Has("requiredParamErrors") +}