Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(CustomMetrics): Allow Different App to Send Custom Metrics #3211

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

asalan316
Copy link
Contributor

@asalan316 asalan316 commented Sep 17, 2024

Previously, only the application sending custom metrics to the autoscaler could be scaled.

The new feature enables users to scale an application based on custom metrics sent by another app (Custom Metrics Producer), This is achieve if:

  • Both applications are bound to same application autoscaler instance
  • The application to scale has the "metric_submission_strategy.allow_from" set to bound_app during the binding process

How It Works

To enable this feature, specify the metric_submission_strategy.allow_from : "bound_app" parameter in the configuration object during the binding process with the application to be scaled (as shown below)

Binding Configuration (aka.scaling policy)

{
  "configuration": {
    "custom_metrics": {
      "metric_submission_strategy": {
        "allow_from": "bound_app"
      }
    }
  },
  "instance_max_count":4,
  "instance_min_count":1,
  "scaling_rules":[
    {
      "metric_type":"test_metric",
      "threshold":500,
      "operator":">",
      "adjustment":"+1"
    }, {
      "metric_type":"test_metric",
      "threshold":100,
      "operator":"<",
      "adjustment":"-1"
    }
  ]
}

Bind to Applications

# Bind autoscaler to application to scale

cf bind-service  app-to-scale  autosocaler -c <binding Configuration.json>

# Bind autoscaler to custom metrics producer app

cf bind-service  custom-metrics-producer-app  autosocaler

custom-metrics-strategy-v1-drawio

Other Changes

  • Introduced additional database bindingDB in metricsforwarder service to retrieve binding information
  • Added New Database schema to validate custom metrics strategy - allowed values are bound_app and same_app (default)
  • Introduced a configuration structure to differentiate between policy and binding configurations
  • Binding parameters are retrieved as follows:
    • For existing bindings (without configuration) - only policy json is displayed (existing behavior)
    • For new bindings - both the configuration and policy json are displayed in the response

@asalan316 asalan316 added the allow-acceptance-tests This label needs to be added to enable the acceptance tests to run. label Sep 17, 2024
@asalan316 asalan316 force-pushed the neighbour-app-cutom-metrics branch 3 times, most recently from 3edfa26 to c217dd7 Compare September 20, 2024 12:59
@asalan316 asalan316 force-pushed the neighbour-app-cutom-metrics branch 8 times, most recently from b30a9fc to 200be0b Compare October 2, 2024 14:32
@asalan316 asalan316 force-pushed the neighbour-app-cutom-metrics branch 7 times, most recently from 31ee44d to 2e9256a Compare October 17, 2024 13:03
@asalan316 asalan316 changed the title Neighbour app custom metrics Allow Different App to Send Custom Metrics Oct 17, 2024
@asalan316 asalan316 changed the title Allow Different App to Send Custom Metrics feat(CustomMetrics): Allow Different App to Send Custom Metrics Oct 17, 2024
@asalan316 asalan316 force-pushed the neighbour-app-cutom-metrics branch 5 times, most recently from 1fb8dce to 840fa60 Compare October 18, 2024 12:46
fix api->broker tests

fix acceptance test

add some logging

fix test

fix db

add acceptance tests

fix db test by setting default to same_app

custom metric strategy should be at the scaling side

add some tests and refactor

fix linters

refactor naming
@asalan316 asalan316 force-pushed the neighbour-app-cutom-metrics branch 3 times, most recently from c5d8a30 to 18a84ce Compare October 18, 2024 14:07
@asalan316 asalan316 marked this pull request as ready for review October 18, 2024 14:19
• [FAILED] [0.063 seconds]
BindingSqldb CreateServiceBinding When service instance exists When service binding is being created first time [It] should succeed
/__w/app-autoscaler-release/app-autoscaler-release/src/autoscaler/db/sqldb/binding_sqldb_test.go:374

  Timeline >>
  {"timestamp":"1729248292.991818190","source":"binding-sqldb-test","message":"binding-sqldb-test.Cleaning service binding test-binding-id-4 failed:doesn't exist","log_level":1,"data":{}}
  {"timestamp":"1729248292.992060423","source":"binding-sqldb-test","message":"binding-sqldb-test.Cleaning service binding test-binding-id-42 failed:doesn't exist","log_level":1,"data":{}}
  {"timestamp":"1729248292.992296696","source":"binding-sqldb-test","message":"binding-sqldb-test.Cleaning service binding test-binding-id-43 failed:doesn't exist","log_level":1,"data":{}}
  {"timestamp":"1729248293.024851084","source":"binding-sqldb-test","message":"binding-sqldb-test.Cleaning service instance test-instance-id-42 failed:doesn't exist","log_level":1,"data":{}}
  {"timestamp":"1729248293.025138617","source":"binding-sqldb-test","message":"binding-sqldb-test.Cleaning service instance test-instance-id-43 failed:doesn't exist","log_level":1,"data":{}}
  {"timestamp":"1729248293.026132822","source":"binding-sqldb-test","message":"binding-sqldb-test.get-service-instance","log_level":2,"data":{"error":"sql: no rows in result set","query":"SELECT * FROM service_instance WHERE service_instance_id = $1","serviceInstanceId":"test-instance-id-4"}}
  {"timestamp":"1729248293.028556824","source":"binding-sqldb-test","message":"binding-sqldb-test.create-service-binding","log_level":2,"data":{"appid":"test-app-id-4","bindingid":"test-binding-id-4","customMetricsStrategy":"","error":"ERROR: insert or update on table \"binding\" violates foreign key constraint \"fk_binding_custom_metrics_strategy\" (SQLSTATE 23503)","query":"INSERT INTO binding(binding_id, service_instance_id, app_id, created_at, custom_metrics_strategy) VALUES($1, $2, $3, $4,$5)","serviceinstanceid":"test-instance-id-4"}}
  [FAILED] in [It] - /__w/app-autoscaler-release/app-autoscaler-release/src/autoscaler/db/sqldb/binding_sqldb_test.go:375 @ 10/18/24 11:44:53.029
  << Timeline

  [FAILED] Unexpected error:
      <*pgconn.PgError | 0xc0003be200>:
      ERROR: insert or update on table "binding" violates foreign key constraint "fk_binding_custom_metrics_strategy" (SQLSTATE 23503)
      {
          Severity: "ERROR",
          SeverityUnlocalized: "ERROR",
          Code: "23503",
          Message: "insert or update on table \"binding\" violates foreign key constraint \"fk_binding_custom_metrics_strategy\"",
          Detail: "Key (custom_metrics_strategy)=() is not present in table \"metrics_submission\".",
          Hint: "",
          Position: 0,
          InternalPosition: 0,
          InternalQuery: "",
          Where: "",
          SchemaName: "public",
          TableName: "binding",
          ColumnName: "",
          DataTypeName: "",
          ConstraintName: "fk_binding_custom_metrics_strategy",
          File: "ri_triggers.c",
          Line: 2608,
          Routine: "ri_ReportViolation",
      }
  occurred
  In [It] at: /__w/app-autoscaler-release/app-autoscaler-release/src/autoscaler/db/sqldb/binding_sqldb_test.go:375 @ 10
