old_console/correlator/rules/action_http.go
2024-11-02 14:12:45 +03:00

134 lines
2.9 KiB
Go

package rules
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"iwarma.ru/console/correlator/events"
"net/http"
"text/template"
"time"
log "github.com/sirupsen/logrus"
)
const (
HttpActionType = "http"
)
// HttpAction Send record via HTTP. Wil use application/json if empty content type set
type HttpAction struct {
Url string
Template string
ContentType string
bodyTemplate *template.Template
}
func (action HttpAction) GetType() string {
return HttpActionType
}
func (action *HttpAction) Perform(events *[]*events.Event) error {
contextLogger := log.WithFields(log.Fields{"type": HttpActionType, "event_count": len(*events)})
contextLogger.Debug("Start action")
defer contextLogger.Debug("End action")
if events == nil {
contextLogger.Error("Nil events provided")
return errors.New("nil events provided")
}
// Create template
if action.bodyTemplate == nil {
bodyTemplate, err := template.New("Action").Parse(action.Template)
if err != nil {
return err
}
action.bodyTemplate = bodyTemplate
}
for _, cur := range *events {
// Render template
var buf bytes.Buffer
err := action.bodyTemplate.Execute(&buf, *cur)
if err != nil {
return err
}
reader := bytes.NewReader(buf.Bytes())
http.DefaultClient.Timeout = time.Second * 30
_, err = http.Post(action.Url, action.ContentType, reader)
if err != nil {
return err
}
}
http.DefaultClient.CloseIdleConnections()
return nil
}
func (action HttpAction) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
CurType string `json:"type"`
Url string `json:"url"`
Template string `json:"template"`
ContentType string `json:"content_type"`
}{
CurType: HttpActionType,
Url: action.Url,
Template: action.Template,
ContentType: action.ContentType,
})
}
func (action *HttpAction) UnmarshalJSON(b []byte) error {
cur := struct {
CurType string `json:"type"`
Url string `json:"url"`
ContentType string `json:"content_type"`
Template string `json:"template"`
}{}
err := json.Unmarshal(b, &cur)
if err != nil {
return err
}
if cur.CurType != HttpActionType {
return fmt.Errorf("bad action type. Expect http, got %s", cur.CurType)
}
action.Url = cur.Url
action.Template = cur.Template
action.ContentType = cur.ContentType
return nil
}
func (action *HttpAction) ParseInterface(v interface{}) error {
m, ok := v.(map[string]interface{})
if !ok {
return fmt.Errorf("can't parse %v from %T", v, v)
}
action.Url, ok = m["url"].(string)
if !ok {
return fmt.Errorf("can't get URL")
}
// Template can be in data or template
if action.Template, ok = m["data"].(string); !ok {
if action.Template, ok = m["template"].(string); !ok {
return fmt.Errorf("can't get template")
}
}
if action.ContentType, ok = m["content_type"].(string); !ok {
return fmt.Errorf("no content type provided")
}
return nil
}