diff --git a/agents/httpagent.go b/agents/httpagent.go
index 92428e3a2..502135388 100644
--- a/agents/httpagent.go
+++ b/agents/httpagent.go
@@ -19,22 +19,25 @@ along with this program. If not, see
package agents
import (
+ "fmt"
"net/http"
"github.com/cgrates/cgrates/config"
+ "github.com/cgrates/cgrates/utils"
"github.com/cgrates/rpcclient"
)
-// NewHttpAgent will construct a HttpAgent
-func NewHttpAgent(sessionS rpcclient.RpcClientConnection,
+// NewHttpAgent will construct a HTTPAgent
+func NewHTTPAgent(sessionS rpcclient.RpcClientConnection,
timezone, reqPayload, rplyPayload string,
- reqProcessors []*config.HttpAgntProcCfg) *HttpAgent {
- return &HttpAgent{sessionS: sessionS, timezone: timezone,
+ reqProcessors []*config.HttpAgntProcCfg) *HTTPAgent {
+ return &HTTPAgent{sessionS: sessionS, timezone: timezone,
reqPayload: reqPayload, rplyPayload: rplyPayload,
reqProcessors: reqProcessors}
}
-type HttpAgent struct {
+// HTTPAgent is a handler for HTTP requests
+type HTTPAgent struct {
sessionS rpcclient.RpcClientConnection
timezone,
reqPayload,
@@ -43,5 +46,40 @@ type HttpAgent struct {
}
// ServeHTTP implements http.Handler interface
-func (ha *HttpAgent) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+func (ha *HTTPAgent) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ _, err := newHAReqDecoder(ha.reqPayload, req) // dcdr
+ if err != nil {
+ utils.Logger.Warning(
+ fmt.Sprintf("<%s> error creating decoder: %s",
+ utils.HTTPAgent, err.Error()))
+ }
+ var processed bool
+ procVars := make(processorVars)
+ rpl := newHTTPReplyFields()
+ for _, reqProcessor := range ha.reqProcessors {
+ var lclProcessed bool
+ if lclProcessed, err = ha.processRequest(reqProcessor, req,
+ procVars, rpl); lclProcessed {
+ processed = lclProcessed
+ }
+ if err != nil || (lclProcessed && !reqProcessor.ContinueOnSuccess) {
+ break
+ }
+ }
+ if err != nil {
+ utils.Logger.Warning(fmt.Sprintf("<%s> error: %s processing request: %s, process vars: %+v",
+ utils.HTTPAgent, err.Error(), utils.ToJSON(req), procVars))
+ return // FixMe with returning some error on HTTP level
+ } else if !processed {
+ utils.Logger.Warning(fmt.Sprintf("<%s> no request processor enabled, ignoring request %s, process vars: %+v",
+ utils.RadiusAgent, utils.ToJSON(req), procVars))
+ return // FixMe with returning some error on HTTP level
+ }
+}
+
+// processRequest represents one processor processing the request
+func (ha *HTTPAgent) processRequest(reqProc *config.HttpAgntProcCfg,
+ req *http.Request, procVars processorVars,
+ reply *httpReplyFields) (processed bool, err error) {
+ return
}
diff --git a/agents/libhttpagent.go b/agents/libhttpagent.go
new file mode 100644
index 000000000..1d9b72a91
--- /dev/null
+++ b/agents/libhttpagent.go
@@ -0,0 +1,71 @@
+/*
+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 (
+ "fmt"
+ "net/http"
+)
+
+// httpReplyField is one field written in HTTP reply
+type httpReplyField struct {
+ fldPath,
+ fldVal string
+}
+
+func newHTTPReplyFields() *httpReplyFields {
+ return &httpReplyFields{indexed: make(map[string]*httpReplyField),
+ ordered: make([]*httpReplyField, 0)}
+}
+
+// httpReplyFields is the reply which will be written to HTTP
+// both flds and ordered are pointig towards same httpReplyField
+type httpReplyFields struct {
+ indexed map[string]*httpReplyField // map[fldPath]*httpReplyField
+ ordered []*httpReplyField // keep order for export
+}
+
+// newHAReqDecoder produces decoders
+func newHAReqDecoder(dcdType string,
+ req *http.Request) (rD httpAgentReqDecoder, err error) {
+ switch dcdType {
+ default:
+ return nil, fmt.Errorf("unsupported decoder type <%s>", dcdType)
+ }
+}
+
+// httpAgentReqDecoder will decode request values
+type httpAgentReqDecoder interface {
+ getFieldVal(fldPath string) (interface{}, error)
+}
+
+// newHAReplyEncoder constructs a httpAgentReqDecoder based on encoder type
+func newHAReplyEncoder(encType string,
+ w http.ResponseWriter) (rE httpAgentReplyEncoder, err error) {
+ switch encType {
+ default:
+ return nil, fmt.Errorf("unsupported encoder type <%s>", encType)
+ }
+}
+
+// httpAgentReplyEncoder will encode fields from httpReplyFields
+// and write content to http writer
+type httpAgentReplyEncoder interface {
+ encode(*httpReplyFields) error
+}
diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go
index a984f5518..db9150f2a 100644
--- a/cmd/cgr-engine/cgr-engine.go
+++ b/cmd/cgr-engine/cgr-engine.go
@@ -368,7 +368,7 @@ func startHTTPAgent(internalSMGChan chan rpcclient.RpcClientConnection, exitChan
}
}
server.RegisterHttpHandler(agntCfg.Url,
- agents.NewHttpAgent(sSConn, agntCfg.Timezone, agntCfg.RequestPayload,
+ agents.NewHTTPAgent(sSConn, agntCfg.Timezone, agntCfg.RequestPayload,
agntCfg.ReplyPayload, agntCfg.RequestProcessors))
}
exitChan <- true
diff --git a/config/httpagntcfg.go b/config/httpagntcfg.go
index d626eee34..efef4a4f9 100644
--- a/config/httpagntcfg.go
+++ b/config/httpagntcfg.go
@@ -77,12 +77,13 @@ func (ca *HttpAgentCfg) loadFromJsonCfg(jsnCfg *HttpAgentJsonCfg) error {
}
type HttpAgntProcCfg struct {
- Id string
- DryRun bool
- Filters []string
- Flags utils.StringMap
- RequestFields []*CfgCdrField
- ReplyFields []*CfgCdrField
+ Id string
+ DryRun bool
+ Filters []string
+ Flags utils.StringMap
+ ContinueOnSuccess bool
+ RequestFields []*CfgCdrField
+ ReplyFields []*CfgCdrField
}
func (ha *HttpAgntProcCfg) loadFromJsonCfg(jsnCfg *HttpAgentProcessorJsnCfg) (err error) {
@@ -104,6 +105,9 @@ func (ha *HttpAgntProcCfg) loadFromJsonCfg(jsnCfg *HttpAgentProcessorJsnCfg) (er
if jsnCfg.Flags != nil {
ha.Flags = utils.StringMapFromSlice(*jsnCfg.Flags)
}
+ if jsnCfg.Continue_on_success != nil {
+ ha.ContinueOnSuccess = *jsnCfg.Continue_on_success
+ }
if jsnCfg.Request_fields != nil {
if ha.RequestFields, err = CfgCdrFieldsFromCdrFieldsJsonCfg(*jsnCfg.Request_fields); err != nil {
return
diff --git a/config/libconfig_json.go b/config/libconfig_json.go
index 2f3f5943d..09587b134 100755
--- a/config/libconfig_json.go
+++ b/config/libconfig_json.go
@@ -383,12 +383,13 @@ type HttpAgentJsonCfg struct {
}
type HttpAgentProcessorJsnCfg struct {
- Id *string
- Dry_run *bool
- Filters *[]string
- Flags *[]string
- Request_fields *[]*CdrFieldJsonCfg
- Reply_fields *[]*CdrFieldJsonCfg
+ Id *string
+ Dry_run *bool
+ Filters *[]string
+ Flags *[]string
+ Continue_on_success *bool
+ Request_fields *[]*CdrFieldJsonCfg
+ Reply_fields *[]*CdrFieldJsonCfg
}
// History server config section