|
| 1 | +# Confidence OpenFeature Local Provider Demo |
| 2 | + |
| 3 | +This demo application demonstrates how to use the Confidence OpenFeature Local Provider in Go. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The demo shows how to: |
| 8 | +- Initialize the LocalResolverFactory with authentication |
| 9 | +- Create and register the OpenFeature provider |
| 10 | +- Evaluate different types of flags (boolean, string, integer, float, object) |
| 11 | +- Use nested flag paths |
| 12 | +- Pass evaluation context with targeting keys |
| 13 | + |
| 14 | +## Prerequisites |
| 15 | + |
| 16 | +1. **Go 1.21 or later** installed |
| 17 | +2. **Confidence Account** with API credentials |
| 18 | +3. **WASM Resolver Module** (resolver.wasm file) |
| 19 | + |
| 20 | +## Configuration |
| 21 | + |
| 22 | +The demo uses environment variables for configuration: |
| 23 | + |
| 24 | +### Required Credentials |
| 25 | + |
| 26 | +```bash |
| 27 | +export CONFIDENCE_API_CLIENT_ID="your-api-client-id" |
| 28 | +export CONFIDENCE_API_CLIENT_SECRET="your-api-client-secret" |
| 29 | +export CONFIDENCE_CLIENT_SECRET="your-application-client-secret" |
| 30 | +``` |
| 31 | + |
| 32 | +### Optional Configuration |
| 33 | + |
| 34 | +```bash |
| 35 | +# Service addresses (defaults to EU region) |
| 36 | +export CONFIDENCE_RESOLVER_STATE_SERVICE_ADDR="resolver.eu.confidence.dev:443" |
| 37 | +export CONFIDENCE_FLAG_LOGGER_SERVICE_ADDR="events.eu.confidence.dev:443" |
| 38 | +export CONFIDENCE_AUTH_SERVICE_ADDR="iam.eu.confidence.dev:443" |
| 39 | + |
| 40 | +# WASM file path (default: ../../../bin/resolver.wasm) |
| 41 | +export CONFIDENCE_WASM_FILE_PATH="/path/to/resolver.wasm" |
| 42 | + |
| 43 | +# State fetching interval in seconds (default: 300 = 5 minutes) |
| 44 | +export CONFIDENCE_RESOLVER_POLL_INTERVAL_SECONDS="300" |
| 45 | +``` |
| 46 | + |
| 47 | +### For US Region |
| 48 | + |
| 49 | +If you're using the US region, set these environment variables: |
| 50 | + |
| 51 | +```bash |
| 52 | +export CONFIDENCE_RESOLVER_STATE_SERVICE_ADDR="resolver.us.confidence.dev:443" |
| 53 | +export CONFIDENCE_FLAG_LOGGER_SERVICE_ADDR="events.us.confidence.dev:443" |
| 54 | +export CONFIDENCE_AUTH_SERVICE_ADDR="iam.us.confidence.dev:443" |
| 55 | +``` |
| 56 | + |
| 57 | +## Getting Your Credentials |
| 58 | + |
| 59 | +1. **API Client ID and Secret**: |
| 60 | + - Go to your Confidence dashboard |
| 61 | + - Navigate to Settings → API Credentials |
| 62 | + - Create a new API credential or use an existing one |
| 63 | + - Copy the Client ID and Client Secret |
| 64 | + |
| 65 | +2. **Application Client Secret**: |
| 66 | + - Go to your Confidence dashboard |
| 67 | + - Navigate to your application settings |
| 68 | + - Copy the Client Secret for your application |
| 69 | + |
| 70 | +3. **WASM Resolver Module**: |
| 71 | + - Download from the Confidence SDK releases |
| 72 | + - Or build from source: `cd ../../../wasm && cargo build --release` |
| 73 | + - The WASM file should be at `../../../bin/resolver.wasm` |
| 74 | + |
| 75 | +## Running the Demo |
| 76 | + |
| 77 | +1. **Install dependencies**: |
| 78 | + ```bash |
| 79 | + go mod tidy |
| 80 | + ``` |
| 81 | + |
| 82 | +2. **Set environment variables**: |
| 83 | + ```bash |
| 84 | + export CONFIDENCE_API_CLIENT_ID="your-api-client-id" |
| 85 | + export CONFIDENCE_API_CLIENT_SECRET="your-api-client-secret" |
| 86 | + export CONFIDENCE_CLIENT_SECRET="your-client-secret" |
| 87 | + ``` |
| 88 | + |
| 89 | +3. **Run the demo**: |
| 90 | + ```bash |
| 91 | + go run main.go |
| 92 | + ``` |
| 93 | + |
| 94 | +## Expected Output |
| 95 | + |
| 96 | +``` |
| 97 | +Starting Confidence OpenFeature Local Provider Demo |
| 98 | +Auth Service: iam.eu.confidence.dev:443 |
| 99 | +Resolver State Service: resolver.eu.confidence.dev:443 |
| 100 | +Flag Logger Service: events.eu.confidence.dev:443 |
| 101 | +WASM File: ../../../bin/resolver.wasm |
| 102 | +
|
| 103 | +Loaded WASM module (XXXXX bytes) |
| 104 | +Creating LocalResolverFactory... |
| 105 | +LocalResolverFactory created successfully |
| 106 | +Creating OpenFeature provider... |
| 107 | +OpenFeature provider registered |
| 108 | +
|
| 109 | +=== Flag Evaluation Demo === |
| 110 | +
|
| 111 | +1. Evaluating boolean flag 'feature-toggle': |
| 112 | + Value: true |
| 113 | + Variant: control |
| 114 | + Reason: TARGETING_MATCH |
| 115 | +
|
| 116 | +2. Evaluating string flag 'welcome-message': |
| 117 | + Value: Welcome! |
| 118 | + Variant: variant-a |
| 119 | + Reason: TARGETING_MATCH |
| 120 | +
|
| 121 | +... |
| 122 | +
|
| 123 | +=== Demo Complete === |
| 124 | +``` |
| 125 | + |
| 126 | +## Demo Examples |
| 127 | + |
| 128 | +The demo includes examples of: |
| 129 | + |
| 130 | +### 1. Boolean Flag |
| 131 | +```go |
| 132 | +boolResult := client.BooleanValueDetails(ctx, "feature-toggle", false, evalCtx) |
| 133 | +``` |
| 134 | + |
| 135 | +### 2. String Flag |
| 136 | +```go |
| 137 | +stringResult := client.StringValueDetails(ctx, "welcome-message", "Hello!", evalCtx) |
| 138 | +``` |
| 139 | + |
| 140 | +### 3. Integer Flag |
| 141 | +```go |
| 142 | +intResult := client.IntValueDetails(ctx, "max-items", 10, evalCtx) |
| 143 | +``` |
| 144 | + |
| 145 | +### 4. Float Flag |
| 146 | +```go |
| 147 | +floatResult := client.FloatValueDetails(ctx, "discount-rate", 0.0, evalCtx) |
| 148 | +``` |
| 149 | + |
| 150 | +### 5. Object Flag |
| 151 | +```go |
| 152 | +objectResult := client.ObjectValueDetails(ctx, "theme-config", map[string]interface{}{}, evalCtx) |
| 153 | +``` |
| 154 | + |
| 155 | +### 6. Nested Flag Value (Dot Notation) |
| 156 | +```go |
| 157 | +// Returns flag_value["primaryColor"] |
| 158 | +stringResult := client.StringValueDetails(ctx, "theme-config.primaryColor", "#000000", evalCtx) |
| 159 | +``` |
| 160 | + |
| 161 | +### 7. Targeting Key |
| 162 | +```go |
| 163 | +evalCtx := openfeature.NewTargetingKey("session-xyz") |
| 164 | +boolResult := client.BooleanValueDetails(ctx, "beta-feature", false, evalCtx) |
| 165 | +``` |
| 166 | + |
| 167 | +## Evaluation Context |
| 168 | + |
| 169 | +The demo shows different ways to create evaluation contexts: |
| 170 | + |
| 171 | +```go |
| 172 | +// With targeting key and attributes |
| 173 | +evalCtx := openfeature.NewEvaluationContext( |
| 174 | + "user-123", |
| 175 | + map[string]interface{}{ |
| 176 | + |
| 177 | + "region": "US", |
| 178 | + "plan": "premium", |
| 179 | + }, |
| 180 | +) |
| 181 | + |
| 182 | +// Just targeting key |
| 183 | +evalCtx := openfeature.NewTargetingKey("session-xyz") |
| 184 | +``` |
| 185 | + |
| 186 | +## Troubleshooting |
| 187 | + |
| 188 | +### "FLAG_NOT_FOUND" Errors |
| 189 | + |
| 190 | +If you see flag not found errors: |
| 191 | +1. Verify you have flags created in your Confidence account |
| 192 | +2. Check that the flag names match exactly |
| 193 | +3. Ensure your client secret is correct |
| 194 | + |
| 195 | +### Authentication Errors |
| 196 | + |
| 197 | +If you see authentication errors: |
| 198 | +1. Verify your API credentials are correct |
| 199 | +2. Check that you're using the correct region (EU vs US) |
| 200 | +3. Ensure your credentials have the necessary permissions |
| 201 | + |
| 202 | +### WASM File Not Found |
| 203 | + |
| 204 | +If you see WASM file errors: |
| 205 | +1. Check the file path: `CONFIDENCE_WASM_FILE_PATH` |
| 206 | +2. Build the WASM module if needed |
| 207 | +3. Verify the file exists and is readable |
| 208 | + |
| 209 | +### Connection Errors |
| 210 | + |
| 211 | +If you see connection errors: |
| 212 | +1. Check your internet connection |
| 213 | +2. Verify the service addresses are correct for your region |
| 214 | +3. Check if you're behind a proxy or firewall |
| 215 | + |
| 216 | +## Next Steps |
| 217 | + |
| 218 | +After running the demo: |
| 219 | + |
| 220 | +1. **Create your own flags** in the Confidence dashboard |
| 221 | +2. **Modify the demo** to evaluate your flags |
| 222 | +3. **Integrate into your application** using the same pattern |
| 223 | +4. **Add your own evaluation context** attributes based on your use case |
| 224 | + |
| 225 | +## Integration Example |
| 226 | + |
| 227 | +Here's a minimal example of integrating the provider into your application: |
| 228 | + |
| 229 | +```go |
| 230 | +package main |
| 231 | + |
| 232 | +import ( |
| 233 | + "context" |
| 234 | + "log" |
| 235 | + "os" |
| 236 | + |
| 237 | + "github.com/open-feature/go-sdk/openfeature" |
| 238 | + provider "github.com/spotify/confidence-resolver-rust/openfeature-provider/go" |
| 239 | + "github.com/tetratelabs/wazero" |
| 240 | +) |
| 241 | + |
| 242 | +func main() { |
| 243 | + ctx := context.Background() |
| 244 | + |
| 245 | + // Load WASM |
| 246 | + wasmBytes, _ := os.ReadFile("resolver.wasm") |
| 247 | + runtime := wazero.NewRuntime(ctx) |
| 248 | + defer runtime.Close(ctx) |
| 249 | + |
| 250 | + // Create factory |
| 251 | + factory, err := provider.NewLocalResolverFactory( |
| 252 | + ctx, runtime, wasmBytes, |
| 253 | + "resolver.eu.confidence.dev:443", |
| 254 | + "events.eu.confidence.dev:443", |
| 255 | + "iam.eu.confidence.dev:443", |
| 256 | + os.Getenv("CONFIDENCE_API_CLIENT_ID"), |
| 257 | + os.Getenv("CONFIDENCE_API_CLIENT_SECRET"), |
| 258 | + ) |
| 259 | + if err != nil { |
| 260 | + log.Fatal(err) |
| 261 | + } |
| 262 | + defer factory.Shutdown(ctx) |
| 263 | + |
| 264 | + // Register provider |
| 265 | + confidenceProvider := provider.NewLocalResolverProvider( |
| 266 | + factory, |
| 267 | + os.Getenv("CONFIDENCE_CLIENT_SECRET"), |
| 268 | + ) |
| 269 | + defer confidenceProvider.Shutdown() |
| 270 | + openfeature.SetProvider(confidenceProvider) |
| 271 | + |
| 272 | + // Use OpenFeature client |
| 273 | + client := openfeature.NewClient("my-app") |
| 274 | + enabled := client.BooleanValue(ctx, "my-feature", false, openfeature.EvaluationContext{}) |
| 275 | + |
| 276 | + if enabled { |
| 277 | + log.Println("Feature enabled!") |
| 278 | + } |
| 279 | +} |
| 280 | +``` |
| 281 | + |
| 282 | +## Resources |
| 283 | + |
| 284 | +- [Confidence Documentation](https://confidence.dev/docs) |
| 285 | +- [OpenFeature Go SDK](https://github.com/open-feature/go-sdk) |
| 286 | +- [OpenFeature Specification](https://openfeature.dev/specification) |
0 commit comments