From 074a499bb4c7e30c3a9d0f00c3edf1aaa2ceb46d Mon Sep 17 00:00:00 2001 From: Matias Melograno Date: Tue, 22 Oct 2019 16:22:16 -0300 Subject: [PATCH 1/5] added IPAddressesEnabled flag --- CHANGES.txt | 3 +++ .../Component/Cache/ImpressionCache.php | 9 +++---- src/SplitIO/Sdk/Client.php | 11 +++++--- src/SplitIO/Sdk/Events/EventQueueMessage.php | 8 +++--- ...taMessage.php => QueueMetadataMessage.php} | 21 ++++++++++----- src/SplitIO/TreatmentImpression.php | 9 +++---- src/SplitIO/Version.php | 2 +- tests/Suite/Sdk/ImpressionsTest.php | 27 ++++++++++++++++--- tests/Suite/Sdk/SdkClientTest.php | 25 ++++++++++++----- tests/Suite/Sdk/SdkReadOnlyTest.php | 3 ++- 10 files changed, 79 insertions(+), 39 deletions(-) rename src/SplitIO/Sdk/{Events/EventQueueMetadataMessage.php => QueueMetadataMessage.php} (68%) diff --git a/CHANGES.txt b/CHANGES.txt index 6b46353c..b9c9b9e1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +6.2.3 (Oct XX, 2019) + - Added flag `IPAddressesEnabled` into options to enable/disable sending MachineName and MachineIP when data is posted in headers. + 6.2.2 (Sep 18, 2019) - Fetch multiple splits at once on getTreatments/getTreatmentsWithConfig - Removed MatcherClient (DependencyMatcher now uses Evaluator directly) diff --git a/src/SplitIO/Component/Cache/ImpressionCache.php b/src/SplitIO/Component/Cache/ImpressionCache.php index b9d12624..9d1c5f4c 100644 --- a/src/SplitIO/Component/Cache/ImpressionCache.php +++ b/src/SplitIO/Component/Cache/ImpressionCache.php @@ -3,22 +3,19 @@ use SplitIO\Component\Common\Di; use SplitIO\Component\Cache\KeyFactory; +use SplitIO\Sdk\QueueMetadataMessage; class ImpressionCache { const IMPRESSIONS_QUEUE_KEY = "SPLITIO.impressions"; const IMPRESSION_KEY_DEFAULT_TTL = 3600; - public function logImpressions($impressions, $metadata) + public function logImpressions($impressions, QueueMetadataMessage $metadata) { $toStore = array_map( function ($imp) use ($metadata) { return json_encode(array( - "m" => array( - "s" => $metadata['sdkVersion'], - "i" => $metadata['machineIp'], - "n" => $metadata['machineName'], - ), + 'm' => $metadata->toArray(), "i" => array( "k" => $imp->getId(), "b" => $imp->getBucketingKey(), diff --git a/src/SplitIO/Sdk/Client.php b/src/SplitIO/Sdk/Client.php index 385af652..c0df7a6c 100644 --- a/src/SplitIO/Sdk/Client.php +++ b/src/SplitIO/Sdk/Client.php @@ -7,7 +7,7 @@ use SplitIO\Component\Cache\MetricsCache; use SplitIO\Sdk\Events\EventDTO; use SplitIO\Sdk\Events\EventQueueMessage; -use SplitIO\Sdk\Events\EventQueueMetadataMessage; +use SplitIO\Sdk\QueueMetadataMessage; use SplitIO\Sdk\Impressions\Impression; use SplitIO\TreatmentImpression; use SplitIO\Sdk\Impressions\ImpressionLabel; @@ -20,6 +20,7 @@ class Client implements ClientInterface private $evaluator = null; private $impressionListener = null; + private $IPAddressesEnabled = true; /** * Flag to get Impression's labels feature enabled @@ -38,6 +39,7 @@ public function __construct($options = array()) if (isset($options['impressionListener'])) { $this->impressionListener = new \SplitIO\Sdk\ImpressionListenerWrapper($options['impressionListener']); } + $this->IPAddressesEnabled = isset($options['IPAddressesEnabled']) ? $options['IPAddressesEnabled'] : true; } /** @@ -305,7 +307,8 @@ private function doInputValidationForTreatments($key, $featureNames, array $attr private function registerData($impressions, $attributes, $metricName, $latency = null) { try { - TreatmentImpression::log($impressions); + $queueMetadata = new QueueMetadataMessage($this->IPAddressesEnabled); + TreatmentImpression::log($impressions, $queueMetadata); if (isset($this->impressionListener)) { $this->impressionListener->sendDataToClient($impressions, $attributes); } @@ -541,8 +544,8 @@ public function track($key, $trafficType, $eventType, $value = null, $properties try { $eventDTO = new EventDTO($key, $trafficType, $eventType, $value, $properties); - $eventMessageMetadata = new EventQueueMetadataMessage(); - $eventQueueMessage = new EventQueueMessage($eventMessageMetadata, $eventDTO); + $queueMetadata = new QueueMetadataMessage($this->IPAddressesEnabled); + $eventQueueMessage = new EventQueueMessage($queueMetadata, $eventDTO); return EventsCache::addEvent($eventQueueMessage); } catch (\Exception $exception) { // @codeCoverageIgnoreStart diff --git a/src/SplitIO/Sdk/Events/EventQueueMessage.php b/src/SplitIO/Sdk/Events/EventQueueMessage.php index b1fa0444..c4e6b9ee 100644 --- a/src/SplitIO/Sdk/Events/EventQueueMessage.php +++ b/src/SplitIO/Sdk/Events/EventQueueMessage.php @@ -1,6 +1,8 @@ metadata = $metadata; $this->event = $event; @@ -26,7 +28,7 @@ public function __construct(EventQueueMetadataMessage $metadata, EventDTO $event /** - * @return EventQueueMetadataMessage + * @return QueueMetadataMessage */ public function getMetadata() { @@ -36,7 +38,7 @@ public function getMetadata() /** * @param mixed $metadata */ - public function setMetadata(EventQueueMetadataMessage $metadata) + public function setMetadata(QueueMetadataMessage $metadata) { $this->metadata = $metadata; } diff --git a/src/SplitIO/Sdk/Events/EventQueueMetadataMessage.php b/src/SplitIO/Sdk/QueueMetadataMessage.php similarity index 68% rename from src/SplitIO/Sdk/Events/EventQueueMetadataMessage.php rename to src/SplitIO/Sdk/QueueMetadataMessage.php index d04a4684..b33844c9 100644 --- a/src/SplitIO/Sdk/Events/EventQueueMetadataMessage.php +++ b/src/SplitIO/Sdk/QueueMetadataMessage.php @@ -1,7 +1,7 @@ sdkVersion = 'php-' . \SplitIO\version(); - $this->machineIP = \SplitIO\getHostIpAddress(); - $this->machineName = 'unknown'; + $this->machineIP = 'na'; + $this->machineName = 'na'; + if ($IPAddressesEnabled) { + $this->machineIP = \SplitIO\getHostIpAddress(); + if ($this->machineIP != 'unknown') { + $this->machineName = 'ip-' . str_replace('.', '-', $this->machineIP); + } else { + $this->machineName = 'unknown'; + } + } } - /** * @return mixed */ diff --git a/src/SplitIO/TreatmentImpression.php b/src/SplitIO/TreatmentImpression.php index aa955f29..e1170001 100644 --- a/src/SplitIO/TreatmentImpression.php +++ b/src/SplitIO/TreatmentImpression.php @@ -4,6 +4,7 @@ use SplitIO\Component\Cache\ImpressionCache; use SplitIO\Sdk\Impressions\Impression; use SplitIO\Component\Common\Di; +use SplitIO\Sdk\QueueMetadataMessage; class TreatmentImpression { @@ -11,7 +12,7 @@ class TreatmentImpression * @param \SplitIO\Sdk\Impressions\Impression $impressions * @return bool */ - public static function log($impressions) + public static function log($impressions, QueueMetadataMessage $metadata) { try { Di::getLogger()->debug($impressions); @@ -22,11 +23,7 @@ public static function log($impressions) $toStore = (is_array($impressions)) ? $impressions : array($impressions); return $impressionCache->logImpressions( $toStore, - array( - 'sdkVersion' => 'php-' . \SplitIO\version(), - 'machineIp' => \SplitIO\getHostIpAddress(), - 'machineName' => null, // TODO - ) + $metadata ); } catch (\Exception $e) { Di::getLogger()->warning('Unable to write impression back to redis.'); diff --git a/src/SplitIO/Version.php b/src/SplitIO/Version.php index 2fd1fd7e..f2726387 100644 --- a/src/SplitIO/Version.php +++ b/src/SplitIO/Version.php @@ -3,5 +3,5 @@ class Version { - const CURRENT = '6.2.2'; + const CURRENT = '6.2.3-rc1'; } diff --git a/tests/Suite/Sdk/ImpressionsTest.php b/tests/Suite/Sdk/ImpressionsTest.php index 602e6db2..cfd75d60 100644 --- a/tests/Suite/Sdk/ImpressionsTest.php +++ b/tests/Suite/Sdk/ImpressionsTest.php @@ -6,6 +6,7 @@ use SplitIO\Sdk\Impressions\Impression; use SplitIO\Test\Suite\Redis\ReflectiveTools; use SplitIO\Component\Cache\ImpressionCache; +use SplitIO\Sdk\QueueMetadataMessage; class ImpressionsTest extends \PHPUnit_Framework_TestCase { @@ -26,6 +27,7 @@ public function testImpressionsAreAdded() $redisClient = ReflectiveTools::clientFromCachePool(Di::getCache()); $redisClient->del(ImpressionCache::IMPRESSIONS_QUEUE_KEY); + $queueMetadata = new QueueMetadataMessage(); TreatmentImpression::log(new Impression( 'someMatchingKey', @@ -35,7 +37,7 @@ public function testImpressionsAreAdded() 123456, 321654, 'someBucketingKey' - )); + ), $queueMetadata); // Assert that the TTL is within a 10-second range (between it was set and retrieved). $ttl = $redisClient->ttl(ImpressionCache::IMPRESSIONS_QUEUE_KEY); @@ -47,6 +49,7 @@ public function testImpressionsAreAdded() $this->assertEquals($decoded['m']['s'], 'php-'.\Splitio\version()); $this->assertEquals($decoded['m']['i'], 'unknown'); + $this->assertEquals($decoded['m']['n'], 'unknown'); $this->assertEquals($decoded['i']['k'], 'someMatchingKey'); $this->assertEquals($decoded['i']['b'], 'someBucketingKey'); $this->assertEquals($decoded['i']['f'], 'someFeature'); @@ -64,7 +67,8 @@ public function testExpirationOnlyOccursOnce() $sdkConfig = array( 'log' => array('adapter' => 'stdout'), - 'cache' => array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options) + 'cache' => array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options), + 'IPAddressEnabled' => false ); //Initializing the SDK instance. @@ -72,6 +76,7 @@ public function testExpirationOnlyOccursOnce() $redisClient = ReflectiveTools::clientFromCachePool(Di::getCache()); $redisClient->del(ImpressionCache::IMPRESSIONS_QUEUE_KEY); + $queueMetadata = new QueueMetadataMessage(false); TreatmentImpression::log(new Impression( 'someMatchingKey', @@ -81,7 +86,7 @@ public function testExpirationOnlyOccursOnce() 123456, 321654, 'someBucketingKey' - )); + ), $queueMetadata); sleep(3); @@ -93,11 +98,25 @@ public function testExpirationOnlyOccursOnce() 123456, 321654, 'someBucketingKey' - )); + ), $queueMetadata); $ttl = $redisClient->ttl(ImpressionCache::IMPRESSIONS_QUEUE_KEY); // $ttl should be lower than or equalt the default impressions TTL minus 3 seconds, // since it should have not been resetted with the last imrpession logged. $this->assertLessThanOrEqual(ImpressionCache::IMPRESSION_KEY_DEFAULT_TTL - 3, $ttl); + + $imp = $redisClient->rpop(ImpressionCache::IMPRESSIONS_QUEUE_KEY); + $decoded = json_decode($imp, true); + + $this->assertEquals($decoded['m']['s'], 'php-'.\Splitio\version()); + $this->assertEquals($decoded['m']['i'], 'na'); + $this->assertEquals($decoded['m']['n'], 'na'); + $this->assertEquals($decoded['i']['k'], 'someMatchingKey'); + $this->assertEquals($decoded['i']['b'], 'someBucketingKey'); + $this->assertEquals($decoded['i']['f'], 'someFeature'); + $this->assertEquals($decoded['i']['t'], 'on'); + $this->assertEquals($decoded['i']['r'], 'label1'); + $this->assertEquals($decoded['i']['m'], 123456); + $this->assertEquals($decoded['i']['c'], 321654); } } diff --git a/tests/Suite/Sdk/SdkClientTest.php b/tests/Suite/Sdk/SdkClientTest.php index 45535b0f..51927739 100644 --- a/tests/Suite/Sdk/SdkClientTest.php +++ b/tests/Suite/Sdk/SdkClientTest.php @@ -209,13 +209,22 @@ public function testLocalClientYAML() ); } - private function validateLastImpression($redisClient, $feature, $key, $treatment) - { + private function validateLastImpression( + $redisClient, + $feature, + $key, + $treatment, + $machineName = 'unknown', + $machineIP = 'unknown' + ) { $raw = $redisClient->rpop(ImpressionCache::IMPRESSIONS_QUEUE_KEY); $parsed = json_decode($raw, true); + echo "parsed " . json_encode($parsed) . "\n"; $this->assertEquals($parsed['i']['f'], $feature); $this->assertEquals($parsed['i']['k'], $key); $this->assertEquals($parsed['i']['t'], $treatment); + $this->assertEquals($parsed['m']['i'], $machineIP); + $this->assertEquals($parsed['m']['n'], $machineName); } public function testClient() @@ -544,7 +553,8 @@ public function testGetTreatmentsWithDistinctFeatures() $sdkConfig = array( 'log' => array('adapter' => 'stdout'), - 'cache' => array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options) + 'cache' => array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options), + 'IPAddressesEnabled' => false ); //Initializing the SDK instance. @@ -565,7 +575,7 @@ public function testGetTreatmentsWithDistinctFeatures() //Check impressions generated $redisClient = ReflectiveTools::clientFromCachePool(Di::getCache()); - $this->validateLastImpression($redisClient, 'sample_feature', 'user1', 'on'); + $this->validateLastImpression($redisClient, 'sample_feature', 'user1', 'on', 'na', 'na'); } public function testGetTreatmentsWithRepeteadedFeatures() @@ -580,7 +590,8 @@ public function testGetTreatmentsWithRepeteadedFeatures() $sdkConfig = array( 'log' => array('adapter' => 'stdout'), - 'cache' => array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options) + 'cache' => array('adapter' => 'predis', 'parameters' => $parameters, 'options' => $options), + 'ipAddress' => '1.2.3.4' ); //Initializing the SDK instance. @@ -602,12 +613,13 @@ public function testGetTreatmentsWithRepeteadedFeatures() // Check impressions $redisClient = ReflectiveTools::clientFromCachePool(Di::getCache()); - $this->validateLastImpression($redisClient, 'sample_feature', 'user1', 'on'); + $this->validateLastImpression($redisClient, 'sample_feature', 'user1', 'on', 'ip-1-2-3-4', '1.2.3.4'); } public function testGetTreatmentsWithRepeteadedAndNullFeatures() { Di::set(Di::KEY_FACTORY_TRACKER, false); + Di::set('ipAddress', null); // unset ipaddress from previous test //Testing version string $this->assertTrue(is_string(\SplitIO\version())); @@ -680,5 +692,4 @@ public function testGetTreatmentsFetchesSplitsInOneCall() $client = new Client(); $client->getTreatments('key1', array('split1', 'split2', 'split3')); } - } diff --git a/tests/Suite/Sdk/SdkReadOnlyTest.php b/tests/Suite/Sdk/SdkReadOnlyTest.php index 229c5c86..adbe450a 100644 --- a/tests/Suite/Sdk/SdkReadOnlyTest.php +++ b/tests/Suite/Sdk/SdkReadOnlyTest.php @@ -9,6 +9,7 @@ use SplitIO\TreatmentImpression; use SplitIO\Grammar\Condition\Partition\TreatmentEnum; use SplitIO\Sdk\Impressions\Impression; +use SplitIO\Sdk\QueueMetadataMessage; class SdkReadOnlyTest extends \PHPUnit_Framework_TestCase { @@ -126,6 +127,6 @@ public function testException() 'something' ); - TreatmentImpression::log($impression); + TreatmentImpression::log($impression, new QueueMetadataMessage()); } } From b8d6cdd0e0ce88cc3f56c66351ca148bf2ec2c4a Mon Sep 17 00:00:00 2001 From: Matias Melograno Date: Thu, 24 Oct 2019 14:22:24 -0300 Subject: [PATCH 2/5] update --- src/SplitIO/Sdk/QueueMetadataMessage.php | 4 ++-- tests/Suite/Sdk/ImpressionsTest.php | 4 ++-- tests/Suite/Sdk/SdkClientTest.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SplitIO/Sdk/QueueMetadataMessage.php b/src/SplitIO/Sdk/QueueMetadataMessage.php index b33844c9..b06af559 100644 --- a/src/SplitIO/Sdk/QueueMetadataMessage.php +++ b/src/SplitIO/Sdk/QueueMetadataMessage.php @@ -15,8 +15,8 @@ class QueueMetadataMessage public function __construct($IPAddressesEnabled = true) { $this->sdkVersion = 'php-' . \SplitIO\version(); - $this->machineIP = 'na'; - $this->machineName = 'na'; + $this->machineIP = 'NA'; + $this->machineName = 'NA'; if ($IPAddressesEnabled) { $this->machineIP = \SplitIO\getHostIpAddress(); if ($this->machineIP != 'unknown') { diff --git a/tests/Suite/Sdk/ImpressionsTest.php b/tests/Suite/Sdk/ImpressionsTest.php index cfd75d60..a7f7628a 100644 --- a/tests/Suite/Sdk/ImpressionsTest.php +++ b/tests/Suite/Sdk/ImpressionsTest.php @@ -109,8 +109,8 @@ public function testExpirationOnlyOccursOnce() $decoded = json_decode($imp, true); $this->assertEquals($decoded['m']['s'], 'php-'.\Splitio\version()); - $this->assertEquals($decoded['m']['i'], 'na'); - $this->assertEquals($decoded['m']['n'], 'na'); + $this->assertEquals($decoded['m']['i'], 'NA'); + $this->assertEquals($decoded['m']['n'], 'NA'); $this->assertEquals($decoded['i']['k'], 'someMatchingKey'); $this->assertEquals($decoded['i']['b'], 'someBucketingKey'); $this->assertEquals($decoded['i']['f'], 'someFeature'); diff --git a/tests/Suite/Sdk/SdkClientTest.php b/tests/Suite/Sdk/SdkClientTest.php index 51927739..83975f65 100644 --- a/tests/Suite/Sdk/SdkClientTest.php +++ b/tests/Suite/Sdk/SdkClientTest.php @@ -575,7 +575,7 @@ public function testGetTreatmentsWithDistinctFeatures() //Check impressions generated $redisClient = ReflectiveTools::clientFromCachePool(Di::getCache()); - $this->validateLastImpression($redisClient, 'sample_feature', 'user1', 'on', 'na', 'na'); + $this->validateLastImpression($redisClient, 'sample_feature', 'user1', 'on', 'NA', 'NA'); } public function testGetTreatmentsWithRepeteadedFeatures() From cbaa9444aace1a58b5e053a6b202f4c4199c8f21 Mon Sep 17 00:00:00 2001 From: Matias Melograno Date: Thu, 31 Oct 2019 14:32:17 -0300 Subject: [PATCH 3/5] moved queueMetadata instantiation to constructor --- src/SplitIO/Sdk/Client.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/SplitIO/Sdk/Client.php b/src/SplitIO/Sdk/Client.php index c0df7a6c..6d6a3100 100644 --- a/src/SplitIO/Sdk/Client.php +++ b/src/SplitIO/Sdk/Client.php @@ -39,7 +39,8 @@ public function __construct($options = array()) if (isset($options['impressionListener'])) { $this->impressionListener = new \SplitIO\Sdk\ImpressionListenerWrapper($options['impressionListener']); } - $this->IPAddressesEnabled = isset($options['IPAddressesEnabled']) ? $options['IPAddressesEnabled'] : true; + $IPAddressesEnabled = isset($options['IPAddressesEnabled']) ? $options['IPAddressesEnabled'] : true; + $this->queueMetadata = new QueueMetadataMessage($IPAddressesEnabled); } /** @@ -307,8 +308,7 @@ private function doInputValidationForTreatments($key, $featureNames, array $attr private function registerData($impressions, $attributes, $metricName, $latency = null) { try { - $queueMetadata = new QueueMetadataMessage($this->IPAddressesEnabled); - TreatmentImpression::log($impressions, $queueMetadata); + TreatmentImpression::log($impressions, $this->queueMetadata); if (isset($this->impressionListener)) { $this->impressionListener->sendDataToClient($impressions, $attributes); } @@ -544,8 +544,7 @@ public function track($key, $trafficType, $eventType, $value = null, $properties try { $eventDTO = new EventDTO($key, $trafficType, $eventType, $value, $properties); - $queueMetadata = new QueueMetadataMessage($this->IPAddressesEnabled); - $eventQueueMessage = new EventQueueMessage($queueMetadata, $eventDTO); + $eventQueueMessage = new EventQueueMessage($this->queueMetadata, $eventDTO); return EventsCache::addEvent($eventQueueMessage); } catch (\Exception $exception) { // @codeCoverageIgnoreStart From c90d7be57c3fce13dab6bc138eff7d4a5251b2d5 Mon Sep 17 00:00:00 2001 From: Matias Melograno Date: Thu, 31 Oct 2019 15:18:02 -0300 Subject: [PATCH 4/5] fixes --- src/SplitIO/Sdk/Client.php | 5 +++-- src/SplitIO/TreatmentImpression.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/SplitIO/Sdk/Client.php b/src/SplitIO/Sdk/Client.php index 6d6a3100..694785c4 100644 --- a/src/SplitIO/Sdk/Client.php +++ b/src/SplitIO/Sdk/Client.php @@ -39,8 +39,9 @@ public function __construct($options = array()) if (isset($options['impressionListener'])) { $this->impressionListener = new \SplitIO\Sdk\ImpressionListenerWrapper($options['impressionListener']); } - $IPAddressesEnabled = isset($options['IPAddressesEnabled']) ? $options['IPAddressesEnabled'] : true; - $this->queueMetadata = new QueueMetadataMessage($IPAddressesEnabled); + $this->queueMetadata = new QueueMetadataMessage( + isset($options['IPAddressesEnabled']) ? $options['IPAddressesEnabled'] : true + ); } /** diff --git a/src/SplitIO/TreatmentImpression.php b/src/SplitIO/TreatmentImpression.php index e1170001..bb4743e0 100644 --- a/src/SplitIO/TreatmentImpression.php +++ b/src/SplitIO/TreatmentImpression.php @@ -17,7 +17,7 @@ public static function log($impressions, QueueMetadataMessage $metadata) try { Di::getLogger()->debug($impressions); if (is_null($impressions) || (is_array($impressions) && 0 == count($impressions))) { - return; + return null; } $impressionCache = new ImpressionCache(); $toStore = (is_array($impressions)) ? $impressions : array($impressions); From 8ab97d96f95defb0f3bd09144a98d712a1840b04 Mon Sep 17 00:00:00 2001 From: Matias Melograno Date: Thu, 31 Oct 2019 15:34:40 -0300 Subject: [PATCH 5/5] removed unnecesary variable --- src/SplitIO/Sdk/Client.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SplitIO/Sdk/Client.php b/src/SplitIO/Sdk/Client.php index 694785c4..2a1581c7 100644 --- a/src/SplitIO/Sdk/Client.php +++ b/src/SplitIO/Sdk/Client.php @@ -20,7 +20,6 @@ class Client implements ClientInterface private $evaluator = null; private $impressionListener = null; - private $IPAddressesEnabled = true; /** * Flag to get Impression's labels feature enabled