Skip to content

Commit a8f2e5f

Browse files
committed
move go local provider to repo
1 parent 1ea86ea commit a8f2e5f

37 files changed

+16699
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../proto
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
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+
"email": "[email protected]",
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)

openfeature-provider/go/demo/demo

21.6 MB
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module github.com/spotify/confidence-resolver-rust/openfeature-provider/go/demo
2+
3+
go 1.24.0
4+
5+
require (
6+
github.com/open-feature/go-sdk v1.16.0
7+
github.com/spotify/confidence-resolver-rust/openfeature-provider/go/confidence v0.0.0
8+
)
9+
10+
require (
11+
github.com/go-logr/logr v1.4.3 // indirect
12+
github.com/tetratelabs/wazero v1.9.0 // indirect
13+
go.uber.org/mock v0.6.0 // indirect
14+
golang.org/x/net v0.44.0 // indirect
15+
golang.org/x/sys v0.36.0 // indirect
16+
golang.org/x/text v0.29.0 // indirect
17+
google.golang.org/genproto v0.0.0-20251029180050-ab9386a59fda // indirect
18+
google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda // indirect
19+
google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f // indirect
20+
google.golang.org/grpc v1.76.0 // indirect
21+
google.golang.org/protobuf v1.36.10 // indirect
22+
)
23+
24+
replace github.com/spotify/confidence-resolver-rust/openfeature-provider/go/confidence => ../
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
2+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
3+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
4+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
5+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
6+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
7+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
8+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
9+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
10+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
11+
github.com/open-feature/go-sdk v1.16.0 h1:5NCHYv5slvNBIZhYXAzAufo0OI59OACZ5tczVqSE+Tg=
12+
github.com/open-feature/go-sdk v1.16.0/go.mod h1:EIF40QcoYT1VbQkMPy2ZJH4kvZeY+qGUXAorzSWgKSo=
13+
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
14+
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
15+
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
16+
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
17+
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
18+
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
19+
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
20+
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
21+
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
22+
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
23+
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
24+
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
25+
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
26+
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
27+
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
28+
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
29+
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
30+
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
31+
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
32+
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
33+
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
34+
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
35+
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
36+
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
37+
google.golang.org/genproto v0.0.0-20251029180050-ab9386a59fda h1:fQ3VVQ11pb84nu0o/8wD6oZq13Q6+HK30P+9GSRlrqk=
38+
google.golang.org/genproto v0.0.0-20251029180050-ab9386a59fda/go.mod h1:1Ic78BnpzY8OaTCmzxJDP4qC9INZPbGZl+54RKjtyeI=
39+
google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda h1:+2XxjfsAu6vqFxwGBRcHiMaDCuZiqXGDUDVWVtrFAnE=
40+
google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo=
41+
google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f h1:1FTH6cpXFsENbPR5Bu8NQddPSaUUE6NA2XdZdDSAJK4=
42+
google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
43+
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
44+
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
45+
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
46+
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=

0 commit comments

Comments
 (0)