github.com/yandex/pandora@v0.5.32/components/guns/grpc/scenario/templater_text.go (about) 1 package scenario 2 3 import ( 4 "fmt" 5 "strings" 6 "sync" 7 "text/template" 8 9 "github.com/yandex/pandora/components/providers/scenario/templater" 10 ) 11 12 func NewTextTemplater() Templater { 13 return &TextTemplater{} 14 } 15 16 type TextTemplater struct { 17 templatesCache sync.Map 18 } 19 20 func (t *TextTemplater) Apply(payload []byte, metadata map[string]string, variables map[string]any, scenarioName, stepName string) ([]byte, error) { 21 const op = "scenario/TextTemplater.Apply" 22 23 strBuilder := &strings.Builder{} 24 tmpl, err := t.getTemplate(string(payload), scenarioName, stepName, "payload") 25 if err != nil { 26 return nil, fmt.Errorf("%s, template.getTemplate payload, %w", op, err) 27 } 28 err = tmpl.Execute(strBuilder, variables) 29 if err != nil { 30 return nil, fmt.Errorf("%s, template.Execute payload, %w", op, err) 31 } 32 payloadStr := strBuilder.String() 33 strBuilder.Reset() 34 35 for k, v := range metadata { 36 tmpl, err = t.getTemplate(v, scenarioName, stepName, k) 37 if err != nil { 38 return nil, fmt.Errorf("%s, template.Execute Header %s, %w", op, k, err) 39 } 40 err = tmpl.Execute(strBuilder, variables) 41 if err != nil { 42 return nil, fmt.Errorf("%s, template.Execute Header %s, %w", op, k, err) 43 } 44 metadata[k] = strBuilder.String() 45 strBuilder.Reset() 46 } 47 return []byte(payloadStr), nil 48 } 49 50 func (t *TextTemplater) getTemplate(tmplBody, scenarioName, stepName, key string) (*template.Template, error) { 51 urlKey := fmt.Sprintf("%s_%s_%s", scenarioName, stepName, key) 52 tmpl, ok := t.templatesCache.Load(urlKey) 53 if !ok { 54 var err error 55 tmpl, err = template.New(urlKey).Funcs(templater.GetFuncs()).Parse(tmplBody) 56 if err != nil { 57 return nil, fmt.Errorf("scenario/TextTemplater.Apply, template.New, %w", err) 58 } 59 t.templatesCache.Store(urlKey, tmpl) 60 } 61 return tmpl.(*template.Template), nil 62 }