mirror of
https://github.com/hatchet-dev/hatchet.git
synced 2025-12-30 21:29:44 -06:00
163 lines
3.5 KiB
Go
163 lines
3.5 KiB
Go
package datautils
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/mitchellh/mapstructure"
|
|
"github.com/rs/zerolog"
|
|
|
|
"github.com/hatchet-dev/hatchet/pkg/constants"
|
|
"github.com/hatchet-dev/hatchet/pkg/errors"
|
|
"github.com/hatchet-dev/hatchet/pkg/logger"
|
|
"github.com/hatchet-dev/hatchet/pkg/validator"
|
|
)
|
|
|
|
func ToJSONMap(data interface{}) (map[string]interface{}, error) {
|
|
// Marshal and unmarshal to/from JSON to get a map[string]interface{}. There are probably better
|
|
// or more efficient ways to do this, but this is the easiest way for now.
|
|
jsonBytes, err := json.Marshal(data)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return JSONBytesToMap(jsonBytes)
|
|
}
|
|
|
|
func JSONBytesToMap(jsonBytes []byte) (map[string]interface{}, error) {
|
|
dataMap := map[string]interface{}{}
|
|
|
|
err := json.Unmarshal(jsonBytes, &dataMap)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if dataMap == nil {
|
|
return map[string]interface{}{}, nil
|
|
}
|
|
|
|
return dataMap, nil
|
|
}
|
|
|
|
type DataDecoderValidator interface {
|
|
DecodeAndValidate(input, target interface{}) error
|
|
}
|
|
|
|
type DefaultDataDecoderValidator struct {
|
|
logger *zerolog.Logger
|
|
alerter errors.Alerter
|
|
validator validator.Validator
|
|
tagName string
|
|
}
|
|
|
|
type DataDecoderValidatorOpt func(*DataDecoderValidatorOpts)
|
|
|
|
type DataDecoderValidatorOpts struct {
|
|
logger *zerolog.Logger
|
|
alerter errors.Alerter
|
|
validator validator.Validator
|
|
tagName string
|
|
}
|
|
|
|
func defaultDataDecoderValidatorOpts() *DataDecoderValidatorOpts {
|
|
logger := logger.NewDefaultLogger("data-decoder-validator")
|
|
|
|
return &DataDecoderValidatorOpts{
|
|
logger: &logger,
|
|
alerter: nil,
|
|
validator: validator.NewDefaultValidator(),
|
|
tagName: "json",
|
|
}
|
|
}
|
|
|
|
func WithValidator(v validator.Validator) DataDecoderValidatorOpt {
|
|
return func(opts *DataDecoderValidatorOpts) {
|
|
opts.validator = v
|
|
}
|
|
}
|
|
|
|
func WithLogger(l *zerolog.Logger) DataDecoderValidatorOpt {
|
|
return func(opts *DataDecoderValidatorOpts) {
|
|
opts.logger = l
|
|
}
|
|
}
|
|
|
|
func WithAlerter(a errors.Alerter) DataDecoderValidatorOpt {
|
|
return func(opts *DataDecoderValidatorOpts) {
|
|
opts.alerter = a
|
|
}
|
|
}
|
|
|
|
func WithTagName(t string) DataDecoderValidatorOpt {
|
|
return func(opts *DataDecoderValidatorOpts) {
|
|
opts.tagName = t
|
|
}
|
|
}
|
|
|
|
func NewDataDecoderValidator(
|
|
f ...DataDecoderValidatorOpt,
|
|
) DataDecoderValidator {
|
|
opts := defaultDataDecoderValidatorOpts()
|
|
|
|
for _, opt := range f {
|
|
opt(opts)
|
|
}
|
|
|
|
return &DefaultDataDecoderValidator{opts.logger, opts.alerter, opts.validator, opts.tagName}
|
|
}
|
|
|
|
func (j *DefaultDataDecoderValidator) DecodeAndValidate(input, target interface{}) error {
|
|
if input == nil {
|
|
return nil
|
|
}
|
|
|
|
if target == nil {
|
|
return fmt.Errorf("target cannot be nil")
|
|
}
|
|
|
|
var requestErr error
|
|
|
|
config := &mapstructure.DecoderConfig{
|
|
Result: target,
|
|
TagName: j.tagName,
|
|
}
|
|
|
|
decoder, err := mapstructure.NewDecoder(config)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := decoder.Decode(input); err != nil {
|
|
return err
|
|
}
|
|
|
|
// validate the request object
|
|
if requestErr = j.validator.Validate(target); requestErr != nil {
|
|
return requestErr
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ExtractCorrelationId extracts correlationId from additionalMetadata if it exists
|
|
func ExtractCorrelationId(additionalMetadata string) *string {
|
|
if additionalMetadata == "" {
|
|
return nil
|
|
}
|
|
|
|
var metadata map[string]any
|
|
if err := json.Unmarshal([]byte(additionalMetadata), &metadata); err != nil {
|
|
return nil
|
|
}
|
|
|
|
if corrId, exists := metadata[string(constants.CorrelationIdKey)]; exists {
|
|
if corrIdStr, ok := corrId.(string); ok {
|
|
return &corrIdStr
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|