Commit 9f727173 authored by Vasilis Katopodis's avatar Vasilis Katopodis
Browse files

feat: send serviceId at the top level of registry requests

parent c270bfeb
Loading
Loading
Loading
Loading
+134 −0
Changes for registryapi/api_test.go: 134 added lines, 0 removed lines.
Original line number Diff line number Diff line
package registryapi

import (
	"context"
	"encoding/json"
	"testing"

	"github.com/lovoo/goka"
	"labs.etsi.org/rep/osl/hypo/code/org.etsi.osl.hypo.core/base.go/pkg/adapters/kogito"
	"labs.etsi.org/rep/osl/hypo/code/org.etsi.osl.hypo.core/pkg-manager.helm/datamodel"
)

type mockLogger struct{}

func (m *mockLogger) Debug(msg string, args ...any)            {}
func (m *mockLogger) Debugf(msg string, args ...any)           {}
func (m *mockLogger) Info(msg string, args ...any)             {}
func (m *mockLogger) Warning(msg string, args ...any)          {}
func (m *mockLogger) Error(err error, msg string, args ...any) {}
func (m *mockLogger) SetLogLevel(level string) error           { return nil }

type gokaContext = goka.Context

type emitRecorder struct {
	gokaContext
	topic goka.Stream
	value string
}

func (r *emitRecorder) Headers() goka.Headers { return goka.Headers{} }

func (r *emitRecorder) Emit(topic goka.Stream, key string, value interface{}, options ...goka.ContextOption) {
	r.topic = topic
	r.value, _ = value.(string)
}

func TestSendRequestsCarryTopLevelServiceID(t *testing.T) {
	const (
		processID    = "7aa45064-f4a7-4a25-a7a2-667afb07c3d1"
		serviceID    = "790daa4d-7f56-4575-8b64-c558cf518bed"
		orderID      = "2c4fecbc-c436-4f8c-a5db-4a1159ebad2a"
		k8sServiceID = "c04f3d66-5350-49ea-8b31-ff325f149232"
		topic        = "get-package-registry-incoming-channel"
	)
	log := &mockLogger{}

	tests := []struct {
		name         string
		send         func(ctx goka.Context) error
		wantType     string
		nestedIDPath []string
	}{
		{
			name: "parsing",
			send: func(ctx goka.Context) error {
				req := &kogito.RequestData[datamodel.ServiceOrder]{ProccessID: processID, Data: datamodel.ServiceOrder{
					ServiceOrderID: orderID, ServiceID: serviceID, ServiceRepositoryURL: "https://charts.example.com/myrepo",
				}}
				return SendRegistryURLRequest(context.Background(), ctx, log, req, "charts.example.com/myrepo", "", topic)
			},
			wantType:     TypeParsing,
			nestedIDPath: []string{"serviceOrderRequest", "serviceOrder", "serviceId"},
		},
		{
			name: "deployment",
			send: func(ctx goka.Context) error {
				req := kogito.RequestData[datamodel.HelmDeployRequest]{ProccessID: processID, Data: datamodel.HelmDeployRequest{
					ServiceOrderID: orderID, ServiceID: serviceID, K8sServiceID: k8sServiceID, ActivateService: true,
				}}
				return SendDeploymentKubeconfigRequest(context.Background(), ctx, log, req, k8sServiceID, []string{"regcred"}, topic)
			},
			wantType:     TypeDeployment,
			nestedIDPath: []string{"serviceOperationRequest", "serviceId"},
		},
		{
			name: "activation",
			send: func(ctx goka.Context) error {
				req := kogito.RequestData[datamodel.ActivationRequest]{ProccessID: processID, Data: datamodel.ActivationRequest{
					ServiceOrderID: orderID, ServiceID: serviceID, K8sServiceID: k8sServiceID, ActivateService: true,
				}}
				return SendActivationKubeconfigRequest(context.Background(), ctx, log, req, k8sServiceID, topic)
			},
			wantType:     TypeActivation,
			nestedIDPath: []string{"serviceOperationRequest", "serviceId"},
		},
		{
			name: "termination",
			send: func(ctx goka.Context) error {
				req := kogito.RequestData[datamodel.TerminationRequest]{ProccessID: processID, Data: datamodel.TerminationRequest{
					ServiceOrderID: orderID, ServiceID: serviceID, K8sServiceID: k8sServiceID,
				}}
				return SendTerminationKubeconfigRequest(context.Background(), ctx, log, req, k8sServiceID, topic)
			},
			wantType:     TypeTermination,
			nestedIDPath: []string{"serviceOperationRequest", "serviceId"},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			rec := &emitRecorder{}
			if err := tt.send(rec); err != nil {
				t.Fatalf("send returned error: %v", err)
			}
			if rec.topic != topic {
				t.Errorf("emitted to topic %q, want %q", rec.topic, topic)
			}

			var got map[string]any
			if err := json.Unmarshal([]byte(rec.value), &got); err != nil {
				t.Fatalf("emitted value is not JSON: %v (%q)", err, rec.value)
			}

			if got["type"] != tt.wantType {
				t.Errorf("type = %v, want %v", got["type"], tt.wantType)
			}
			if got["serviceId"] != serviceID {
				t.Errorf("top-level serviceId = %v, want %v", got["serviceId"], serviceID)
			}

			var nested any = got
			for _, key := range tt.nestedIDPath {
				obj, ok := nested.(map[string]any)
				if !ok {
					t.Fatalf("path %v: %q is not an object in %s", tt.nestedIDPath, key, rec.value)
				}
				nested = obj[key]
			}
			if nested != serviceID {
				t.Errorf("nested %v = %v, want %v (passthrough must stay unchanged)", tt.nestedIDPath, nested, serviceID)
			}
		})
	}
}
+2 −0
Changes for registryapi/helpers.go: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ func sendRegistryURLRequest(traceCtx context.Context, ctx goka.Context, log logg
	log.Debug("service_id=%s msg=\"Preparing RegistryURLRequest payload. Target URL: %s\"", serviceID, url)
	msg := RegistryURLRequest{
		Type:                requestType,
		ServiceID:           serviceID,
		ServiceOrderRequest: serviceReq,
		URL:                 url,
		SchedulerNamespace:  schedulerNamespace,
@@ -56,6 +57,7 @@ func sendKubeconfigRequestInternal(traceCtx context.Context, ctx goka.Context, l
	log.Debug("service_id=%s msg=\"Preparing KubeconfigRequest payload. Target KubernetesServiceID: %s\"", serviceID, kubernetesServiceID)
	msg := KubeconfigRequest{
		Type:                requestType,
		ServiceID:           serviceID,
		ServiceOperationReq: opReq,
		KubernetesServiceID: kubernetesServiceID,
		SecretNames:         secretNames,
+2 −0
Changes for registryapi/requests.go: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ const (

type RegistryURLRequest struct {
	Type                string              `json:"type"`
	ServiceID           string              `json:"serviceId"`
	ServiceOrderRequest ServiceOrderRequest `json:"serviceOrderRequest"`
	URL                 string              `json:"url"`
	SchedulerNamespace  string              `json:"schedulerNamespace"`
@@ -16,6 +17,7 @@ type RegistryURLRequest struct {

type KubeconfigRequest struct {
	Type                string                  `json:"type"`
	ServiceID           string                  `json:"serviceId"`
	ServiceOperationReq ServiceOperationRequest `json:"serviceOperationRequest"`
	KubernetesServiceID string                  `json:"kubernetesServiceID"`
	SecretNames         []string                `json:"secretNames"`