@@ -4,12 +4,18 @@ import (
44 "context"
55 "fmt"
66 "net/http"
7+ "os"
8+ "strconv"
9+ "strings"
10+ "time"
711
812 "github.com/open-feature/go-sdk-contrib/providers/ofrep/internal/evaluate"
913 "github.com/open-feature/go-sdk-contrib/providers/ofrep/internal/outbound"
1014 "github.com/open-feature/go-sdk/openfeature"
1115)
1216
17+ var _ openfeature.FeatureProvider = (* Provider )(nil )
18+
1319// Provider implementation for OFREP
1420type Provider struct {
1521 evaluator Evaluator
@@ -22,6 +28,7 @@ type Option func(*outbound.Configuration)
2228func NewProvider (baseUri string , options ... Option ) * Provider {
2329 cfg := outbound.Configuration {
2430 BaseURI : baseUri ,
31+ Timeout : 10 * time .Second ,
2532 }
2633
2734 for _ , option := range options {
@@ -67,14 +74,21 @@ func (p Provider) Hooks() []openfeature.Hook {
6774
6875// options of the OFREP provider
6976
70- // WithHeaderProvider allows to configure a custom header callback to set a custom authorization header
77+ // WithHeader allows to set a custom header to be used for authorization.
78+ func WithHeader (name , value string ) func (* outbound.Configuration ) {
79+ return WithHeaderProvider (func () (string , string ) {
80+ return name , value
81+ })
82+ }
83+
84+ // WithHeaderProvider allows to configure a custom header callback to set a custom authorization header.
7185func WithHeaderProvider (callback outbound.HeaderCallback ) func (* outbound.Configuration ) {
7286 return func (c * outbound.Configuration ) {
7387 c .Callbacks = append (c .Callbacks , callback )
7488 }
7589}
7690
77- // WithBearerToken allows to set token to be used for bearer token authorization
91+ // WithBearerToken allows to set token to be used for bearer token authorization.
7892func WithBearerToken (token string ) func (* outbound.Configuration ) {
7993 return func (c * outbound.Configuration ) {
8094 c .Callbacks = append (c .Callbacks , func () (string , string ) {
@@ -83,7 +97,7 @@ func WithBearerToken(token string) func(*outbound.Configuration) {
8397 }
8498}
8599
86- // WithApiKeyAuth allows to set token to be used for api key authorization
100+ // WithApiKeyAuth allows to set token to be used for api key authorization.
87101func WithApiKeyAuth (token string ) func (* outbound.Configuration ) {
88102 return func (c * outbound.Configuration ) {
89103 c .Callbacks = append (c .Callbacks , func () (string , string ) {
@@ -92,9 +106,73 @@ func WithApiKeyAuth(token string) func(*outbound.Configuration) {
92106 }
93107}
94108
95- // WithClient allows to provide a pre-configured http.Client for the communication with the OFREP service
109+ // WithClient allows to provide a pre-configured http.Client for the communication with the OFREP service.
96110func WithClient (client * http.Client ) func (configuration * outbound.Configuration ) {
97111 return func (configuration * outbound.Configuration ) {
98112 configuration .Client = client
99113 }
100114}
115+
116+ // WithBaseURI allows to set the base URI of the OFREP service.
117+ func WithBaseURI (baseURI string ) func (configuration * outbound.Configuration ) {
118+ return func (configuration * outbound.Configuration ) {
119+ configuration .BaseURI = baseURI
120+ }
121+ }
122+
123+ // WithTimeout allows to set the timeout for the http client used for communication with the OFREP service.
124+ func WithTimeout (timeout time.Duration ) func (configuration * outbound.Configuration ) {
125+ return func (configuration * outbound.Configuration ) {
126+ configuration .Timeout = timeout
127+ }
128+ }
129+
130+ // WithFromEnv uses environment variables to configure the provider.
131+ //
132+ // Experimental: This feature is experimental and may change in future versions.
133+ //
134+ // Supported environment variables:
135+ // - OFREP_ENDPOINT: base URI for the OFREP service
136+ // - OFREP_TIMEOUT: timeout duration (e.g., "30s", "500ms")
137+ // - OFREP_API_KEY: API key for X-API-Key authentication
138+ // - OFREP_BEARER_TOKEN: token for Bearer authentication
139+ // - OFREP_HEADERS: comma-separated custom headers (e.g., "Key1=Value1,Key2=Value2")
140+ func WithFromEnv () func (* outbound.Configuration ) {
141+ envHandlers := map [string ]func (* outbound.Configuration , string ){
142+ "OFREP_ENDPOINT" : func (c * outbound.Configuration , v string ) {
143+ WithBaseURI (v )(c )
144+ },
145+ "OFREP_TIMEOUT" : func (c * outbound.Configuration , v string ) {
146+ if t , err := time .ParseDuration (v ); err == nil && t > 0 {
147+ WithTimeout (t )(c )
148+ return
149+ }
150+ // as the specification is not finalized, also support raw milliseconds
151+ t , err := strconv .Atoi (v )
152+ if err == nil && t > 0 {
153+ WithTimeout (time .Duration (t ) * time .Millisecond )(c )
154+ }
155+ },
156+ "OFREP_API_KEY" : func (c * outbound.Configuration , v string ) {
157+ WithApiKeyAuth (v )(c )
158+ },
159+ "OFREP_BEARER_TOKEN" : func (c * outbound.Configuration , v string ) {
160+ WithBearerToken (v )(c )
161+ },
162+ "OFREP_HEADERS" : func (c * outbound.Configuration , v string ) {
163+ for pair := range strings .SplitSeq (v , "," ) {
164+ kv := strings .SplitN (strings .TrimSpace (pair ), "=" , 2 )
165+ if len (kv ) == 2 {
166+ WithHeader (kv [0 ], kv [1 ])(c )
167+ }
168+ }
169+ },
170+ }
171+ return func (c * outbound.Configuration ) {
172+ for key , handler := range envHandlers {
173+ if v := os .Getenv (key ); v != "" {
174+ handler (c , v )
175+ }
176+ }
177+ }
178+ }
0 commit comments