diff --git a/.gitignore b/.gitignore
index d2e6e56..6830e4e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
/vendor/
/tools/
/bin/
+/tmp/
/.phpunit.cache/
composer.lock
diff --git a/.phive/phars.xml b/.phive/phars.xml
index f3f8d24..e54880b 100644
--- a/.phive/phars.xml
+++ b/.phive/phars.xml
@@ -1,4 +1,7 @@
-
+
+
+
+
diff --git a/README.md b/README.md
index 5e0f262..0602f46 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,29 @@ This is a Symfony bridge for the framework agnostic [Correlation ID library](htt
* [The value of a correlation ID](https://blog.rapid7.com/2016/12/23/the-value-of-correlation-ids/)
* [Identity Correlation on Wikipedia](https://en.wikipedia.org/wiki/Identity_correlation)
+## Installation
+
+```sh
+composer require phauthentic/correlation-id-symfony-bundle
+```
+
+## Configuration
+
+You can configure three different settings to control the behavior:
+
+* `response_header_name` - The name of the response header for the ID.
+* `request_header_name` - The name of the request header for the ID.
+* `pass_through` - If the ID from the request should be passed to the response enable this. This is useful if you are dealing with a microservice that is not exposed to the public but gets further actions delegated from the entry point and must retain the original ID.
+
+`config/correlation_id.yaml`:
+
+```yaml
+correlation_id:
+ response_header_name: 'X-Correlation-ID'
+ request_header_name: 'X-Correlation-ID'
+ pass_through: false
+```
+
## Copyright & License
Licensed under the [MIT license](LICENSE).
diff --git a/composer.lock b/composer.lock
index b1ce428..9b97a2e 100644
--- a/composer.lock
+++ b/composer.lock
@@ -12,12 +12,12 @@
"source": {
"type": "git",
"url": "https://github.com/Phauthentic/correlation-id.git",
- "reference": "a7ee97ae0c166407df5e0ca3ca8326c3702ae7f4"
+ "reference": "9e0e298bd34665e05ff5ac9505379d67e6d45ef9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Phauthentic/correlation-id/zipball/a7ee97ae0c166407df5e0ca3ca8326c3702ae7f4",
- "reference": "a7ee97ae0c166407df5e0ca3ca8326c3702ae7f4",
+ "url": "https://api.github.com/repos/Phauthentic/correlation-id/zipball/9e0e298bd34665e05ff5ac9505379d67e6d45ef9",
+ "reference": "9e0e298bd34665e05ff5ac9505379d67e6d45ef9",
"shasum": ""
},
"require": {
@@ -54,7 +54,7 @@
"issues": "https://github.com/Phauthentic/correlation-id/issues",
"source": "https://github.com/Phauthentic/correlation-id/tree/2.0.0"
},
- "time": "2024-03-27T23:29:11+00:00"
+ "time": "2024-03-27T23:51:34+00:00"
},
{
"name": "psr/event-dispatcher",
@@ -1380,16 +1380,16 @@
},
{
"name": "phpstan/phpstan",
- "version": "1.10.65",
+ "version": "1.10.66",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "3c657d057a0b7ecae19cb12db446bbc99d8839c6"
+ "reference": "94779c987e4ebd620025d9e5fdd23323903950bd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3c657d057a0b7ecae19cb12db446bbc99d8839c6",
- "reference": "3c657d057a0b7ecae19cb12db446bbc99d8839c6",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/94779c987e4ebd620025d9e5fdd23323903950bd",
+ "reference": "94779c987e4ebd620025d9e5fdd23323903950bd",
"shasum": ""
},
"require": {
@@ -1438,7 +1438,7 @@
"type": "tidelift"
}
],
- "time": "2024-03-23T10:30:26+00:00"
+ "time": "2024-03-28T16:17:31+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -1763,16 +1763,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "10.5.15",
+ "version": "10.5.16",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "86376e05e8745ed81d88232ff92fee868247b07b"
+ "reference": "18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/86376e05e8745ed81d88232ff92fee868247b07b",
- "reference": "86376e05e8745ed81d88232ff92fee868247b07b",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd",
+ "reference": "18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd",
"shasum": ""
},
"require": {
@@ -1844,7 +1844,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.15"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.16"
},
"funding": [
{
@@ -1860,7 +1860,7 @@
"type": "tidelift"
}
],
- "time": "2024-03-22T04:17:47+00:00"
+ "time": "2024-03-28T10:08:10+00:00"
},
{
"name": "psr/container",
diff --git a/config/correlation_id.yaml b/config/correlation_id.yaml
new file mode 100644
index 0000000..0212eec
--- /dev/null
+++ b/config/correlation_id.yaml
@@ -0,0 +1,3 @@
+correlation_id:
+ response_header_name: 'X-Correlation-ID'
+ request_header_name: 'X-Correlation-ID'
diff --git a/config/services.yaml b/config/services.yaml
index 7bf8b83..a04773a 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -1,4 +1,9 @@
services:
Phauthentic\CorrelationIdBundle\EventSubscriber\CorrelationIdSubscriber:
+ arguments:
+ $config:
+ response_header_name: '%correlation_id.response_header_name%'
+ request_header_name: '%correlation_id.request_header_name%'
+ pass_through: '%correlation_id.pass_through%'
tags:
- { name: 'kernel.event_subscriber' }
diff --git a/grumphp.yml b/grumphp.yml
new file mode 100644
index 0000000..751b291
--- /dev/null
+++ b/grumphp.yml
@@ -0,0 +1,45 @@
+grumphp:
+ ascii:
+ failed: resources/grumphp-grumpy.txt
+ succeeded: resources/grumphp-happy.txt
+ fixer:
+ enabled: true
+ fix_by_default: true
+ tasks:
+ phpstan:
+ autoload_file: ~
+ configuration: phpstan.neon
+ level: null
+ force_patterns: []
+ ignore_patterns: []
+ triggered_by: ['php']
+ memory_limit: "-1"
+ use_grumphp_paths: true
+ phpmd:
+ whitelist_patterns: []
+ exclude: []
+ report_format: text
+ ruleset: ['cleancode', 'codesize', 'naming', 'design', 'unusedcode']
+ triggered_by: ['php']
+ phpcs:
+ standard: []
+ severity: ~
+ error_severity: ~
+ warning_severity: ~
+ tab_width: ~
+ report: full
+ report_width: ~
+ whitelist_patterns: []
+ encoding: ~
+ ignore_patterns: []
+ sniffs: []
+ triggered_by: [php]
+ exclude: []
+ show_sniffs_error_path: true
+ phpunit:
+ config_file: phpunit.xml.dist
+ testsuite: ~
+ group: []
+ exclude_group: []
+ always_execute: false
+ order: null
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 16739ac..95fce90 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,22 +1,22 @@
-
-
-
-
-
-
-
-
-
-
- tests
-
-
-
-
- src
-
-
+
+
+
+
+
+
+
+
+
+
+ tests
+
+
+
diff --git a/resources/grumphp-grumpy.txt b/resources/grumphp-grumpy.txt
new file mode 100644
index 0000000..e69de29
diff --git a/resources/grumphp-happy.txt b/resources/grumphp-happy.txt
new file mode 100644
index 0000000..b2a6350
--- /dev/null
+++ b/resources/grumphp-happy.txt
@@ -0,0 +1,2 @@
+
+All good!
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
new file mode 100644
index 0000000..5045b70
--- /dev/null
+++ b/src/DependencyInjection/Configuration.php
@@ -0,0 +1,32 @@
+getRootNode()
+ ->children()
+ ->booleanNode('pass_through')
+ ->defaultValue(false)
+ ->end()
+ ->scalarNode('response_header_name')
+ ->defaultValue('X-Correlation-ID')
+ ->end()
+ ->scalarNode('request_header_name')
+ ->defaultValue('X-Correlation-ID')
+ ->end()
+ ->end();
+
+ return $treeBuilder;
+ }
+}
diff --git a/src/DependencyInjection/CorrelationIdExtension.php b/src/DependencyInjection/CorrelationIdExtension.php
index 0a39ed2..0b40421 100644
--- a/src/DependencyInjection/CorrelationIdExtension.php
+++ b/src/DependencyInjection/CorrelationIdExtension.php
@@ -18,7 +18,18 @@ class CorrelationIdExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container): void
{
- $yamlLoader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../../config'));
+ $configuration = new Configuration();
+ $config = $this->processConfiguration($configuration, $configs);
+
+ $container->setParameter('correlation_id.request_header_name', $config['response_header_name']);
+ $container->setParameter('correlation_id.response_header_name', $config['response_header_name']);
+ $container->setParameter('correlation_id.pass_through', $config['pass_through']);
+
+ $yamlLoader = new Loader\YamlFileLoader(
+ $container,
+ new FileLocator(__DIR__ . '/../../config')
+ );
+
$yamlLoader->load('services.yaml');
}
}
diff --git a/src/EventSubscriber/CorrelationIdSubscriber.php b/src/EventSubscriber/CorrelationIdSubscriber.php
index ac1f96e..1e33fa7 100644
--- a/src/EventSubscriber/CorrelationIdSubscriber.php
+++ b/src/EventSubscriber/CorrelationIdSubscriber.php
@@ -4,6 +4,8 @@
namespace Phauthentic\CorrelationIdBundle\EventSubscriber;
+use InvalidArgumentException;
+use Exception;
use Phauthentic\Infrastructure\Utils\CorrelationID;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
@@ -12,25 +14,63 @@
class CorrelationIdSubscriber implements EventSubscriberInterface
{
- private string $header = 'X-Correlation-ID';
+ private string $requestHeaderName = 'X-Correlation-ID';
+ private string $responseHeaderName = 'X-Correlation-ID';
+ private bool $passthrough = false;
+ /**
+ * @param array $config
+ * @return void
+ */
+ public function __construct(array $config = [])
+ {
+ if (isset($config['request_header_name'])) {
+ $this->requestHeaderName = (string)$config['request_header_name'];
+ }
+
+ if (isset($config['response_header_name'])) {
+ $this->responseHeaderName = (string)$config['response_header_name'];
+ }
+
+ if (isset($config['pass_through'])) {
+ $this->passthrough = (bool)$config['pass_through'];
+ }
+ }
+
+ /**
+ * @SuppressWarnings(PHPMD.StaticAccess)
+ *
+ * @param RequestEvent $event
+ * @return void
+ */
public function onKernelRequest(RequestEvent $event): void
{
- $event->getRequest()->attributes->set($this->header, CorrelationID::toString());
+ $event->getRequest()->attributes->set($this->requestHeaderName, CorrelationID::toString());
}
+ /**
+ * @SuppressWarnings(PHPMD.StaticAccess)
+ *
+ * @param ResponseEvent $event
+ * @return void
+ * @throws InvalidArgumentException
+ * @throws Exception
+ */
public function onKernelResponse(ResponseEvent $event): void
{
- if ($event->getRequest()->headers->has($this->header)) {
+ if (
+ $this->passthrough
+ && $event->getRequest()->headers->has($this->requestHeaderName)
+ ) {
$event->getResponse()->headers->set(
- $this->header,
- $event->getRequest()->headers->get($this->header)
+ $this->responseHeaderName,
+ $event->getRequest()->headers->get($this->requestHeaderName)
);
return;
}
- $event->getResponse()->headers->set($this->header, CorrelationID::toString());
+ $event->getResponse()->headers->set($this->responseHeaderName, CorrelationID::toString());
}
public static function getSubscribedEvents(): array
diff --git a/src/Resources/config/correlation_id.yaml b/src/Resources/config/correlation_id.yaml
deleted file mode 100644
index 7bf8b83..0000000
--- a/src/Resources/config/correlation_id.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-services:
- Phauthentic\CorrelationIdBundle\EventSubscriber\CorrelationIdSubscriber:
- tags:
- - { name: 'kernel.event_subscriber' }
diff --git a/tests/EventSubscriber/CorrelationIdSubscriberTest.php b/tests/EventSubscriber/CorrelationIdSubscriberTest.php
index b15b344..7d51d4f 100644
--- a/tests/EventSubscriber/CorrelationIdSubscriberTest.php
+++ b/tests/EventSubscriber/CorrelationIdSubscriberTest.php
@@ -18,6 +18,9 @@ class CorrelationIdSubscriberTest extends TestCase
{
private const CORRELATION_ID = 'd8d089ec-72c8-44c1-a0bf-1906e5fc3524';
+ /**
+ * @SuppressWarnings(PHPMD.StaticAccess)
+ */
public function setUp(): void
{
$reflection = new ReflectionClass(CorrelationID::class);
@@ -26,6 +29,26 @@ public function setUp(): void
parent::setUp();
}
+ public function testOnKernelRequestConfigWithOtherHeader(): void
+ {
+ $request = new Request();
+ $request->headers->set('X-Correlation-ID', self::CORRELATION_ID);
+
+ $requestEvent = new RequestEvent(
+ $this->createMock(\Symfony\Component\HttpKernel\HttpKernelInterface::class),
+ $request,
+ null
+ );
+
+ $subscriber = new CorrelationIdSubscriber([
+ 'request_header_name' => 'CID-IN',
+ ]);
+ $subscriber->onKernelRequest($requestEvent);
+
+ $this->assertNotEmpty($request->attributes->get('CID-IN'));
+ $this->assertSame(self::CORRELATION_ID, $request->attributes->get('CID-IN'));
+ }
+
public function testOnKernelRequest(): void
{
$request = new Request();
@@ -61,6 +84,28 @@ public function testOnKernelResponse(): void
$this->assertNotEmpty($response->headers->get('X-Correlation-ID'));
}
+ public function testOnKernelResponseConfigWithOtherHeader(): void
+ {
+ $response = new Response();
+
+ $responseEvent = new ResponseEvent(
+ $this->createMock(\Symfony\Component\HttpKernel\HttpKernelInterface::class),
+ new Request(),
+ 1,
+ $response
+ );
+
+ $subscriber = new CorrelationIdSubscriber([
+ 'response_header_name' => 'CID-OUT',
+ ]);
+ $subscriber->onKernelResponse($responseEvent);
+
+ $this->assertNotEmpty($response->headers->get('CID-OUT'));
+ }
+
+ /**
+ * @SuppressWarnings(PHPMD.StaticAccess)
+ */
public function testGetSubscribedEvents(): void
{
$subscribedEvents = CorrelationIdSubscriber::getSubscribedEvents();