radius-project / radius

Radius is a cloud-native, portable application platform that makes app development easier for teams building cloud-native apps.
https://radapp.io
Apache License 2.0
1.49k stars 95 forks source link

Implementation of Dapr Building Block: Configuration Store #7889

Closed SoTrx closed 1 month ago

SoTrx commented 1 month ago

Overview of feature request

The Dapr configuration building block allows for dynamic configuration updates, including feature flag management.

For Radius, supporting this building block could enhance the "code once, deploy everywhere" approach, as platform differences may necessitate the use of feature flags.

Acceptance criteria

Additional context

https://docs.dapr.io/developing-applications/building-blocks/configuration/

Would you like to support us?

AB#13152

radius-triage-bot[bot] commented 1 month ago

:wave: @SoTrx Thanks for filing this feature request.

A project maintainer will review this feature request and get back to you soon.

We also welcome community contributions! If you would like to pick this item up sooner and submit a pull request, please visit our contribution guidelines and assign this to yourself by commenting "/assign" on this issue.

For more information on our triage process please visit our triage overview

radius-triage-bot[bot] commented 1 month ago

:+1: We've reviewed this issue and have agreed to add it to our backlog. Please subscribe to this issue for notifications, we'll provide updates when we pick it up.

We also welcome community contributions! If you would like to pick this item up sooner and submit a pull request, please visit our contribution guidelines and assign this to yourself by commenting "/assign" on this issue.

For more information on our triage process please visit our triage overview

lakshmimsft commented 1 month ago

@SoTrx, thanks for your willingness to contribute! Pls don't hesitate to reach out for support.

SoTrx commented 1 month ago

/assign

SoTrx commented 1 month ago

Changes for users

This update introduces the Dapr Configuration Building Block, enabling applications to consume configuration data as read-only key/value pairs and receive notifications via callback when changes occur. The configuration is stored in a backing service, which can be any Dapr-supported service. From a Radius user perspective, the configuration store is accessed as Applications.Dapr/configurationStores.

resource myapp 'Applications.Core/containers@2023-10-01-preview' = {
  name: '${baseName}-ctnr'
  properties: {
    connections: {
      config: {
        source: configStore.id
      }
    }
  ...
  }
}

resource configStore 'Applications.Dapr/configurationStores@2023-10-01-preview' = {
  name: '${baseName}-cpn'
  properties: {
    application: app.id
    environment: env.id
  }
}

Using a connection with a configurationStore injects the corresponding Dapr component name into the app container environment variable as CONNECTION_$(connection_name)_COMPONENTNAME. This allows the application to access the configuration as shown below:

ctx := context.Background()
client, _:= dapr.NewClient()
// Retrieve the initial configuration values for key "config_key"
items, err := client.GetConfigurationItems(ctx, CONNECTION_CONFIG_COMPONENTNAME, ["config_key"])
// Subscribe to updates to the values of "config_key"
subId, _:= client.SubscribeConfigurationItems(ctx, CONNECTION_CONFIG_COMPONENTNAME, []string{"config_key"})

Changes in Radius

This change adds the resource type Applications.Dapr/ConfigurationStores to the Dapr resource provider. This addition has no side effects on other resources in the provider.

This changes adds the resource type application.Dapr/ConfigurationStores to the Dapr resource provider. This addition has no side-effect on other resources in the provider.

Frontend

model DaprConfigurationStoreResource
  is TrackedResourceRequired<
    DaprConfigurationStoreProperties,
    "DaprConfigurationStores"
  > {
  @doc("Configuration Store name")
  @key("configurationStoreName")
  @path
  @segment("configurationStores")
  name: ResourceNameString;
}

@doc("Dapr configuration store portable resource properties")
model DaprConfigurationStoreProperties {
  ...EnvironmentScopedResource;
  ...DaprResourceProperties;

  @doc("A collection of references to resources associated with the configuration store")
  resources?: ResourceReference[];

  ...RecipeBaseProperties;
}

Inner representation

type DaprConfigurationStore struct {
    v1.BaseResource

     // (Properties common to other components)
    Properties DaprConfigurationStoreProperties `json:"properties"`

    // ResourceMetadata represents internal DataModel properties common to all portable resource types.
    datamodel.PortableResourceMetadata
}

Example emitted component

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: configstore
  [labels]
spec:
  type: configuration.redis
  metadata:
  - name: redisHost
    value: localhost:6379
  - name: redisPassword
    value: <PASSWORD>

Let me know If I need to add anything to this description