diff --git a/agents/janusagent.go b/agents/janusagent.go index 2c2e3cbb5..7e748dc8c 100644 --- a/agents/janusagent.go +++ b/agents/janusagent.go @@ -19,10 +19,12 @@ along with this program. If not, see package agents import ( + "fmt" "net/http" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" ) // NewJanusAgent will construct a JanusAgent @@ -47,51 +49,54 @@ type JanusAgent struct { // ServeHTTP implements http.Handler interface func (ja *JanusAgent) ServeHTTP(w http.ResponseWriter, req *http.Request) { - /*dcdr, err := newHADataProvider(ha.reqPayload, req) // dcdr will provide information from request + dcdr, err := newJanusHTTPjsonDP(req) // dcdr will provide information from request if err != nil { utils.Logger.Warning( fmt.Sprintf("<%s> error creating decoder: %s", utils.HTTPAgent, err.Error())) + http.Error(w, err.Error(), http.StatusBadRequest) return } - cgrRplyNM := &utils.DataNode{Type: utils.NMMapType, Map: make(map[string]*utils.DataNode)} - rplyNM := utils.NewOrderedNavigableMap() - opts := utils.MapStorage{} - reqVars := &utils.DataNode{Type: utils.NMMapType, Map: map[string]*utils.DataNode{utils.RemoteHost: utils.NewLeafNode(req.RemoteAddr)}} - for _, reqProcessor := range ha.reqProcessors { - agReq := NewAgentRequest(dcdr, reqVars, cgrRplyNM, rplyNM, - opts, reqProcessor.Tenant, ha.dfltTenant, - utils.FirstNonEmpty(reqProcessor.Timezone, - config.CgrConfig().GeneralCfg().DefaultTimezone), - ha.filterS, nil) - lclProcessed, err := processRequest(context.TODO(), reqProcessor, agReq, - utils.HTTPAgent, ha.connMgr, ha.sessionConns, - agReq.filterS) + utils.Logger.Debug(dcdr.String()) + /* + cgrRplyNM := &utils.DataNode{Type: utils.NMMapType, Map: make(map[string]*utils.DataNode)} + rplyNM := utils.NewOrderedNavigableMap() + opts := utils.MapStorage{} + reqVars := &utils.DataNode{Type: utils.NMMapType, Map: map[string]*utils.DataNode{utils.RemoteHost: utils.NewLeafNode(req.RemoteAddr)}} + for _, reqProcessor := range ha.reqProcessors { + agReq := NewAgentRequest(dcdr, reqVars, cgrRplyNM, rplyNM, + opts, reqProcessor.Tenant, ha.dfltTenant, + utils.FirstNonEmpty(reqProcessor.Timezone, + config.CgrConfig().GeneralCfg().DefaultTimezone), + ha.filterS, nil) + lclProcessed, err := processRequest(context.TODO(), reqProcessor, agReq, + utils.HTTPAgent, ha.connMgr, ha.sessionConns, + agReq.filterS) + if err != nil { + utils.Logger.Warning( + fmt.Sprintf("<%s> error: %s processing request: %s", + utils.HTTPAgent, err.Error(), utils.ToJSON(agReq))) + return // FixMe with returning some error on HTTP level + } + if !lclProcessed { + continue + } + if lclProcessed && !reqProcessor.Flags.GetBool(utils.MetaContinue) { + break + } + } + encdr, err := newHAReplyEncoder(ha.rplyPayload, w) if err != nil { utils.Logger.Warning( - fmt.Sprintf("<%s> error: %s processing request: %s", - utils.HTTPAgent, err.Error(), utils.ToJSON(agReq))) - return // FixMe with returning some error on HTTP level + fmt.Sprintf("<%s> error creating reply encoder: %s", + utils.HTTPAgent, err.Error())) + return } - if !lclProcessed { - continue + if err = encdr.Encode(rplyNM); err != nil { + utils.Logger.Warning( + fmt.Sprintf("<%s> error: %s encoding out %s", + utils.HTTPAgent, err.Error(), utils.ToJSON(rplyNM))) + return } - if lclProcessed && !reqProcessor.Flags.GetBool(utils.MetaContinue) { - break - } - } - encdr, err := newHAReplyEncoder(ha.rplyPayload, w) - if err != nil { - utils.Logger.Warning( - fmt.Sprintf("<%s> error creating reply encoder: %s", - utils.HTTPAgent, err.Error())) - return - } - if err = encdr.Encode(rplyNM); err != nil { - utils.Logger.Warning( - fmt.Sprintf("<%s> error: %s encoding out %s", - utils.HTTPAgent, err.Error(), utils.ToJSON(rplyNM))) - return - } */ } diff --git a/agents/libjanusagent.go b/agents/libjanusagent.go new file mode 100644 index 000000000..6d29f50ac --- /dev/null +++ b/agents/libjanusagent.go @@ -0,0 +1,79 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package agents + +import ( + "encoding/json" + "net/http" + "net/http/httputil" + + "github.com/cgrates/cgrates/utils" +) + +// newJanusHTTPjsonDP is the constructor for janusHTTPjsonDP struct +func newJanusHTTPjsonDP(req *http.Request) (utils.DataProvider, error) { + jHj := &janusHTTPjsonDP{req: req, cache: utils.MapStorage{}} + if err := json.NewDecoder(req.Body).Decode(&jHj.reqBody); err != nil { + return nil, err + } + return jHj, nil +} + +// janusHTTPjsonDP implements utils.DataProvider, serving as JSON data decoder +// decoded data is only searched once and cached +type janusHTTPjsonDP struct { + req *http.Request + reqBody map[string]interface{} // unmarshal JSON body here + cache utils.MapStorage +} + +// String is part of utils.DataProvider interface +// when called, it will display the already parsed values out of cache +func (jHj *janusHTTPjsonDP) String() string { + byts, _ := httputil.DumpRequest(jHj.req, true) + return string(byts) +} + +// FieldAsInterface is part of utils.DataProvider interface +func (jHj *janusHTTPjsonDP) FieldAsInterface(fldPath []string) (data any, err error) { + if len(fldPath) != 1 { + return nil, utils.ErrNotFound + } + if data, err = jHj.cache.FieldAsInterface(fldPath); err != nil { + if err != utils.ErrNotFound { // item found in cache + return + } + err = nil // cancel previous err + } else { + return // data found in cache + } + data = jHj.reqBody[fldPath[0]] + jHj.cache.Set(fldPath, data) + return +} + +// FieldAsString is part of utils.DataProvider interface +func (jHj *janusHTTPjsonDP) FieldAsString(fldPath []string) (data string, err error) { + var valIface any + valIface, err = jHj.FieldAsInterface(fldPath) + if err != nil { + return + } + return utils.IfaceAsString(valIface), nil +}