Skip to content

Commit

Permalink
Merge main to preview (#373)
Browse files Browse the repository at this point in the history
* Add a constructor without FeatureManagementOption parameter for FeatureManager (#363)

* add new constructor

* update

* Target on .NET 8.0 (#365)

* target on .NET 8.0

* remove file

* add net8.0 for Microsoft.FeatureManagement.AspNetCore

* update package version

* update

* Add feature management schema for main branch (#362)

* schema file added

* README update

* update

* update

* update README & remove the Microsoft schema file

* update readme

* update

* Updates test schema and adjusts title (#372)

* Support Microsoft Feature Management schema for main branch (#370)

* use snake case

* do not support root fall back for MS schema & remove EnsureInit

* update

* rename variable

* update .NET FM schema

* re-add schema link

* add whitespace (#374)

* update

---------

Co-authored-by: Ross Grambo <rossgrambo@microsoft.com>
  • Loading branch information
zhiyuanliang-ms and rossgrambo authored Feb 23, 2024
1 parent 40b3ca6 commit 9a7f2ff
Show file tree
Hide file tree
Showing 13 changed files with 427 additions and 325 deletions.
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ The feature management library supports appsettings.json as a feature flag sourc

The `FeatureManagement` section of the json document is used by convention to load feature flag settings. In the section above, we see that we have provided three different features. Features define their feature filters using the `EnabledFor` property. In the feature filters for `FeatureT` we see `AlwaysOn`. This feature filter is built-in and if specified will always enable the feature. The `AlwaysOn` feature filter does not require any configuration, so it only has the `Name` property. `FeatureU` has no filters in its `EnabledFor` property and thus will never be enabled. Any functionality that relies on this feature being enabled will not be accessible as long as the feature filters remain empty. However, as soon as a feature filter is added that enables the feature it can begin working. `FeatureV` specifies a feature filter named `TimeWindow`. This is an example of a configurable feature filter. We can see in the example that the filter has a `Parameters` property. This is used to configure the filter. In this case, the start and end times for the feature to be active are configured.

The detailed schema of the `FeatureManagement` section can be found [here](./schemas/FeatureManagement.Dotnet.v1.0.0.schema.json).

**Advanced:** The usage of colon ':' in feature flag names is forbidden.

#### On/Off Declaration
Expand Down Expand Up @@ -126,7 +128,7 @@ The `RequirementType` property of a feature flag is used to determine if the fil

A `RequirementType` of `All` changes the traversal. First, if there are no filters, the feature will be disabled. Then, the feature-filters are traversed until one of the filters decides that the feature should be disabled. If no filter indicates that the feature should be disabled, then it will be considered enabled.

```
``` JavaScript
"FeatureW": {
"RequirementType": "All",
"EnabledFor": [
Expand Down Expand Up @@ -154,7 +156,7 @@ In the above example, `FeatureW` specifies a `RequirementType` of `All`, meaning
`Status` is an optional property of a feature flag that controls how a flag's enabled state is evaluated. By default, the status of a flag is `Conditional`, meaning that feature filters should be evaluated to determine if the flag is enabled. If the `Status` of a flag is set to `Disabled` then feature filters are not evaluated and the flag is always considered to be disabled.


```
``` JavaScript
"FeatureX": {
"Status": "Disabled",
"EnabledFor": [
Expand All @@ -167,6 +169,36 @@ In the above example, `FeatureW` specifies a `RequirementType` of `All`, meaning

In this example, even though the `AlwaysOn` filter would normally always make the feature enabled, the `Status` property is set to `Disabled`, so this feature will always be disabled.

#### Microsoft Feature Management Schema

The feature management library also supports the usage of the [`Microsoft Feature Management schema`](https://github.com/Azure/AppConfiguration/blob/main/docs/FeatureManagement/FeatureManagement.v1.0.0.schema.json) to declare feature flags. This schema is language agnostic in origin and is supported by all Microsoft feature management libraries.

``` JavaScript
{
"feature_management": {
"feature_flags": [
{
"id": "FeatureT",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 July 2023 00:00:00 GMT"
}
}
]
}
}
]
}
}
```

**Note:** If the `feature_management` section can be found in the configuration, the `FeatureManagement` section will be ignored.

## Consumption

The basic form of feature management is checking if a feature flag is enabled and then performing actions based on the result. This is done through the `IFeatureManager`'s `IsEnabledAsync` method.
Expand Down
6 changes: 4 additions & 2 deletions build/install-dotnet.ps1
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Installs .NET 6 and .NET 7 for CI/CD environment
# Installs .NET 6, .NET 7 and .NET 8 for CI/CD environment
# see: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script#examples

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;

&([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Channel 6.0

&([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Channel 7.0
&([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Channel 7.0

&([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Channel 8.0
112 changes: 112 additions & 0 deletions schemas/FeatureManagement.Dotnet.v1.0.0.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "A .NET Feature Management Configuration",
"required": [
"FeatureManagement"
],
"properties":{
"FeatureManagement": {
"type": "object",
"title": "Feature Management",
"description": "Declares feature management configuration.",
"required": [],
"patternProperties": {
"^[^:]*$": {
"description": "Declares a feature flag.",
"anyOf": [
{
"type": "boolean",
"title": "On/Off Feature Flag",
"description": "A feature flag that always returns the same value."
},
{
"type": "object",
"title": "Conditional Feature Flag",
"description": "A feature flag which value is dynamic based on a set of feature filters",
"required": [
"EnabledFor"
],
"properties": {
"RequirementType": {
"type": "string",
"title": "Requirement Type",
"description": "Determines whether any or all registered feature filters must be enabled for the feature to be considered enabled.",
"enum": [
"Any",
"All"
],
"default": "Any"
},
"EnabledFor": {
"oneOf": [
{
"type": "array",
"title": "Feature Filter Collection",
"description": "Feature filters that are evaluated to conditionally enable the flag.",
"items": {
"type": "object",
"title": "Feature Filter Declaration",
"required": [
"Name"
],
"properties": {
"Name": {
"type": "string",
"title": "Feature Filter Name",
"description": "The name used to refer to and require a feature filter.",
"default": "",
"examples": [
"Percentage",
"TimeWindow"
],
"pattern": "^[^:]*$"
},
"Parameters": {
"type": "object",
"title": "Feature Filter Parameters",
"description": "Custom parameters for a given feature filter. A feature filter can require any set of parameters of any type.",
"required": [],
"patternProperties": {
"^.*$": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
},
{
"type": "object"
},
{
"type": "number"
},
{
"type": "array"
},
{
"type": "boolean"
}
]
}
}
}
}
}
},
{
"type": "boolean"
}
]
},
"additionalProperties": false
}
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<Import Project="..\..\build\Versioning.props" />

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>..\..\build\Microsoft.FeatureManagement.snk</AssemblyOriginatorKeyFile>
Expand Down
Loading

0 comments on commit 9a7f2ff

Please sign in to comment.