Repository: kedacore/http-add-on
Pull request #1299 (2025-05-21 07:22:00)

scaler: allow using HSO and SO with different names
<!-- Thank you for contributing!

     Read more about how you can contribute in our contribution guide:
     https://github.com/kedacore/http-add-on/blob/main/CONTRIBUTING.md
-->

Follow up on the work done in: https://github.com/kedacore/http-add-on/pull/1296

This should allow using HSO and SO with different names.

Fixes https://github.com/kedacore/http-add-on/issues/1293



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5badca5..11eda45 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,7 +26,7 @@ This changelog keeps track of work items that have been completed and are ready
 ### New
 
 - **General**: Add configurable tracing support to the interceptor proxy ([#1021](https://github.com/kedacore/http-add-on/pull/1021))
-- **General**: TODO ([#TODO](https://github.com/kedacore/http-add-on/issues/TODO))
+- **General**: Allow using HSO and SO with different names ([#1293](https://github.com/kedacore/http-add-on/issues/1293))
 
 ### Improvements
 
diff --git a/pkg/k8s/namespacedname.go b/pkg/k8s/namespacedname.go
index 42d887a..566d796 100644
--- a/pkg/k8s/namespacedname.go
+++ b/pkg/k8s/namespacedname.go
@@ -29,3 +29,14 @@ func NamespacedNameFromScaledObjectRef(sor *externalscaler.ScaledObjectRef) *typ
 		Name:      sor.GetName(),
 	}
 }
+
+func NamespacedNameFromNameAndNamespace(name, namespace string) *types.NamespacedName {
+	if name == "" || namespace == "" {
+		return nil
+	}
+
+	return &types.NamespacedName{
+		Name:      name,
+		Namespace: namespace,
+	}
+}
diff --git a/scaler/handlers.go b/scaler/handlers.go
index cad7d7a..3e604f8 100644
--- a/scaler/handlers.go
+++ b/scaler/handlers.go
@@ -96,20 +96,14 @@ func (e *impl) StreamIsActive(scaledObject *externalscaler.ScaledObjectRef, serv
 		case <-ticker.C:
 			active, err := e.IsActive(server.Context(), scaledObject)
 			if err != nil {
-				e.lggr.Error(
-					err,
-					"error getting active status in stream",
-				)
+				e.lggr.Error(err, "error getting active status in stream")
 				return err
 			}
 			err = server.Send(&externalscaler.IsActiveResponse{
 				Result: active.Result,
 			})
 			if err != nil {
-				e.lggr.Error(
-					err,
-					"error sending the active result in stream",
-				)
+				e.lggr.Error(err, "error sending the active result in stream")
 				return err
 			}
 		}
@@ -119,14 +113,13 @@ func (e *impl) StreamIsActive(scaledObject *externalscaler.ScaledObjectRef, serv
 func (e *impl) GetMetricSpec(_ context.Context, sor *externalscaler.ScaledObjectRef) (*externalscaler.GetMetricSpecResponse, error) {
 	lggr := e.lggr.WithName("GetMetricSpec")
 
-	namespacedName := k8s.NamespacedNameFromScaledObjectRef(sor)
-	metricName := MetricName(namespacedName)
-
 	scalerMetadata := sor.GetScalerMetadata()
 	httpScaledObjectName, ok := scalerMetadata[k8s.HTTPScaledObjectKey]
 	if !ok {
 		if scalerMetadata != nil {
 			if interceptorTargetPendingRequests, ok := scalerMetadata[keyInterceptorTargetPendingRequests]; ok {
+				// generated the metric name for the ScaledObject targeting the interceptor
+				metricName := MetricName(k8s.NamespacedNameFromScaledObjectRef(sor))
 				return e.interceptorMetricSpec(metricName, interceptorTargetPendingRequests)
 			}
 		}
@@ -140,6 +133,10 @@ func (e *impl) GetMetricSpec(_ context.Context, sor *externalscaler.ScaledObject
 		lggr.Error(err, "unable to get HTTPScaledObject", "name", sor.Name, "namespace", sor.Namespace, "httpScaledObjectName", httpScaledObjectName)
 		return nil, err
 	}
+
+	// generated the metric name for HTTPScaledObject
+	metricName := MetricName(k8s.NamespacedNameFromNameAndNamespace(httpScaledObjectName, sor.Namespace))
+
 	targetValue := int64(ptr.Deref(httpso.Spec.TargetPendingRequests, 100))
 
 	if httpso.Spec.ScalingMetric != nil {
@@ -186,14 +183,13 @@ func (e *impl) GetMetrics(_ context.Context, metricRequest *externalscaler.GetMe
 	lggr := e.lggr.WithName("GetMetrics")
 	sor := metricRequest.ScaledObjectRef
 
-	namespacedName := k8s.NamespacedNameFromScaledObjectRef(sor)
-	metricName := MetricName(namespacedName)
-
 	scalerMetadata := sor.GetScalerMetadata()
 	httpScaledObjectName, ok := scalerMetadata[k8s.HTTPScaledObjectKey]
 	if !ok {
 		if scalerMetadata != nil {
 			if _, ok := scalerMetadata[keyInterceptorTargetPendingRequests]; ok {
+				// generated the metric name for the ScaledObject targeting the interceptor
+				metricName := MetricName(k8s.NamespacedNameFromScaledObjectRef(sor))
 				return e.interceptorMetrics(metricName)
 			}
 		}
@@ -208,6 +204,10 @@ func (e *impl) GetMetrics(_ context.Context, metricRequest *externalscaler.GetMe
 		return nil, err
 	}
 
+	// generated the metric name for HTTPScaledObject
+	namespacedName := k8s.NamespacedNameFromNameAndNamespace(httpScaledObjectName, sor.Namespace)
+	metricName := MetricName(namespacedName)
+
 	key := namespacedName.String()
 	count := e.pinger.counts()[key]
 


Test patch:
diff --git a/scaler/handlers_test.go b/scaler/handlers_test.go
index 1820626..bd9c6eb 100644
--- a/scaler/handlers_test.go
+++ b/scaler/handlers_test.go
@@ -45,7 +45,7 @@ func TestStreamIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -65,7 +65,7 @@ func TestStreamIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -88,7 +88,7 @@ func TestStreamIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -113,7 +113,7 @@ func TestStreamIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -138,7 +138,7 @@ func TestStreamIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -163,7 +163,7 @@ func TestStreamIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -188,7 +188,7 @@ func TestStreamIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -347,7 +347,7 @@ func TestIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -369,7 +369,7 @@ func TestIsActive(t *testing.T) {
 			setup: func(t *testing.T, qp *queuePinger) {
 				namespacedName := &types.NamespacedName{
 					Namespace: "default",
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -505,7 +505,7 @@ func TestGetMetricSpecTable(t *testing.T) {
 				r.NotNil(res)
 				r.Len(res.MetricSpecs, 1)
 				spec := res.MetricSpecs[0]
-				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: t.Name()}), spec.MetricName)
+				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: validHTTPScaledObjectName}), spec.MetricName)
 				r.Equal(int64(123), spec.TargetSize)
 			},
 			scalerMetadata: map[string]string{
@@ -556,7 +556,7 @@ func TestGetMetricSpecTable(t *testing.T) {
 				r.NotNil(res)
 				r.Len(res.MetricSpecs, 1)
 				spec := res.MetricSpecs[0]
-				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: t.Name()}), spec.MetricName)
+				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: validHTTPScaledObjectName}), spec.MetricName)
 				r.Equal(int64(123), spec.TargetSize)
 			},
 			scalerMetadata: map[string]string{
@@ -719,9 +719,9 @@ func TestGetMetrics(t *testing.T) {
 				r := require.New(t)
 				r.NoError(err)
 				r.NotNil(res)
-				r.Equal(1, len(res.MetricValues))
+				r.Len(res.MetricValues, 1)
 				metricVal := res.MetricValues[0]
-				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: t.Name()}), metricVal.MetricName)
+				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: validHTTPScaledObjectName}), metricVal.MetricName)
 				r.Equal(int64(0), metricVal.MetricValue)
 			},
 			defaultTargetMetric: int64(200),