@asalan316 asalan316 added allow-acceptance-tests This label needs to be added to enable the acceptance tests to run. and removed allow-acceptance-tests This label needs to be added to enable the acceptance tests to run. labels Oct 21, 2024
@asalan316 asalan316 force-pushed the neighbour-app-cutom-metrics branch 3 times, most recently from b105a31 to 3b57893 Compare October 22, 2024 11:40
@@ -103,7 +113,7 @@ func (*CustomMetricAPIClient) PostCustomMetric(ctx context.Context, appConfig *c
}

metrics := createSingletonMetric(metricName, metricValue)

logger.Info("sending metric to autoscaler for app", "appId", appId, "metricName", metricName, "metricValue", metricValue)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: included for better logging from the test side

bonzofenix and others added 2 commits October 24, 2024 15:27
 • Abstracted database configuration logic into configureDb function for reuse
 • Extended configuration to support BindingDb alongside PolicyDb
 • Updated tests to reflect additional BindingDb configuration
 • Added binding_db tag to mta.tpl.yaml resources
@bonzofenix bonzofenix removed the allow-acceptance-tests This label needs to be added to enable the acceptance tests to run. label Oct 24, 2024
@bonzofenix bonzofenix added the allow-acceptance-tests This label needs to be added to enable the acceptance tests to run. label Oct 25, 2024
Copy link

sonarcloud bot commented Oct 25, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
4.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarCloud

@@ -24,6 +24,10 @@ templates:
policy_db.crt.erb: config/certs/policy_db/crt
policy_db.key.erb: config/certs/policy_db/key

binding_db_ca.crt.erb: config/certs/binding_db/ca.crt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering we have added a new database for the metrics forwarder, we need to ensure that the MTA deployment is functioning correctly: https://github.com/cloudfoundry/app-autoscaler-release/actions/runs/11464983060/job/31903137875?pr=3211. Currently, it seems to be failing due to a different error.

We will need to add the bindingDB tag in the PostgreSQL user-provided service: https://github.com/cloudfoundry/app-autoscaler-release/blob/main/src/autoscaler/mta.tpl.yaml#L43.

Additionally, we must check the metrics forwarder configuration to ensure we are loading the database when running on Cloud Foundry as well: https://github.com/cloudfoundry/app-autoscaler-release/blob/main/src/autoscaler/metricsforwarder/config/config.go#L124.cloudfoundry/app-autoscaler-release/blob/main/src/autoscaler/metricsforwarder/config/config.go#L124

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asalan316 this should fix it: a373e94

// Therefore, only mtls connection will be supported for custom metrics in future
Context("when scaling by custom metrics", func() {
BeforeEach(func() {
//instanceName = CreatePolicy(cfg, appToScaleName, appToScaleGUID, policy)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to remove this commented test

// Therefore, only mtls connection will be supported for custom metrics in future
Context("when scaling by custom metrics", func() {
BeforeEach(func() {
//instanceName = CreatePolicy(cfg, appToScaleName, appToScaleGUID, policy)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we remove this comment?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in this file are all for logging purposes, right? The app that sends metrics should behave the same, even if it is not scaling itself.

policy, err := os.ReadFile(policyFile)
fmt.Println("policy", string(policy)) //FIXME
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we remove this ?

@@ -192,6 +223,7 @@ var _ = Describe("AutoScaler Service Broker", func() {
var instance serviceInstance
It("should update a service instance from one plan to another plan", func() {
servicePlans := GetServicePlans(cfg)
fmt.Println("servicePlans", servicePlans)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mayber we remove this too or turn it into a By statement?

testAppId = "app-to-scale-id"
vars["appid"] = testAppId
req.Header.Add("X-Forwarded-Client-Cert", MustReadXFCCcert(validClientCert2))
// ToDO: this should be read via configurations aka scaling policy binding parameters
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we look into this TODO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
allow-acceptance-tests This label needs to be added to enable the acceptance tests to run. skip-cleanup
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants