diff --git a/providers/GoFeatureFlag/src/config/Config.php b/providers/GoFeatureFlag/src/config/Config.php index 510bc9e1..8ba5851f 100644 --- a/providers/GoFeatureFlag/src/config/Config.php +++ b/providers/GoFeatureFlag/src/config/Config.php @@ -19,17 +19,38 @@ class Config */ private ?ClientInterface $httpclient; + /** + * @var array exporterMetadata - is the metadata we send to the GO Feature Flag relay proxy when we report + * the evaluation data usage. + * + * ‼️Important: If you are using a GO Feature Flag relay proxy before version v1.41.0, the information of this + * field will not be added to your feature events. + */ + private array $exporterMetadata = []; + /** * @param string $endpoint - The endpoint to your GO Feature Flag Instance * @param string|null $apiKey - API Key to use to connect to GO Feature Flag * @param array|null $customHeaders - Custom headers you want to send + * @param array|null $exporterMetadata - Metadata to send to the relay proxy during evaluation data collection * @param ClientInterface|null $httpclient - The HTTP Client to use (if you want to use a custom one) */ - public function __construct(string $endpoint, ?string $apiKey = '', ?array $customHeaders = [], ?ClientInterface $httpclient = null) - { + public function __construct( + string $endpoint, + ?string $apiKey = '', + ?array $customHeaders = [], + ?array $exporterMetadata = [], + ?ClientInterface $httpclient = null, + ) { $this->httpclient = $httpclient; $this->endpoint = $endpoint; $this->customHeaders = $customHeaders ?? []; + + // set default exporter metadata fields + $this->exporterMetadata = $exporterMetadata ?? []; + $this->exporterMetadata['openfeature'] = true; + $this->exporterMetadata['provider'] = 'php'; + if ($apiKey !== null && $apiKey !== '') { $this->customHeaders['Authorization'] = 'Bearer ' . $apiKey; } @@ -57,4 +78,12 @@ public function getHttpClient(): ?ClientInterface { return $this->httpclient; } + + /** + * @return array + */ + public function getExporterMetadata(): array + { + return $this->exporterMetadata; + } } diff --git a/providers/GoFeatureFlag/src/controller/OfrepApi.php b/providers/GoFeatureFlag/src/controller/OfrepApi.php index d5d17edb..1b0f1700 100644 --- a/providers/GoFeatureFlag/src/controller/OfrepApi.php +++ b/providers/GoFeatureFlag/src/controller/OfrepApi.php @@ -75,6 +75,9 @@ public function evaluate(string $flagKey, EvaluationContext $evaluationContext): ['targetingKey' => $evaluationContext->getTargetingKey()], ); + // Add exporter metadata to the context + $fields['gofeatureflag'] = ['exporterMetadata' => $this->options->getExporterMetadata()]; + $requestBody = json_encode(['context' => $fields]); if ($requestBody === false) { throw new ParseException('failed to encode request body'); diff --git a/providers/GoFeatureFlag/tests/unit/GoFeatureFlagProviderTest.php b/providers/GoFeatureFlag/tests/unit/GoFeatureFlagProviderTest.php index e990ec90..2f1b0a68 100644 --- a/providers/GoFeatureFlag/tests/unit/GoFeatureFlagProviderTest.php +++ b/providers/GoFeatureFlag/tests/unit/GoFeatureFlagProviderTest.php @@ -21,6 +21,7 @@ use ReflectionException; use function PHPUnit\Framework\assertEquals; +use function json_decode; use function json_encode; class GoFeatureFlagProviderTest extends TestCase @@ -474,6 +475,52 @@ public function testReturnAnErrorAPIResponseIf500(): void assertEquals('boolean_flag', $got->getFlagKey()); } + public function testShouldSendExporterMetadataInContext(): void + { + $mockClient = $this->createMock(ClientInterface::class); + $mockResponse = new Response(200, [], json_encode([ + 'key' => 'integer_key', + 'value' => 42, + 'reason' => 'TARGETING_MATCH', + 'variant' => 'default', + ])); + + $requestBody = ''; + $mockClient + ->expects($this->once()) + ->method('sendRequest') + ->willReturnCallback(function ($request) use ($mockResponse, &$requestBody) { + $requestBody = $request->getBody()->getContents(); + + return $mockResponse; + }); + + $config = new Config( + 'http://gofeatureflag.org', + null, + [], + ['key1' => 'value', 'key2' => 123, 'key3' => 123.45], + ); + + $provider = new GoFeatureFlagProvider($config); + $this->mockHttpClient($provider, $mockClient); + + $api = OpenFeatureAPI::getInstance(); + $api->setProvider($provider); + $client = $api->getClient(); + $client->getBooleanDetails('boolean_flag', false, $this->defaultEvaluationContext); + + // get the request body of the request received by the mock client + $want = ['key1' => 'value', + 'key2' => 123, + 'key3' => 123.45, + 'openfeature' => true, + 'provider' => 'php', + ]; + $got = json_decode($requestBody, true)['context']['gofeatureflag']['exporterMetadata']; + assertEquals($want, $got); + } + protected function setUp(): void { parent::setUp();