// Copyright (c) Abstract Machines // SPDX-License-Identifier: Apache-2.0 package tracing import ( "context" "github.com/absmach/magistrala/bootstrap" smqauthn "github.com/absmach/magistrala/pkg/authn" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) var _ bootstrap.Service = (*tracingMiddleware)(nil) type tracingMiddleware struct { tracer trace.Tracer svc bootstrap.Service } // New returns a new bootstrap service with tracing capabilities. func New(svc bootstrap.Service, tracer trace.Tracer) bootstrap.Service { return &tracingMiddleware{tracer, svc} } // Add traces the "Add" operation of the wrapped bootstrap.Service. func (tm *tracingMiddleware) Add(ctx context.Context, session smqauthn.Session, token string, cfg bootstrap.Config) (bootstrap.Config, error) { ctx, span := tm.tracer.Start(ctx, "svc_register_user", trace.WithAttributes( attribute.String("config_id", cfg.ID), attribute.String("domain_id ", cfg.DomainID), attribute.String("name", cfg.Name), attribute.String("external_id", cfg.ExternalID), attribute.String("content", cfg.Content), attribute.String("status", cfg.Status.String()), )) defer span.End() return tm.svc.Add(ctx, session, token, cfg) } // View traces the "View" operation of the wrapped bootstrap.Service. func (tm *tracingMiddleware) View(ctx context.Context, session smqauthn.Session, id string) (bootstrap.Config, error) { ctx, span := tm.tracer.Start(ctx, "svc_view_user", trace.WithAttributes( attribute.String("id", id), )) defer span.End() return tm.svc.View(ctx, session, id) } // Update traces the "Update" operation of the wrapped bootstrap.Service. func (tm *tracingMiddleware) Update(ctx context.Context, session smqauthn.Session, cfg bootstrap.Config) error { ctx, span := tm.tracer.Start(ctx, "svc_update_user", trace.WithAttributes( attribute.String("name", cfg.Name), attribute.String("content", cfg.Content), attribute.String("config_id", cfg.ID), attribute.String("domain_id ", cfg.DomainID), )) defer span.End() return tm.svc.Update(ctx, session, cfg) } // UpdateCert traces the "UpdateCert" operation of the wrapped bootstrap.Service. func (tm *tracingMiddleware) UpdateCert(ctx context.Context, session smqauthn.Session, id, clientCert, clientKey, caCert string) (bootstrap.Config, error) { ctx, span := tm.tracer.Start(ctx, "svc_update_cert", trace.WithAttributes( attribute.String("config_id", id), )) defer span.End() return tm.svc.UpdateCert(ctx, session, id, clientCert, clientKey, caCert) } // List traces the "List" operation of the wrapped bootstrap.Service. func (tm *tracingMiddleware) List(ctx context.Context, session smqauthn.Session, filter bootstrap.Filter, offset, limit uint64) (bootstrap.ConfigsPage, error) { ctx, span := tm.tracer.Start(ctx, "svc_list_users", trace.WithAttributes( attribute.Int64("offset", int64(offset)), attribute.Int64("limit", int64(limit)), )) defer span.End() return tm.svc.List(ctx, session, filter, offset, limit) } // Remove traces the "Remove" operation of the wrapped bootstrap.Service. func (tm *tracingMiddleware) Remove(ctx context.Context, session smqauthn.Session, id string) error { ctx, span := tm.tracer.Start(ctx, "svc_remove_user", trace.WithAttributes( attribute.String("id", id), )) defer span.End() return tm.svc.Remove(ctx, session, id) } // Bootstrap traces the "Bootstrap" operation of the wrapped bootstrap.Service. func (tm *tracingMiddleware) Bootstrap(ctx context.Context, externalKey, externalID string, secure bool) (bootstrap.Config, error) { ctx, span := tm.tracer.Start(ctx, "svc_bootstrap_user", trace.WithAttributes( attribute.String("external_id", externalID), attribute.Bool("secure", secure), )) defer span.End() return tm.svc.Bootstrap(ctx, externalKey, externalID, secure) } func (tm *tracingMiddleware) EnableConfig(ctx context.Context, session smqauthn.Session, id string) (bootstrap.Config, error) { ctx, span := tm.tracer.Start(ctx, "svc_enable_config", trace.WithAttributes( attribute.String("id", id), )) defer span.End() return tm.svc.EnableConfig(ctx, session, id) } func (tm *tracingMiddleware) DisableConfig(ctx context.Context, session smqauthn.Session, id string) (bootstrap.Config, error) { ctx, span := tm.tracer.Start(ctx, "svc_disable_config", trace.WithAttributes( attribute.String("id", id), )) defer span.End() return tm.svc.DisableConfig(ctx, session, id) } func (tm *tracingMiddleware) CreateProfile(ctx context.Context, session smqauthn.Session, p bootstrap.Profile) (bootstrap.Profile, error) { ctx, span := tm.tracer.Start(ctx, "svc_create_profile", trace.WithAttributes( attribute.String("name", p.Name), attribute.String("domain_id", p.DomainID), )) defer span.End() return tm.svc.CreateProfile(ctx, session, p) } func (tm *tracingMiddleware) ViewProfile(ctx context.Context, session smqauthn.Session, profileID string) (bootstrap.Profile, error) { ctx, span := tm.tracer.Start(ctx, "svc_view_profile", trace.WithAttributes( attribute.String("profile_id", profileID), )) defer span.End() return tm.svc.ViewProfile(ctx, session, profileID) } func (tm *tracingMiddleware) UpdateProfile(ctx context.Context, session smqauthn.Session, p bootstrap.Profile) (bootstrap.Profile, error) { ctx, span := tm.tracer.Start(ctx, "svc_update_profile", trace.WithAttributes( attribute.String("profile_id", p.ID), )) defer span.End() return tm.svc.UpdateProfile(ctx, session, p) } func (tm *tracingMiddleware) ListProfiles(ctx context.Context, session smqauthn.Session, offset, limit uint64, name string) (bootstrap.ProfilesPage, error) { ctx, span := tm.tracer.Start(ctx, "svc_list_profiles", trace.WithAttributes( attribute.Int64("offset", int64(offset)), attribute.Int64("limit", int64(limit)), )) defer span.End() return tm.svc.ListProfiles(ctx, session, offset, limit, name) } func (tm *tracingMiddleware) DeleteProfile(ctx context.Context, session smqauthn.Session, profileID string) error { ctx, span := tm.tracer.Start(ctx, "svc_delete_profile", trace.WithAttributes( attribute.String("profile_id", profileID), )) defer span.End() return tm.svc.DeleteProfile(ctx, session, profileID) } func (tm *tracingMiddleware) AssignProfile(ctx context.Context, session smqauthn.Session, configID, profileID string) error { ctx, span := tm.tracer.Start(ctx, "svc_assign_profile", trace.WithAttributes( attribute.String("config_id", configID), attribute.String("profile_id", profileID), )) defer span.End() return tm.svc.AssignProfile(ctx, session, configID, profileID) } func (tm *tracingMiddleware) BindResources(ctx context.Context, session smqauthn.Session, token, configID string, bindings []bootstrap.BindingRequest) error { ctx, span := tm.tracer.Start(ctx, "svc_bind_resources", trace.WithAttributes( attribute.String("config_id", configID), )) defer span.End() return tm.svc.BindResources(ctx, session, token, configID, bindings) } func (tm *tracingMiddleware) ListBindings(ctx context.Context, session smqauthn.Session, configID string) ([]bootstrap.BindingSnapshot, error) { ctx, span := tm.tracer.Start(ctx, "svc_list_bindings", trace.WithAttributes( attribute.String("config_id", configID), )) defer span.End() return tm.svc.ListBindings(ctx, session, configID) } func (tm *tracingMiddleware) RefreshBindings(ctx context.Context, session smqauthn.Session, token, configID string) error { ctx, span := tm.tracer.Start(ctx, "svc_refresh_bindings", trace.WithAttributes( attribute.String("config_id", configID), )) defer span.End() return tm.svc.RefreshBindings(ctx, session, token, configID) }