Skip to content

Commit

Permalink
feat: add domain as an openfeature concept (#229)
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Beemer <[email protected]>
  • Loading branch information
beeme1mr authored Jan 24, 2024
1 parent 2ad67fc commit afe1c7e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 39 deletions.
10 changes: 5 additions & 5 deletions specification.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
{
"id": "Requirement 1.1.3",
"machine_id": "requirement_1_1_3",
"content": "The `API` MUST provide a function to bind a given `provider` to one or more client `name`s. If the client-name already has a bound provider, it is overwritten with the new mapping.",
"content": "The `API` MUST provide a function to bind a given `provider` to one or more clients using a `domain`. If the domain already has a bound provider, it is overwritten with the new mapping.",
"RFC 2119 keyword": "MUST",
"children": []
},
Expand All @@ -59,7 +59,7 @@
{
"id": "Requirement 1.1.6",
"machine_id": "requirement_1_1_6",
"content": "The `API` MUST provide a function for creating a `client` which accepts the following options: - name (optional): A logical string identifier for the client.",
"content": "The `API` MUST provide a function for creating a `client` which accepts the following options: - domain (optional): A logical string identifier for binding clients to provider.",
"RFC 2119 keyword": "MUST",
"children": []
},
Expand All @@ -80,7 +80,7 @@
{
"id": "Requirement 1.2.2",
"machine_id": "requirement_1_2_2",
"content": "The client interface MUST define a `metadata` member or accessor, containing an immutable `name` field or accessor of type string, which corresponds to the `name` value supplied during client creation.",
"content": "The client interface MUST define a `metadata` member or accessor, containing an immutable `domain` field or accessor of type string, which corresponds to the `domain` value supplied during client creation.",
"RFC 2119 keyword": "MUST",
"children": []
},
Expand Down Expand Up @@ -523,14 +523,14 @@
{
"id": "Conditional Requirement 3.2.2.3",
"machine_id": "conditional_requirement_3_2_2_3",
"content": "The API MUST have a method for setting `evaluation context` for a provider bound to a named client.",
"content": "The API MUST have a method for setting `evaluation context` for a `domain`.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Conditional Requirement 3.2.2.4",
"machine_id": "conditional_requirement_3_2_2_4",
"content": "The API MUST have a a mechanism to manage `evaluation context` for an associated name.",
"content": "The API MUST have a mechanism to manage `evaluation context` for an associated `domain`.",
"RFC 2119 keyword": "MUST",
"children": []
}
Expand Down
7 changes: 5 additions & 2 deletions specification/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A list of terms used within the OpenFeature specification.
sidebar_position: 1
---

# Glossary
# Glossary <!-- omit from toc -->

This document defines some terms that are used across this specification.

Expand All @@ -28,6 +28,7 @@ This document defines some terms that are used across this specification.
- [Evaluation API](#evaluation-api)
- [Flag Management System](#flag-management-system)
- [Provider](#provider)
- [Domain](#domain)
- [Integration](#integration)
- [Evaluation Context](#evaluation-context)
- [Evaluating Flag Values](#evaluating-flag-values)
Expand Down Expand Up @@ -107,7 +108,9 @@ A source-of-truth for flag values and rules. Flag management systems may include

An SDK-compliant implementation which resolves flag values from a particular flag management system, allowing the use of the [Evaluation API](./sections/01-flag-evaluation.md#13-flag-evaluation) as an abstraction for the system in question.

Providers can be used in two ways. Client-specific providers are active for specific clients, based on their name. The default provider is used if there are no client-specific mappings setup.
### Domain

An identifier which logically binds clients with providers, allowing for multiple providers to be used simultaneously within a single application.

### Integration

Expand Down
63 changes: 41 additions & 22 deletions specification/sections/01-flag-evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,29 @@ It's important that multiple instances of the `API` not be active, so that state
OpenFeature.setProvider(new MyProvider());
```

This provider is used if a client is not bound to a specific provider through its name.
The example above sets the default provider.
This provider is used if a client is not bound to a specific provider via a [domain](../glossary.md#domain).

See [provider](./02-providers.md), [creating clients](#creating-clients).
See [provider](./02-providers.md), [creating clients](#creating-clients) for details.

#### Requirement 1.1.2.2

> The `provider mutator` function **MUST** invoke the `initialize` function on the newly registered provider before using it to resolve flag values.
Application authors can await the newly set `provider's` readiness using the `PROVIDER_READY` event.
Provider instances which are already active (because they have been bound to other `names` or otherwise) need not be initialized again.
Provider instances which are already active (because they have been bound to another `domain` or otherwise) need not be initialized again.
The `provider's` readiness can state can be determined from its `status` member/accessor.

See [event handlers and initialization](./05-events.md#event-handlers-and-initialization), [provider initialization](./02-providers.md#24-initialization).
See [event handlers and initialization](./05-events.md#event-handlers-and-initialization), [provider initialization](./02-providers.md#24-initialization), [domain](../glossary.md#domain) for details.

#### Requirement 1.1.2.3

> The `provider mutator` function **MUST** invoke the `shutdown` function on the previously registered provider once it's no longer being used to resolve flag values.
When a provider is no longer in use, it should be disposed of using its `shutdown` mechanism.
Provider instances which are bound to multiple names won't be shut down until the last binding is removed.
Provider instances which are bound to multiple `domains` won't be shut down until the last binding is removed.

see: [shutdown](./02-providers.md#25-shutdown), [setting a provider](#setting-a-provider)
see [shutdown](./02-providers.md#25-shutdown), [setting a provider](#setting-a-provider), [domain](../glossary.md#domain) for details.

#### Requirement 1.1.2.4

Expand All @@ -61,28 +62,30 @@ see: [shutdown](./02-providers.md#25-shutdown), [setting a provider](#setting-a-
This function not only sets the provider, but ensures that the provider is ready (or in error) before returning or settling.

```java
// default client
// default provider
OpenFeatureAPI.getInstance().setProviderAndWait(myprovider); // this method blocks until the provider is ready or in error
// client uses the default provider
Client client = OpenFeatureAPI.getInstance().getClient();

// named client
OpenFeatureAPI.getInstance().setProviderAndWait('client-name', myprovider); // this method blocks until the provider is ready or in error
Client client = OpenFeatureAPI.getInstance().getClient('client-name');
// provider associated with domain-1
OpenFeatureAPI.getInstance().setProviderAndWait('domain-1', myprovider); // this method blocks until the provider is ready or in error
// client uses provider associated with the domain named 'domain-1'
Client client = OpenFeatureAPI.getInstance().getClient('domain-1');
```

Though it's possible to use [events](./05-events.md) to await provider readiness, such functions can make things simpler for `application authors` and `integrators`.

#### Requirement 1.1.3

> The `API` **MUST** provide a function to bind a given `provider` to one or more client `name`s. If the client-name already has a bound provider, it is overwritten with the new mapping.
> The `API` **MUST** provide a function to bind a given `provider` to one or more clients using a `domain`. If the domain already has a bound provider, it is overwritten with the new mapping.
```java
OpenFeature.setProvider("client-name", new MyProvider());
OpenFeature.setProvider("domain-1", new MyProvider());
```

Named clients can be associated with a particular provider by supplying a matching name when the provider is set.
Clients can be associated with a particular provider by supplying a matching `domain`` when the provider is set.

See [creating clients](#creating-clients).
See [creating clients](#creating-clients), [domain](../glossary.md#domain) for details.

#### Requirement 1.1.4

Expand All @@ -104,25 +107,38 @@ See [hooks](./04-hooks.md) for details.
OpenFeature.getProviderMetadata();
```

See [provider](./02-providers.md) for details.
It's possible to access provider metadata using a `domain`.
If a provider has not be registered under the requested domain, the default provider metadata is returned.

```typescript
// example provider accessor
OpenFeature.getProviderMetadata("domain-1");
```

See [provider](./02-providers.md), [domain](../glossary.md#domain) for details.

### Creating clients

#### Requirement 1.1.6

> The `API` **MUST** provide a function for creating a `client` which accepts the following options:
>
> - name (optional): A logical string identifier for the client.
> - domain (optional): A logical string identifier for binding clients to provider.
```java
// example client creation and retrieval
OpenFeature.getClient("my-named-client");
OpenFeature.getClient();
```

The name is a logical identifier for the client which may be associated with a particular provider by the application integrator.
If a client name is not bound to a particular provider, the client is associated with the default provider.
It's possible to create a client that is associated with a `domain`.
The client will use a provider in the same `domain` if one exists, otherwise, the default provide is used.

See [setting a provider](#setting-a-provider) for details.
```java
// example client creation and retrieval using a domain
OpenFeature.getClient("domain-1");
```

See [setting a provider](#setting-a-provider), [domain](../glossary.md#domain) for details.

#### Requirement 1.1.7

Expand All @@ -145,12 +161,15 @@ See [hooks](./04-hooks.md) for details.

#### Requirement 1.2.2

> The client interface **MUST** define a `metadata` member or accessor, containing an immutable `name` field or accessor of type string, which corresponds to the `name` value supplied during client creation.
> The client interface **MUST** define a `metadata` member or accessor, containing an immutable `domain` field or accessor of type string, which corresponds to the `domain` value supplied during client creation.
```typescript
client.getMetadata().getName(); // "my-client"
client.getMetadata().getDomain(); // "domain-1"
```

In previous drafts, this property was called `name`.
For backwards compatibility, implementations should consider `name` an alias to `domain`.

### 1.3. Flag Evaluation

[![hardening](https://img.shields.io/static/v1?label=Status&message=hardening&color=yellow)](https://github.com/open-feature/spec/tree/main/specification#hardening)
Expand Down
12 changes: 6 additions & 6 deletions specification/sections/03-evaluation-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,19 @@ In the static-context paradigm, context is global. The client and invocation can

##### Conditional Requirement 3.2.2.3

> The API **MUST** have a method for setting `evaluation context` for a provider bound to a named client.
> The API **MUST** have a method for setting `evaluation context` for a `domain`.
In the static-context paradigm, provider specific context can be set using the associated name.
In the static-context paradigm, provider specific context can be set using the associated `domain`.
The global context is used if there is no matching provider specific context.

See [setting a provider](./01-flag-evaluation.md#setting-a-provider) for details.
See [setting a provider](./01-flag-evaluation.md#setting-a-provider), [domain](../glossary.md#domain) for details.

##### Conditional Requirement 3.2.2.4

> The API **MUST** have a a mechanism to manage `evaluation context` for an associated name.
> The API **MUST** have a mechanism to manage `evaluation context` for an associated `domain`.
In the static-context paradigm, it must be possible to create and remove provider-specific context.
See [setting a provider](./01-flag-evaluation.md#setting-a-provider) for details.
In the static-context paradigm, it's possible to create and remove provider-specific context.
See [setting a provider](./01-flag-evaluation.md#setting-a-provider), [domain](../glossary.md#domain) for details.

#### Requirement 3.2.3

Expand Down
8 changes: 4 additions & 4 deletions specification/sections/05-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ see: [provider event types](./../types.md#provider-events) and [event handlers](

> When a `provider` signals the occurrence of a particular `event`, event handlers on clients which are not associated with that provider **MUST NOT** run.
Providers bound to a named client constitute their own "events scope".
Providers bound to a `domain` constitute their own "events scope".

see: [setting a provider](./01-flag-evaluation.md#setting-a-provider)
see [setting a provider](./01-flag-evaluation.md#setting-a-provider), [domain](../glossary.md#domain) for details.

#### Requirement 5.1.4

Expand Down Expand Up @@ -83,9 +83,9 @@ see: [provider events](#51-provider-events), [`provider event types`](../types.m
> The `event details` **MUST** contain the `provider name` associated with the event.
The `provider name` indicates the provider from which the event originated.
This is especially relevant for global event handlers used for general monitoring, such as alerting on provider errors.
This is especially relevant for global event handlers used for general monitoring, such as alerting on provider errors.

See [setting a provider](./01-flag-evaluation.md#setting-a-provider), [creating clients](./01-flag-evaluation.md#creating-clients).
See [setting a provider](./01-flag-evaluation.md#setting-a-provider), [creating clients](./01-flag-evaluation.md#creating-clients).

#### Requirement 5.2.4

Expand Down

0 comments on commit afe1c7e

Please sign in to comment.