update as per the comment in pr
This commit is contained in:
78
pkg/plugin/implementation/otelsetup/cmd/plugin.go
Normal file
78
pkg/plugin/implementation/otelsetup/cmd/plugin.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/beckn-one/beckn-onix/pkg/log"
|
||||
"github.com/beckn-one/beckn-onix/pkg/plugin/implementation/otelsetup"
|
||||
"github.com/beckn-one/beckn-onix/pkg/telemetry"
|
||||
)
|
||||
|
||||
// metricsProvider implements the MetricsProvider interface for the otelsetup plugin.
|
||||
type metricsProvider struct {
|
||||
impl otelsetup.Setup
|
||||
}
|
||||
|
||||
// New creates a new telemetry provider instance.
|
||||
func (m metricsProvider) New(ctx context.Context, config map[string]string) (*telemetry.Provider, func() error, error) {
|
||||
if ctx == nil {
|
||||
return nil, nil, errors.New("context cannot be nil")
|
||||
}
|
||||
|
||||
// Convert map[string]string to telemetry.Config
|
||||
telemetryConfig := &telemetry.Config{
|
||||
ServiceName: config["serviceName"],
|
||||
ServiceVersion: config["serviceVersion"],
|
||||
Environment: config["environment"],
|
||||
}
|
||||
|
||||
// Parse enableMetrics as boolean
|
||||
if enableMetricsStr, ok := config["enableMetrics"]; ok && enableMetricsStr != "" {
|
||||
enableMetrics, err := strconv.ParseBool(enableMetricsStr)
|
||||
if err != nil {
|
||||
log.Warnf(ctx, "Invalid enableMetrics value '%s', defaulting to true: %v", enableMetricsStr, err)
|
||||
telemetryConfig.EnableMetrics = true
|
||||
} else {
|
||||
telemetryConfig.EnableMetrics = enableMetrics
|
||||
}
|
||||
} else {
|
||||
telemetryConfig.EnableMetrics = true // Default to true if not specified or empty
|
||||
}
|
||||
|
||||
// Apply defaults if fields are empty
|
||||
if telemetryConfig.ServiceName == "" {
|
||||
telemetryConfig.ServiceName = telemetry.DefaultConfig().ServiceName
|
||||
}
|
||||
if telemetryConfig.ServiceVersion == "" {
|
||||
telemetryConfig.ServiceVersion = telemetry.DefaultConfig().ServiceVersion
|
||||
}
|
||||
if telemetryConfig.Environment == "" {
|
||||
telemetryConfig.Environment = telemetry.DefaultConfig().Environment
|
||||
}
|
||||
|
||||
log.Debugf(ctx, "Telemetry config mapped: %+v", telemetryConfig)
|
||||
provider, err := m.impl.New(ctx, telemetryConfig)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, err, "Failed to create telemetry provider instance")
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Wrap the Shutdown function to match the closer signature
|
||||
var closer func() error
|
||||
if provider != nil && provider.Shutdown != nil {
|
||||
closer = func() error {
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
return provider.Shutdown(shutdownCtx)
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof(ctx, "Telemetry provider instance created successfully")
|
||||
return provider, closer, nil
|
||||
}
|
||||
|
||||
// Provider is the exported plugin instance
|
||||
var Provider = metricsProvider{}
|
||||
311
pkg/plugin/implementation/otelsetup/cmd/plugin_test.go
Normal file
311
pkg/plugin/implementation/otelsetup/cmd/plugin_test.go
Normal file
@@ -0,0 +1,311 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/beckn-one/beckn-onix/pkg/telemetry"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMetricsProviderNew_Success(t *testing.T) {
|
||||
provider := metricsProvider{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
config map[string]string
|
||||
}{
|
||||
{
|
||||
name: "Valid config with all fields",
|
||||
ctx: context.Background(),
|
||||
config: map[string]string{
|
||||
"serviceName": "test-service",
|
||||
"serviceVersion": "1.0.0",
|
||||
"enableMetrics": "true",
|
||||
"environment": "test",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid config with minimal fields (uses defaults)",
|
||||
ctx: context.Background(),
|
||||
config: map[string]string{},
|
||||
},
|
||||
{
|
||||
name: "Valid config with enableMetrics false",
|
||||
ctx: context.Background(),
|
||||
config: map[string]string{
|
||||
"enableMetrics": "false",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid config with partial fields",
|
||||
ctx: context.Background(),
|
||||
config: map[string]string{
|
||||
"serviceName": "custom-service",
|
||||
"serviceVersion": "2.0.0",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
telemetryProvider, cleanup, err := provider.New(tt.ctx, tt.config)
|
||||
|
||||
require.NoError(t, err, "New() should not return error")
|
||||
require.NotNil(t, telemetryProvider, "New() should return non-nil provider")
|
||||
|
||||
// Test cleanup function if it exists
|
||||
if cleanup != nil {
|
||||
err := cleanup()
|
||||
assert.NoError(t, err, "cleanup() should not return error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricsProviderNew_Failure(t *testing.T) {
|
||||
provider := metricsProvider{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
config map[string]string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Nil context",
|
||||
ctx: nil,
|
||||
config: map[string]string{},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
telemetryProvider, cleanup, err := provider.New(tt.ctx, tt.config)
|
||||
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err, "New() should return error for nil context")
|
||||
assert.Nil(t, telemetryProvider, "New() should return nil provider on error")
|
||||
assert.Nil(t, cleanup, "New() should return nil cleanup on error")
|
||||
} else {
|
||||
assert.NoError(t, err, "New() should not return error")
|
||||
assert.NotNil(t, telemetryProvider, "New() should return non-nil provider")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricsProviderNew_ConfigConversion(t *testing.T) {
|
||||
provider := metricsProvider{}
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config map[string]string
|
||||
expectedConfig *telemetry.Config
|
||||
}{
|
||||
{
|
||||
name: "All fields provided",
|
||||
config: map[string]string{
|
||||
"serviceName": "my-service",
|
||||
"serviceVersion": "3.0.0",
|
||||
"enableMetrics": "true",
|
||||
"environment": "production",
|
||||
},
|
||||
expectedConfig: &telemetry.Config{
|
||||
ServiceName: "my-service",
|
||||
ServiceVersion: "3.0.0",
|
||||
EnableMetrics: true,
|
||||
Environment: "production",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Empty config uses defaults",
|
||||
config: map[string]string{},
|
||||
expectedConfig: &telemetry.Config{
|
||||
ServiceName: telemetry.DefaultConfig().ServiceName,
|
||||
ServiceVersion: telemetry.DefaultConfig().ServiceVersion,
|
||||
EnableMetrics: true, // Default when not specified
|
||||
Environment: telemetry.DefaultConfig().Environment,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "EnableMetrics false",
|
||||
config: map[string]string{
|
||||
"enableMetrics": "false",
|
||||
},
|
||||
expectedConfig: &telemetry.Config{
|
||||
ServiceName: telemetry.DefaultConfig().ServiceName,
|
||||
ServiceVersion: telemetry.DefaultConfig().ServiceVersion,
|
||||
EnableMetrics: false,
|
||||
Environment: telemetry.DefaultConfig().Environment,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Invalid enableMetrics defaults to true",
|
||||
config: map[string]string{
|
||||
"enableMetrics": "invalid",
|
||||
},
|
||||
expectedConfig: &telemetry.Config{
|
||||
ServiceName: telemetry.DefaultConfig().ServiceName,
|
||||
ServiceVersion: telemetry.DefaultConfig().ServiceVersion,
|
||||
EnableMetrics: true, // Defaults to true on parse error
|
||||
Environment: telemetry.DefaultConfig().Environment,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
telemetryProvider, cleanup, err := provider.New(ctx, tt.config)
|
||||
|
||||
require.NoError(t, err, "New() should not return error")
|
||||
require.NotNil(t, telemetryProvider, "New() should return non-nil provider")
|
||||
|
||||
// Verify that the provider was created (we can't directly check internal config,
|
||||
// but we can verify the provider is functional)
|
||||
if tt.expectedConfig.EnableMetrics {
|
||||
assert.NotNil(t, telemetryProvider.MetricsHandler, "MetricsHandler should be set when metrics enabled")
|
||||
}
|
||||
|
||||
if cleanup != nil {
|
||||
err := cleanup()
|
||||
assert.NoError(t, err, "cleanup() should not return error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricsProviderNew_BooleanParsing(t *testing.T) {
|
||||
provider := metricsProvider{}
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
enableMetrics string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "True string",
|
||||
enableMetrics: "true",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "False string",
|
||||
enableMetrics: "false",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "True uppercase",
|
||||
enableMetrics: "TRUE",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "False uppercase",
|
||||
enableMetrics: "FALSE",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid value defaults to true",
|
||||
enableMetrics: "invalid",
|
||||
expected: true, // Defaults to true on parse error
|
||||
},
|
||||
{
|
||||
name: "Empty string defaults to true",
|
||||
enableMetrics: "",
|
||||
expected: true, // Defaults to true when not specified
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
config := map[string]string{
|
||||
"enableMetrics": tt.enableMetrics,
|
||||
}
|
||||
|
||||
telemetryProvider, cleanup, err := provider.New(ctx, config)
|
||||
|
||||
require.NoError(t, err, "New() should not return error")
|
||||
require.NotNil(t, telemetryProvider, "New() should return non-nil provider")
|
||||
|
||||
// Verify metrics handler is set based on enableMetrics
|
||||
if tt.expected {
|
||||
assert.NotNil(t, telemetryProvider.MetricsHandler, "MetricsHandler should be set when metrics enabled")
|
||||
}
|
||||
|
||||
if cleanup != nil {
|
||||
err := cleanup()
|
||||
assert.NoError(t, err, "cleanup() should not return error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricsProviderNew_CleanupFunction(t *testing.T) {
|
||||
provider := metricsProvider{}
|
||||
ctx := context.Background()
|
||||
|
||||
config := map[string]string{
|
||||
"serviceName": "test-service",
|
||||
"serviceVersion": "1.0.0",
|
||||
"enableMetrics": "true",
|
||||
"environment": "test",
|
||||
}
|
||||
|
||||
telemetryProvider, cleanup, err := provider.New(ctx, config)
|
||||
|
||||
require.NoError(t, err, "New() should not return error")
|
||||
require.NotNil(t, telemetryProvider, "New() should return non-nil provider")
|
||||
require.NotNil(t, cleanup, "New() should return non-nil cleanup function")
|
||||
|
||||
// Test that cleanup can be called successfully
|
||||
err = cleanup()
|
||||
assert.NoError(t, err, "cleanup() should not return error")
|
||||
}
|
||||
|
||||
func TestProviderVariable(t *testing.T) {
|
||||
assert.NotNil(t, Provider, "Provider should not be nil")
|
||||
|
||||
// Verify Provider implements the interface correctly
|
||||
ctx := context.Background()
|
||||
config := map[string]string{
|
||||
"serviceName": "test",
|
||||
"serviceVersion": "1.0.0",
|
||||
"enableMetrics": "true",
|
||||
}
|
||||
|
||||
telemetryProvider, cleanup, err := Provider.New(ctx, config)
|
||||
|
||||
require.NoError(t, err, "Provider.New() should not return error")
|
||||
require.NotNil(t, telemetryProvider, "Provider.New() should return non-nil provider")
|
||||
|
||||
if cleanup != nil {
|
||||
err := cleanup()
|
||||
assert.NoError(t, err, "cleanup() should not return error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetricsProviderNew_DefaultValues(t *testing.T) {
|
||||
provider := metricsProvider{}
|
||||
ctx := context.Background()
|
||||
|
||||
// Test with completely empty config
|
||||
config := map[string]string{}
|
||||
|
||||
telemetryProvider, cleanup, err := provider.New(ctx, config)
|
||||
|
||||
require.NoError(t, err, "New() should not return error with empty config")
|
||||
require.NotNil(t, telemetryProvider, "New() should return non-nil provider")
|
||||
|
||||
// Verify defaults are applied by checking that provider is functional
|
||||
assert.NotNil(t, telemetryProvider.MetricsHandler, "MetricsHandler should be set with defaults")
|
||||
|
||||
if cleanup != nil {
|
||||
err := cleanup()
|
||||
assert.NoError(t, err, "cleanup() should not return error")
|
||||
}
|
||||
}
|
||||
|
||||
22
pkg/plugin/implementation/otelsetup/otelsetup.go
Normal file
22
pkg/plugin/implementation/otelsetup/otelsetup.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package otelsetup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/beckn-one/beckn-onix/pkg/telemetry"
|
||||
)
|
||||
|
||||
// Setup wires the telemetry provider using the shared telemetry package. This
|
||||
// is the concrete implementation behind the MetricsProvider interface.
|
||||
type Setup struct{}
|
||||
|
||||
// New initializes the underlying telemetry provider. The returned provider
|
||||
// exposes the HTTP handler and shutdown hooks that the core application can
|
||||
// manage directly.
|
||||
func (Setup) New(ctx context.Context, cfg *telemetry.Config) (*telemetry.Provider, error) {
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("telemetry config cannot be nil")
|
||||
}
|
||||
return telemetry.NewProvider(ctx, cfg)
|
||||
}
|
||||
Reference in New Issue
Block a user