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: flagd provider basic functionality #31

Merged

Conversation

bacherfl
Copy link
Contributor

This PR builds upon the work that @benjiro did with regards to the Flagd implementation. In this PR, I added the Readme, added the remaining xml doc comments and added Unit tests.

benjiro and others added 2 commits January 31, 2023 15:21
Signed-off-by: Benjamin Evenson <[email protected]>
Signed-off-by: Florian Bacher <[email protected]>
@bacherfl bacherfl force-pushed the feat/flagd-provider-implementation branch from 2bb8961 to aa8b6ca Compare January 31, 2023 14:21
Signed-off-by: Florian Bacher <[email protected]>
Signed-off-by: Florian Bacher <[email protected]>
@toddbaert
Copy link
Member

I'll be looking at this today/tomorrow. Thanks @bacherfl !

@toddbaert toddbaert force-pushed the feat/flagd-provider-implementation branch from 47f7160 to b6cfdb1 Compare February 2, 2023 21:27
Copy link
Member

@toddbaert toddbaert left a comment

Choose a reason for hiding this comment

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

wow @bacherfl and @benjiro ! Nice work. I think this looks good for a alpha release. I think the only thing I would like to see addressed in this PR would be changes to just throw in error conditions instead of manually returning the default - the SDK does that for us. Your tests look good to me as well. Quick question - did you manually test this as well with a small sample app of some kind? We will soon write integration tests using this provider in the dotnet SDK, so it will get tested rigorously eventually... I'm just wondering.

One other thing I will do is make sure to set this as a 0.0.1 release (if I don't do that, it will default to 1.0.0, which I'm sure we don't want at the moment). I can do this with changes to the release manifest, so don't worry and let me handle that part once we are otherwise set to merge! - this is already done.

The other things to do are:

  • automatically generate the grpc assets
  • add an LRU cache
  • automatic config via environment variables
  • Unix socket support
  • TLS support

I will create separate issues for these, and anyone can do them. Really great work, again!

src/OpenFeature.Contrib.Providers.Flagd/FlagdProvider.cs Outdated Show resolved Hide resolved
Comment on lines 1 to 4
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: schema/v1/schema.proto
// </auto-generated>
Copy link
Member

@toddbaert toddbaert Feb 2, 2023

Choose a reason for hiding this comment

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

Unless you see some reason not to, I would .gitignore all this generated code and simply make sure the build reliably produces it. Again something we don't have to do now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, having this in the .gitignore definitely makes sense! I will try to get the files being generated on demand by the build and will let you know if I manage to do it in this PR, or if i need to do some more research + an extra PR to set this up in a more tidy way

Copy link
Contributor Author

Choose a reason for hiding this comment

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

alright, I think I managed to do it :) the Grpc client is now generated during the build, based on the .proto file in the imported submodule. @toddbaert do you know if in the build pipeline all git submodules are pulled when checking out the code? If not, i think this might need to be adapted to make the build + tests pass

Copy link
Member

Choose a reason for hiding this comment

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

I will add this!

Copy link
Member

Choose a reason for hiding this comment

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

I've done it.

