From a7ee97ae0c166407df5e0ca3ca8326c3702ae7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Kr=C3=A4mer?= <4996022+floriankraemer@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:29:11 +0100 Subject: [PATCH] Removing the hard dependency on ramsey/uuid (#6) --- .github/workflows/ci.yml | 16 +++++------ .gitignore | 2 ++ .scrutinizer.yml | 10 ++----- composer.json | 10 ++++--- phpunit.xml.dist | 39 +++++++------------------ readme.md | 16 ++++++++--- src/Utils/CorrelationID.php | 43 +++++++++++++++++----------- tests/TestCase/CorrelationIDTest.php | 1 - 8 files changed, 68 insertions(+), 69 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 491f762..7584e13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,10 +9,10 @@ jobs: strategy: fail-fast: false matrix: - php-version: ['7.4', '8.0', '8.1', '8.2', '8.3'] + php-version: ['8.1', '8.2', '8.3'] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 with: fetch-depth: 1 @@ -20,26 +20,26 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} - extensions: json, pdo, ldap + extensions: json tools: pecl coverage: pcov - name: Composer install run: | - if [[ ${{ matrix.prefer-lowest == '7.4' }} ]]; then + if [[ ${{ matrix.prefer-lowest == '8.1' }} ]]; then composer update --prefer-lowest --prefer-stable else composer install fi - name: Run PHPUnit run: | - if [[ ${{ matrix.php-version }} == '7.4' ]]; then + if [[ ${{ matrix.php-version }} == '8.1' ]]; then bin/phpunit --coverage-clover=coverage.xml else bin/phpunit fi - name: Code Coverage Report - if: success() && matrix.php-version == '7.4' + if: success() && matrix.php-version == '8.1' uses: codecov/codecov-action@v2 validation: @@ -54,8 +54,8 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.4' - extensions: json, pdo, ldap + php-version: '8.3' + extensions: json coverage: none tools: pecl diff --git a/.gitignore b/.gitignore index 24b14b3..250e51a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .idea /.phpunit.result.cache +/.phpunit.cache /tmp /vendor /bin +composer.lock diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 3bbd31e..abd9b13 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -3,7 +3,7 @@ build: analysis: environment: php: - version: 7.4 + version: 8.3 project_setup: override: - 'true' @@ -15,14 +15,10 @@ build: coverage: file: 'coverage.xml' format: 'php-clover' - php74: + php81: environment: php: - version: 7.4 - php80: - environment: - php: - version: 8.0 + version: 8.1 filter: excluded_paths: - 'tests/*' diff --git a/composer.json b/composer.json index 3c10fcb..ab7ee97 100644 --- a/composer.json +++ b/composer.json @@ -3,17 +3,19 @@ "description": "Correlation ID and PSR7 middleware to inject it", "type": "library", "require": { - "php": "^7.4 || ^8.0", - "ramsey/uuid": "^3.0 || ^4.0", + "php": "^8.1", "psr/http-message": "^1.0", "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^9.0", - "phpstan/phpstan": "^0.12.0", + "phpunit/phpunit": "^10.0", + "phpstan/phpstan": "^1.10.0", "squizlabs/php_codesniffer": "^3.6" }, + "suggest": { + "ramsey/uuid": "If you want to use this UUID generator for the correlation ID. It will be automatically used instead of built in UUID4v1 generator if it is available." + }, "license": "MIT", "authors": [ { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 523b9d7..6e32a99 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,30 +1,13 @@ - - - - ./tests/TestCase - - - - - ./src - - + + + + ./tests/TestCase + + + + + src + + diff --git a/readme.md b/readme.md index 4aa1fdc..d519aa5 100644 --- a/readme.md +++ b/readme.md @@ -4,6 +4,8 @@ [![Scrutinizer Coverage](https://img.shields.io/scrutinizer/coverage/g/Phauthentic/correlation-id/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/Phauthentic/correlation-id/) [![Code Quality](https://img.shields.io/scrutinizer/g/Phauthentic/correlation-id/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/Phauthentic/correlation-id/) +An implementation of a Correlation ID and a framework agnostic PSR 15-HTTP middlware. + > A Correlation ID, also known as a Transit ID, is a unique identifier value that is attached to requests and messages that allow reference to a particular transaction or event chain. The Correlation Pattern, which depends on the use of Correlation ID is a well documented Enterprise Integration Pattern. * [The value of a correlation ID](https://blog.rapid7.com/2016/12/23/the-value-of-correlation-ids/) @@ -11,15 +13,19 @@ ## Documentation -### Correlation ID +### The Correlation ID Value Object The correlation ID is a singleton class that will always return the same ID for the current life-cycle of the request. -### Middleware +Calling `CorrelationID::toString()` will return a string and will return the same string for the whole live cycle of the application. You can compare a string to the Correlation ID by calling `CorrelationID::sameAs('your-string')`. + +By default it uses its internal implementation to generate a UUID v4 as value of the Correlation ID. If you are using [ramsey/uuid](https://github.com/ramsey/uuid), it will use it automatically. + +### PSR 15 HTTP Middleware The middleware will automatically put the correlation ID into your request object as attribute and header value. By default both use the `CorrelationID` name. -``` +```php $middleware = new CorrelationIDMiddleware( CorrelationID::toString() ); @@ -27,12 +33,14 @@ $middleware = new CorrelationIDMiddleware( ### Response -Since there is no standard for where this needs to be done, just add the correlation ID to your response where ever it suits your architecture or framework. +Since there is no standard for where this needs to be done, just add the correlation ID to your response where it suits your architecture or framework the best. ```php $response->withHeader('CorrelationID', CorrelationId::toString()); ``` +For Symfony there is a [bundle](https://github.com/Phauthentic/correlation-id-symfony-bundle) available that will automatically make the Correlation ID available in the request and response object. + ## Copyright & License Licensed under the [MIT license](LICENSE.txt). diff --git a/src/Utils/CorrelationID.php b/src/Utils/CorrelationID.php index 1f74638..8dbc207 100644 --- a/src/Utils/CorrelationID.php +++ b/src/Utils/CorrelationID.php @@ -18,14 +18,34 @@ namespace Phauthentic\Infrastructure\Utils; use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; class CorrelationID implements CorrelationIDInterface { /** * @var string The correlation ID. */ - protected static $uuid; + protected static string $value; + + /** + * Generates a new UUIDv4. + * + * @return string + * @throws \Random\RandomException; + */ + protected static function generate(): string + { + if (class_alias('Ramsey\Uuid\Uuid', 'Uuid')) { + /** @phpstan-ignore-next-line */ + return Uuid::uuid4()->toString(); + } + + $data = random_bytes(16); + + $data[6] = chr(ord($data[6]) & 0x0f | 0x40); + $data[8] = chr(ord($data[8]) & 0x3f | 0x80); + + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); + } /** * Turns this object into an UUID string. @@ -35,11 +55,11 @@ class CorrelationID implements CorrelationIDInterface */ public static function toString(): string { - if (empty(static::$uuid)) { - static::$uuid = static::generate()->toString(); + if (empty(static::$value)) { + static::$value = static::generate(); } - return static::$uuid; + return static::$value; } /** @@ -50,18 +70,7 @@ public static function toString(): string */ public static function sameAs(string $otherID): bool { - return static::$uuid === $otherID; - } - - /** - * Generates a new correlation ID. - * - * @return \Ramsey\Uuid\UuidInterface - * @throws \Exception - */ - protected static function generate(): UuidInterface - { - return Uuid::uuid4(); + return static::$value === $otherID; } /** diff --git a/tests/TestCase/CorrelationIDTest.php b/tests/TestCase/CorrelationIDTest.php index 2228f24..33209c2 100644 --- a/tests/TestCase/CorrelationIDTest.php +++ b/tests/TestCase/CorrelationIDTest.php @@ -35,7 +35,6 @@ public function testCorrelationId(): void $result2 = CorrelationID::toString(); $this->assertEquals($result, $result2); - $string = CorrelationID::toString(); $this->assertTrue(CorrelationID::sameAs(CorrelationID::toString())); $this->assertFalse(CorrelationID::sameAs('1234')); }