@@ -741,7 +741,7 @@ func TestGetMetrics(t *testing.T) {
 
 				namespacedName := &types.NamespacedName{
 					Namespace: ns,
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -759,9 +759,9 @@ func TestGetMetrics(t *testing.T) {
 				r := require.New(t)
 				r.NoError(err)
 				r.NotNil(res)
-				r.Equal(1, len(res.MetricValues))
+				r.Len(res.MetricValues, 1)
 				metricVal := res.MetricValues[0]
-				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: t.Name()}), metricVal.MetricName)
+				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: validHTTPScaledObjectName}), metricVal.MetricName)
 				r.Equal(int64(201), metricVal.MetricValue)
 			},
 			defaultTargetMetric: int64(200),
@@ -781,7 +781,7 @@ func TestGetMetrics(t *testing.T) {
 
 				namespacedName := &types.NamespacedName{
 					Namespace: ns,
-					Name:      t.Name(),
+					Name:      validHTTPScaledObjectName,
 				}
 				key := namespacedName.String()
 
@@ -799,9 +799,9 @@ func TestGetMetrics(t *testing.T) {
 				r := require.New(t)
 				r.NoError(err)
 				r.NotNil(res)
-				r.Equal(1, len(res.MetricValues))
+				r.Len(res.MetricValues, 1)
 				metricVal := res.MetricValues[0]
-				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: t.Name()}), metricVal.MetricName)
+				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: validHTTPScaledObjectName}), metricVal.MetricName)
 				// the value here needs to be the same thing as
 				// the sum of the values in the fake queue created
 				// in the setup function
@@ -839,7 +839,7 @@ func TestGetMetrics(t *testing.T) {
 				r := require.New(t)
 				r.NoError(err)
 				r.NotNil(res)
-				r.Equal(1, len(res.MetricValues))
+				r.Len(res.MetricValues, 1)
 				metricVal := res.MetricValues[0]
 				r.Equal(MetricName(&types.NamespacedName{Namespace: ns, Name: t.Name()}), metricVal.MetricName)
 				// the value here needs to be the same thing as