src/OpenFeature.Contrib.Providers.Flagd/FlagdProvider.cs Outdated Show resolved Hide resolved
}
catch (Grpc.Core.RpcException e)
{
return GetDefaultWithException<bool>(e, flagKey, defaultValue);
Copy link
Member

@toddbaert toddbaert Feb 2, 2023

Choose a reason for hiding this comment

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

I would simplify the logic here a bit just to throw an informative error (you still make need to set the correct error code). The SDK itself will always handle any errors by defaulting. The most straightforward thing for a provider to do is simply throw an error with the correct code. https://github.com/open-feature/dotnet-sdk/blob/main/src/OpenFeature/Error/FeatureProviderException.cs

https://docs.openfeature.dev/docs/reference/concepts/provider#how-should-i-handle-error-conditions

This will be slightly easier when this is done, but you can do it now by just setting the right error type on the existing generic error class.

@bacherfl
Copy link
Contributor Author

bacherfl commented Feb 3, 2023

wow @bacherfl and @benjiro ! Nice work. I think this looks good for a alpha release. I think the only thing I would like to see addressed in this PR would be changes to just throw in error conditions instead of manually returning the default - the SDK does that for us. Your tests look good to me as well. Quick question - did you manually test this as well with a small sample app of some kind? We will soon write integration tests using this provider in the dotnet SDK, so it will get tested rigorously eventually... I'm just wondering.

One other thing I will do is make sure to set this as a 0.0.1 release (if I don't do that, it will default to 1.0.0, which I'm sure we don't want at the moment). I can do this with changes to the release manifest, so don't worry and let me handle that part once we are otherwise set to merge!

The other things to do are:

  • automatically generate the grpc assets
  • add an LRU cache
  • automatic config via environment variables
  • Unix socket support
  • TLS support

I will create separate issues for these, and anyone can do them. Really great work, again!

Hi @toddbaert thanks a lot for the review! I will address your comments as soon as possible and will keep you updated when I have pushed my changes! Regarding your question: I did do a quick manual test by running flagd locally and using the SDK with the Flagd provider registered (i.e. the example from the readme) - will do that again once I have made all adaptations to make sure everything works as expected :)

@toddbaert
Copy link
Member

I've created 3 related issues. @bacherfl if you'd like to be assigned any of these, let me know.

#35
#36
#37

@bacherfl bacherfl marked this pull request as ready for review February 9, 2023 15:42
Comment on lines +31 to +32
<PackageReference Include="Grpc.Tools" Version="2.51.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for looking into this!

My only (minor) suggestion here is to move this and the ItemGroup element referencing the .proto file together, and add a little comment on how this generates the sources.

Comment on lines +1 to +96
# Flagd Feature Flag .NET Provider

Coming soon!
The Flagd Flag provider allows you to connect to your Flagd instance.

# .Net SDK usage

## Install dependencies

The first things we will do is install the **Open Feature SDK** and the **GO Feature Flag provider**.

### .NET Cli
```shell
dotnet add package OpenFeature.Contrib.Providers.Flagd
```
### Package Manager

```shell
NuGet\Install-Package OpenFeature.Contrib.Providers.Flagd
```
### Package Reference

```xml
<PackageReference Include="OpenFeature.Contrib.Providers.Flagd" />
```
### Packet cli

```shell
paket add OpenFeature.Contrib.Providers.Flagd
```

### Cake

```shell
// Install OpenFeature.Contrib.Providers.Flagd as a Cake Addin
#addin nuget:?package=OpenFeature.Contrib.Providers.Flagd

// Install OpenFeature.Contrib.Providers.Flagd as a Cake Tool
#tool nuget:?package=OpenFeature.Contrib.Providers.Flagd
```

## Using the FlagdProvider with the OpenFeature SDK

This example assumes that the flagd server is running locally
For example, you can start flagd with the following example configuration:

```shell
flagd start --uri https://raw.githubusercontent.com/open-feature/flagd/main/config/samples/example_flags.json
```

When the flagd service is running, you can use the SDK with the FlagdProvider as in the following example console application:

```csharp
using OpenFeature.Contrib.Providers.Flagd;

namespace OpenFeatureTestApp
{
class Hello {
static void Main(string[] args) {
var flagdProvider = new FlagdProvider(new Uri("http://localhost:8013"));

// Set the flagdProvider as the provider for the OpenFeature SDK
OpenFeature.Api.Instance.SetProvider(flagdProvider);

var client = OpenFeature.Api.Instance.GetClient("my-app");

var val = client.GetBooleanValue("myBoolFlag", false, null);

// Print the value of the 'myBoolFlag' feature flag
System.Console.WriteLine(val.Result.ToString());
}
}
}
```

### Configuring the FlagdProvider

The URI of the flagd server to which the `FlagdProvider` connects to can either be passed directly to the constructor, or be configured using the following environment variables:

| Option name | Environment variable name | Type | Default | Values |
| --------------------- | ------------------------------- | ------- | --------- | ------------- |
| host | FLAGD_HOST | string | localhost | |
| port | FLAGD_PORT | number | 8013 | |
| tls | FLAGD_TLS | boolean | false | |

So for example, if you would like to pass the URI directly, you can initialise it as follows:

```csharp
var flagdProvider = new FlagdProvider(new Uri("http://localhost:8013"));
```

Or, if you rely on the environment variables listed above, you can use the empty costructor:


```csharp
var flagdProvider = new FlagdProvider();
```
Copy link
Member

Choose a reason for hiding this comment

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

Nothing to say except great work!

Signed-off-by: Todd Baert <[email protected]>
@toddbaert toddbaert force-pushed the feat/flagd-provider-implementation branch from d734bfc to 27f592f Compare February 10, 2023 19:52
@toddbaert toddbaert self-requested a review February 10, 2023 19:54
Signed-off-by: Todd Baert <[email protected]>
@toddbaert toddbaert force-pushed the feat/flagd-provider-implementation branch from c7e13b1 to 8877ada Compare February 10, 2023 20:25
@toddbaert
Copy link
Member

toddbaert commented Feb 10, 2023

@bacherfl Amazing work! Everything seems to work great. I made very some small changes (and one suggestion above):

  • pulled in the submodule in the CI as you mentioned
  • added conditional compilation for non NETSTANDARD2_0 platforms (see commit, and here for more info)
  • ran dotnet format

I think we are done here 😎 . I can't thank you enough for your help.

Comment on lines +376 to +383
#if NETSTANDARD2_0
return new Service.ServiceClient(GrpcChannel.ForAddress(url));
#else
return new Service.ServiceClient(GrpcChannel.ForAddress(url, new GrpcChannelOptions
{
HttpHandler = new WinHttpHandler()
}));
#endif
Copy link
Member

@toddbaert toddbaert Feb 10, 2023

Choose a reason for hiding this comment

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

@benjiro does this look right to you? It seems to pass in all the test scenarios now (462 was previously failing).

@bacherfl
Copy link
Contributor Author

@bacherfl Amazing work! Everything seems to work great. I made very some small changes (and one suggestion above):

  • pulled in the submodule in the CI as you mentioned
  • added conditional compilation for non NETSTANDARD2_0 platforms (see commit, and here for more info)
  • ran dotnet format

I think we are done here 😎 . I can't thank you enough for your help.

Thanks @toddbaert for the review and your help! I just pushed the suggested changes with regards to the .csproj file, so the PR should be good to go :)

@toddbaert toddbaert changed the title feat: flagd provider implementation feat: flagd provider basic functionality Feb 13, 2023
@toddbaert toddbaert merged commit 5ed9336 into open-feature:main Feb 13, 2023
@github-actions github-actions bot mentioned this pull request Feb 13, 2023
vpetrusevici pushed a commit to vpetrusevici/open-feature-dotnet-sdk-contrib that referenced this pull request Oct 18, 2023
feat: implement the flagd provider

Signed-off-by: Florian Bacher <[email protected]>
Co-authored-by: Benjamin Evenson <[email protected]>
Co-authored-by: Todd Baert <[email protected]>
Signed-off-by: Vladimir Petrusevici <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants