Skel of HTTPAgent with interfaces for both request and reply decoder/encoders

This commit is contained in:
DanB
2018-06-06 19:45:54 +02:00
parent e20b9f628a
commit 11ca6b1933
5 changed files with 133 additions and 19 deletions

View File

@@ -19,22 +19,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
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
}

71
agents/libhttpagent.go Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>
*/
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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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