github.com/yandex/pandora@v0.5.32/components/providers/scenario/http/templater/templater_text.go (about)

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