Fix Zeebe metadata duration issue

Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com>
This commit is contained in:
Bernd Verst 2022-09-12 16:38:50 -07:00
parent 2b5650c2fa
commit 393f24280b
4 changed files with 66 additions and 13 deletions

View File

@ -15,12 +15,11 @@ package zeebe
import (
"errors"
"time"
"github.com/camunda/zeebe/clients/go/v8/pkg/zbc"
"github.com/dapr/components-contrib/bindings"
"github.com/dapr/kit/config"
metadata "github.com/dapr/components-contrib/metadata"
"github.com/dapr/kit/logger"
)
@ -37,10 +36,10 @@ type ClientFactoryImpl struct {
// https://docs.zeebe.io/operations/authentication.html
type clientMetadata struct {
GatewayAddr string `json:"gatewayAddr" mapstructure:"gatewayAddr"`
GatewayKeepAlive time.Duration `json:"gatewayKeepAlive" mapstructure:"gatewayKeepAlive"`
CaCertificatePath string `json:"caCertificatePath" mapstructure:"caCertificatePath"`
UsePlaintextConnection bool `json:"usePlainTextConnection,string" mapstructure:"usePlainTextConnection"`
GatewayAddr string `json:"gatewayAddr" mapstructure:"gatewayAddr"`
GatewayKeepAlive metadata.Duration `json:"gatewayKeepAlive" mapstructure:"gatewayKeepAlive"`
CaCertificatePath string `json:"caCertificatePath" mapstructure:"caCertificatePath"`
UsePlaintextConnection bool `json:"usePlainTextConnection,string" mapstructure:"usePlainTextConnection"`
}
// NewClientFactoryImpl returns a new ClientFactory instance.
@ -58,7 +57,7 @@ func (c *ClientFactoryImpl) Get(metadata bindings.Metadata) (zbc.Client, error)
GatewayAddress: meta.GatewayAddr,
UsePlaintextConnection: meta.UsePlaintextConnection,
CaCertificatePath: meta.CaCertificatePath,
KeepAlive: meta.GatewayKeepAlive,
KeepAlive: meta.GatewayKeepAlive.Duration,
})
if err != nil {
return nil, err
@ -67,9 +66,9 @@ func (c *ClientFactoryImpl) Get(metadata bindings.Metadata) (zbc.Client, error)
return client, nil
}
func (c *ClientFactoryImpl) parseMetadata(metadata bindings.Metadata) (*clientMetadata, error) {
func (c *ClientFactoryImpl) parseMetadata(meta bindings.Metadata) (*clientMetadata, error) {
var m clientMetadata
err := config.Decode(metadata.Properties, &m)
err := metadata.DecodeMetadata(meta.Properties, &m)
if err != nil {
return nil, err
}

View File

@ -28,7 +28,6 @@ import (
"github.com/dapr/components-contrib/bindings"
"github.com/dapr/components-contrib/bindings/zeebe"
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/kit/config"
"github.com/dapr/kit/logger"
)
@ -111,13 +110,12 @@ func (z *ZeebeJobWorker) Read(ctx context.Context, handler bindings.Handler) err
return nil
}
func (z *ZeebeJobWorker) parseMetadata(metadata bindings.Metadata) (*jobWorkerMetadata, error) {
func (z *ZeebeJobWorker) parseMetadata(meta bindings.Metadata) (*jobWorkerMetadata, error) {
var m jobWorkerMetadata
err := config.Decode(metadata.Properties, &m)
err := metadata.DecodeMetadata(meta.Properties, &m)
if err != nil {
return nil, err
}
return &m, nil
}

View File

@ -18,8 +18,11 @@ package metadata
import (
"encoding/json"
"errors"
"reflect"
"strconv"
"time"
"github.com/mitchellh/mapstructure"
)
type Duration struct {
@ -53,6 +56,42 @@ func (d *Duration) UnmarshalJSON(b []byte) error {
}
}
// This helper function is used to decode durations within a map[string]interface{} into a struct.
// It must be used in conjunction with mapstructure's DecodeHook.
// This is used in utils.DecodeMetadata to decode durations in metadata.
//
// mapstructure.NewDecoder(&mapstructure.DecoderConfig{
// DecodeHook: mapstructure.ComposeDecodeHookFunc(
// toTimeDurationHookFunc()),
// Metadata: nil,
// Result: result,
// })
func toTimeDurationHookFunc() mapstructure.DecodeHookFunc {
return func(
f reflect.Type,
t reflect.Type,
data interface{},
) (interface{}, error) {
if t != reflect.TypeOf(Duration{}) {
return data, nil
}
switch f.Kind() {
case reflect.String:
val, err := time.ParseDuration(data.(string))
if err != nil {
return nil, err
}
return Duration{Duration: val}, nil
case reflect.Float64:
val := time.Duration(data.(float64))
return val, nil
default:
return data, nil
}
}
}
// ToISOString returns the duration formatted as a ISO-8601 duration string (-ish).
// This methods supports days, hours, minutes, and seconds. It assumes all durations are in UTC time and are not impacted by DST (so all days are 24-hours long).
// This method does not support fractions of seconds, and durations are truncated to seconds.

View File

@ -19,6 +19,7 @@ import (
"strconv"
"time"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
)
@ -124,3 +125,19 @@ func GetMetadataProperty(props map[string]string, keys ...string) (val string, o
}
return "", false
}
// DecodeMetadata decodes metadata into a struct
// This is an extension of mitchellh/mapstructure which also supports decoding durations
func DecodeMetadata(input map[string]string, result interface{}) error {
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: mapstructure.ComposeDecodeHookFunc(
toTimeDurationHookFunc()),
Metadata: nil,
Result: &result,
})
if err != nil {
return err
}
err = decoder.Decode(input)
return err
}