diff --git a/README.md b/README.md index 41bc3880..e815ef66 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,27 @@ This library is loosely based upon the [official GO client](https://github.com/h | 0.6.x | 0.7-0.8 | | v1.x | 0.9-current | | v2.x | 0.9-current | +| v3.x | 0.9-current | | dev-main | current | Newer versions of the api lib will probably work in a limited capacity with older versions of Consul, but no guarantee is made and backwards compatibility issues will not be addressed. +### V3 Breaking Changes + +There are a couple breaking changes between v2 and v3: + +1. The `FakeMap` class has been removed. +2. The `FakeSlice` class has been removed. +3. The `ReadableDuration` class has been removed. +4. All models now have parameterized constructors. + * For the life of V3 I will continue to support construction from associative arrays, but the parameterized + constructors are the preferred method of construction. + * Construction via associative array will be removed entirely in V4 (whenever I get around to that). +5. All of that `Transcoding` nonsense has been removed. +6. The root `Config` class may no longer be constructed with a map. You must use constructor parameters. +7. All "map" fields are now defined as `\stdClass` objects. + ## Composer This lib is designed to be used with [Composer](https://getcomposer.org) @@ -28,7 +44,7 @@ Require Entry: ```json { "require": { - "dcarbone/php-consul-api": "^v2.0" + "dcarbone/php-consul-api": "^v3.0" } } ``` @@ -53,22 +69,28 @@ $config = \DCarbone\PHPConsulAPI\Config::newDefaultConfig(); You may alternatively define values yourself: ```php -$config = new \DCarbone\PHPConsulAPI\Config([ - 'HttpClient' => $client, // [required] Client conforming to GuzzleHttp\ClientInterface - 'Address' => 'address of server', // [required] - - 'Scheme' => 'http or https', // [optional] defaults to "http" - 'Datacenter' => 'name of datacenter', // [optional] - 'HttpAuth' => 'user:pass', // [optional] - 'WaitTime' => '0s', // [optional] amount of time to wait on certain blockable endpoints. go time duration string format. - 'Token' => 'auth token', // [optional] default auth token to use - 'TokenFile' => 'file with auth token', // [optional] file containing auth token string - 'InsecureSkipVerify' => false, // [optional] if set to true, ignores all SSL validation - 'CAFile' => '', // [optional] path to ca cert file, see http://docs.guzzlephp.org/en/latest/request-options.html#verify - 'CertFile' => '', // [optional] path to client public key. if set, requires KeyFile also be set - 'KeyFile' => '', // [optional] path to client private key. if set, requires CertFile also be set - 'JSONEncodeOpts'=> 0, // [optional] php json encode opt value to use when serializing requests -]); +$config = new \DCarbone\PHPConsulAPI\Config( + // required fields + HttpClient: $client, // [required] Client conforming to GuzzleHttp\ClientInterface + Address: 'address of server', // [required] + + // optional fields + Scheme: 'http or https', // [optional] defaults to "http" + Datacenter: 'name of datacenter', // [optional] + HttpAuth: 'user:pass', // [optional] + WaitTime: '0s', // [optional] amount of time to wait on certain blockable endpoints. go time duration string format. + Token: 'auth token', // [optional] default auth token to use + TokenFile: 'file with auth token', // [optional] file containing auth token string + InsecureSkipVerify: false, // [optional] if set to true, ignores all SSL validation + CAFile: '', // [optional] path to ca cert file, see http://docs.guzzlephp.org/en/latest/request-options.html#verify + CertFile: '', // [optional] path to client public key. if set, requires KeyFile also be set + KeyFile: '', // [optional] path to client private key. if set, requires CertFile also be set + + // php specific options + JSONEncodeOpts: JSON_UNESCAPED_SLASHES, + JSONDecodeMaxDepth: 512, + JSONDecodeOpts: 0, +); ``` #### Configuration Note: @@ -83,11 +105,11 @@ prior to constructing a PHPConsulAPI Config object. As an example: ```php -$proxyClient = new \GuzzleHttp\Client(['proxy' => 'whatever proxy you want']]); -$config = new \DCarbone\PHPConsulAPI\Config([ - 'HttpClient' => $proxyClient, - 'Address' => 'address of server', -]); +$proxyClient = new \GuzzleHttp\Client(['proxy' => 'whatever proxy you want']); +$config = new \DCarbone\PHPConsulAPI\Config( + HttpClient: $proxyClient, + Address: 'address of server', +); ``` When constructing your client, if you are using the `GuzzleHttp\Client` object directly or derivative thereof, you may diff --git a/composer.json b/composer.json index abff10c1..b106011d 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ } }, "require-dev": { - "phpunit/phpunit": "^10.5 || ^11.0" + "phpunit/phpunit": "^10.5 || ^11.0", + "phpstan/phpstan": "~2.1.11" }, "autoload-dev": { "files": [ diff --git a/composer.lock b/composer.lock index c2e968d1..74de3870 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "01cc136766bba4c1a8f16d214945f536", + "content-hash": "86e172995bb9ccdc446f6a028d8ea25a", "packages": [ { "name": "dcarbone/gohttp", @@ -941,37 +941,95 @@ }, "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "phpstan/phpstan", + "version": "2.1.11", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "8ca5f79a8f63c49b2359065832a654e1ec70ac30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8ca5f79a8f63c49b2359065832a654e1ec70ac30", + "reference": "8ca5f79a8f63c49b2359065832a654e1ec70ac30", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-03-24T13:45:00+00:00" + }, { "name": "phpunit/php-code-coverage", - "version": "11.0.9", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/14d63fbcca18457e49c6f8bebaa91a87e8e188d7", - "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^5.4.0", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-text-template": "^4.0.1", - "sebastian/code-unit-reverse-lookup": "^4.0.1", - "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.0", - "sebastian/lines-of-code": "^3.0.1", - "sebastian/version": "^5.0.2", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^11.5.2" + "phpunit/phpunit": "^10.1" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -980,7 +1038,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "11.0.x-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -1009,7 +1067,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.9" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -1017,32 +1075,32 @@ "type": "github" } ], - "time": "2025-02-25T13:26:39+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "5.1.0", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1070,7 +1128,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -1078,28 +1136,28 @@ "type": "github" } ], - "time": "2024-08-27T05:02:59+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", - "version": "5.0.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-pcntl": "*" @@ -1107,7 +1165,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1133,8 +1191,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" }, "funding": [ { @@ -1142,32 +1199,32 @@ "type": "github" } ], - "time": "2024-07-03T05:07:44+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { "name": "phpunit/php-text-template", - "version": "4.0.1", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1194,7 +1251,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -1202,32 +1259,32 @@ "type": "github" } ], - "time": "2024-07-03T05:08:43+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", - "version": "7.0.1", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1253,8 +1310,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" }, "funding": [ { @@ -1262,20 +1318,20 @@ "type": "github" } ], - "time": "2024-07-03T05:09:35+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { "name": "phpunit/phpunit", - "version": "11.5.15", + "version": "10.5.45", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "4b6a4ee654e5e0c5e1f17e2f83c0f4c91dee1f9c" + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4b6a4ee654e5e0c5e1f17e2f83c0f4c91dee1f9c", - "reference": "4b6a4ee654e5e0c5e1f17e2f83c0f4c91dee1f9c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", "shasum": "" }, "require": { @@ -1285,26 +1341,26 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.0", + "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.9", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-invoker": "^5.0.1", - "phpunit/php-text-template": "^4.0.1", - "phpunit/php-timer": "^7.0.1", - "sebastian/cli-parser": "^3.0.2", - "sebastian/code-unit": "^3.0.3", - "sebastian/comparator": "^6.3.1", - "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.0", - "sebastian/exporter": "^6.3.0", - "sebastian/global-state": "^7.0.2", - "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.1.2", - "sebastian/version": "^5.0.2", - "staabm/side-effects-detector": "^1.0.5" + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.3", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.2", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.0", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" }, "suggest": { "ext-soap": "To be able to generate mocks based on WSDL files" @@ -1315,7 +1371,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "11.5-dev" + "dev-main": "10.5-dev" } }, "autoload": { @@ -1347,7 +1403,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.15" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" }, "funding": [ { @@ -1363,32 +1419,32 @@ "type": "tidelift" } ], - "time": "2025-03-23T16:02:11+00:00" + "time": "2025-02-06T16:08:12+00:00" }, { "name": "sebastian/cli-parser", - "version": "3.0.2", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -1412,7 +1468,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" }, "funding": [ { @@ -1420,32 +1476,32 @@ "type": "github" } ], - "time": "2024-07-03T04:41:36+00:00" + "time": "2024-03-02T07:12:49+00:00" }, { "name": "sebastian/code-unit", - "version": "3.0.3", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.5" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -1468,8 +1524,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" }, "funding": [ { @@ -1477,32 +1532,32 @@ "type": "github" } ], - "time": "2025-03-19T07:56:08+00:00" + "time": "2023-02-03T06:58:43+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "4.0.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1524,8 +1579,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" }, "funding": [ { @@ -1533,39 +1587,36 @@ "type": "github" } ], - "time": "2024-07-03T04:45:54+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { "name": "sebastian/comparator", - "version": "6.3.1", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/24b8fbc2c8e201bb1308e7b05148d6ab393b6959", - "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/diff": "^6.0", - "sebastian/exporter": "^6.0" + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^11.4" - }, - "suggest": { - "ext-bcmath": "For comparing BcMath\\Number objects" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.3-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1605,7 +1656,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.1" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -1613,33 +1664,33 @@ "type": "github" } ], - "time": "2025-03-07T06:57:01+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", - "version": "4.0.1", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + "reference": "68ff824baeae169ec9f2137158ee529584553799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "3.2-dev" } }, "autoload": { @@ -1663,7 +1714,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -1671,33 +1722,33 @@ "type": "github" } ], - "time": "2024-07-03T04:49:50+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/diff", - "version": "6.0.2", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0", - "symfony/process": "^4.2 || ^5" + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1730,7 +1781,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" }, "funding": [ { @@ -1738,27 +1789,27 @@ "type": "github" } ], - "time": "2024-07-03T04:53:05+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "sebastian/environment", - "version": "7.2.0", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-posix": "*" @@ -1766,7 +1817,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "7.2-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -1794,7 +1845,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" }, "funding": [ { @@ -1802,34 +1853,34 @@ "type": "github" } ], - "time": "2024-07-03T04:54:44+00:00" + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", - "version": "6.3.0", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", - "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/recursion-context": "^6.0" + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^11.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1872,7 +1923,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" }, "funding": [ { @@ -1880,35 +1931,35 @@ "type": "github" } ], - "time": "2024-12-05T09:17:50+00:00" + "time": "2024-03-02T07:17:12+00:00" }, { "name": "sebastian/global-state", - "version": "7.0.2", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1934,7 +1985,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" }, "funding": [ { @@ -1942,33 +1993,33 @@ "type": "github" } ], - "time": "2024-07-03T04:57:36+00:00" + "time": "2024-03-02T07:19:19+00:00" }, { "name": "sebastian/lines-of-code", - "version": "3.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -1992,7 +2043,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -2000,34 +2051,34 @@ "type": "github" } ], - "time": "2024-07-03T04:58:38+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { "name": "sebastian/object-enumerator", - "version": "6.0.1", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2049,8 +2100,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" }, "funding": [ { @@ -2058,32 +2108,32 @@ "type": "github" } ], - "time": "2024-07-03T05:00:13+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { "name": "sebastian/object-reflector", - "version": "4.0.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -2105,8 +2155,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -2114,32 +2163,32 @@ "type": "github" } ], - "time": "2024-07-03T05:01:32+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "6.0.2", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2169,8 +2218,7 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { @@ -2178,32 +2226,32 @@ "type": "github" } ], - "time": "2024-07-03T05:10:34+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { "name": "sebastian/type", - "version": "5.1.2", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e" + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", - "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^11.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2226,8 +2274,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -2235,29 +2282,29 @@ "type": "github" } ], - "time": "2025-03-18T13:35:50+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { "name": "sebastian/version", - "version": "5.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2280,8 +2327,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -2289,59 +2335,7 @@ "type": "github" } ], - "time": "2024-10-09T05:16:32+00:00" - }, - { - "name": "staabm/side-effects-detector", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/staabm/side-effects-detector.git", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.6", - "phpunit/phpunit": "^9.6.21", - "symfony/var-dumper": "^5.4.43", - "tomasvotruba/type-coverage": "1.0.0", - "tomasvotruba/unused-public": "1.0.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "lib/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A static analysis tool to detect side effects in PHP code", - "keywords": [ - "static analysis" - ], - "support": { - "issues": "https://github.com/staabm/side-effects-detector/issues", - "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" - }, - "funding": [ - { - "url": "https://github.com/staabm", - "type": "github" - } - ], - "time": "2024-10-20T05:08:20+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { "name": "theseer/tokenizer", diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..e05e39d2 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 6 + paths: + - src + - tests \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index 0699e390..4aeef048 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,35 +16,35 @@ ./tests/Usage/ConfigUsageTest.php - - ./tests/Usage/RequestUsageTest.php - + + + - - - + + + ./tests/Usage/Agent - - ./tests/Usage/Catalog - - - ./tests/Usage/Coordinate - - - ./tests/Usage/KV - - - ./tests/Usage/Operator - - - ./tests/Usage/Session - + + + + + + + + + + + + + + + - - ./tests/Usage/Random - + + + diff --git a/src/ACL/ACLAuthMethod.php b/src/ACL/ACLAuthMethod.php index bb7d2d9d..3cdd2661 100644 --- a/src/ACL/ACLAuthMethod.php +++ b/src/ACL/ACLAuthMethod.php @@ -22,67 +22,70 @@ use DCarbone\Go\Time; use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLAuthMethod extends AbstractModel { - protected const FIELDS = [ - self::FIELD_DISPLAY_NAME => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_DESCRIPTION => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_MAX_TOKEN_TTL => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_DURATION, - Transcoding::FIELD_MARSHAL_AS => Transcoding::STRING, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_TOKEN_LOCALITY => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_NAMESPACE_RULES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLAuthMethodNamespaceRule::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::class, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_DISPLAY_NAME = 'DisplayName'; - private const FIELD_DESCRIPTION = 'Description'; - private const FIELD_MAX_TOKEN_TTL = 'MaxTokenTTL'; - private const FIELD_TOKEN_LOCALITY = 'TokenLocality'; - private const FIELD_NAMESPACE_RULES = 'NamespaceRules'; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $ID = ''; - public string $Name = ''; - public string $Type = ''; - public string $DisplayName = ''; - public string $Description = ''; + public string $Name; + public string $Type; + public string $DisplayName; + public string $Description; public Time\Duration $MaxTokenTTL; - public string $TokenLocality = ''; - public array $config = []; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public array $NamespaceRules = []; - public string $Namespace = ''; - - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!isset($this->MaxTokenTTL)) { - $this->MaxTokenTTL = new Time\Duration(); + public string $TokenLocality; + public null|\stdClass $Config; + public int $CreateIndex; + public int $ModifyIndex; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLAuthMethodNamespaceRule[] */ + public array $NamespaceRules; + public string $Namespace; + public string $Partition; + + /** + * @param array|null $data Deprecated, will be removed. + * @param string $Name + * @param string $Type + * @param string $DisplayName + * @param string $Description + * @param int|float|string|\DateInterval|\DCarbone\Go\Time\Duration|null $MaxTokenTTL + * @param string $TokenLocality + * @param null|\stdClass $Config + * @param int $CreateIndex + * @param int $ModifyIndex + * @param iterable<\DCarbone\PHPConsulAPI\ACL\ACLAuthMethodNamespaceRule> $NamespaceRules + * @param string $Namespace + * @param string $Partition + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Name = '', + string $Type = '', + string $DisplayName = '', + string $Description = '', + null|int|float|string|\DateInterval|Time\Duration $MaxTokenTTL = null, + string $TokenLocality = '', + null|\stdClass $Config = null, + int $CreateIndex = 0, + int $ModifyIndex = 0, + iterable $NamespaceRules = [], + string $Namespace = '', + string $Partition = '', + ) { + $this->Name = $Name; + $this->Type = $Type; + $this->DisplayName = $DisplayName; + $this->Description = $Description; + $this->setMaxTokenTTL($MaxTokenTTL); + $this->TokenLocality = $TokenLocality; + $this->Config = $Config; + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->setNamespaceRules(...$NamespaceRules); + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } - public function getID(): string - { - return $this->ID; - } - - public function setID(string $ID): ACLAuthMethod - { - $this->ID = $ID; - return $this; - } - public function getName(): string { return $this->Name; @@ -132,9 +135,9 @@ public function getMaxTokenTTL(): Time\Duration return $this->MaxTokenTTL; } - public function setMaxTokenTTL(int|string|Time\Duration $MaxTokenTTL): self + public function setMaxTokenTTL(null|int|float|string|\DateInterval|Time\Duration $MaxTokenTTL): self { - $this->MaxTokenTTL = Time::ParseDuration($MaxTokenTTL); + $this->MaxTokenTTL = Time::Duration($MaxTokenTTL); return $this; } @@ -149,14 +152,14 @@ public function setTokenLocality(string $TokenLocality): self return $this; } - public function getConfig(): array + public function getConfig(): null|\stdClass { - return $this->config; + return $this->Config; } - public function setConfig(array $config): self + public function setConfig(null|\stdClass $Config): self { - $this->config = $config; + $this->Config = $Config; return $this; } @@ -182,14 +185,23 @@ public function setModifyIndex(int $ModifyIndex): self return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLAuthMethodNamespaceRule[] + */ public function getNamespaceRules(): array { return $this->NamespaceRules; } - public function setNamespaceRules(array $NamespaceRules): self + public function addNamespaceRule(ACLAuthMethodNamespaceRule $rule): self + { + $this->NamespaceRules[] = $rule; + return $this; + } + + public function setNamespaceRules(ACLAuthMethodNamespaceRule ...$rules): self { - $this->NamespaceRules = $NamespaceRules; + $this->NamespaceRules = $rules; return $this; } @@ -203,4 +215,67 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('MaxTokenTTL' === $k) { + $n->setMaxTokenTTL($v); + } elseif ('NamespaceRules' === $k) { + $n->NamespaceRules = []; + foreach ($v as $vv) { + $n->NamespaceRules[] = ACLAuthMethodNamespaceRule::jsonUnserialize($vv); + } + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + if ('' !== $this->DisplayName) { + $out->DisplayName = $this->DisplayName; + } + if ('' !== $this->Description) { + $out->Description = $this->Description; + } + if (0 !== $this->MaxTokenTTL->Nanoseconds()) { + $out->MaxTokenTTL = (string)$this->MaxTokenTTL; + } + if ('' !== $this->TokenLocality) { + $out->TokenLocality = $this->TokenLocality; + } + $out->Config = $this->Config; + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + if ([] !== $this->NamespaceRules) { + $out->NamespaceRules = $this->NamespaceRules; + } + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } } diff --git a/src/ACL/ACLAuthMethodListEntry.php b/src/ACL/ACLAuthMethodListEntry.php index 3a54d9f7..ae35c351 100644 --- a/src/ACL/ACLAuthMethodListEntry.php +++ b/src/ACL/ACLAuthMethodListEntry.php @@ -22,32 +22,13 @@ use DCarbone\Go\Time; use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLAuthMethodListEntry extends AbstractModel { - protected const FIELDS = [ - self::FIELD_DISPLAY_NAME => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_DESCRIPTION => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_MAX_TOKEN_TTL => [ - Transcoding::FIELD_MARSHAL_AS => Transcoding::STRING, - Transcoding::FIELD_OMITEMPTY => true, - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_DURATION, - ], - self::FIELD_TOKEN_LOCALITY => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_DISPLAY_NAME = 'DisplayName'; - private const FIELD_DESCRIPTION = 'Description'; - private const FIELD_MAX_TOKEN_TTL = 'MaxTokenTTL'; - private const FIELD_TOKEN_LOCALITY = 'TokenLocality'; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $Name = ''; - public string $Type = ''; - public string $DisplayName = ''; - public string $Description = ''; + public string $Name; + public string $Type; + public string $DisplayName; + public string $Description; public Time\Duration $MaxTokenTTL; /** * TokenLocality defines the kind of token that this auth method produces. @@ -55,9 +36,35 @@ class ACLAuthMethodListEntry extends AbstractModel * @var string */ public string $TokenLocality; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $Namespace = ''; + public int $CreateIndex; + public int $ModifyIndex; + public string $Namespace; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Name = '', + string $Type = '', + string $DisplayName = '', + string $Description = '', + null|int|float|string|\DateInterval|Time\Duration $MaxTokenTTL = null, + string $TokenLocality = '', + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $Namespace = '' + ) { + $this->Name = $Name; + $this->Type = $Type; + $this->DisplayName = $DisplayName; + $this->Description = $Description; + $this->setMaxTokenTTL($MaxTokenTTL); + $this->TokenLocality = $TokenLocality; + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->Namespace = $Namespace; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getName(): string { @@ -108,9 +115,9 @@ public function getMaxTokenTTL(): Time\Duration return $this->MaxTokenTTL; } - public function setMaxTokenTTL(Time\Duration $MaxTokenTTL): self + public function setMaxTokenTTL(null|int|float|string|\DateInterval|Time\Duration $MaxTokenTTL): self { - $this->MaxTokenTTL = $MaxTokenTTL; + $this->MaxTokenTTL = Time::Duration($MaxTokenTTL); return $this; } @@ -171,13 +178,46 @@ public function setNamespace(string $Namespace): self return $this; } - public function jsonSerialize(): array + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static { - $out = parent::jsonSerialize(); - if (!isset($this->MaxTokenTTL) || 0 === $this->MaxTokenTTL->Nanoseconds()) { - $out[self::FIELD_MAX_TOKEN_TTL] = ''; - } else { - $out[self::FIELD_MAX_TOKEN_TTL] = (string)$this->MaxTokenTTL; + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if (null === $v) { + continue; + } + if ('MaxTokenTTL' === $k) { + $n->setMaxTokenTTL($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + $out->Type = $this->Type; + if ('' !== $this->DisplayName) { + $out->DisplayName = $this->DisplayName; + } + if ('' !== $this->Description) { + $out->Description = $this->Description; + } + if (0 !== $this->MaxTokenTTL->Nanoseconds()) { + $out->MaxTokenTTL = (string)$this->MaxTokenTTL; + } + if ('' !== $this->TokenLocality) { + $out->TokenLocality = $this->TokenLocality; + } + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; } return $out; } diff --git a/src/ACL/ACLAuthMethodListEntryQueryResponse.php b/src/ACL/ACLAuthMethodListEntryQueryResponse.php index 7233b6c2..268e6554 100644 --- a/src/ACL/ACLAuthMethodListEntryQueryResponse.php +++ b/src/ACL/ACLAuthMethodListEntryQueryResponse.php @@ -25,18 +25,21 @@ class ACLAuthMethodListEntryQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $ACLAuthMethodListEntries = []; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLAuthMethodListEntry[] */ + public array $ACLAuthMethodListEntries = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLAuthMethodListEntry[] + */ + public function getValue(): array { return $this->ACLAuthMethodListEntries; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLAuthMethodListEntries = []; - foreach ($decodedData as $datum) { - $this->ACLAuthMethodListEntries[] = new ACLAuthMethodListEntry($datum); + foreach ($decoded as $datum) { + $this->ACLAuthMethodListEntries[] = ACLAuthMethodListEntry::jsonUnserialize($datum); } } } diff --git a/src/ACL/ACLAuthMethodNamespaceRule.php b/src/ACL/ACLAuthMethodNamespaceRule.php index c6b76694..23b3b773 100644 --- a/src/ACL/ACLAuthMethodNamespaceRule.php +++ b/src/ACL/ACLAuthMethodNamespaceRule.php @@ -21,20 +21,23 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLAuthMethodNamespaceRule extends AbstractModel { - protected const FIELDS = [ - self::FIELD_SELECTOR => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_BIND_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; + public string $Selector; + public string $BindNamespace; - private const FIELD_SELECTOR = 'Selector'; - private const FIELD_BIND_NAMESPACE = 'BindNamespace'; - - public string $Selector = ''; - public string $BindNamespace = ''; + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Selector = '', + string $BindNamespace = '', + ) { + $this->Selector = $Selector; + $this->BindNamespace = $BindNamespace; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getSelector(): string { @@ -57,4 +60,28 @@ public function setBindNamespace(string $BindNamespace): self $this->BindNamespace = $BindNamespace; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ('' !== $this->Selector) { + $out->Selector = $this->Selector; + } + if ('' !== $this->BindNamespace) { + $out->BindNamespace = $this->BindNamespace; + } + return $out; + } } diff --git a/src/ACL/ACLAuthMethodQueryResponse.php b/src/ACL/ACLAuthMethodQueryResponse.php index a3a26039..5c51602f 100644 --- a/src/ACL/ACLAuthMethodQueryResponse.php +++ b/src/ACL/ACLAuthMethodQueryResponse.php @@ -25,15 +25,19 @@ class ACLAuthMethodQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?ACLAuthMethod $ACLAuthMethod = null; + public null|ACLAuthMethod $ACLAuthMethod = null; - public function getValue(): ?ACLAuthMethod + public function getValue(): null|ACLAuthMethod { return $this->ACLAuthMethod; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLAuthMethod = new ACLAuthMethod((array)$decodedData); + if (null === $decoded) { + $this->ACLAuthMethod = null; + return; + } + $this->ACLAuthMethod = $this->ACLAuthMethod::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLAuthMethodWriteResponse.php b/src/ACL/ACLAuthMethodWriteResponse.php index 0a609b71..61f17997 100644 --- a/src/ACL/ACLAuthMethodWriteResponse.php +++ b/src/ACL/ACLAuthMethodWriteResponse.php @@ -25,15 +25,19 @@ class ACLAuthMethodWriteResponse extends AbstractValuedWriteResponse implements UnmarshalledResponseInterface { - public ?ACLAuthMethod $ACLAuthMethod = null; + public null|ACLAuthMethod $ACLAuthMethod = null; - public function getValue(): ?ACLAuthMethod + public function getValue(): null|ACLAuthMethod { return $this->ACLAuthMethod; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLAuthMethod = new ACLAuthMethod((array)$decodedData); + if (null === $decoded) { + $this->ACLAuthMethod = null; + return; + } + $this->ACLAuthMethod = ACLAuthMethod::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLBindingRule.php b/src/ACL/ACLBindingRule.php index 0a359399..0be0e60a 100644 --- a/src/ACL/ACLBindingRule.php +++ b/src/ACL/ACLBindingRule.php @@ -21,25 +21,44 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLBindingRule extends AbstractModel { - protected const FIELDS = [ - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_NAMESPACE = 'Namespace'; - - public string $ID = ''; - public string $Description = ''; - public string $AuthMethod = ''; - public string $Selector = ''; - public string $BindType = ''; - public string $BindName = ''; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $Namespace = ''; + public string $ID; + public string $Description; + public string $AuthMethod; + public string $Selector; + public string $BindType; + public string $BindName; + public int $CreateIndex; + public int $ModifyIndex; + public string $Namespace; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ID = '', + string $Description = '', + string $AuthMethod = '', + string $Selector = '', + string $BindType = '', + string $BindName = '', + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $Namespace = '' + ) { + $this->ID = $ID; + $this->Description = $Description; + $this->AuthMethod = $AuthMethod; + $this->Selector = $Selector; + $this->BindType = $BindType; + $this->BindName = $BindName; + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->Namespace = $Namespace; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getID(): string { @@ -139,4 +158,33 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ID = $this->ID; + $out->Description = $this->Description; + $out->AuthMethod = $this->AuthMethod; + $out->Selector = $this->Selector; + $out->BindType = $this->BindType; + $out->BindName = $this->BindName; + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + return $out; + } } diff --git a/src/ACL/ACLBindingRuleQueryResponse.php b/src/ACL/ACLBindingRuleQueryResponse.php index ee85a37d..73381657 100644 --- a/src/ACL/ACLBindingRuleQueryResponse.php +++ b/src/ACL/ACLBindingRuleQueryResponse.php @@ -25,15 +25,19 @@ class ACLBindingRuleQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?ACLBindingRule $ACLBindingRule = null; + public null|ACLBindingRule $ACLBindingRule = null; - public function getValue(): ?ACLBindingRule + public function getValue(): null|ACLBindingRule { return $this->ACLBindingRule; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLBindingRule = new ACLBindingRule((array)$decodedData); + if (null === $decoded) { + $this->ACLBindingRule = null; + return; + } + $this->ACLBindingRule = ACLBindingRule::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLBindingRuleWriteResponse.php b/src/ACL/ACLBindingRuleWriteResponse.php index c1ba51c1..471cb66c 100644 --- a/src/ACL/ACLBindingRuleWriteResponse.php +++ b/src/ACL/ACLBindingRuleWriteResponse.php @@ -25,15 +25,19 @@ class ACLBindingRuleWriteResponse extends AbstractValuedWriteResponse implements UnmarshalledResponseInterface { - public ?ACLBindingRule $ACLBindingRule = null; + public null|ACLBindingRule $ACLBindingRule = null; - public function getValue(): ?ACLBindingRule + public function getValue(): null|ACLBindingRule { return $this->ACLBindingRule; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLBindingRule = new ACLBindingRule((array)$decodedData); + if (null === $decoded) { + $this->ACLBindingRule = null; + return; + } + $this->ACLBindingRule = ACLBindingRule::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLBindingRulesQueryResponse.php b/src/ACL/ACLBindingRulesQueryResponse.php index 59d77a58..cf6d7d59 100644 --- a/src/ACL/ACLBindingRulesQueryResponse.php +++ b/src/ACL/ACLBindingRulesQueryResponse.php @@ -25,18 +25,22 @@ class ACLBindingRulesQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $ACLBindingRules = []; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLBindingRule[] */ + public array $ACLBindingRules = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLBindingRule[] + */ + public function getValue(): array { return $this->ACLBindingRules; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->ACLBindingRules = []; - foreach ($decodedData as $datum) { - $this->ACLBindingRules[] = new ACLBindingRule($datum); + foreach ($decoded as $datum) { + $this->ACLBindingRules[] = ACLBindingRule::jsonUnserialize($datum); } } } diff --git a/src/ACL/ACLClient.php b/src/ACL/ACLClient.php index 79e3daa0..af9c7531 100644 --- a/src/ACL/ACLClient.php +++ b/src/ACL/ACLClient.php @@ -34,27 +34,27 @@ public function Bootstrap(): ValuedWriteStringResponse return $this->_executePutValuedStr('v1/acl/bootstrap', null, null); } - public function Create(ACLEntry $acl, ?WriteOptions $opts = null): ValuedWriteStringResponse + public function Create(ACLEntry $acl, null|WriteOptions $opts = null): ValuedWriteStringResponse { return $this->_executePutValuedStr('v1/acl/create', $acl, $opts); } - public function Update(ACLEntry $acl, ?WriteOptions $opts = null): WriteResponse + public function Update(ACLEntry $acl, null|WriteOptions $opts = null): WriteResponse { return $this->_executePut('v1/acl/update', $acl, $opts); } - public function Destroy(string $id, ?WriteOptions $opts = null): WriteResponse + public function Destroy(string $id, null|WriteOptions $opts = null): WriteResponse { return $this->_executePut(sprintf('v1/acl/destroy/%s', $id), null, $opts); } - public function Clone(string $id, ?WriteOptions $opts = null): ValuedWriteStringResponse + public function Clone(string $id, null|WriteOptions $opts = null): ValuedWriteStringResponse { return $this->_executePutValuedStr(sprintf('v1/acl/clone/%s', $id), null, $opts); } - public function Info(string $id, ?QueryOptions $opts = null): ACLEntriesResponse + public function Info(string $id, null|QueryOptions $opts = null): ACLEntriesResponse { $resp = $this->_requireOK($this->_doGet(sprintf('v1/acl/info/%s', $id), $opts)); $ret = new ACLEntriesResponse(); @@ -62,7 +62,7 @@ public function Info(string $id, ?QueryOptions $opts = null): ACLEntriesResponse return $ret; } - public function List(?QueryOptions $opts = null): ACLEntriesResponse + public function List(null|QueryOptions $opts = null): ACLEntriesResponse { $resp = $this->_requireOK($this->_doGet('v1/acl/list', $opts)); $ret = new ACLEntriesResponse(); @@ -70,7 +70,7 @@ public function List(?QueryOptions $opts = null): ACLEntriesResponse return $ret; } - public function Replication(?QueryOptions $opts = null): ACLReplicationStatusResponse + public function Replication(null|QueryOptions $opts = null): ACLReplicationStatusResponse { $resp = $this->_requireOK($this->_doGet('/v1/acl/replication', $opts)); $ret = new ACLReplicationStatusResponse(); @@ -78,7 +78,7 @@ public function Replication(?QueryOptions $opts = null): ACLReplicationStatusRes return $ret; } - public function TokenCreate(ACLToken $token, ?WriteOptions $opts = null): ACLTokenWriteResponse + public function TokenCreate(ACLToken $token, null|WriteOptions $opts = null): ACLTokenWriteResponse { $resp = $this->_requireOK($this->_doPut('/v1/acl/token', $token, $opts)); $ret = new ACLTokenWriteResponse(); @@ -86,7 +86,7 @@ public function TokenCreate(ACLToken $token, ?WriteOptions $opts = null): ACLTok return $ret; } - public function TokenUpdate(ACLToken $token, ?WriteOptions $opts = null): ACLTokenWriteResponse + public function TokenUpdate(ACLToken $token, null|WriteOptions $opts = null): ACLTokenWriteResponse { $ret = new ACLTokenWriteResponse(); if ('' === $token->AccessorID) { @@ -98,34 +98,44 @@ public function TokenUpdate(ACLToken $token, ?WriteOptions $opts = null): ACLTok return $ret; } - public function TokenClone(string $tokenID, string $description, ?WriteOptions $opts = null): ACLTokenWriteResponse + public function TokenClone(string $accessorID, string $description, null|WriteOptions $opts = null): ACLTokenWriteResponse { $ret = new ACLTokenWriteResponse(); - if ('' === $tokenID) { + if ('' === $accessorID) { $ret->Err = new Error('must specify tokenID for Token Cloning'); return $ret; } $resp = $this->_requireOK( - $this->_doPut(sprintf('/v1/acl/token/%s/clone', $tokenID), ['description' => $description], $opts) + $this->_doPut(sprintf('/v1/acl/token/%s/clone', $accessorID), ['description' => $description], $opts) ); $this->_unmarshalResponse($resp, $ret); return $ret; } - public function TokenDelete(string $tokenID, ?WriteOptions $opts = null): WriteResponse + public function TokenDelete(string $accessorID, null|WriteOptions $opts = null): WriteResponse { - return $this->_executeDelete(sprintf('/v1/acl/token/%s', $tokenID), $opts); + return $this->_executeDelete(sprintf('/v1/acl/token/%s', $accessorID), $opts); } - public function TokenRead(string $tokenID, ?QueryOptions $opts = null): ACLTokenQueryResponse + public function TokenRead(string $accessorID, null|QueryOptions $opts = null): ACLTokenQueryResponse { - $resp = $this->_requireOK($this->_doGet(sprintf('/v1/acl/token/%s', $tokenID), $opts)); + $resp = $this->_requireOK($this->_doGet(sprintf('/v1/acl/token/%s', $accessorID), $opts)); $ret = new ACLTokenQueryResponse(); $this->_unmarshalResponse($resp, $ret); return $ret; } - public function TokenReadSelf(?QueryOptions $opts = null): ACLTokenQueryResponse + public function TokenReadExpanded(string $accessorID, null|QueryOptions $opts = null): ACLTokenExpandedQueryResponse + { + $req = $this->_newGetRequest(sprintf('/v1/acl/token/%s', $accessorID), $opts); + $req->params->set('expanded', 'true'); + $resp = $this->_requireOK($this->_do($req)); + $ret = new ACLTokenExpandedQueryResponse(); + $this->_unmarshalResponse($resp, $ret); + return $ret; + } + + public function TokenReadSelf(null|QueryOptions $opts = null): ACLTokenQueryResponse { $resp = $this->_requireOK($this->_doGet('/v1/acl/token/self', $opts)); $ret = new ACLTokenQueryResponse(); @@ -133,7 +143,7 @@ public function TokenReadSelf(?QueryOptions $opts = null): ACLTokenQueryResponse return $ret; } - public function TokenList(?QueryOptions $opts = null): ACLTokenListEntryQueryResponse + public function TokenList(null|QueryOptions $opts = null): ACLTokenListEntryQueryResponse { $resp = $this->_requireOK($this->_doGet('/v1/acl/tokens', $opts)); $ret = new ACLTokenListEntryQueryResponse(); @@ -141,7 +151,7 @@ public function TokenList(?QueryOptions $opts = null): ACLTokenListEntryQueryRes return $ret; } - public function PolicyCreate(ACLPolicy $policy, ?WriteOptions $opts = null): ACLPolicyWriteResponse + public function PolicyCreate(ACLPolicy $policy, null|WriteOptions $opts = null): ACLPolicyWriteResponse { $ret = new ACLPolicyWriteResponse(); if ('' !== $policy->ID) { @@ -153,7 +163,7 @@ public function PolicyCreate(ACLPolicy $policy, ?WriteOptions $opts = null): ACL return $ret; } - public function PolicyUpdate(ACLPolicy $policy, ?WriteOptions $opts = null): ACLPolicyWriteResponse + public function PolicyUpdate(ACLPolicy $policy, null|WriteOptions $opts = null): ACLPolicyWriteResponse { $ret = new ACLPolicyWriteResponse(); if ('' === $policy->ID) { @@ -165,12 +175,12 @@ public function PolicyUpdate(ACLPolicy $policy, ?WriteOptions $opts = null): ACL return $ret; } - public function PolicyDelete(string $policyID, ?WriteOptions $opts = null): WriteResponse + public function PolicyDelete(string $policyID, null|WriteOptions $opts = null): WriteResponse { return $this->_executeDelete(sprintf('/v1/acl/policy/%s', $policyID), $opts); } - public function PolicyRead(string $policyID, ?QueryOptions $opts = null): ACLPolicyQueryResponse + public function PolicyRead(string $policyID, null|QueryOptions $opts = null): ACLPolicyQueryResponse { $resp = $this->_requireOK($this->_doGet(sprintf('/v1/acl/policy/%s', $policyID), $opts)); $ret = new ACLPolicyQueryResponse(); @@ -178,7 +188,7 @@ public function PolicyRead(string $policyID, ?QueryOptions $opts = null): ACLPol return $ret; } - public function PolicyReadByName(string $policyName, ?QueryOptions $opts = null): ACLPolicyQueryResponse + public function PolicyReadByName(string $policyName, null|QueryOptions $opts = null): ACLPolicyQueryResponse { $resp = $this->_requireOK($this->_doGet(sprintf('/v1/acl/policy/name/%s', $policyName), $opts)); $ret = new ACLPolicyQueryResponse(); @@ -186,7 +196,7 @@ public function PolicyReadByName(string $policyName, ?QueryOptions $opts = null) return $ret; } - public function PolicyList(?QueryOptions $opts = null): ACLPolicyListEntryQueryResponse + public function PolicyList(null|QueryOptions $opts = null): ACLPolicyListEntryQueryResponse { $resp = $this->_requireOK($this->_doGet('/v1/acl/policies', $opts)); $ret = new ACLPolicyListEntryQueryResponse(); @@ -194,7 +204,7 @@ public function PolicyList(?QueryOptions $opts = null): ACLPolicyListEntryQueryR return $ret; } - public function RoleCreate(ACLRole $role, ?WriteOptions $opts = null): ACLRoleWriteResponse + public function RoleCreate(ACLRole $role, null|WriteOptions $opts = null): ACLRoleWriteResponse { $ret = new ACLRoleWriteResponse(); if ('' !== $role->ID) { @@ -206,7 +216,7 @@ public function RoleCreate(ACLRole $role, ?WriteOptions $opts = null): ACLRoleWr return $ret; } - public function RoleUpdate(ACLRole $role, ?WriteOptions $opts = null): ACLRoleWriteResponse + public function RoleUpdate(ACLRole $role, null|WriteOptions $opts = null): ACLRoleWriteResponse { $ret = new ACLRoleWriteResponse(); if ('' === $role->ID) { @@ -218,12 +228,12 @@ public function RoleUpdate(ACLRole $role, ?WriteOptions $opts = null): ACLRoleWr return $ret; } - public function RoleDelete(string $roleID, ?WriteOptions $opts = null): WriteResponse + public function RoleDelete(string $roleID, null|WriteOptions $opts = null): WriteResponse { return $this->_executeDelete(sprintf('/v1/acl/role/%s', $roleID), $opts); } - public function RoleRead(string $roleID, ?QueryOptions $opts = null): ACLRoleQueryResponse + public function RoleRead(string $roleID, null|QueryOptions $opts = null): ACLRoleQueryResponse { $resp = $this->_requireNotFoundOrOK($this->_doGet(sprintf('/v1/acl/role/%s', $roleID), $opts)); $ret = new ACLRoleQueryResponse(); @@ -231,7 +241,7 @@ public function RoleRead(string $roleID, ?QueryOptions $opts = null): ACLRoleQue return $ret; } - public function RoleReadByName(string $roleName, ?QueryOptions $opts = null): ACLRoleQueryResponse + public function RoleReadByName(string $roleName, null|QueryOptions $opts = null): ACLRoleQueryResponse { $resp = $this->_requireOK($this->_doGet(sprintf('/v1/acl/role/name/%s', $roleName), $opts)); $ret = new ACLRoleQueryResponse(); @@ -239,7 +249,7 @@ public function RoleReadByName(string $roleName, ?QueryOptions $opts = null): AC return $ret; } - public function RoleList(?QueryOptions $opts = null): ACLRolesQueryResponse + public function RoleList(null|QueryOptions $opts = null): ACLRolesQueryResponse { $resp = $this->_requireOK($this->_doGet('/v1/acl/roles', $opts)); $ret = new ACLRolesQueryResponse(); @@ -247,7 +257,7 @@ public function RoleList(?QueryOptions $opts = null): ACLRolesQueryResponse return $ret; } - public function AuthMethodCreate(ACLAuthMethod $authMethod, ?WriteOptions $opts = null): ACLAuthMethodWriteResponse + public function AuthMethodCreate(ACLAuthMethod $authMethod, null|WriteOptions $opts = null): ACLAuthMethodWriteResponse { $ret = new ACLAuthMethodWriteResponse(); if ('' !== $authMethod->Name) { @@ -259,7 +269,7 @@ public function AuthMethodCreate(ACLAuthMethod $authMethod, ?WriteOptions $opts return $ret; } - public function AuthMethodUpdate(ACLAuthMethod $authMethod, ?WriteOptions $opts = null): ACLAuthMethodWriteResponse + public function AuthMethodUpdate(ACLAuthMethod $authMethod, null|WriteOptions $opts = null): ACLAuthMethodWriteResponse { $ret = new ACLAuthMethodWriteResponse(); if ('' === $authMethod->ID) { @@ -271,12 +281,12 @@ public function AuthMethodUpdate(ACLAuthMethod $authMethod, ?WriteOptions $opts return $ret; } - public function AuthMethodDelete(string $authMethodID, ?WriteOptions $opts = null): WriteResponse + public function AuthMethodDelete(string $authMethodID, null|WriteOptions $opts = null): WriteResponse { return $this->_executeDelete(sprintf('/v1/acl/authMethod/%s', $authMethodID), $opts); } - public function AuthMethodRead(string $authMethodID, ?QueryOptions $opts = null): ACLAuthMethodQueryResponse + public function AuthMethodRead(string $authMethodID, null|QueryOptions $opts = null): ACLAuthMethodQueryResponse { $resp = $this->_requireNotFoundOrOK($this->_doGet(sprintf('/v1/acl/authMethod/%s', $authMethodID), $opts)); $ret = new ACLAuthMethodQueryResponse(); @@ -284,7 +294,7 @@ public function AuthMethodRead(string $authMethodID, ?QueryOptions $opts = null) return $ret; } - public function AuthMethodList(?QueryOptions $opts = null): ACLAuthMethodListEntryQueryResponse + public function AuthMethodList(null|QueryOptions $opts = null): ACLAuthMethodListEntryQueryResponse { $resp = $this->_requireOK($this->_doGet('/v1/acl/auth-methods', $opts)); $ret = new ACLAuthMethodListEntryQueryResponse(); @@ -292,10 +302,8 @@ public function AuthMethodList(?QueryOptions $opts = null): ACLAuthMethodListEnt return $ret; } - public function BindingRuleCreate( - ACLBindingRule $bindingRule, - ?WriteOptions $opts = null - ): ACLBindingRuleWriteResponse { + public function BindingRuleCreate(ACLBindingRule $bindingRule, null|WriteOptions $opts = null): ACLBindingRuleWriteResponse + { $ret = new ACLBindingRuleWriteResponse(); if ('' !== $bindingRule->ID) { $ret->Err = new Error('cannot specify an id in BindingRule Create'); @@ -306,10 +314,8 @@ public function BindingRuleCreate( return $ret; } - public function BindingRuleUpdate( - ACLBindingRule $bindingRule, - ?WriteOptions $opts = null - ): ACLBindingRuleWriteResponse { + public function BindingRuleUpdate(ACLBindingRule $bindingRule, null|WriteOptions $opts = null): ACLBindingRuleWriteResponse + { $ret = new ACLBindingRuleWriteResponse(); if ('' === $bindingRule->ID) { $ret->Err = new Error('must specify an ID in BindingRule Update'); @@ -320,12 +326,12 @@ public function BindingRuleUpdate( return $ret; } - public function BindingRuleDelete(string $bindingRuleID, ?WriteOptions $opts = null): WriteResponse + public function BindingRuleDelete(string $bindingRuleID, null|WriteOptions $opts = null): WriteResponse { return $this->_executeDelete(sprintf('/v1/acl/binding-rule/%s', $bindingRuleID), $opts); } - public function BindingRuleRead(string $bindingRuleID, ?QueryOptions $opts = null): ACLBindingRuleQueryResponse + public function BindingRuleRead(string $bindingRuleID, null|QueryOptions $opts = null): ACLBindingRuleQueryResponse { $resp = $this->_requireNotFoundOrOK($this->_doGet(sprintf('/v1/acl/binding-rule/%s', $bindingRuleID), $opts)); $ret = new ACLBindingRuleQueryResponse(); @@ -333,7 +339,7 @@ public function BindingRuleRead(string $bindingRuleID, ?QueryOptions $opts = nul return $ret; } - public function BindingRuleList(?QueryOptions $opts = null): ACLBindingRulesQueryResponse + public function BindingRuleList(null|QueryOptions $opts = null): ACLBindingRulesQueryResponse { $resp = $this->_requireOK($this->_doGet('/v1/acl/binding-rules', $opts)); $ret = new ACLBindingRulesQueryResponse(); @@ -341,7 +347,7 @@ public function BindingRuleList(?QueryOptions $opts = null): ACLBindingRulesQuer return $ret; } - public function Login(ACLLoginParams $login, ?WriteOptions $opts = null): ACLTokenWriteResponse + public function Login(ACLLoginParams $login, null|WriteOptions $opts = null): ACLTokenWriteResponse { $resp = $this->_requireOK($this->_doPost('/v1/acl/login', $login, $opts)); $ret = new ACLTokenWriteResponse(); @@ -349,12 +355,12 @@ public function Login(ACLLoginParams $login, ?WriteOptions $opts = null): ACLTok return $ret; } - public function Logout(?WriteOptions $opts = null): WriteResponse + public function Logout(null|WriteOptions $opts = null): WriteResponse { return $this->_executePost('/v1/acl/logout', null, $opts); } - public function OIDCAuthURL(ACLOIDCAuthURLParams $auth, ?WriteOptions $opts = null): ValuedWriteStringResponse + public function OIDCAuthURL(ACLOIDCAuthURLParams $auth, null|WriteOptions $opts = null): ValuedWriteStringResponse { $ret = new ValuedWriteStringResponse(); if ('' === $auth->AuthMethod) { @@ -366,7 +372,7 @@ public function OIDCAuthURL(ACLOIDCAuthURLParams $auth, ?WriteOptions $opts = nu return $ret; } - public function OIDCCallback(ACLOIDCCallbackParams $auth, ?WriteOptions $opts = null): ACLTokenWriteResponse + public function OIDCCallback(ACLOIDCCallbackParams $auth, null|WriteOptions $opts = null): ACLTokenWriteResponse { $ret = new ACLTokenWriteResponse(); if ('' === $auth->AuthMethod) { diff --git a/src/ACL/ACLEntriesResponse.php b/src/ACL/ACLEntriesResponse.php index f9c4af8f..e4bd298a 100644 --- a/src/ACL/ACLEntriesResponse.php +++ b/src/ACL/ACLEntriesResponse.php @@ -25,17 +25,22 @@ class ACLEntriesResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { + /** @var \DCarbone\PHPConsulAPI\ACL\ACLEntry[] */ public array $ACLEntries = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLEntry[] + */ + public function getValue(): array { return $this->ACLEntries; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - foreach ($decodedData as $entry) { - $this->ACLEntries[] = new ACLEntry($entry); + $this->ACLEntries = []; + foreach ($decoded as $entry) { + $this->ACLEntries[] = ACLEntry::jsonUnserialize($entry); } } } diff --git a/src/ACL/ACLEntry.php b/src/ACL/ACLEntry.php index 4bc149f5..1ed8c060 100644 --- a/src/ACL/ACLEntry.php +++ b/src/ACL/ACLEntry.php @@ -24,12 +24,32 @@ class ACLEntry extends AbstractModel { - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $ID = ''; - public string $Name = ''; - public string $Type = ''; - public string $Rules = ''; + public int $CreateIndex; + public int $ModifyIndex; + public string $ID; + public string $Name; + public string $Type; + public string $Rules; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $ID = '', + string $Name = '', + string $Type = '', + string $Rules = '' + ) { + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->ID = $ID; + $this->Name = $Name; + $this->Type = $Type; + $this->Rules = $Rules; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getCreateIndex(): int { @@ -96,4 +116,28 @@ public function setRules(string $rules): self $this->Rules = $rules; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + $out->ID = $this->ID; + $out->Name = $this->Name; + $out->Type = $this->Type; + $out->Rules = $this->Rules; + return $out; + } } diff --git a/src/ACL/ACLLink.php b/src/ACL/ACLLink.php index 905e0a98..42324c08 100644 --- a/src/ACL/ACLLink.php +++ b/src/ACL/ACLLink.php @@ -24,16 +24,60 @@ class ACLLink extends AbstractModel { - public string $ID = ''; - public string $Name = ''; + public string $ID; + public string $Name; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ID = '', + string $Name = '', + ) { + $this->ID = $ID; + $this->Name = $Name; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getID(): string { return $this->ID; } + public function setID(string $ID): self + { + $this->ID = $ID; + return $this; + } + public function getName(): string { return $this->Name; } + + public function setName(string $Name): self + { + $this->Name = $Name; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ID = $this->ID; + $out->Name = $this->Name; + return $out; + } } diff --git a/src/ACL/ACLLoginParams.php b/src/ACL/ACLLoginParams.php index 19ce55aa..d4df6b65 100644 --- a/src/ACL/ACLLoginParams.php +++ b/src/ACL/ACLLoginParams.php @@ -21,20 +21,26 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\FakeMap; -use DCarbone\PHPConsulAPI\Transcoding; class ACLLoginParams extends AbstractModel { - protected const FIELDS = [ - self::FIELD_META => Transcoding::MAP_FIELD + [Transcoding::FIELD_OMITEMPTY => true], - ]; - - private const FIELD_META = 'Meta'; - - public string $AuthMethod = ''; - public string $BearerToken = ''; - public ?FakeMap $Meta = null; + public string $AuthMethod; + public string $BearerToken; + public null|array $Meta; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $AuthMethod = '', + string $BearerToken = '', + null|array|\stdClass $Meta = null, + ) { + $this->AuthMethod = $AuthMethod; + $this->BearerToken = $BearerToken; + $this->setMeta($Meta); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getAuthMethod(): string { @@ -58,14 +64,44 @@ public function setBearerToken(string $BearerToken): self return $this; } - public function getMeta(): ?FakeMap + public function getMeta(): array { return $this->Meta; } - public function setMeta(mixed $Meta): self + public function setMeta(null|array|\stdClass $Meta): self { - $this->Meta = FakeMap::parse($Meta); + $this->Meta = match($Meta) { + null => null, + default => (array)$Meta, + }; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Meta' === $k) { + $n->setMeta($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->AuthMethod = $this->AuthMethod; + $out->BearerToken = $this->BearerToken; + if (null !== $this->Meta && [] !== $this->Meta) { + $out->Meta = $this->Meta; + } + return $out; + } } diff --git a/src/ACL/ACLNodeIdentity.php b/src/ACL/ACLNodeIdentity.php index 400aca2d..7dee2ad8 100644 --- a/src/ACL/ACLNodeIdentity.php +++ b/src/ACL/ACLNodeIdentity.php @@ -24,8 +24,20 @@ class ACLNodeIdentity extends AbstractModel { - public string $NodeName = ''; - public string $Datacenter = ''; + public string $NodeName; + public string $Datacenter; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $NodeName = '', + string $Datacenter = '' + ) { + $this->NodeName = $NodeName; + $this->Datacenter = $Datacenter; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getNodeName(): string { @@ -36,4 +48,24 @@ public function getDatacenter(): string { return $this->Datacenter; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->NodeName = $this->NodeName; + $out->Datacenter = $this->Datacenter; + return $out; + } } diff --git a/src/ACL/ACLOIDCAuthURLParams.php b/src/ACL/ACLOIDCAuthURLParams.php index e5384cb7..bb996202 100644 --- a/src/ACL/ACLOIDCAuthURLParams.php +++ b/src/ACL/ACLOIDCAuthURLParams.php @@ -21,21 +21,29 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\FakeMap; -use DCarbone\PHPConsulAPI\Transcoding; class ACLOIDCAuthURLParams extends AbstractModel { - protected const FIELDS = [ - self::FIELD_META => Transcoding::MAP_FIELD + [Transcoding::FIELD_OMITEMPTY => true], - ]; - - private const FIELD_META = 'Meta'; - - public string $AuthMethod = ''; - public string $RedirectURI = ''; - public string $ClientNonce = ''; - public ?FakeMap $Meta = null; + public string $AuthMethod; + public string $RedirectURI; + public string $ClientNonce; + public null|array $Meta; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $AuthMethod = '', + string $RedirectURI = '', + string $ClientNonce = '', + null|array|\stdClass $Meta = null + ) { + $this->AuthMethod = $AuthMethod; + $this->RedirectURI = $RedirectURI; + $this->ClientNonce = $ClientNonce; + $this->setMeta($Meta); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getAuthMethod(): string { @@ -70,14 +78,46 @@ public function setClientNonce(string $ClientNonce): self return $this; } - public function getMeta(): ?FakeMap + public function getMeta(): null|array { return $this->Meta; } - public function setMeta(mixed $Meta): self + public function setMeta(null|array|\stdClass $Meta): self { - $this->Meta = FakeMap::parse($Meta); + $this->Meta = match($Meta) { + null => null, + default => (array)$Meta, + }; return $this; } + + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Meta' === $k) { + $n->setMeta($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->AuthMethod = $this->AuthMethod; + $out->RedirectURI = $this->RedirectURI; + $out->ClientNonce = $this->ClientNonce; + if (null !== $this->Meta && [] !== $this->Meta) { + $out->Meta = $this->Meta; + } + return $out; + } } diff --git a/src/ACL/ACLOIDCCallbackParams.php b/src/ACL/ACLOIDCCallbackParams.php index 1d7b196a..ea0995be 100644 --- a/src/ACL/ACLOIDCCallbackParams.php +++ b/src/ACL/ACLOIDCCallbackParams.php @@ -24,10 +24,26 @@ class ACLOIDCCallbackParams extends AbstractModel { - public string $AuthMethod = ''; - public string $State = ''; - public string $Code = ''; - public string $ClientNonce = ''; + public string $AuthMethod; + public string $State; + public string $Code; + public string $ClientNonce; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $AuthMethod = '', + string $State = '', + string $Code = '', + string $ClientNonce = '', + ) { + $this->AuthMethod = $AuthMethod; + $this->State = $State; + $this->Code = $Code; + $this->ClientNonce = $ClientNonce; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getAuthMethod(): string { @@ -72,4 +88,26 @@ public function setClientNonce(string $ClientNonce): self $this->ClientNonce = $ClientNonce; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->AuthMethod = $this->AuthMethod; + $out->State = $this->State; + $out->Code = $this->Code; + $out->ClientNonce = $this->ClientNonce; + return $out; + } } diff --git a/src/ACL/ACLPolicy.php b/src/ACL/ACLPolicy.php index 88dd5d56..f025ba4e 100644 --- a/src/ACL/ACLPolicy.php +++ b/src/ACL/ACLPolicy.php @@ -21,25 +21,49 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLPolicy extends AbstractModel { - protected const FIELDS = [ - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_NAMESPACE = 'Namespace'; - - public string $ID = ''; - public string $Name = ''; - public string $Description = ''; - public string $Rules = ''; - public array $Datacenters = []; - public string $Hash = ''; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $Namespace = ''; + public string $ID; + public string $Name; + public string $Description; + public string $Rules; + /** @var string[] */ + public array $Datacenters; + public string $Hash; + public int $CreateIndex; + public int $ModifyIndex; + public string $Namespace; + public string $Partition; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ID = '', + string $Name = '', + string $Description = '', + string $Rules = '', + iterable $Datacenters = [], + string $Hash = '', + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $Namespace = '', + string $Partition = '', + ) { + $this->ID = $ID; + $this->Name = $Name; + $this->Description = $Description; + $this->Rules = $Rules; + $this->setDatacenters(...$Datacenters); + $this->Datacenters = $Datacenters; + $this->Hash = $Hash; + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getID(): string { @@ -85,12 +109,15 @@ public function setRules(string $Rules): self return $this; } + /** + * @return string[] + */ public function getDatacenters(): array { return $this->Datacenters; } - public function setDatacenters(array $Datacenters): self + public function setDatacenters(string ...$Datacenters): self { $this->Datacenters = $Datacenters; return $this; @@ -139,4 +166,51 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Datacenters' === $k) { + $n->setDatacenters(...$v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ID = $this->ID; + $out->Name = $this->Name; + $out->Description = $this->Description; + $out->Rules = $this->Rules; + $out->Datacenters = $this->Datacenters; + $out->Hash = $this->Hash; + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } } diff --git a/src/ACL/ACLPolicyListEntry.php b/src/ACL/ACLPolicyListEntry.php index 6cb4e67e..ec329888 100644 --- a/src/ACL/ACLPolicyListEntry.php +++ b/src/ACL/ACLPolicyListEntry.php @@ -21,24 +21,44 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLPolicyListEntry extends AbstractModel { - protected const FIELDS = [ - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_NAMESPACE = 'Namespace'; - - public string $ID = ''; - public string $Name = ''; - public string $Description = ''; - public array $Datacenters = []; - public string $Hash = ''; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $Namespace = ''; + public string $ID; + public string $Name; + public string $Description; + public array $Datacenters; + public string $Hash; + public int $CreateIndex; + public int $ModifyIndex; + public string $Namespace; + public string $Partition; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ID = '', + string $Name = '', + string $Description = '', + iterable $Datacenters = [], + string $Hash = '', + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $Namespace = '', + string $Partition = '', + ) { + $this->ID = $ID; + $this->Name = $Name; + $this->Description = $Description; + $this->setDatacenters(...$Datacenters); + $this->Hash = $Hash; + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getID(): string { @@ -78,7 +98,7 @@ public function getDatacenters(): array return $this->Datacenters; } - public function setDatacenters(array $Datacenters): self + public function setDatacenters(string ...$Datacenters): self { $this->Datacenters = $Datacenters; return $this; @@ -127,4 +147,50 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Datacenters' === $k) { + $n->setDatacenters(...$v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ID = $this->ID; + $out->Name = $this->Name; + $out->Description = $this->Description; + $out->Datacenters = $this->Datacenters; + $out->Hash = $this->Hash; + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } } diff --git a/src/ACL/ACLPolicyListEntryQueryResponse.php b/src/ACL/ACLPolicyListEntryQueryResponse.php index 96f28700..0fd2ac10 100644 --- a/src/ACL/ACLPolicyListEntryQueryResponse.php +++ b/src/ACL/ACLPolicyListEntryQueryResponse.php @@ -25,18 +25,22 @@ class ACLPolicyListEntryQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $ACLPolicyListEntries = []; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLPolicyListEntry[] */ + public array $ACLPolicyListEntries = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLPolicyListEntry[] + */ + public function getValue(): array { return $this->ACLPolicyListEntries; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->ACLPolicyListEntries = []; - foreach ($decodedData as $datum) { - $this->ACLPolicyListEntries[] = new ACLPolicyListEntry($datum); + foreach ($decoded as $datum) { + $this->ACLPolicyListEntries[] = ACLPolicyListEntry::jsonUnserialize($datum); } } } diff --git a/src/ACL/ACLPolicyQueryResponse.php b/src/ACL/ACLPolicyQueryResponse.php index e8aeb668..50895ba5 100644 --- a/src/ACL/ACLPolicyQueryResponse.php +++ b/src/ACL/ACLPolicyQueryResponse.php @@ -25,15 +25,19 @@ class ACLPolicyQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?ACLPolicy $ACLPolicy = null; + public null|ACLPolicy $ACLPolicy = null; - public function getValue(): ?ACLPolicy + public function getValue(): null|ACLPolicy { return $this->ACLPolicy; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLPolicy = new ACLPolicy((array)$decodedData); + if (null === $decoded) { + $this->ACLPolicy = null; + return; + } + $this->ACLPolicy = ACLPolicy::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLPolicyWriteResponse.php b/src/ACL/ACLPolicyWriteResponse.php index 1e9439d5..a9b74b46 100644 --- a/src/ACL/ACLPolicyWriteResponse.php +++ b/src/ACL/ACLPolicyWriteResponse.php @@ -25,15 +25,19 @@ class ACLPolicyWriteResponse extends AbstractValuedWriteResponse implements UnmarshalledResponseInterface { - public ?ACLPolicy $ACLPolicy = null; + public null|ACLPolicy $ACLPolicy = null; - public function getValue(): ?ACLPolicy + public function getValue(): null|ACLPolicy { return $this->ACLPolicy; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLPolicy = new ACLPolicy((array)$decodedData); + if (null === $decoded) { + $this->ACLPolicy = null; + return; + } + $this->ACLPolicy = ACLPolicy::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLReplicationStatus.php b/src/ACL/ACLReplicationStatus.php index 479bc9c2..a147ce55 100644 --- a/src/ACL/ACLReplicationStatus.php +++ b/src/ACL/ACLReplicationStatus.php @@ -22,39 +22,39 @@ use DCarbone\Go\Time; use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLReplicationStatus extends AbstractModel { - protected const FIELDS = [ - self::FIELD_LAST_SUCCESS => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_TIME, - ], - self::FIELD_LAST_ERROR => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_TIME, - ], - ]; - - private const FIELD_LAST_SUCCESS = 'LastSuccess'; - private const FIELD_LAST_ERROR = 'LastError'; - - public bool $Enabled = false; - public bool $Running = false; - public string $SourceDatacenter = ''; - public int $ReplicatedIndex = 0; - public int $ReplicatedRoleIndex = 0; - public int $ReplicatedTokenIndex = 0; + public bool $Enabled; + public bool $Running; + public string $SourceDatacenter; + public int $ReplicatedIndex; + public int $ReplicatedRoleIndex; + public int $ReplicatedTokenIndex; public Time\Time $LastSuccess; public Time\Time $LastError; - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!isset($this->LastSuccess)) { - $this->LastSuccess = Time::New(); - } - if (!isset($this->LastError)) { - $this->LastError = Time::New(); + public function __construct( + null|array $data = null, // Deprecated, will be removed. + bool $Enabled = false, + bool $Running = false, + string $SourceDatacenter = '', + int $ReplicatedIndex = 0, + int $ReplicatedRoleIndex = 0, + int $ReplicatedTokenIndex = 0, + null|Time\Time $LastSuccess = null, + null|Time\Time $LastError = null, + ) { + $this->Enabled = $Enabled; + $this->Running = $Running; + $this->SourceDatacenter = $SourceDatacenter; + $this->ReplicatedIndex = $ReplicatedIndex; + $this->ReplicatedRoleIndex = $ReplicatedRoleIndex; + $this->ReplicatedTokenIndex = $ReplicatedTokenIndex; + $this->LastSuccess = $LastSuccess ?? Time::New(); + $this->LastError = $LastError ?? Time::New(); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -97,4 +97,36 @@ public function getLastError(): Time\Time { return $this->LastError; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('LastSuccess' === $k) { + $n->LastSuccess = Time\Time::createFromFormat(DATE_RFC3339, $v); + } elseif ('LastError' === $k) { + $n->LastError = Time\Time::createFromFormat(DATE_RFC3339, $v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Enabled = $this->Enabled; + $out->Running = $this->Running; + $out->SourceDatacenter = $this->SourceDatacenter; + $out->ReplicatedIndex = $this->ReplicatedIndex; + $out->ReplicatedRoleIndex = $this->ReplicatedRoleIndex; + $out->ReplicatedTokenIndex = $this->ReplicatedTokenIndex; + $out->LastSuccess = $this->LastSuccess->format(DATE_RFC3339); + $out->LastError = $this->LastError->format(DATE_RFC3339); + return $out; + } } diff --git a/src/ACL/ACLReplicationStatusResponse.php b/src/ACL/ACLReplicationStatusResponse.php index df71f30f..51438d44 100644 --- a/src/ACL/ACLReplicationStatusResponse.php +++ b/src/ACL/ACLReplicationStatusResponse.php @@ -25,15 +25,19 @@ class ACLReplicationStatusResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?ACLReplicationStatus $ACLReplicationStatus = null; + public null|ACLReplicationStatus $ACLReplicationStatus = null; - public function getValue(): ?ACLReplicationStatus + public function getValue(): null|ACLReplicationStatus { return $this->ACLReplicationStatus; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLReplicationStatus = new ACLReplicationStatus((array)$decodedData); + if (null === $decoded) { + $this->ACLReplicationStatus = null; + return; + } + $this->ACLReplicationStatus = ACLReplicationStatus::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLRole.php b/src/ACL/ACLRole.php index 1913ea18..d88c50e9 100644 --- a/src/ACL/ACLRole.php +++ b/src/ACL/ACLRole.php @@ -21,47 +21,57 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLRole extends AbstractModel { - protected const FIELDS = [ - self::FIELD_POLICIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLTokenPolicyLink::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_SERVICE_IDENTITIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLServiceIdentity::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_NODE_IDENTITIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLNodeIdentity::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_POLICIES = 'Policies'; - private const FIELD_SERVICE_IDENTITIES = 'ServiceIdentities'; - private const FIELD_NODE_IDENTITIES = 'NodeIdentities'; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $ID = ''; - public string $Name = ''; - public string $Description = ''; - public array $Policies = []; - public array $ServiceIdentities = []; - public array $NodeIdentities = []; - public string $Hash = ''; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $Namespace = ''; + public string $ID; + public string $Name; + public string $Description; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLRolePolicyLink[] */ + public array $Policies; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLServiceIdentity[] */ + public array $ServiceIdentities; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLNodeIdentity[] */ + public array $NodeIdentities; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLTemplatedPolicy[] */ + public array $TemplatedPolicies; + public string $Hash; + public int $CreateIndex; + public int $ModifyIndex; + public string $Namespace; + public string $Partition; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ID = '', + string $Name = '', + string $Description = '', + iterable $Policies = [], + iterable $ServiceIdentities = [], + iterable $NodeIdentities = [], + iterable $TemplatedPolicies = [], + string $Hash = '', + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $Namespace = '', + string $Partition = '', + ) { + $this->ID = $ID; + $this->Name = $Name; + $this->Description = $Description; + $this->setPolicies(...$Policies); + $this->setServiceIdentities(...$ServiceIdentities); + $this->setNodeIdentities(...$NodeIdentities); + $this->setTemplatedPolicies(...$TemplatedPolicies); + $this->Hash = $Hash; + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getID(): string { @@ -96,39 +106,62 @@ public function setDescription(string $Description): self return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLRolePolicyLink[] + */ public function getPolicies(): array { return $this->Policies; } - public function setPolicies(array $Policies): self + public function setPolicies(ACLRolePolicyLink ...$Policies): self { $this->Policies = $Policies; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLServiceIdentity[] + */ public function getServiceIdentities(): array { return $this->ServiceIdentities; } - public function setServiceIdentities(array $ServiceIdentities): self + public function setServiceIdentities(ACLServiceIdentity ...$ServiceIdentities): self { $this->ServiceIdentities = $ServiceIdentities; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLNodeIdentity[] + */ public function getNodeIdentities(): array { return $this->NodeIdentities; } - public function setNodeIdentities(array $NodeIdentities): self + public function setNodeIdentities(ACLNodeIdentity ...$NodeIdentities): self { $this->NodeIdentities = $NodeIdentities; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLTemplatedPolicy[] + */ + public function getTemplatedPolicies(): array + { + return $this->TemplatedPolicies; + } + + public function setTemplatedPolicies(ACLTemplatedPolicy ...$TemplatedPolicies): self + { + $this->TemplatedPolicies = $TemplatedPolicies; + return $this; + } + public function getHash(): string { return $this->Hash; @@ -172,4 +205,75 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Policies' === $k) { + foreach ($v as $vv) { + $n->Policies[] = ACLTokenPolicyLink::jsonUnserialize($vv); + } + } elseif ('ServiceIdentities' === $k) { + foreach ($v as $vv) { + $n->ServiceIdentities[] = ACLServiceIdentity::jsonUnserialize($vv); + } + } elseif ('NodeIdentities' === $k) { + foreach ($v as $vv) { + $n->NodeIdentities[] = ACLNodeIdentity::jsonUnserialize($vv); + } + } elseif ('TemplatedPolicies' === $k) { + foreach ($v as $vv) { + $n->TemplatedPolicies[] = ACLTemplatedPolicy::jsonUnserialize($vv); + } + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ID = $this->ID; + $out->Name = $this->Name; + $out->Description = $this->Description; + $out->Hash = $this->Hash; + if ([] !== $this->Policies) { + $out->Policies = $this->Policies; + } + if ([] !== $this->ServiceIdentities) { + $out->ServiceIdentities = $this->ServiceIdentities; + } + if ([] !== $this->NodeIdentities) { + $out->NodeIdentities = $this->NodeIdentities; + } + if ([] !== $this->TemplatedPolicies) { + $out->TemplatedPolicies = $this->TemplatedPolicies; + } + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } } diff --git a/src/ACL/ACLRoleQueryResponse.php b/src/ACL/ACLRoleQueryResponse.php index 4ffbe236..9106283e 100644 --- a/src/ACL/ACLRoleQueryResponse.php +++ b/src/ACL/ACLRoleQueryResponse.php @@ -25,15 +25,19 @@ class ACLRoleQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?ACLRole $ACLRole = null; + public null|ACLRole $ACLRole = null; - public function getValue(): ?ACLRole + public function getValue(): null|ACLRole { return $this->ACLRole; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLRole = new ACLRole((array)$decodedData); + if (null === $decoded) { + $this->ACLRole = null; + return; + } + $this->ACLRole = ACLRole::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLRoleWriteResponse.php b/src/ACL/ACLRoleWriteResponse.php index cb94ff4e..0827b545 100644 --- a/src/ACL/ACLRoleWriteResponse.php +++ b/src/ACL/ACLRoleWriteResponse.php @@ -25,15 +25,19 @@ class ACLRoleWriteResponse extends AbstractValuedWriteResponse implements UnmarshalledResponseInterface { - public ?ACLRole $ACLRole = null; + public null|ACLRole $ACLRole = null; - public function getValue(): ?ACLRole + public function getValue(): null|ACLRole { return $this->ACLRole; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLRole = new ACLRole((array)$decodedData); + if (null === $decoded) { + $this->ACLRole = null; + return; + } + $this->ACLRole = ACLRole::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLRolesQueryResponse.php b/src/ACL/ACLRolesQueryResponse.php index 37d58657..d07d6036 100644 --- a/src/ACL/ACLRolesQueryResponse.php +++ b/src/ACL/ACLRolesQueryResponse.php @@ -25,18 +25,22 @@ class ACLRolesQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $ACLRoles = []; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLRole[] */ + public array $ACLRoles = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLRole[] + */ + public function getValue(): array { return $this->ACLRoles; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->ACLRoles = []; - foreach ($decodedData as $datum) { - $this->ACLRoles[] = new ACLRole($datum); + foreach ($decoded as $datum) { + $this->ACLRoles[] = ACLRole::jsonUnserialize($datum); } } } diff --git a/src/ACL/ACLServiceIdentity.php b/src/ACL/ACLServiceIdentity.php index 99d7d938..f93681d0 100644 --- a/src/ACL/ACLServiceIdentity.php +++ b/src/ACL/ACLServiceIdentity.php @@ -21,30 +21,67 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLServiceIdentity extends AbstractModel { - protected const FIELDS = [ - self::FIELD_DATACENTERS => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::STRING, - Transcoding::FIELD_OMITEMPTY => true, - ], - ]; + public string $ServiceName; + /** @var string[] */ + public array $Datacenters; - private const FIELD_DATACENTERS = 'Datacenters'; - - public string $ServiceName = ''; - public array $Datacenters = []; + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ServiceName = '', + iterable $Datacenters = [] + ) { + $this->ServiceName = $ServiceName; + $this->setDatacenters(...$Datacenters); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getServiceName(): string { return $this->ServiceName; } + /** + * @return string[] + */ public function getDatacenters(): array { return $this->Datacenters; } + + public function setDatacenters(string ...$datacenters): self + { + $this->Datacenters = $datacenters; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Datacenters' === $k) { + $n->setDatacenters(...$v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ServiceName = $this->ServiceName; + if ([] !== $this->Datacenters) { + $out->Datacenters = $this->Datacenters; + } + return $out; + } } diff --git a/src/ACL/ACLTemplatedPolicy.php b/src/ACL/ACLTemplatedPolicy.php new file mode 100644 index 00000000..6db39783 --- /dev/null +++ b/src/ACL/ACLTemplatedPolicy.php @@ -0,0 +1,108 @@ +TemplateName = $TemplateName; + $this->TemplateVariables = $TemplateVariables; + $this->setDatacenters(...$Datacenters); + } + + public function getTemplateName(): string + { + return $this->TemplateName; + } + + public function setTemplateName(string $TemplateName): self + { + $this->TemplateName = $TemplateName; + return $this; + } + + public function getTemplateVariables(): null|ACLTemplatedPolicyVariables + { + return $this->TemplateVariables; + } + + public function setTemplateVariables(null|ACLTemplatedPolicyVariables $TemplateVariables): ACLTemplatedPolicy + { + $this->TemplateVariables = $TemplateVariables; + return $this; + } + + /** + * @return string[] + */ + public function getDatacenters(): array + { + return $this->Datacenters; + } + + public function setDatacenters(string ...$Datacenters): ACLTemplatedPolicy + { + $this->Datacenters = $Datacenters; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('TemplateVariables' === $k) { + $n->setTemplateVariables($v); + } elseif ('Datacenters' === $k) { + $n->setDatacenters(...$v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->TemplateName = $this->TemplateName; + if (null !== $this->TemplateVariables) { + $out->TemplateVariables = $this->TemplateVariables; + } + if ([] !== $this->Datacenters) { + $out->Datacenters = $this->Datacenters; + } + return $out; + } +} diff --git a/src/ACL/ACLTemplatedPolicyVariables.php b/src/ACL/ACLTemplatedPolicyVariables.php new file mode 100644 index 00000000..c36c7cf2 --- /dev/null +++ b/src/ACL/ACLTemplatedPolicyVariables.php @@ -0,0 +1,63 @@ +Name = $Name; + } + + public function getName(): string + { + return $this->Name; + } + + public function setName(string $Name): self + { + $this->Name = $Name; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + return $out; + } +} \ No newline at end of file diff --git a/src/ACL/ACLToken.php b/src/ACL/ACLToken.php index d417a98d..a09aebe4 100644 --- a/src/ACL/ACLToken.php +++ b/src/ACL/ACLToken.php @@ -22,278 +22,77 @@ use DCarbone\Go\Time; use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLToken extends AbstractModel { - protected const FIELDS = [ - self::FIELD_POLICIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLTokenPolicyLink::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_ROLES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLTokenRoleLink::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_SERVICE_IDENTITIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLServiceIdentity::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_NODE_IDENTITIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLNodeIdentity::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_AUTH_METHOD => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_EXPIRATION_TTL => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_DURATION, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_EXPIRATION_TIME => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_NULLABLE_TIME, - Transcoding::FIELD_NULLABLE => true, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_CREATE_TIME => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_TIME, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_RULES => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_POLICIES = 'Policies'; - private const FIELD_ROLES = 'Roles'; - private const FIELD_SERVICE_IDENTITIES = 'ServiceIdentities'; - private const FIELD_NODE_IDENTITIES = 'NodeIdentities'; - private const FIELD_AUTH_METHOD = 'AuthMethod'; - private const FIELD_EXPIRATION_TTL = 'ExpirationTTL'; - private const FIELD_EXPIRATION_TIME = 'ExpirationTime'; - private const FIELD_CREATE_TIME = 'CreateTime'; - private const FIELD_RULES = 'Rules'; - private const FIELD_NAMESPACE = 'Namespace'; - - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $AccessorID = ''; - public string $SecretID = ''; - public string $Description = ''; - public array $Policies = []; - public array $Roles = []; - public array $ServiceIdentities = []; - public array $NodeIdentities = []; - public bool $Local = false; - public string $AuthMethod = ''; - public Time\Duration $ExpirationTTL; - public ?Time\Time $ExpirationTime = null; - public Time\Time $CreateTime; - public string $Hash = ''; - public string $Namespace = ''; - - public string $Rules = ''; - - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!isset($this->ExpirationTTL)) { - $this->ExpirationTTL = new Time\Duration(); - } - if (!isset($this->CreateTime)) { - $this->CreateTime = Time::New(); - } - } - - public function getCreateIndex(): int - { - return $this->CreateIndex; - } - - public function setCreateIndex(int $CreateIndex): self - { + use ACLTokenFields; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $AccessorID = '', + string $SecretID = '', + string $Description = '', + iterable $Policies = [], + iterable $Roles = [], + iterable $ServiceIdentities = [], + iterable $NodeIdentities = [], + iterable $TemplatePolicies = [], + bool $Local = false, + string $AuthMethod = '', + null|int|float|string|\DateInterval|Time\Duration $ExpirationTTL = null, + null|Time\Time $ExpirationTime = null, + null|Time\Time $CreateTime = null, + string $Hash = '', + string $Namespace = '', + string $Rules = '', + string $Partition = '', + string $AuthMethodNamespace = '', + ) { $this->CreateIndex = $CreateIndex; - return $this; - } - - public function getModifyIndex(): int - { - return $this->ModifyIndex; - } - - public function setModifyIndex(int $ModifyIndex): self - { $this->ModifyIndex = $ModifyIndex; - return $this; - } - - public function getAccessorID(): string - { - return $this->AccessorID; - } - - public function setAccessorID(string $AccessorID): self - { $this->AccessorID = $AccessorID; - return $this; - } - - public function getSecretID(): string - { - return $this->SecretID; - } - - public function setSecretID(string $SecretID): self - { $this->SecretID = $SecretID; - return $this; - } - - public function getDescription(): string - { - return $this->Description; - } - - public function setDescription(string $Description): self - { $this->Description = $Description; - return $this; - } - - public function getPolicies(): array - { - return $this->Policies; - } - - public function setPolicies(array $Policies): self - { - $this->Policies = $Policies; - return $this; - } - - public function getRoles(): array - { - return $this->Roles; - } - - public function setRoles(array $Roles): self - { - $this->Roles = $Roles; - return $this; - } - - public function getServiceIdentities(): array - { - return $this->ServiceIdentities; - } - - public function setServiceIdentities(array $ServiceIdentities): self - { - $this->ServiceIdentities = $ServiceIdentities; - return $this; - } - - public function getNodeIdentities(): array - { - return $this->NodeIdentities; - } - - public function setNodeIdentities(array $NodeIdentities): self - { - $this->NodeIdentities = $NodeIdentities; - return $this; - } - - public function isLocal(): bool - { - return $this->Local; - } - - public function setLocal(bool $Local): self - { + $this->setPolicies(...$Policies); + $this->setRoles(...$Roles); + $this->setServiceIdentities(...$ServiceIdentities); + $this->setNodeIdentities(...$NodeIdentities); + $this->setTemplatePolicies(...$TemplatePolicies); $this->Local = $Local; - return $this; - } - - public function getAuthMethod(): string - { - return $this->AuthMethod; - } - - public function setAuthMethod(string $AuthMethod): self - { $this->AuthMethod = $AuthMethod; - return $this; - } - - public function getExpirationTTL(): Time\Duration - { - return $this->ExpirationTTL; - } - - public function setExpirationTTL(Time\Duration $ExpirationTTL): self - { - $this->ExpirationTTL = $ExpirationTTL; - return $this; - } - - public function getExpirationTime(): ?Time\Time - { - return $this->ExpirationTime; - } - - public function setExpirationTime(?Time\Time $ExpirationTime): self - { - $this->ExpirationTime = $ExpirationTime; - return $this; - } - - public function getCreateTime(): Time\Time - { - return $this->CreateTime; - } - - public function setCreateTime(Time\Time $CreateTime): self - { - $this->CreateTime = $CreateTime; - return $this; - } - - public function getHash(): string - { - return $this->Hash; - } - - public function setHash(string $Hash): self - { + $this->setExpirationTTL($ExpirationTTL); + $this->setExpirationTime($ExpirationTime); + $this->CreateTime = $CreateTime ?? Time::New(); $this->Hash = $Hash; - return $this; - } - - public function getNamespace(): string - { - return $this->Namespace; - } - - public function setNamespace(string $Namespace): self - { $this->Namespace = $Namespace; - return $this; + $this->Rules = $Rules; + $this->Partition = $Partition; + $this->AuthMethodNamespace = $AuthMethodNamespace; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } } - public function getRules(): string + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static { - return $this->Rules; + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if (!$n->_jsonUnserializeField($k, $v, $n)) { + $n->{$k} = $v; + } + } + return $n; } - public function setRules(string $Rules): self + public function jsonSerialize(): \stdClass { - $this->Rules = $Rules; - return $this; + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $this->_jsonSerialize($out); + return $out; } } diff --git a/src/ACL/ACLTokenExpanded.php b/src/ACL/ACLTokenExpanded.php new file mode 100644 index 00000000..4713b067 --- /dev/null +++ b/src/ACL/ACLTokenExpanded.php @@ -0,0 +1,221 @@ +setExpandedPolicies(...$ExpandedPolicies); + $this->setExpandedRoles(...$ExpandedRoles); + $this->setNamespaceDefaultPolicyIDs(...$NamespaceDefaultPolicyIDs); + $this->setNamespaceDefaultRoleIDs(...$NamespaceDefaultRoleIDs); + $this->AgentACLDefaultPolicy = $AgentACLDefaultPolicy; + $this->AgentACLDownPolicy = $AgentACLDownPolicy; + $this->ResolvedByAgent = $ResolvedByAgent; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } + + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLPolicy[] + */ + public function getExpandedPolicies(): array + { + return $this->ExpandedPolicies; + } + + public function setExpandedPolicies(ACLPolicy ...$ExpandedPolicies): self + { + $this->ExpandedPolicies = $ExpandedPolicies; + return $this; + } + + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLRole[] + */ + public function getExpandedRoles(): array + { + return $this->ExpandedRoles; + } + + public function setExpandedRoles(ACLRole ...$ExpandedRoles): self + { + $this->ExpandedRoles = $ExpandedRoles; + return $this; + } + + /** + * @return string[] + */ + public function getNamespaceDefaultPolicyIDs(): array + { + return $this->NamespaceDefaultPolicyIDs; + } + + public function setNamespaceDefaultPolicyIDs(string ...$NamespaceDefaultPolicyIDs): self + { + $this->NamespaceDefaultPolicyIDs = $NamespaceDefaultPolicyIDs; + return $this; + } + + /** + * @return string[] + */ + public function getNamespaceDefaultRoleIDs(): array + { + return $this->NamespaceDefaultRoleIDs; + } + + public function setNamespaceDefaultRoleIDs(string ...$NamespaceDefaultRoleIDs): self + { + $this->NamespaceDefaultRoleIDs = $NamespaceDefaultRoleIDs; + return $this; + } + + public function getAgentACLDefaultPolicy(): string + { + return $this->AgentACLDefaultPolicy; + } + + public function setAgentACLDefaultPolicy(string $AgentACLDefaultPolicy): self + { + $this->AgentACLDefaultPolicy = $AgentACLDefaultPolicy; + return $this; + } + + public function getAgentACLDownPolicy(): string + { + return $this->AgentACLDownPolicy; + } + + public function setAgentACLDownPolicy(string $AgentACLDownPolicy): self + { + $this->AgentACLDownPolicy = $AgentACLDownPolicy; + return $this; + } + + public function getResolvedByAgent(): string + { + return $this->ResolvedByAgent; + } + + public function setResolvedByAgent(string $ResolvedByAgent): self + { + $this->ResolvedByAgent = $ResolvedByAgent; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|ACLToken $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ($n->_jsonUnserializeField($k, $v, $n)) { + continue; + } elseif ('ExpandedPolicies' === $k) { + foreach ($v as $vv) { + $n->ExpandedPolicies[] = ACLPolicy::jsonUnserialize($vv); + } + } elseif ('ExpandedRoles' === $k) { + foreach ($v as $vv) { + $n->ExpandedRoles[] = ACLRole::jsonUnserialize($vv); + } + } elseif ('NamespaceDefaultPolicyIDs' === $k) { + $n->setNamespaceDefaultPolicyIDs(...$v); + } elseif ('NamespaceDefaultRoleIDs' === $k) { + $n->setNamespaceDefaultRoleIDs(...$v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + return parent::jsonSerialize(); // TODO: Change the autogenerated stub + } +} diff --git a/src/ACL/ACLTokenExpandedQueryResponse.php b/src/ACL/ACLTokenExpandedQueryResponse.php new file mode 100644 index 00000000..09e6c9f6 --- /dev/null +++ b/src/ACL/ACLTokenExpandedQueryResponse.php @@ -0,0 +1,43 @@ +ACLTokenExpanded; + } + + public function unmarshalValue(mixed $decoded): void + { + if (null === $decoded) { + $this->ACLTokenExpanded = null; + return; + } + $this->ACLTokenExpanded = ACLTokenExpanded::jsonUnserialize($decoded); + } +} diff --git a/src/ACL/ACLTokenFields.php b/src/ACL/ACLTokenFields.php new file mode 100644 index 00000000..f37248d8 --- /dev/null +++ b/src/ACL/ACLTokenFields.php @@ -0,0 +1,373 @@ +CreateIndex; + } + + public function setCreateIndex(int $CreateIndex): self + { + $this->CreateIndex = $CreateIndex; + return $this; + } + + public function getModifyIndex(): int + { + return $this->ModifyIndex; + } + + public function setModifyIndex(int $ModifyIndex): self + { + $this->ModifyIndex = $ModifyIndex; + return $this; + } + + public function getAccessorID(): string + { + return $this->AccessorID; + } + + public function setAccessorID(string $AccessorID): self + { + $this->AccessorID = $AccessorID; + return $this; + } + + public function getSecretID(): string + { + return $this->SecretID; + } + + public function setSecretID(string $SecretID): self + { + $this->SecretID = $SecretID; + return $this; + } + + public function getDescription(): string + { + return $this->Description; + } + + public function setDescription(string $Description): self + { + $this->Description = $Description; + return $this; + } + + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLTokenPolicyLink[] + */ + public function getPolicies(): array + { + return $this->Policies; + } + + public function setPolicies(ACLTokenPolicyLink ...$Policies): self + { + $this->Policies = $Policies; + return $this; + } + + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLTokenRoleLink[] + */ + public function getRoles(): array + { + return $this->Roles; + } + + public function setRoles(ACLTokenRoleLink ...$Roles): self + { + $this->Roles = $Roles; + return $this; + } + + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLServiceIdentity[] + */ + public function getServiceIdentities(): array + { + return $this->ServiceIdentities; + } + + public function setServiceIdentities(ACLServiceIdentity ...$ServiceIdentities): self + { + $this->ServiceIdentities = $ServiceIdentities; + return $this; + } + + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLNodeIdentity[] + */ + public function getNodeIdentities(): array + { + return $this->NodeIdentities; + } + + public function setNodeIdentities(ACLNodeIdentity ...$NodeIdentities): self + { + $this->NodeIdentities = $NodeIdentities; + return $this; + } + + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLTemplatedPolicy[] + */ + public function getTemplatePolicies(): array + { + return $this->TemplatePolicies; + } + + public function setTemplatePolicies(ACLTemplatedPolicy ...$TemplatePolicies): self + { + $this->TemplatePolicies = $TemplatePolicies; + return $this; + } + + public function isLocal(): bool + { + return $this->Local; + } + + public function setLocal(bool $Local): self + { + $this->Local = $Local; + return $this; + } + + public function getAuthMethod(): string + { + return $this->AuthMethod; + } + + public function setAuthMethod(string $AuthMethod): self + { + $this->AuthMethod = $AuthMethod; + return $this; + } + + public function getExpirationTTL(): Time\Duration + { + return $this->ExpirationTTL; + } + + public function setExpirationTTL(null|int|float|string|\DateInterval|Time\Duration $ExpirationTTL): self + { + $this->ExpirationTTL = Time::Duration($ExpirationTTL); + return $this; + } + + public function getExpirationTime(): Time\Time + { + return $this->ExpirationTime; + } + + public function setExpirationTime(null|Time\Time $ExpirationTime): self + { + $this->ExpirationTime = $ExpirationTime; + return $this; + } + + public function getCreateTime(): Time\Time + { + return $this->CreateTime; + } + + public function setCreateTime(Time\Time $CreateTime): self + { + $this->CreateTime = $CreateTime; + return $this; + } + + public function getHash(): string + { + return $this->Hash; + } + + public function setHash(string $Hash): self + { + $this->Hash = $Hash; + return $this; + } + + public function getNamespace(): string + { + return $this->Namespace; + } + + public function setNamespace(string $Namespace): self + { + $this->Namespace = $Namespace; + return $this; + } + + public function getRules(): string + { + return $this->Rules; + } + + public function setRules(string $Rules): self + { + $this->Rules = $Rules; + return $this; + } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public function getAuthMethodNamespace(): string + { + return $this->AuthMethodNamespace; + } + + public function setAuthMethodNamespace(string $AuthMethodNamespace): self + { + $this->AuthMethodNamespace = $AuthMethodNamespace; + return $this; + } + + public function _jsonUnserializeField(string $k, mixed $v, object $n): bool + { + if ('Policies' === $k) { + foreach ($v as $vv) { + $n->Policies[] = ACLTokenPolicyLink::jsonUnserialize($vv); + } + } elseif ('Roles' === $k) { + foreach ($v as $vv) { + $n->Roles[] = ACLTokenRoleLink::jsonUnserialize($vv); + } + } elseif ('ServiceIdentities' === $k) { + foreach ($v as $vv) { + $n->ServiceIdentities[] = ACLServiceIdentity::jsonUnserialize($vv); + } + } elseif ('NodeIdentities' === $k) { + foreach ($v as $vv) { + $n->NodeIdentities[] = ACLNodeIdentity::jsonUnserialize($vv); + } + } elseif ('TemplatePolicies' === $k) { + foreach ($v as $vv) { + $n->TemplatePolicies[] = ACLTemplatedPolicy::jsonUnserialize($vv); + } + } elseif ('ExpirationTTL' === $k) { + $n->setExpirationTTL($v); + } elseif ('ExpirationTime' === $k) { + $n->ExpirationTime = (null === $v ? $v : Time\Time::createFromFormat(DATE_RFC3339, $v)); + } elseif ('CreateTime' === $k) { + $n->CreateTime = Time\Time::createFromFormat(DATE_RFC3339, $v); + } else { + return false; + } + + return true; + } + + protected function _jsonSerialize(\stdClass $out): void + { + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + $out->AccessorID = $this->AccessorID; + $out->SecretID = $this->SecretID; + $out->Description = $this->Description; + if ([] !== $this->Policies) { + $out->Policies = $this->Policies; + } + if ([] !== $this->Roles) { + $out->Roles = $this->Roles; + } + if ([] !== $this->ServiceIdentities) { + $out->ServiceIdentities = $this->ServiceIdentities; + } + if ([] !== $this->NodeIdentities) { + $out->NodeIdentities = $this->NodeIdentities; + } + if ([] !== $this->TemplatePolicies) { + $out->TemplatePolicies = $this->TemplatePolicies; + } + $out->Local = $this->Local; + if ('' !== $this->AuthMethod) { + $out->AuthMethod = $this->AuthMethod; + } + if (0 !== $this->ExpirationTTL->Nanoseconds()) { + $out->ExpirationTTL = $this->ExpirationTTL; + } + if (null !== $this->ExpirationTime) { + $out->ExpirationTime = $this->ExpirationTime->format(DATE_RFC3339); + } + if (!$this->CreateTime->isZero()) { + $out->CreateTime = $this->CreateTime->format(DATE_RFC3339); + } + $out->Hash = $this->Hash; + if ('' !== $this->Rules) { + $out->Rules = $this->Rules; + } + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + if ('' !== $this->AuthMethodNamespace) { + $out->AuthMethodNamespace = $this->AuthMethodNamespace; + } + } +} diff --git a/src/ACL/ACLTokenListEntry.php b/src/ACL/ACLTokenListEntry.php index eff21026..f1a707df 100644 --- a/src/ACL/ACLTokenListEntry.php +++ b/src/ACL/ACLTokenListEntry.php @@ -22,77 +22,77 @@ use DCarbone\Go\Time; use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ACLTokenListEntry extends AbstractModel { - protected const FIELDS = [ - self::FIELD_POLICIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLTokenPolicyLink::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_ROLES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLTokenRoleLink::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_SERVICE_IDENTITIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLServiceIdentity::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_NODE_IDENTITIES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ACLNodeIdentity::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_AUTH_METHOD => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_EXPIRATION_TIME => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_NULLABLE_TIME, - Transcoding::FIELD_NULLABLE => true, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_CREATE_TIME => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_TIME, - ], - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_POLICIES = 'Policies'; - private const FIELD_ROLES = 'Roles'; - private const FIELD_SERVICE_IDENTITIES = 'ServiceIdentities'; - private const FIELD_NODE_IDENTITIES = 'NodeIdentities'; - private const FIELD_AUTH_METHOD = 'AuthMethod'; - private const FIELD_EXPIRATION_TIME = 'ExpirationTime'; - private const FIELD_CREATE_TIME = 'CreateTime'; - private const FIELD_NAMESPACE = 'Namespace'; - - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $AccessorID = ''; - public string $Description = ''; - public array $Policies = []; - public array $Roles = []; - public array $ServiceIdentities = []; - public array $NodeIdentities = []; - public bool $Local = false; - public string $AuthMethod = ''; - public ?Time\Time $ExpirationTime = null; + public int $CreateIndex; + public int $ModifyIndex; + public string $AccessorID; + public string $SecretID; + public string $Description; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLTokenPolicyLink[] */ + public array $Policies; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLRolePolicyLink[] */ + public array $Roles; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLServiceIdentity[] */ + public array $ServiceIdentities; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLNodeIdentity[] */ + public array $NodeIdentities; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLTemplatedPolicy[] */ + public array $TemplatedPolicies; + public bool $Local; + public string $AuthMethod; + public null|Time\Time $ExpirationTime = null; public Time\Time $CreateTime; - public string $Hash = ''; - public bool $Legacy = false; - public string $Namespace = ''; - - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!isset($this->CreateTime)) { - $this->CreateTime = Time::New(); + public string $Hash; + public bool $Legacy; + public string $Namespace; + public string $Partition; + public string $AuthMethodNamespace; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $AccessorID = '', + string $SecretID = '', + string $Description = '', + iterable $Policies = [], + iterable $Roles = [], + iterable $ServiceIdentities = [], + iterable $NodeIdentities = [], + iterable $TemplatedPolicies = [], + bool $Local = false, + string $AuthMethod = '', + null|Time\Time $ExpirationTime = null, + null|Time\Time $CreateTime = null, + string $Hash = '', + bool $Legacy = false, + string $Namespace = '', + string $Partition = '', + string $AuthMethodNamespace = '', + ) { + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->AccessorID = $AccessorID; + $this->SecretID = $SecretID; + $this->Description = $Description; + $this->setPolicies(...$Policies); + $this->setRoles(...$Roles); + $this->setServiceIdentities(...$ServiceIdentities); + $this->setNodeIdentities(...$NodeIdentities); + $this->setTemplatedPolicies(...$TemplatedPolicies); + $this->Local = $Local; + $this->AuthMethod = $AuthMethod; + $this->setExpirationTime($ExpirationTime); + $this->CreateTime = $CreateTime ?? Time::New(); + $this->Hash = $Hash; + $this->Legacy = $Legacy; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + $this->AuthMethodNamespace = $AuthMethodNamespace; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -129,6 +129,17 @@ public function setAccessorID(string $AccessorID): self return $this; } + public function getSecretID(): string + { + return $this->SecretID; + } + + public function setSecretID(string $SecretID): self + { + $this->SecretID = $SecretID; + return $this; + } + public function getDescription(): string { return $this->Description; @@ -140,50 +151,76 @@ public function setDescription(string $Description): self return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLTokenPolicyLink[] + */ public function getPolicies(): array { return $this->Policies; } - public function setPolicies(array $Policies): self + public function setPolicies(ACLTokenPolicyLink ...$Policies): self { $this->Policies = $Policies; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLRolePolicyLink[] + */ public function getRoles(): array { return $this->Roles; } - public function setRoles(array $Roles): self + public function setRoles(ACLTokenRoleLink ...$Roles): self { $this->Roles = $Roles; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLServiceIdentity[] + */ public function getServiceIdentities(): array { return $this->ServiceIdentities; } - public function setServiceIdentities(array $ServiceIdentities): self + public function setServiceIdentities(ACLServiceIdentity ...$ServiceIdentities): self { $this->ServiceIdentities = $ServiceIdentities; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLNodeIdentity[] + */ public function getNodeIdentities(): array { return $this->NodeIdentities; } - public function setNodeIdentities(array $NodeIdentities): self + public function setNodeIdentities(ACLNodeIdentity ...$NodeIdentities): self { $this->NodeIdentities = $NodeIdentities; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLTemplatedPolicy[] + */ + public function getTemplatedPolicies(): array + { + return $this->TemplatedPolicies; + } + + public function setTemplatedPolicies(ACLTemplatedPolicy ...$TemplatedPolicies): self + { + $this->TemplatedPolicies = $TemplatedPolicies; + return $this; + } + public function isLocal(): bool { return $this->Local; @@ -206,12 +243,12 @@ public function setAuthMethod(string $AuthMethod): self return $this; } - public function getExpirationTime(): ?Time\Time + public function getExpirationTime(): null|Time\Time { return $this->ExpirationTime; } - public function setExpirationTime(?Time\Time $ExpirationTime): self + public function setExpirationTime(null|Time\Time $ExpirationTime): self { $this->ExpirationTime = $ExpirationTime; return $this; @@ -260,4 +297,108 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public function getAuthMethodNamespace(): string + { + return $this->AuthMethodNamespace; + } + + public function setAuthMethodNamespace(string $AuthMethodNamespace): self + { + $this->AuthMethodNamespace = $AuthMethodNamespace; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Policies' === $k) { + foreach ($v as $vv) { + $n->Policies[] = ACLTokenPolicyLink::jsonUnserialize($vv); + } + } elseif ('Roles' === $k) { + foreach ($v as $vv) { + $n->Roles[] = ACLTokenRoleLink::jsonUnserialize($vv); + } + } elseif ('ServiceIdentities' === $k) { + foreach ($v as $vv) { + $n->ServiceIdentities[] = ACLServiceIdentity::jsonUnserialize($vv); + } + } elseif ('NodeIdentities' === $k) { + foreach ($v as $vv) { + $n->NodeIdentities[] = ACLNodeIdentity::jsonUnserialize($vv); + } + } elseif ('TemplatedPolicies' === $k) { + foreach ($v as $vv) { + $n->TemplatedPolicies[] = ACLTemplatedPolicy::jsonUnserialize($vv); + } + } elseif ('ExpirationTime' === $k) { + $n->ExpirationTime = (null === $v ? null : Time\Time::createFromFormat(DATE_RFC3339, $v)); + } elseif ('CreateTime' === $k) { + $n->CreateTime = Time\Time::createFromFormat(DATE_RFC3339, $v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + $out->AccessorID = $this->AccessorID; + $out->SecretID = $this->SecretID; + $out->Description = $this->Description; + if ([] !== $this->Policies) { + $out->Policies = $this->Policies; + } + if ([] !== $this->Roles) { + $out->Roles = $this->Roles; + } + if ([] !== $this->ServiceIdentities) { + $out->ServiceIdentities = $this->ServiceIdentities; + } + if ([] !== $this->NodeIdentities) { + $out->NodeIdentities = $this->NodeIdentities; + } + if ([] !== $this->TemplatedPolicies) { + $out->TemplatedPolicies = $this->TemplatedPolicies; + } + $out->Local = $this->Local; + if ('' !== $this->AuthMethod) { + $out->AuthMethod = $this->AuthMethod; + } + if (null !== $this->ExpirationTime) { + $out->ExpirationTime = $this->ExpirationTime->format(DATE_RFC3339); + } + $out->CreateTime = $this->CreateTime->format(DATE_RFC3339); + $out->Hash = $this->Hash; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + if ('' !== $this->AuthMethodNamespace) { + $out->AuthMethodNamespace = $this->AuthMethodNamespace; + } + return $out; + } } diff --git a/src/ACL/ACLTokenListEntryQueryResponse.php b/src/ACL/ACLTokenListEntryQueryResponse.php index 529e314b..350bf618 100644 --- a/src/ACL/ACLTokenListEntryQueryResponse.php +++ b/src/ACL/ACLTokenListEntryQueryResponse.php @@ -25,18 +25,22 @@ class ACLTokenListEntryQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $ACLTokenListEntries = []; + /** @var \DCarbone\PHPConsulAPI\ACL\ACLTokenListEntry[] */ + public array $ACLTokenListEntries = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\ACL\ACLTokenListEntry[] + */ + public function getValue(): array { return $this->ACLTokenListEntries; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->ACLTokenListEntries = []; - foreach ($decodedData as $datum) { - $this->ACLTokenListEntries[] = new ACLTokenListEntry($datum); + foreach ($decoded as $datum) { + $this->ACLTokenListEntries[] = ACLTokenListEntry::jsonUnserialize($datum); } } } diff --git a/src/ACL/ACLTokenQueryResponse.php b/src/ACL/ACLTokenQueryResponse.php index 5092f215..c9d0c160 100644 --- a/src/ACL/ACLTokenQueryResponse.php +++ b/src/ACL/ACLTokenQueryResponse.php @@ -25,15 +25,19 @@ class ACLTokenQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?ACLToken $ACLToken = null; + public null|ACLToken $ACLToken = null; - public function getValue(): ?ACLToken + public function getValue(): null|ACLToken { return $this->ACLToken; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLToken = new ACLToken((array)$decodedData); + if (null === $decoded) { + $this->ACLToken = null; + return; + } + $this->ACLToken = ACLToken::jsonUnserialize($decoded); } } diff --git a/src/ACL/ACLTokenWriteResponse.php b/src/ACL/ACLTokenWriteResponse.php index 1a1a4d91..6a654d55 100644 --- a/src/ACL/ACLTokenWriteResponse.php +++ b/src/ACL/ACLTokenWriteResponse.php @@ -25,15 +25,19 @@ class ACLTokenWriteResponse extends AbstractValuedWriteResponse implements UnmarshalledResponseInterface { - public ?ACLToken $ACLToken = null; + public null|ACLToken $ACLToken = null; public function getValue(): ?ACLToken { return $this->ACLToken; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->ACLToken = new ACLToken((array)$decodedData); + if (null === $decoded) { + $this->ACLToken = null; + return; + } + $this->ACLToken = ACLToken::jsonUnserialize($decoded); } } diff --git a/src/HasSettableStringTags.php b/src/ACL/BindingRuleBindType.php similarity index 69% rename from src/HasSettableStringTags.php rename to src/ACL/BindingRuleBindType.php index c617b70d..98103191 100644 --- a/src/HasSettableStringTags.php +++ b/src/ACL/BindingRuleBindType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace DCarbone\PHPConsulAPI; +namespace DCarbone\PHPConsulAPI\ACL; /* Copyright 2016-2025 Daniel Carbone (daniel.p.carbone@gmail.com) @@ -20,17 +20,11 @@ limitations under the License. */ -trait HasSettableStringTags +enum BindingRuleBindType: string { - public function setTags(array $tags): static - { - $this->Tags = $tags; - return $this; - } - - public function addTag(string $tag): static - { - $this->Tags[] = $tag; - return $this; - } + case Service = 'service'; + case Role = 'role'; + case Node = 'node'; + case Policy = 'policy'; + case TemplatedPolicy = 'templated-policy'; } diff --git a/src/ACL/KubernetesAuthMethodConfig.php b/src/ACL/KubernetesAuthMethodConfig.php index 15459bbe..958c8081 100644 --- a/src/ACL/KubernetesAuthMethodConfig.php +++ b/src/ACL/KubernetesAuthMethodConfig.php @@ -21,24 +21,26 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\FakeMap; -use DCarbone\PHPConsulAPI\Transcoding; class KubernetesAuthMethodConfig extends AbstractModel { - protected const FIELDS = [ - self::FIELD_HOST => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_CA_CERT => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_SERVICE_ACCOUNT_JWT => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_HOST = 'Host'; - private const FIELD_CA_CERT = 'CACert'; - private const FIELD_SERVICE_ACCOUNT_JWT = 'ServiceAccountJWT'; - - public string $Host = ''; - public string $CACert = ''; - public string $ServiceAccountJWT = ''; + public string $Host; + public string $CACert; + public string $ServiceAccountJWT; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Host = '', + string $CACert = '', + string $ServiceAccountJWT = '' + ) { + $this->Host = $Host; + $this->CACert = $CACert; + $this->ServiceAccountJWT = $ServiceAccountJWT; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getHost(): string { @@ -77,16 +79,41 @@ public function setServiceAccountJWT(string $ServiceAccountJWT): self * RenderToConfig converts this into a map[string]interface{} suitable for use * in the ACLAuthMethod.Config field. * - * @return \DCarbone\PHPConsulAPI\FakeMap + * @return array */ - public function RenderToConfig(): FakeMap + public function RenderToConfig(): array + { + return [ + 'Host' => $this->Host, + 'CACert' => $this->CACert, + 'ServiceAccountJWT' => $this->ServiceAccountJWT, + ]; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass { - return new FakeMap( - [ - self::FIELD_HOST => $this->Host, - self::FIELD_CA_CERT => $this->CACert, - self::FIELD_SERVICE_ACCOUNT_JWT => $this->ServiceAccountJWT, - ] - ); + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ('' !== $this->Host) { + $out->Host = $this->Host; + } + if ('' !== $this->CACert) { + $out->CACert = $this->CACert; + } + if ('' !== $this->ServiceAccountJWT) { + $out->ServiceAccountJWT = $this->ServiceAccountJWT; + } + return $out; } } diff --git a/src/ACL/OIDCAuthMethodConfig.php b/src/ACL/OIDCAuthMethodConfig.php index d8568659..f2ea6528 100644 --- a/src/ACL/OIDCAuthMethodConfig.php +++ b/src/ACL/OIDCAuthMethodConfig.php @@ -24,4 +24,29 @@ class OIDCAuthMethodConfig extends AbstractModel { + public function __construct( + null|array $data = null, // Deprecated, will be removed. + ) { + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + return $out; + } } diff --git a/src/AbstractClient.php b/src/AbstractClient.php index 0a9b322e..99ebe77d 100644 --- a/src/AbstractClient.php +++ b/src/AbstractClient.php @@ -58,14 +58,14 @@ protected function _buildGuzzleRequestOptions(Request $r): array $opts[GuzzleRequestOptions::SSL_KEY] = $this->_config->KeyFile; } - if (null !== $r->timeout && 0 < ($ttl = \intval($r->timeout->Seconds(), 10))) { + if (null !== $r->timeout && 0 < ($ttl = intval($r->timeout->Seconds(), 10))) { $opts[GuzzleRequestOptions::TIMEOUT] = $ttl; } // todo: per-request content and accept value setting. $body = $r->getBody(); if (null !== $body) { - if (\is_scalar($body)) { + if (is_scalar($body)) { $opts[GuzzleRequestOptions::BODY] = $body; } else { $opts[GuzzleRequestOptions::JSON] = $body; @@ -92,12 +92,12 @@ protected function _newPutRequest(string $path, mixed $body, ?RequestOptions $op return $this->_newRequest(HTTP\MethodPut, $path, $body, $opts); } - protected function _newGetRequest(string $path, ?QueryOptions $opts): Request + protected function _newGetRequest(string $path, null|QueryOptions $opts): Request { return $this->_newRequest(HTTP\MethodGet, $path, null, $opts); } - protected function _newDeleteRequest(string $path, ?WriteOptions $opts): Request + protected function _newDeleteRequest(string $path, null|WriteOptions $opts): Request { return $this->_newRequest(HTTP\MethodDelete, $path, null, $opts); } @@ -132,7 +132,7 @@ protected function _do(Request $r): RequestResponse } // calculate execution time - $dur = new Time\Duration(\intval((microtime(true) - $start) * Time::Second, 10)); + $dur = new Time\Duration(intval((microtime(true) - $start) * Time::Second, 10)); return new RequestResponse($r->meta(), $dur, $response, $err); } @@ -155,7 +155,7 @@ protected function _requireStatus(RequestResponse $r, int ...$allowed): RequestR sprintf( '%s - Expected response to be instance of \\Psr\\Message\\ResponseInterface, %s seen.', static::class, - \is_object($r->Response) ? \get_class($r->Response) : \gettype($r->Response) + is_object($r->Response) ? get_class($r->Response) : gettype($r->Response) ) ); return $r; @@ -167,7 +167,7 @@ protected function _requireStatus(RequestResponse $r, int ...$allowed): RequestR $actualCode = $r->Response->getStatusCode(); // If response code is in allowed list, move right along - if (\in_array($actualCode, $allowed, true)) { + if (in_array($actualCode, $allowed, true)) { return $r; } @@ -195,7 +195,7 @@ protected function _requireNotFoundOrOK(RequestResponse $r): RequestResponse return $this->_requireStatus($r, HTTP\StatusOK, HTTP\StatusNotFound); } - protected function _doGet(string $path, ?QueryOptions $opts): RequestResponse + protected function _doGet(string $path, null|QueryOptions $opts): RequestResponse { return $this->_do($this->_newGetRequest($path, $opts)); } @@ -210,16 +210,22 @@ protected function _doPut(string $path, mixed $body, ?RequestOptions $opts): Req return $this->_do($this->_newPutRequest($path, $body, $opts)); } - protected function _doDelete(string $path, ?WriteOptions $opts): RequestResponse + protected function _doDelete(string $path, null|WriteOptions $opts): RequestResponse { return $this->_do($this->_newDeleteRequest($path, $opts)); } protected function _decodeBody(StreamInterface $body): DecodedBody { - $data = @json_decode((string)$body, true); + $data = @json_decode( + json: (string)$body, + associative: false, + depth: $this->_config->JSONDecodeMaxDepth, + flags: $this->_config->JSONDecodeOpts, + ); - if (\JSON_ERROR_NONE === json_last_error()) { + $jsonErr = json_last_error(); + if (\JSON_ERROR_NONE === $jsonErr) { return new DecodedBody($data, null); } @@ -227,15 +233,16 @@ protected function _decodeBody(StreamInterface $body): DecodedBody null, new Error( sprintf( - '%s - Unable to parse response as JSON. Message: %s', + '%s - Unable to parse response as JSON: (%d) %s', static::class, + $jsonErr, json_last_error_msg() ) ) ); } - protected function _executePut(string $path, mixed $body, ?WriteOptions $opts): WriteResponse + protected function _executePut(string $path, mixed $body, null|WriteOptions $opts): WriteResponse { $resp = $this->_requireOK($this->_doPut($path, $body, $opts)); $ret = new WriteResponse(); @@ -243,7 +250,7 @@ protected function _executePut(string $path, mixed $body, ?WriteOptions $opts): return $ret; } - protected function _executePost(string $path, mixed $body, ?WriteOptions $opts): WriteResponse + protected function _executePost(string $path, mixed $body, null|WriteOptions $opts): WriteResponse { $resp = $this->_requireOK($this->_doPost($path, $body, $opts)); $ret = new WriteResponse(); @@ -251,7 +258,7 @@ protected function _executePost(string $path, mixed $body, ?WriteOptions $opts): return $ret; } - protected function _executeDelete(string $path, ?WriteOptions $opts): WriteResponse + protected function _executeDelete(string $path, null|WriteOptions $opts): WriteResponse { $resp = $this->_requireOK($this->_doDelete($path, $opts)); $ret = new WriteResponse(); @@ -259,7 +266,7 @@ protected function _executeDelete(string $path, ?WriteOptions $opts): WriteRespo return $ret; } - protected function _executePutValuedStr(string $path, mixed $body, ?WriteOptions $opts): ValuedWriteStringResponse + protected function _executePutValuedStr(string $path, mixed $body, null|WriteOptions $opts): ValuedWriteStringResponse { $r = $this->_newPutRequest($path, $body, $opts); $resp = $this->_requireOK($this->_do($r)); @@ -268,7 +275,7 @@ protected function _executePutValuedStr(string $path, mixed $body, ?WriteOptions return $ret; } - protected function _executeGetValuedStr(string $path, ?QueryOptions $opts): ValuedQueryStringResponse + protected function _executeGetValuedStr(string $path, null|QueryOptions $opts): ValuedQueryStringResponse { $r = $this->_newGetRequest($path, $opts); $resp = $this->_requireOK($this->_do($r)); @@ -277,7 +284,7 @@ protected function _executeGetValuedStr(string $path, ?QueryOptions $opts): Valu return $ret; } - protected function _executeGetValuedStrs(string $path, ?QueryOptions $opts): ValuedQueryStringsResponse + protected function _executeGetValuedStrs(string $path, null|QueryOptions $opts): ValuedQueryStringsResponse { $r = $this->_newGetRequest($path, $opts); $resp = $this->_requireOK($this->_do($r)); @@ -296,21 +303,15 @@ protected function _executeGetValuedStrs(string $path, ?QueryOptions $opts): Val protected function _unmarshalResponse(RequestResponse $resp, AbstractResponse $ret): void { // determine if this response contains a *Meta field - // TODO: change to use interfaces + instanceof? - if (property_exists($ret, Transcoding::FIELD_QUERY_META)) { + if ($ret instanceof QueryResponseInterface) { $ret->QueryMeta = $resp->buildQueryMeta(); - } elseif (property_exists($ret, Transcoding::FIELD_WRITE_META)) { + } elseif ($ret instanceof WriteResponseInterface) { $ret->WriteMeta = $resp->buildWriteMeta(); } - // todo: can probably assume that all responses have an Err field... - $hasErrField = property_exists($ret, Transcoding::FIELD_ERR); - // if there was an error in the response, set and return if (null !== $resp->Err) { - if ($hasErrField) { - $ret->Err = $resp->Err; - } + $ret->Err = $resp->Err; return; } @@ -322,9 +323,7 @@ protected function _unmarshalResponse(RequestResponse $resp, AbstractResponse $r // attempt response decode $dec = $this->_decodeBody($resp->Response->getBody()); if (null !== $dec->Err) { - if ($hasErrField) { - $ret->Err = $dec->Err; - } + $ret->Err = $dec->Err; return; } diff --git a/src/AbstractModel.php b/src/AbstractModel.php index d38bae8b..61225a70 100644 --- a/src/AbstractModel.php +++ b/src/AbstractModel.php @@ -22,38 +22,15 @@ abstract class AbstractModel implements \JsonSerializable { - use Marshaller; - use Unmarshaller; - - protected const FIELDS = []; - + /** @var array */ private array $_dyn = []; - /** - * AbstractModel constructor. - * - * Convenience method to help set scalar types. Any extending class must have a constructor that builds any - * array / object properties it may have. - * - * @param array|null $data - */ - public function __construct(?array $data = []) - { - // fast path for "empty" - if (null === $data || [] === $data) { - return; - } - foreach ($data as $field => $value) { - $this->unmarshalField($field, $value); - } - } - - public function __set(string $field, $value): void + public function __set(string $field, mixed $value): void { $this->_dyn[$field] = $value; } - public function &__get(string $field) + public function &__get(string $field): mixed { if (!array_key_exists($field, $this->_dyn)) { $this->_dyn[$field] = null; @@ -61,29 +38,17 @@ public function &__get(string $field) return $this->_dyn[$field]; } + public function __unset(string $field): void + { + unset($this->_dyn[$field]); + } + /** - * todo: this picks up non-public fields. externalize this at some point. - * - * @return array + * @return array */ - public function jsonSerialize(): array + public function _getDynamicFields(): array { - $out = []; - // marshal fields - foreach ((array)$this as $field => $value) { - // marshal dynamically defined fields - // todo: this is crap. - if (substr($field, -4) === '_dyn') { - if ([] !== $value) { - foreach ($value as $k => $v) { - $this->marshalField($out, $k, $v); - } - } - } else { - $this->marshalField($out, $field, $value); - } - } - return $out; + return $this->_dyn; } public function __toString(): string diff --git a/src/AbstractValuedQueryResponse.php b/src/AbstractValuedQueryResponse.php index c56bec8a..a2ab90d9 100644 --- a/src/AbstractValuedQueryResponse.php +++ b/src/AbstractValuedQueryResponse.php @@ -20,14 +20,14 @@ limitations under the License. */ -abstract class AbstractValuedQueryResponse extends AbstractResponse implements ValuedResponseInterface +abstract class AbstractValuedQueryResponse extends AbstractResponse implements QueryResponseInterface, ValuedResponseInterface { use QueryMetaContainer; use ErrorContainer; public function offsetExists(mixed $offset): bool { - return \is_int($offset) && 0 <= $offset && $offset < 3; + return is_int($offset) && 0 <= $offset && $offset < 3; } public function offsetGet(mixed $offset): mixed diff --git a/src/AbstractValuedResponse.php b/src/AbstractValuedResponse.php index 0d602a4b..1e8fc823 100644 --- a/src/AbstractValuedResponse.php +++ b/src/AbstractValuedResponse.php @@ -26,7 +26,7 @@ abstract class AbstractValuedResponse extends AbstractResponse implements Valued public function offsetExists(mixed $offset): bool { - return \is_int($offset) && 0 <= $offset && $offset < 2; + return is_int($offset) && 0 <= $offset && $offset < 2; } public function offsetGet(mixed $offset): mixed diff --git a/src/AbstractValuedWriteResponse.php b/src/AbstractValuedWriteResponse.php index 03e5a13e..c380bcd0 100644 --- a/src/AbstractValuedWriteResponse.php +++ b/src/AbstractValuedWriteResponse.php @@ -27,7 +27,7 @@ abstract class AbstractValuedWriteResponse extends AbstractResponse implements V public function offsetExists(mixed $offset): bool { - return \is_int($offset) && 0 <= $offset && $offset < 3; + return is_int($offset) && 0 <= $offset && $offset < 3; } public function offsetGet(mixed $offset): mixed diff --git a/src/Agent/AgentCheck.php b/src/Agent/AgentCheck.php index 55235175..62b82292 100644 --- a/src/Agent/AgentCheck.php +++ b/src/Agent/AgentCheck.php @@ -22,38 +22,51 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Health\HealthCheckDefinition; -use DCarbone\PHPConsulAPI\Transcoding; class AgentCheck extends AbstractModel { - protected const FIELDS = [ - self::FIELD_DEFINITION => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => HealthCheckDefinition::class, - ], - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_DEFINITION = 'Definition'; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $Node = ''; - public string $CheckID = ''; - public string $Name = ''; - public string $Status = ''; - public string $Notes = ''; - public string $Output = ''; - public string $ServiceID = ''; - public string $ServiceName = ''; - public string $Type = ''; + public string $Node; + public string $CheckID; + public string $Name; + public string $Status; + public string $Notes; + public string $Output; + public string $ServiceID; + public string $ServiceName; + public string $Type; public HealthCheckDefinition $Definition; - public string $Namespace = ''; - - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!isset($this->Definition)) { - $this->Definition = new HealthCheckDefinition(null); + public string $Namespace; + public string $Partition; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Node = '', + string $CheckID = '', + string $Name = '', + string $Status = '', + string $Notes = '', + string $Output = '', + string $ServiceID = '', + string $ServiceName = '', + string $Type = '', + null|HealthCheckDefinition $Definition = null, + string $Namespace = '', + string $Partition = '', + ) { + $this->Node = $Node; + $this->CheckID = $CheckID; + $this->Name = $Name; + $this->Status = $Status; + $this->Notes = $Notes; + $this->Output = $Output; + $this->ServiceID = $ServiceID; + $this->ServiceName = $ServiceName; + $this->Type = $Type; + $this->Definition = $Definition ?? new HealthCheckDefinition(); + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -177,6 +190,45 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Definition' === $k) { + $n->Definition = HealthCheckDefinition::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Node = $this->Node; + $out->CheckID = $this->CheckID; + $out->Name = $this->Name; + $out->Status = $this->Status; + $out->Notes = $this->Notes; + $out->Output = $this->Output; + $out->ServiceID = $this->ServiceID; + $out->ServiceName = $this->ServiceName; + $out->Type = $this->Type; + $out->Definition = $this->Definition; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } + public function __toString(): string { return $this->CheckID; diff --git a/src/Agent/AgentCheckRegistration.php b/src/Agent/AgentCheckRegistration.php index 0a2210f0..4fa4bebe 100644 --- a/src/Agent/AgentCheckRegistration.php +++ b/src/Agent/AgentCheckRegistration.php @@ -20,23 +20,78 @@ limitations under the License. */ -use DCarbone\PHPConsulAPI\Transcoding; - class AgentCheckRegistration extends AgentServiceCheck { - protected const FIELDS = [ - self::FIELD_ID => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_SERVICE_ID => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_ID = 'ID'; - private const FIELD_SERVICE_ID = 'ServiceID'; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $ID = ''; - public string $ServiceID = ''; - public string $Namespace = ''; + public string $ID; + public string $ServiceID; + public string $Namespace; + public string $Partition; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ID = '', + string $ServiceID = '', + string $CheckID = '', + string $Name = '', + iterable $ScriptArgs = [], + string $DockerContainerID = '', + string $Shell = '', + string $Interval = '', + string $Timeout = '', + string $TTL = '', + string $HTTP = '', + iterable $Header = [], + string $Method = '', + string $TCP = '', + string $Status = '', + string $Notes = '', + bool $TLSSkipVerify = false, + string $GRPC = '', + bool $GRPCUseTLS = false, + string $H2PING = '', + bool $H2PingUseTLS = false, + string $AliasNode = '', + string $AliasService = '', + int $SuccessBeforePassing = 0, + int $FailuresBeforeCritical = 0, + string $DeregisterCriticalServiceAfter = '', + string $Namespace = '', + string $Partition = '', + ) { + parent::__construct( + CheckID: $CheckID, + Name: $Name, + ScriptArgs: $ScriptArgs, + DockerContainerID: $DockerContainerID, + Shell: $Shell, + Interval: $Interval, + Timeout: $Timeout, + TTL: $TTL, + HTTP: $HTTP, + Header: $Header, + Method: $Method, + TCP: $TCP, + Status: $Status, + Notes: $Notes, + TLSSkipVerify: $TLSSkipVerify, + GRPC: $GRPC, + GRPCUseTLS: $GRPCUseTLS, + H2PING: $H2PING, + H2PINGUseTLS: $H2PingUseTLS, + AliasNode: $AliasNode, + AliasService: $AliasService, + SuccessBeforePassing: $SuccessBeforePassing, + FailuresBeforeCritical: $FailuresBeforeCritical, + DeregisterCriticalServiceAfter: $DeregisterCriticalServiceAfter, + ); + $this->ID = $ID; + $this->ServiceID = $ServiceID; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getID(): string { @@ -70,4 +125,28 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public function jsonSerialize(): \stdClass + { + $out = parent::jsonSerialize(); + if ('' !== $this->ID) { + $out->ID = $this->ID; + } + if ('' !== $this->ServiceID) { + $out->ServiceID = $this->ServiceID; + } + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if (isset($out->Name) && $out->Name === '') { + unset($out->Name); + } + if (isset($out->Notes) && $out->Notes === '') { + unset($out->Notes); + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } } diff --git a/src/Agent/AgentCheckUpdate.php b/src/Agent/AgentCheckUpdate.php index aed5f53a..8e0bb063 100644 --- a/src/Agent/AgentCheckUpdate.php +++ b/src/Agent/AgentCheckUpdate.php @@ -22,10 +22,22 @@ use DCarbone\PHPConsulAPI\AbstractModel; -final class AgentCheckUpdate extends AbstractModel +class AgentCheckUpdate extends AbstractModel { - public string $Status = ''; - public string $Output = ''; + public string $Status; + public string $Output; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Status = '', + string $Output = '' + ) { + $this->Status = $Status; + $this->Output = $Output; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getStatus(): string { @@ -49,6 +61,26 @@ public function setOutput(string $output): self return $this; } + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Status = $this->Status; + $out->Output = $this->Output; + return $out; + } + public function __toString(): string { return sprintf('%s: %s', $this->Status, $this->Output); diff --git a/src/Agent/AgentChecksResponse.php b/src/Agent/AgentChecksResponse.php index 4cf50761..dc4bdc67 100644 --- a/src/Agent/AgentChecksResponse.php +++ b/src/Agent/AgentChecksResponse.php @@ -25,18 +25,22 @@ class AgentChecksResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?array $Checks = null; + /** @var \DCarbone\PHPConsulAPI\Agent\AgentCheck[] */ + public array $Checks = []; + /** + * @return \DCarbone\PHPConsulAPI\Agent\AgentCheck[]|null + */ public function getValue(): ?array { return $this->Checks; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->Checks = []; - foreach ($decodedData as $k => $v) { - $this->Checks[$k] = new AgentCheck($v); + foreach ($decoded as $k => $v) { + $this->Checks[$k] = AgentCheck::jsonUnserialize($v); } } } diff --git a/src/Agent/AgentClient.php b/src/Agent/AgentClient.php index 7e896ead..2bc90f40 100644 --- a/src/Agent/AgentClient.php +++ b/src/Agent/AgentClient.php @@ -31,7 +31,7 @@ class AgentClient extends AbstractClient { - private ?MapResponse $_self = null; + private null|MapResponse $_self = null; public function Self(bool $refresh = false): MapResponse { @@ -63,7 +63,7 @@ public function Metrics(): MetricsInfoResponse return $ret; } - public function Reload(): ?Error + public function Reload(): null|Error { return $this->_executePut('v1/agent/reload', null, null)->Err; } @@ -76,8 +76,8 @@ public function NodeName(bool $refresh = false): ValuedStringResponse if (null !== $self->Err) { return $ret; } - if (isset($self->Map['Config'], $self->Map['Config']['NodeName'])) { - $ret->Value = $self->Map['Config']['NodeName']; + if (isset($self->Map->Config, $self->Map->Config->NodeName)) { + $ret->Value = $self->Map->Config->NodeName; } return $ret; } @@ -146,29 +146,28 @@ public function AgentHealthServiceByName(string $service): AgentHealthServicesRe $resp = $this->_requireOK($this->_do($r)); if (null !== $resp->Err) { - return new AgentHealthServicesResponse(Consul::HealthCritical, null, $resp->Err); + return new AgentHealthServicesResponse(Consul::HealthCritical, [], $resp->Err); } if (HTTP\StatusNotFound === $resp->Response->getStatusCode()) { - return new AgentHealthServicesResponse(Consul::HealthCritical, null, null); + return new AgentHealthServicesResponse(Consul::HealthCritical, [], null); } $dec = $this->_decodeBody($resp->Response->getBody()); if (null !== $dec->Err) { - return new AgentHealthServicesResponse(Consul::HealthCritical, null, $dec->Err); + return new AgentHealthServicesResponse(Consul::HealthCritical, [], $dec->Err); } $status = match ($resp->Response->getStatusCode()) { HTTP\StatusOK => Consul::HealthPassing, HTTP\StatusTooManyRequests => Consul::HealthWarning, - HTTP\StatusServiceUnavailable => Consul::HealthCritical, default => Consul::HealthCritical, }; return new AgentHealthServicesResponse($status, $dec->Decoded, null); } - public function Service(string $serviceID, ?QueryOptions $opts = null): AgentServiceResponse + public function Service(string $serviceID, null|QueryOptions $opts = null): AgentServiceResponse { $resp = $this->_requireOK($this->_doGet(sprintf('v1/agent/service/%s', $serviceID), $opts)); $ret = new AgentServiceResponse(); @@ -197,7 +196,7 @@ public function MemberOpts(MemberOpts $memberOpts): AgentMembersResponse return $ret; } - public function ServiceRegisterOpts(AgentServiceRegistration $service, ServiceRegisterOpts $registerOpts): ?Error + public function ServiceRegisterOpts(AgentServiceRegistration $service, ServiceRegisterOpts $registerOpts): null|Error { $r = $this->_newPutRequest('v1/agent/service/register', $service, null); if ($registerOpts->ReplaceExistingChecks) { @@ -206,33 +205,33 @@ public function ServiceRegisterOpts(AgentServiceRegistration $service, ServiceRe return $this->_requireOK($this->_do($r))->Err; } - public function ServiceRegister(AgentServiceRegistration $service): ?Error + public function ServiceRegister(AgentServiceRegistration $service): null|Error { - return $this->ServiceRegisterOpts($service, new ServiceRegisterOpts(['ReplaceExistingChecks' => false])); + return $this->ServiceRegisterOpts($service, new ServiceRegisterOpts(ReplaceExistingChecks: false)); } - public function ServiceDeregister(string $serviceID): ?Error + public function ServiceDeregister(string $serviceID): null|Error { $r = new Request(HTTP\MethodPut, sprintf('v1/agent/service/deregister/%s', $serviceID), $this->_config, null); return $this->_requireOK($this->_do($r))->Err; } - public function PassTTL(string $checkID, string $note): ?Error + public function PassTTL(string $checkID, string $note): null|Error { return $this->UpdateTTL($checkID, $note, 'pass'); } - public function WarnTTL(string $checkID, string $note): ?Error + public function WarnTTL(string $checkID, string $note): null|Error { return $this->UpdateTTL($checkID, $note, 'warn'); } - public function FailTTL(string $checkID, string $note): ?Error + public function FailTTL(string $checkID, string $note): null|Error { return $this->UpdateTTL($checkID, $note, 'fail'); } - public function UpdateTTL(string $checkID, string $output, string $status): ?Error + public function UpdateTTL(string $checkID, string $output, string $status): null|Error { switch ($status) { case Consul::HealthPassing: @@ -262,17 +261,17 @@ public function UpdateTTL(string $checkID, string $output, string $status): ?Err return $this->_requireOK($this->_do($r))->Err; } - public function CheckRegister(AgentCheckRegistration $check): ?Error + public function CheckRegister(AgentCheckRegistration $check): null|Error { return $this->_executePut('v1/agent/check/register', $check, null)->Err; } - public function CheckDeregister(string $checkID): ?Error + public function CheckDeregister(string $checkID): null|Error { return $this->_executePut(sprintf('v1/agent/check/deregister/%s', $checkID), null, null)->Err; } - public function Join(string $addr, bool $wan = false): ?Error + public function Join(string $addr, bool $wan = false): null|Error { $r = $this->_newPutRequest(sprintf('v1/agent/join/%s', $addr), null, null); if ($wan) { @@ -281,24 +280,24 @@ public function Join(string $addr, bool $wan = false): ?Error return $this->_requireOK($this->_do($r))->Err; } - public function Leave(): ?Error + public function Leave(): null|Error { return $this->_executePut('v1/agent/leave', null, null)->Err; } - public function ForceLeave(string $node): ?Error + public function ForceLeave(string $node): null|Error { return $this->_executePut(sprintf('v1/agent/force-leave/%s', $node), null, null)->Err; } - public function ForceLeavePrune(string $node): ?Error + public function ForceLeavePrune(string $node): null|Error { $r = $this->_newPutRequest(sprintf('v1/agent/force-leave/%s', $node), null, null); $r->params->set('prune', '1'); return $this->_requireOK($this->_do($r))->Err; } - public function EnableServiceMaintenance(string $serviceID, string $reason = ''): ?Error + public function EnableServiceMaintenance(string $serviceID, string $reason = ''): null|Error { $r = $this->_newPutRequest(sprintf('v1/agent/service/maintenance/%s', $serviceID), null, null); $r->params->set('enable', 'true'); @@ -306,14 +305,14 @@ public function EnableServiceMaintenance(string $serviceID, string $reason = '') return $this->_requireOK($this->_do($r))->Err; } - public function DisableServiceMaintenance(string $serviceID): ?Error + public function DisableServiceMaintenance(string $serviceID): null|Error { $r = $this->_newPutRequest(sprintf('v1/agent/service/maintenance/%s', $serviceID), null, null); $r->params->set('enable', 'false'); return $this->_requireOK($this->_do($r))->Err; } - public function EnableNodeMaintenance(string $reason = ''): ?Error + public function EnableNodeMaintenance(string $reason = ''): null|Error { $r = $this->_newPutRequest('v1/agent/maintenance', null, null); $r->params->set('enable', 'true'); @@ -321,7 +320,7 @@ public function EnableNodeMaintenance(string $reason = ''): ?Error return $this->_requireOK($this->_do($r))->Err; } - public function DisableNodeMaintenance(): ?Error + public function DisableNodeMaintenance(): null|Error { $r = $this->_newPutRequest('v1/agent/maintenance', null, null); $r->params->set('enable', 'false'); diff --git a/src/Agent/AgentHealthServiceResponse.php b/src/Agent/AgentHealthServiceResponse.php index 1da8b3c8..5ada9735 100644 --- a/src/Agent/AgentHealthServiceResponse.php +++ b/src/Agent/AgentHealthServiceResponse.php @@ -28,15 +28,19 @@ class AgentHealthServiceResponse extends AbstractResponse { use ErrorContainer; - public string $AggregatedStatus = ''; - public ?AgentServiceChecksInfo $AgentServiceChecksInfo = null; + public string $AggregatedStatus; + public null|AgentServiceChecksInfo $AgentServiceChecksInfo; - public function __construct(string $aggregatedStatus, ?array $checkInfo, ?Error $err) - { + public function __construct( + string $aggregatedStatus, + null|\stdClass $checksInfo, + null|Error $err + ) { $this->AggregatedStatus = $aggregatedStatus; - if (null !== $checkInfo) { - $this->AgentServiceChecksInfo = new AgentServiceChecksInfo($checkInfo); + if (null !== $checksInfo) { + $checksInfo = AgentServiceChecksInfo::jsonUnserialize($checksInfo); } + $this->AgentServiceChecksInfo = $checksInfo; $this->Err = $err; } @@ -45,17 +49,17 @@ public function getAggregatedStatus(): string return $this->AggregatedStatus; } - public function getAgentServiceChecksInfos(): ?AgentServiceChecksInfo + public function getAgentServiceChecksInfos(): null|AgentServiceChecksInfo { return $this->AgentServiceChecksInfo; } public function offsetExists(mixed $offset): bool { - return \is_int($offset) && 0 <= $offset && $offset < 3; + return is_int($offset) && 0 <= $offset && $offset < 3; } - public function offsetGet(mixed $offset): Error|string|null|AgentServiceChecksInfo + public function offsetGet(mixed $offset): string|AgentServiceChecksInfo|Error|null { if (0 === $offset) { return $this->AggregatedStatus; diff --git a/src/Agent/AgentHealthServicesResponse.php b/src/Agent/AgentHealthServicesResponse.php index d6d3a4c6..f529be51 100644 --- a/src/Agent/AgentHealthServicesResponse.php +++ b/src/Agent/AgentHealthServicesResponse.php @@ -28,17 +28,21 @@ class AgentHealthServicesResponse extends AbstractResponse { use ErrorContainer; - public string $AggregatedStatus = ''; - public ?array $AgentServiceChecksInfos = null; + public string $AggregatedStatus; + /** @var \DCarbone\PHPConsulAPI\Agent\AgentServiceChecksInfo[] */ + public array $AgentServiceChecksInfos; - public function __construct(string $aggregatedStatus, ?array $checkInfos, ?Error $err) + /** + * @param string $aggregatedStatus + * @param \stdClass[] $checkInfos + * @param \DCarbone\PHPConsulAPI\Error|null $err + */ + public function __construct(string $aggregatedStatus, array $checkInfos, null|Error $err) { $this->AggregatedStatus = $aggregatedStatus; - if (null !== $checkInfos) { - $this->AgentServiceChecksInfos = []; - foreach ($checkInfos as $checkInfo) { - $this->AgentServiceChecksInfos[] = new AgentServiceChecksInfo($checkInfo); - } + $this->AgentServiceChecksInfos = []; + foreach ($checkInfos as $checkInfo) { + $this->AgentServiceChecksInfos[] = AgentServiceChecksInfo::jsonUnserialize($checkInfo); } $this->Err = $err; } @@ -48,17 +52,24 @@ public function getAggregatedStatus(): string return $this->AggregatedStatus; } - public function getAgentServiceChecksInfos(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Agent\AgentServiceChecksInfo[] + */ + public function getAgentServiceChecksInfos(): array { return $this->AgentServiceChecksInfos; } public function offsetExists(mixed $offset): bool { - return \is_int($offset) && 0 <= $offset && $offset < 3; + return is_int($offset) && 0 <= $offset && $offset < 3; } - public function offsetGet(mixed $offset): mixed + /** + * @param mixed $offset + * @return string|\DCarbone\PHPConsulAPI\Agent\AgentServiceChecksInfo[]|\DCarbone\PHPConsulAPI\Error|null + */ + public function offsetGet(mixed $offset): string|array|Error|null { if (0 === $offset) { return $this->AggregatedStatus; diff --git a/src/Agent/AgentMember.php b/src/Agent/AgentMember.php index 80167a8c..8f53b40b 100644 --- a/src/Agent/AgentMember.php +++ b/src/Agent/AgentMember.php @@ -22,22 +22,74 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Consul; -use DCarbone\PHPConsulAPI\HasStringTags; class AgentMember extends AbstractModel { - use HasStringTags; - - public string $Name = ''; - public string $Addr = ''; - public int $Port = 0; - public string $Status = ''; - public int $ProtocolMin = 0; - public int $ProtocolMax = 0; - public int $ProtocolCur = 0; - public int $DelegateMin = 0; - public int $DelegateMax = 0; - public int $DelegateCur = 0; + public string $Name; + public string $Addr; + public int $Port; + public null|\stdClass $Tags; + /** + * Status of the Member which corresponds to github.com/hashicorp/serf/serf.MemberStatus + * Value is one of: + * AgentMemberNone = 0 + * AgentMemberAlive = 1 + * AgentMemberLeaving = 2 + * AgentMemberLeft = 3 + * AgentMemberFailed = 4 + * @var int + */ + public int $Status; + public int $ProtocolMin; + public int $ProtocolMax; + public int $ProtocolCur; + public int $DelegateMin; + public int $DelegateMax; + public int $DelegateCur; + + /** + * @param array|null $data // Deprecated, will be removed. + * @param string $Name + * @param string $Addr + * @param int $Port + * @param \stdClass|null $Tags + * @param int $Status + * @param int $ProtocolMin + * @param int $ProtocolMax + * @param int $ProtocolCur + * @param int $DelegateMin + * @param int $DelegateMax + * @param int $DelegateCur + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Name = '', + string $Addr = '', + int $Port = 0, + null|\stdClass $Tags = null, + int $Status = 0, + int $ProtocolMin = 0, + int $ProtocolMax = 0, + int $ProtocolCur = 0, + int $DelegateMin = 0, + int $DelegateMax = 0, + int $DelegateCur = 0, + ) { + $this->Name = $Name; + $this->Addr = $Addr; + $this->Port = $Port; + $this->Tags = $Tags; + $this->Status = $Status; + $this->ProtocolMin = $ProtocolMin; + $this->ProtocolMax = $ProtocolMax; + $this->ProtocolCur = $ProtocolCur; + $this->DelegateMin = $DelegateMin; + $this->DelegateMax = $DelegateMax; + $this->DelegateCur = $DelegateCur; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getName(): string { @@ -54,7 +106,7 @@ public function getPort(): int return $this->Port; } - public function getStatus(): string + public function getStatus(): int { return $this->Status; } @@ -89,13 +141,13 @@ public function getDelegateCur(): int return $this->DelegateCur; } - public function ACLMode(): string + public function ACLMode(): MemberACLMode { return match ($this->Tags[Consul::MemberTagKeyACLMode] ?? null) { - Consul::ACLModeDisabled => Consul::ACLModeDisabled, - Consul::ACLModeEnabled => Consul::ACLModeEnabled, - Consul::ACLModeLegacy => Consul::ACLModeLegacy, - default => Consul::ACLModeUnknown, + MemberACLMode::Disabled->value => MemberACLMode::Disabled, + MemberACLMode::Enabled->value => MemberACLMode::Enabled, + MemberACLMode::Legacy->value => MemberACLMode::Legacy, + default => MemberACLMode::Unknown, }; } @@ -105,6 +157,35 @@ public function IsConsulServer(): bool Consul::MemberTagValueRoleServer === $this->Tags[Consul::MemberTagKeyACLMode]; } + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + $out->Addr = $this->Addr; + $out->Port = $this->Port; + $out->Tags = $this->Tags; + $out->Status = $this->Status; + $out->ProtocolMin = $this->ProtocolMin; + $out->ProtocolMax = $this->ProtocolMax; + $out->ProtocolCur = $this->ProtocolCur; + $out->DelegateMin = $this->DelegateMin; + $out->DelegateMax = $this->DelegateMax; + $out->DelegateCur = $this->DelegateCur; + return $out; + } + public function __toString(): string { return $this->Name; diff --git a/src/Agent/AgentMembersResponse.php b/src/Agent/AgentMembersResponse.php index 816c924e..6005c021 100644 --- a/src/Agent/AgentMembersResponse.php +++ b/src/Agent/AgentMembersResponse.php @@ -25,18 +25,22 @@ class AgentMembersResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?array $Members = null; + /** @var \DCarbone\PHPConsulAPI\Agent\AgentMember[] */ + public array $Members = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Agent\AgentMember[] + */ + public function getValue(): array { return $this->Members; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->Members = []; - foreach ($decodedData as $member) { - $this->Members[] = new AgentMember($member); + foreach ($decoded as $member) { + $this->Members[] = AgentMember::jsonUnserialize($member); } } } diff --git a/src/Agent/AgentService.php b/src/Agent/AgentService.php index dd4de64e..c7506c32 100644 --- a/src/Agent/AgentService.php +++ b/src/Agent/AgentService.php @@ -22,83 +22,104 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Catalog\ServiceAddress; -use DCarbone\PHPConsulAPI\FakeMap; -use DCarbone\PHPConsulAPI\HasStringTags; -use DCarbone\PHPConsulAPI\Transcoding; +use DCarbone\PHPConsulAPI\Peering\Locality; class AgentService extends AbstractModel { - use HasStringTags; - - protected const FIELDS = [ - self::FIELD_KIND => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_META => Transcoding::MAP_FIELD, - self::FIELD_TAGGED_ADDRESSES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ServiceAddress::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_WEIGHTS => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentWeights::class, - ], - self::FIELD_CREATE_INDEX => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_MODIFY_INDEX => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_CONTENT_HASH => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_PROXY => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentServiceConnectProxyConfig::class, - Transcoding::FIELD_NULLABLE => true, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_CONNECT => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentServiceConnect::class, - Transcoding::FIELD_NULLABLE => true, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_DATACENTER => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_KIND = 'Kind'; - private const FIELD_META = 'Meta'; - private const FIELD_TAGGED_ADDRESSES = 'TaggedAddresses'; - private const FIELD_WEIGHTS = 'Weights'; - private const FIELD_CREATE_INDEX = 'CreateIndex'; - private const FIELD_MODIFY_INDEX = 'ModifyIndex'; - private const FIELD_CONTENT_HASH = 'ContentHash'; - private const FIELD_PROXY = 'Proxy'; - private const FIELD_CONNECT = 'Connect'; - private const FIELD_NAMESPACE = 'Namespace'; - private const FIELD_DATACENTER = 'Datacenter'; - - public string $Kind = ''; - public string $ID = ''; - public string $Service = ''; - public FakeMap $Meta; - public int $Port = 0; - public string $Address = ''; - public array $TaggedAddresses = []; + public string $Kind; + public string $ID; + public string $Service; + /** @var array */ + public array $Tags; + public null|\stdClass $Meta; + public int $Port; + public string $Address; + public string $SocketPath; + public null|\stdClass $TaggedAddresses; public AgentWeights $Weights; - public bool $EnableTagOverride = false; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - public string $ContentHash = ''; - public ?AgentServiceConnectProxyConfig $Proxy = null; - public ?AgentServiceConnect $Connect = null; - public string $Namespace = ''; - public string $Datacenter = ''; - - public function __construct(?array $data = []) - { - parent::__construct($data); - if (!isset($this->Weights)) { - $this->Weights = new AgentWeights(null); - } - if (!isset($this->Meta)) { - $this->Meta = new FakeMap(null); + public bool $EnableTagOverride; + public int $CreateIndex; + public int $ModifyIndex; + public string $ContentHash; + public null|AgentServiceConnectProxyConfig $Proxy; + public null|AgentServiceConnect $Connect; + public string $PeerName; + public string $Namespace; + public string $Partition; + public string $Datacenter; + public null|Locality $Locality; + + /** + * @param array |null $data Deprecated, will be removed. + * @param string $Kind + * @param string $ID + * @param string $Service + * @param string $SocketPath + * @param iterable $Tags + * @param \stdClass|null $Meta + * @param int $Port + * @param string $Address + * @param \stdClass|null $TaggedAddresses + * @param \DCarbone\PHPConsulAPI\Agent\AgentWeights|null $Weights + * @param bool $EnableTagOverride + * @param int $CreateIndex + * @param int $ModifyIndex + * @param string $ContentHash + * @param \DCarbone\PHPConsulAPI\Agent\AgentServiceConnectProxyConfig|null $Proxy + * @param \DCarbone\PHPConsulAPI\Agent\AgentServiceConnect|null $Connect + * @param string $PeerName + * @param string $Namespace + * @param string $Partition + * @param string $Datacenter + * @param \DCarbone\PHPConsulAPI\Peering\Locality|null $Locality + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Kind = '', + string $ID = '', + string $Service = '', + string $SocketPath = '', + iterable $Tags = [], + null|\stdClass $Meta = null, + int $Port = 0, + string $Address = '', + null|\stdClass $TaggedAddresses = null, + null|AgentWeights $Weights = null, + bool $EnableTagOverride = false, + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $ContentHash = '', + null|AgentServiceConnectProxyConfig $Proxy = null, + null|AgentServiceConnect $Connect = null, + string $PeerName = '', + string $Namespace = '', + string $Partition = '', + string $Datacenter = '', + null|Locality $Locality = null, + ) { + $this->Kind = $Kind; + $this->ID = $ID; + $this->Service = $Service; + $this->Meta = $Meta; + $this->Port = $Port; + $this->setTags(...$Tags); + $this->Address = $Address; + $this->SocketPath = $SocketPath; + $this->setTaggedAddresses($TaggedAddresses); + $this->Weights = $Weights ?? new AgentWeights(); + $this->EnableTagOverride = $EnableTagOverride; + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->ContentHash = $ContentHash; + $this->Proxy = $Proxy; + $this->Connect = $Connect; + $this->PeerName = $PeerName; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + $this->Datacenter = $Datacenter; + $this->Locality = $Locality; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -135,12 +156,26 @@ public function setService(string $Service): self return $this; } - public function getMeta(): FakeMap + /** + * @return array + */ + public function getTags(): array + { + return $this->Tags; + } + + public function setTags(string ...$Tags): self + { + $this->Tags = $Tags; + return $this; + } + + public function getMeta(): null|\stdClass { return $this->Meta; } - public function setMeta(FakeMap $Meta): self + public function setMeta(null|\stdClass $Meta): self { $this->Meta = $Meta; return $this; @@ -168,14 +203,21 @@ public function setAddress(string $Address): self return $this; } - public function getTaggedAddresses(): array + public function getTaggedAddresses(): null|\stdClass { return $this->TaggedAddresses; } - public function setTaggedAddresses(array $TaggedAddresses): self + public function setTaggedAddresses(null|\stdClass $TaggedAddresses): self { - $this->TaggedAddresses = $TaggedAddresses; + if (null === $TaggedAddresses) { + $this->TaggedAddresses = null; + return $this; + } + $this->TaggedAddresses = new \stdClass(); + foreacH($TaggedAddresses as $k => $v) { + $this->TaggedAddresses->{$k} = $v instanceof ServiceAddress ? $v : ServiceAddress::jsonUnserialize($v); + } return $this; } @@ -234,28 +276,39 @@ public function setContentHash(string $ContentHash): self return $this; } - public function getProxy(): ?AgentServiceConnectProxyConfig + public function getProxy(): null|AgentServiceConnectProxyConfig { return $this->Proxy; } - public function setProxy(?AgentServiceConnectProxyConfig $Proxy): self + public function setProxy(null|AgentServiceConnectProxyConfig $Proxy): self { $this->Proxy = $Proxy; return $this; } - public function getConnect(): ?AgentServiceConnect + public function getConnect(): null|AgentServiceConnect { return $this->Connect; } - public function setConnect(?AgentServiceConnect $Connect): self + public function setConnect(null|AgentServiceConnect $Connect): self { $this->Connect = $Connect; return $this; } + public function getPeerName(): string + { + return $this->PeerName; + } + + public function setPeerName(string $PeerName): self + { + $this->PeerName = $PeerName; + return $this; + } + public function getNamespace(): string { return $this->Namespace; @@ -267,6 +320,17 @@ public function setNamespace(string $Namespace): self return $this; } + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + public function getDatacenter(): string { return $this->Datacenter; @@ -277,4 +341,96 @@ public function setDatacenter(string $Datacenter): self $this->Datacenter = $Datacenter; return $this; } + + public function getLocality(): null|Locality + { + return $this->Locality; + } + + public function setLocality(null|Locality $Locality): self + { + $this->Locality = $Locality; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Tags' === $k) { + $n->setTags(...$v); + } elseif ('Meta' === $k) { + $n->setMeta($v); + } elseif ('Proxy' === $k) { + $n->Proxy = null === $v ? null : AgentServiceConnectProxyConfig::jsonUnserialize($v); + } elseif ('Weights' === $k) { + $n->Weights = AgentWeights::jsonUnserialize($v); + } elseif ('TaggedAddresses' === $k) { + $n->settaggedAddresses($v); + } elseif ('Connect' === $k) { + $n->Connect = null === $v ? null : AgentServiceConnect::jsonUnserialize($v); + } elseif ('Locality' === $k) { + $n->Locality = null === $v ? null : Locality::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ('' !== $this->Kind) { + $out->Kind = $this->Kind; + } + $out->ID = $this->ID; + $out->Service = $this->Service; + $out->Tags = $this->Tags; + $out->Meta = $this->Meta; + $out->Port = $this->Port; + $out->Address = $this->Address; + if ('' !== $this->SocketPath) { + $out->SocketPath = $this->SocketPath; + } + if (null !== $this->TaggedAddresses) { + $out->TaggedAddresses = $this->TaggedAddresses; + } + $out->Weights = $this->Weights; + $out->EnableTagOverride = $this->EnableTagOverride; + if (0 !== $this->CreateIndex) { + $out->CreateIndex = $this->CreateIndex; + } + if (0 !== $this->ModifyIndex) { + $out->ModifyIndex = $this->ModifyIndex; + } + if ('' !== $this->ContentHash) { + $out->ContentHash = $this->ContentHash; + } + if (null !== $this->Proxy) { + $out->Proxy = $this->Proxy; + } + if (null !== $this->Connect) { + $out->Connect = $this->Connect; + } + if ('' !== $this->PeerName) { + $out->PeerName = $this->PeerName; + } + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + if ('' !== $this->Datacenter) { + $out->Datacenter = $this->Datacenter; + } + if (null !== $this->Locality) { + $out->Locality = $this->Locality; + } + return $out; + } } diff --git a/src/Agent/AgentServiceCheck.php b/src/Agent/AgentServiceCheck.php index c31a3319..0f85b602 100644 --- a/src/Agent/AgentServiceCheck.php +++ b/src/Agent/AgentServiceCheck.php @@ -21,91 +21,118 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class AgentServiceCheck extends AbstractModel { - protected const FIELDS = [ - self::FIELD_CHECK_ID => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_NAME => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_SCRIPT_ARGS => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::STRING, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_DOCKER_CONTAINER_ID => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_SHELL => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_INTERVAL => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_TIMEOUT => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_TTL => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_HTTP => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_HEADER => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::MIXED, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_METHOD => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_BODY => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_TCP => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_STATUS => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_NOTES => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_TLS_SKIP_VERIFY => Transcoding::OMITEMPTY_BOOLEAN_FIELD, - self::FIELD_GRPC => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_GRPC_USE_TLS => Transcoding::OMITEMPTY_BOOLEAN_FIELD, - self::FIELD_ALIAS_NODE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_ALIAS_SERVICE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_SUCCESS_BEFORE_PASSING => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_FAILURES_BEFORE_CRITICAL => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_DEREGISTER_CRITICAL_SERVICE_AFTER => Transcoding::OMITEMPTY_BOOLEAN_FIELD, - ]; - - private const FIELD_CHECK_ID = 'CheckID'; - private const FIELD_NAME = 'Name'; - private const FIELD_SCRIPT_ARGS = 'ScriptArgs'; - private const FIELD_DOCKER_CONTAINER_ID = 'DockerContainerID'; - private const FIELD_SHELL = 'Shell'; - private const FIELD_INTERVAL = 'Interval'; - private const FIELD_TIMEOUT = 'Timeout'; - private const FIELD_TTL = 'TTL'; - private const FIELD_HTTP = 'HTTP'; - private const FIELD_HEADER = 'Header'; - private const FIELD_METHOD = 'Method'; - private const FIELD_BODY = 'Body'; - private const FIELD_TCP = 'TCP'; - private const FIELD_STATUS = 'Status'; - private const FIELD_NOTES = 'Notes'; - private const FIELD_TLS_SKIP_VERIFY = 'TLSSkipVerify'; - private const FIELD_GRPC = 'GRPC'; - private const FIELD_GRPC_USE_TLS = 'GRPCUseTLS'; - private const FIELD_ALIAS_NODE = 'AliasNode'; - private const FIELD_ALIAS_SERVICE = 'AliasService'; - private const FIELD_SUCCESS_BEFORE_PASSING = 'SuccessBeforePassing'; - private const FIELD_FAILURES_BEFORE_CRITICAL = 'FailuresBeforeCritical'; - private const FIELD_DEREGISTER_CRITICAL_SERVICE_AFTER = 'DeregisterCriticalServiceAfter'; - - public string $CheckID = ''; - public string $Name = ''; - public array $ScriptArgs = []; - public string $DockerContainerID = ''; - public string $Shell = ''; - public string $Interval = ''; - public string $Timeout = ''; - public string $TTL = ''; - public string $HTTP = ''; - public array $Header = []; - public string $Method = ''; - public string $TCP = ''; - public string $Status = ''; - public string $Notes = ''; - public bool $TLSSkipVerify = false; - public string $GRPC = ''; - public bool $GRPCUseTLS = false; - public string $AliasNode = ''; - public string $AliasService = ''; - public int $SuccessBeforePassing = 0; - public int $FailuresBeforeCritical = 0; - - public string $DeregisterCriticalServiceAfter = ''; + public string $CheckID; + public string $Name; + /** @var string[] */ + public array $ScriptArgs; + public string $DockerContainerID; + public string $Shell; + public string $Interval; + public string $Timeout; + public string $TTL; + public string $HTTP; + public null|\stdClass $Header; + public string $Method; + public string $TCP; + public string $Status; + public string $Notes; + public bool $TLSSkipVerify; + public string $GRPC; + public bool $GRPCUseTLS; + public string $H2PING; + public bool $H2PINGUseTLS; + public string $AliasNode; + public string $AliasService; + public int $SuccessBeforePassing; + public int $FailuresBeforeCritical; + public string $DeregisterCriticalServiceAfter; + + /** + * @param array|null $data // Deprecated, will be removed. + * @param string $CheckID + * @param string $Name + * @param iterable $ScriptArgs + * @param string $DockerContainerID + * @param string $Shell + * @param string $Interval + * @param string $Timeout + * @param string $TTL + * @param string $HTTP + * @param \stdClass|null $Header + * @param string $Method + * @param string $TCP + * @param string $Status + * @param string $Notes + * @param bool $TLSSkipVerify + * @param string $GRPC + * @param bool $GRPCUseTLS + * @param string $H2PING + * @param bool $H2PINGUseTLS + * @param string $AliasNode + * @param string $AliasService + * @param int $SuccessBeforePassing + * @param int $FailuresBeforeCritical + * @param string $DeregisterCriticalServiceAfter + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $CheckID = '', + string $Name = '', + iterable $ScriptArgs = [], + string $DockerContainerID = '', + string $Shell = '', + string $Interval = '', + string $Timeout = '', + string $TTL = '', + string $HTTP = '', + null|\stdClass $Header = null, + string $Method = '', + string $TCP = '', + string $Status = '', + string $Notes = '', + bool $TLSSkipVerify = false, + string $GRPC = '', + bool $GRPCUseTLS = false, + string $H2PING = '', + bool $H2PINGUseTLS = false, + string $AliasNode = '', + string $AliasService = '', + int $SuccessBeforePassing = 0, + int $FailuresBeforeCritical = 0, + string $DeregisterCriticalServiceAfter = '', + ) { + $this->CheckID = $CheckID; + $this->Name = $Name; + $this->ScriptArgs = []; + $this->setScriptArgs(...$ScriptArgs); + $this->DockerContainerID = $DockerContainerID; + $this->Shell = $Shell; + $this->Interval = $Interval; + $this->Timeout = $Timeout; + $this->TTL = $TTL; + $this->HTTP = $HTTP; + $this->Header = $Header; + $this->Method = $Method; + $this->TCP = $TCP; + $this->Status = $Status; + $this->Notes = $Notes; + $this->TLSSkipVerify = $TLSSkipVerify; + $this->GRPC = $GRPC; + $this->GRPCUseTLS = $GRPCUseTLS; + $this->H2PING = $H2PING; + $this->H2PINGUseTLS = $H2PINGUseTLS; + $this->AliasNode = $AliasNode; + $this->AliasService = $AliasService; + $this->SuccessBeforePassing = $SuccessBeforePassing; + $this->FailuresBeforeCritical = $FailuresBeforeCritical; + $this->DeregisterCriticalServiceAfter = $DeregisterCriticalServiceAfter; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getCheckID(): string { @@ -129,12 +156,15 @@ public function setName(string $name): self return $this; } + /** + * @return array + */ public function getScriptArgs(): array { return $this->ScriptArgs; } - public function setScriptArgs(array $args): self + public function setScriptArgs(string ...$args): self { $this->ScriptArgs = $args; return $this; @@ -206,14 +236,14 @@ public function setHTTP(string $http): self return $this; } - public function getHeader(): array + public function getHeader(): null|\stdClass { return $this->Header; } - public function setHeader(array $header): self + public function setHeader(null|\stdClass $Header): self { - $this->Header = $header; + $this->Header = $Header; return $this; } @@ -288,6 +318,28 @@ public function isGRPCUseTLS(): bool return $this->GRPCUseTLS; } + public function getH2PING(): string + { + return $this->H2PING; + } + + public function setH2PING(string $H2PING): AgentServiceCheck + { + $this->H2PING = $H2PING; + return $this; + } + + public function isH2PINGUseTLS(): bool + { + return $this->H2PINGUseTLS; + } + + public function setH2PINGUseTLS(bool $H2PINGUseTLS): AgentServiceCheck + { + $this->H2PINGUseTLS = $H2PINGUseTLS; + return $this; + } + public function setGRPCUseTLS(bool $GRPCUseTLS): self { $this->GRPCUseTLS = $GRPCUseTLS; @@ -348,4 +400,94 @@ public function setDeregisterCriticalServiceAfter(string $deregisterCriticalServ $this->DeregisterCriticalServiceAfter = $deregisterCriticalServiceAfter; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ('' !== $this->CheckID) { + $out->CheckID = $this->CheckID; + } + if ('' !== $this->Name) { + $out->Name = $this->Name; + } + if ([] !== $this->ScriptArgs) { + $out->ScriptArgs = $this->ScriptArgs; + } + if ('' !== $this->DockerContainerID) { + $out->DockerContainerID = $this->DockerContainerID; + } + if ('' !== $this->Shell) { + $out->Shell = $this->Shell; + } + if ('' !== $this->Interval) { + $out->Interval = $this->Interval; + } + if ('' !== $this->Timeout) { + $out->Timeout = $this->Timeout; + } + if ('' !== $this->TTL) { + $out->TTL = $this->TTL; + } + if ('' !== $this->HTTP) { + $out->HTTP = $this->HTTP; + } + if (null !== $this->Header) { + $out->Header = $this->Header; + } + if ('' !== $this->Method) { + $out->Method = $this->Method; + } + if ('' !== $this->TCP) { + $out->TCP = $this->TCP; + } + if ('' !== $this->Status) { + $out->Status = $this->Status; + } + if ('' !== $this->Notes) { + $out->Notes = $this->Notes; + } + if ($this->TLSSkipVerify) { + $out->TLSSkipVerify = $this->TLSSkipVerify; + } + if ('' !== $this->GRPC) { + $out->GRPC = $this->GRPC; + } + if ($this->GRPCUseTLS) { + $out->GRPCUseTLS = $this->GRPCUseTLS; + } + if ('' !== $this->H2PING) { + $out->H2PING = $this->H2PING; + } + if ($this->H2PINGUseTLS) { + $out->H2PINGUseTLS = $this->H2PINGUseTLS; + } + if ('' !== $this->AliasNode) { + $out->AliasNode = $this->AliasNode; + } + if ('' !== $this->AliasService) { + $out->AliasService = $this->AliasService; + } + if (0 !== $this->SuccessBeforePassing) { + $out->SuccessBeforePassing = $this->SuccessBeforePassing; + } + if (0 !== $this->FailuresBeforeCritical) { + $out->FailuresBeforeCritical = $this->FailuresBeforeCritical; + } + if ('' !== $this->DeregisterCriticalServiceAfter) { + $out->DeregisterCriticalServiceAfter = $this->DeregisterCriticalServiceAfter; + } + return $out; + } } diff --git a/src/Agent/AgentServiceChecks.php b/src/Agent/AgentServiceChecks.php index 314f9339..78684b5d 100644 --- a/src/Agent/AgentServiceChecks.php +++ b/src/Agent/AgentServiceChecks.php @@ -21,14 +21,85 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\FakeSlice; -class AgentServiceChecks extends FakeSlice +class AgentServiceChecks implements \JsonSerializable, \Countable, \ArrayAccess { - protected string $containedClass = AgentServiceCheck::class; + /** @var \DCarbone\PHPConsulAPI\Agent\AgentServiceCheck[] */ + public array $Checks; - protected function newChild(array $data): AbstractModel + public function __construct( + iterable $Checks = [], + ) { + $this->setChecks(...$Checks); + } + + /** + * @return \DCarbone\PHPConsulAPI\Agent\AgentServiceCheck[] + */ + public function getChecks(): array + { + return $this->Checks; + } + + public function setChecks(AgentServiceCheck ...$Checks): self + { + $this->Checks = $Checks; + return $this; + } + + public function getIterator(): iterable + { + if ([] === $this->Checks) { + return new \EmptyIterator(); + } + return new \ArrayIterator($this->Checks); + } + + public function count(): int + { + return count($this->Checks); + } + + public function offsetExists(mixed $offset): bool + { + return isset($this->Checks[$offset]); + } + + public function offsetGet(mixed $offset): null|AgentServiceCheck + { + return $this->Checks[$offset] ?? null; + } + + public function offsetSet(mixed $offset, mixed $value): void + { + if (is_int($offset) && $value instanceof AgentServiceCheck) { + $this->Checks[$offset] = $value; + } else { + throw new \InvalidArgumentException(sprintf( + 'Invalid offset %s or value %s, expected int and %s.', + var_export($offset, true), + var_export($value, true), + AgentServiceCheck::class + )); + } + } + + public function offsetUnset(mixed $offset): void + { + unset($this->Checks[$offset]); + } + + public static function jsonUnserialize(array $decoded): static + { + $n = new static(); + foreach ($decoded as $v) { + $n->Checks[] = AgentServiceCheck::jsonUnserialize($v); + } + return $n; + } + + public function jsonSerialize(): array { - return new AgentServiceCheck($data); + return $this->Checks; } } diff --git a/src/Agent/AgentServiceChecksInfo.php b/src/Agent/AgentServiceChecksInfo.php index f2fb3dd6..99c377a2 100644 --- a/src/Agent/AgentServiceChecksInfo.php +++ b/src/Agent/AgentServiceChecksInfo.php @@ -22,34 +22,24 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Health\HealthChecks; -use DCarbone\PHPConsulAPI\Transcoding; class AgentServiceChecksInfo extends AbstractModel { - protected const FIELDS = [ - self::FIELD_SERVICE => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentService::class, - Transcoding::FIELD_NULLABLE => true, - ], - self::FIELD_CHECKS => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => HealthChecks::class, - ], - ]; - - private const FIELD_SERVICE = 'Service'; - private const FIELD_CHECKS = 'Checks'; - - public string $AggregatedStatus = ''; - public ?AgentService $Service = null; + public string $AggregatedStatus; + public null|AgentService $Service; public HealthChecks $Checks; - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!isset($this->Checks)) { - $this->Checks = new HealthChecks(); + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $AggregatedStatus = '', + null|AgentService $Service = null, + null|HealthChecks $Checks = null, + ) { + $this->AggregatedStatus = $AggregatedStatus; + $this->Service = $Service; + $this->Checks = $Checks ?? new HealthChecks(); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -64,12 +54,12 @@ public function setAggregatedStatus(string $AggregatedStatus): self return $this; } - public function getService(): ?AgentService + public function getService(): null|AgentService { return $this->Service; } - public function setService(?AgentService $Service): self + public function setService(null|AgentService $Service): self { $this->Service = $Service; return $this; @@ -85,6 +75,34 @@ public function setChecks(HealthChecks $Checks): self $this->Checks = $Checks; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Checks' === $k) { + $n->Checks = HealthChecks::jsonUnserialize($v); + } elseif ('Service' === $k) { + $n->Service = null === $v ? null : AgentService::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->AggregatedStatus = $this->AggregatedStatus; + $out->Service = $this->Service; + $out->Checks = $this->Checks; + return $out; + } + public function __toString(): string { return $this->AggregatedStatus; diff --git a/src/Agent/AgentServiceConnect.php b/src/Agent/AgentServiceConnect.php index 3f629e57..adce2dfd 100644 --- a/src/Agent/AgentServiceConnect.php +++ b/src/Agent/AgentServiceConnect.php @@ -21,24 +21,23 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class AgentServiceConnect extends AbstractModel { - protected const FIELDS = [ - self::FIELD_NATIVE => Transcoding::OMITEMPTY_BOOLEAN_FIELD, - self::FIELD_SIDECAR_SERVICE => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => AgentServiceRegistration::class, - Transcoding::FIELD_OMITEMPTY => true, - ], - ]; + public bool $Native; + public null|AgentServiceRegistration $SidecarService; - private const FIELD_NATIVE = 'Native'; - private const FIELD_SIDECAR_SERVICE = 'SidecarService'; - - public bool $Native = false; - public array $SidecarService = []; + public function __construct( + null|array $data = null, // Deprecated, will be removed. + bool $Native = false, + null|AgentServiceRegistration $SidecarService = null, + ) { + $this->Native = $Native; + $this->SidecarService = $SidecarService; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function isNative(): bool { @@ -51,14 +50,42 @@ public function setNative(bool $Native): self return $this; } - public function getSidecarService(): array + public function getSidecarService(): null|AgentServiceRegistration { return $this->SidecarService; } - public function setSidecarService(array $SidecarService): self + public function setSidecarService(AgentServiceRegistration $SidecarService): self { $this->SidecarService = $SidecarService; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('SidecarService' === $k) { + $n->SidecarService = AgentServiceRegistration::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ($this->Native) { + $out->Native = $this->Native; + } + if (null !== $this->SidecarService) { + $out->SidecarService = $this->SidecarService; + } + return $out; + } } diff --git a/src/Agent/AgentServiceConnectProxyConfig.php b/src/Agent/AgentServiceConnectProxyConfig.php index 0fc59582..c237081a 100644 --- a/src/Agent/AgentServiceConnectProxyConfig.php +++ b/src/Agent/AgentServiceConnectProxyConfig.php @@ -21,76 +21,84 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; +use DCarbone\PHPConsulAPI\ConfigEntry\AccessLogsConfig; +use DCarbone\PHPConsulAPI\ConfigEntry\EnvoyExtension; use DCarbone\PHPConsulAPI\ConfigEntry\ExposeConfig; use DCarbone\PHPConsulAPI\ConfigEntry\MeshGatewayConfig; -use DCarbone\PHPConsulAPI\FakeMap; -use DCarbone\PHPConsulAPI\Transcoding; +use DCarbone\PHPConsulAPI\ConfigEntry\ProxyMode; +use DCarbone\PHPConsulAPI\ConfigEntry\TransparentProxyConfig; class AgentServiceConnectProxyConfig extends AbstractModel { - protected const FIELDS = [ - self::FIELD_ENVOY_EXTENSIONS => [ - Transcoding::FIELD_CLASS => EnvoyExtension::class, - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_DESTINATION_SERVICE_NAME => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_DESTINATION_SERVICE_ID => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_LOCAL_SERVICE_ADDRESS => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_LOCAL_SERVICE_PORT => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_CONFIG => Transcoding::OMITEMPTY_MAP_FIELD, - self::FIELD_UPSTREAMS => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => Upstream::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_MESH_GATEWAY => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => MeshGatewayConfig::class, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_EXPOSE => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => ExposeConfig::class, - ], - ]; - - private const FIELD_ENVOY_EXTENSIONS = 'EnvoyExtension'; - private const FIELD_DESTINATION_SERVICE_NAME = 'DestinationServiceName'; - private const FIELD_DESTINATION_SERVICE_ID = 'DestinationServiceID'; - private const FIELD_LOCAL_SERVICE_ADDRESS = 'LocalServiceAddress'; - private const FIELD_LOCAL_SERVICE_PORT = 'LocalServicePort'; - private const FIELD_CONFIG = 'Config'; - private const FIELD_UPSTREAMS = 'Upstreams'; - private const FIELD_MESH_GATEWAY = 'MeshGateway'; - private const FIELD_EXPOSE = 'Expose'; - - public array $EnvoyExtensions = []; - public string $DestinationServiceName = ''; - public string $DestinationServiceID = ''; - public string $LocalServiceAddress = ''; - public int $LocalServicePort = 0; - public ?FakeMap $Config = null; - public string $LocalServiceSocketPath = ''; - public string $Mode = ''; - public ?TransparentProxyConfig $TransparentProxy = null; - public array $Upstreams = []; - public MeshGatewayConfig $MeshGateway; - public ExposeConfig $Expose; - - public function __construct(?array $data = []) - { - parent::__construct($data); - if (!isset($this->MeshGateway)) { - $this->MeshGateway = new MeshGatewayConfig(null); - } - if (!isset($this->Expose)) { - $this->Expose = new ExposeConfig(null); + /** @var \DCarbone\PHPConsulAPI\ConfigEntry\EnvoyExtension[] */ + public array $EnvoyExtensions; + public string $DestinationServiceName; + public string $DestinationServiceID; + public string $LocalServiceAddress; + public int $LocalServicePort; + public string $LocalServiceSocketPath; + public ProxyMode $Mode; + public null|TransparentProxyConfig $TransparentProxy; + public null|\stdClass $Config; + /** @var \DCarbone\PHPConsulAPI\Agent\Upstream[] */ + public array $Upstreams; + public null|MeshGatewayConfig $MeshGateway; + public null|ExposeConfig $Expose; + public null|AccessLogsConfig $AccessLogs; + + /** + * @param array|null $data + * @param iterable<\DCarbone\PHPConsulAPI\ConfigEntry\EnvoyExtension> $EnvoyExtensions + * @param string $DestinationServiceName + * @param string $DestinationServiceID + * @param string $LocalServiceAddress + * @param int $LocalServicePort + * @param string $LocalServiceSocketPath + * @param string|\DCarbone\PHPConsulAPI\ConfigEntry\ProxyMode $Mode + * @param \DCarbone\PHPConsulAPI\ConfigEntry\TransparentProxyConfig|null $TransparentProxy + * @param null|\stdClass $Config + * @param iterable<\DCarbone\PHPConsulAPI\Agent\Upstream> $Upstreams + * @param \DCarbone\PHPConsulAPI\ConfigEntry\MeshGatewayConfig|null $MeshGateway + * @param \DCarbone\PHPConsulAPI\ConfigEntry\ExposeConfig|null $Expose + * @param \DCarbone\PHPConsulAPI\ConfigEntry\AccessLogsConfig|null $AccessLogs + */ + public function __construct( + null|array $data = [], // Deprecated, will be removed. + iterable $EnvoyExtensions = [], + string $DestinationServiceName = '', + string $DestinationServiceID = '', + string $LocalServiceAddress = '', + int $LocalServicePort = 0, + string $LocalServiceSocketPath = '', + string|ProxyMode $Mode = ProxyMode::Default, + null|TransparentProxyConfig $TransparentProxy = null, + null|\stdClass $Config = null, + iterable $Upstreams = [], + null|MeshGatewayConfig $MeshGateway = null, + null|ExposeConfig $Expose = null, + null|AccessLogsConfig $AccessLogs = null, + ) { + $this->setEnvoyExtensions(...$EnvoyExtensions); + $this->DestinationServiceName = $DestinationServiceName; + $this->DestinationServiceID = $DestinationServiceID; + $this->LocalServiceAddress = $LocalServiceAddress; + $this->LocalServicePort = $LocalServicePort; + $this->Config = $Config; + $this->LocalServiceSocketPath = $LocalServiceSocketPath; + $this->Mode = $Mode instanceof ProxyMode ? $Mode : ProxyMode::from($Mode); + $this->TransparentProxy = $TransparentProxy; + $this->setUpstreams(...$Upstreams); + $this->MeshGateway = $MeshGateway; + $this->Expose = $Expose; + $this->AccessLogs = $AccessLogs; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } + /** + * @return \DCarbone\PHPConsulAPI\ConfigEntry\EnvoyExtension[] + */ public function getEnvoyExtensions(): array { return $this->EnvoyExtensions; @@ -102,7 +110,7 @@ public function addEnvoyExtension(EnvoyExtension $envoyExtension): self return $this; } - public function setEnvoyExtensions(array $EnvoyExtensions): self + public function setEnvoyExtensions(EnvoyExtension ...$EnvoyExtensions): self { $this->EnvoyExtensions = $EnvoyExtensions; return $this; @@ -163,69 +171,160 @@ public function setLocalServiceSocketPath(string $LocalServiceSocketPath): self return $this; } - public function getMode(): string + public function getMode(): ProxyMode { return $this->Mode; } - public function setMode(string $Mode): self + public function setMode(string|ProxyMode $Mode): self { - $this->Mode = $Mode; + $this->Mode = $Mode instanceof ProxyMode ? $Mode : ProxyMode::from($Mode); return $this; } - public function getTransparentProxy(): ?TransparentProxyConfig + public function getTransparentProxy(): null|TransparentProxyConfig { return $this->TransparentProxy; } - public function setTransparentProxy(?TransparentProxyConfig $TransparentProxy): self + public function setTransparentProxy(null|TransparentProxyConfig $TransparentProxy): self { $this->TransparentProxy = $TransparentProxy; return $this; } - public function getConfig(): ?FakeMap + public function getConfig(): null|\stdClass { return $this->Config; } - public function setConfig(array|FakeMap|\stdClass|null $Config): self + public function setConfig(null|\stdClass $Config): self { - $this->Config = FakeMap::parse($Config); + $this->Config = $Config; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\Agent\Upstream[] + */ public function getUpstreams(): array { return $this->Upstreams; } - public function setUpstreams(array $Upstreams): self + public function setUpstreams(Upstream ...$Upstreams): self { $this->Upstreams = $Upstreams; return $this; } - public function getMeshGateway(): MeshGatewayConfig + public function getMeshGateway(): null|MeshGatewayConfig { return $this->MeshGateway; } - public function setMeshGateway(MeshGatewayConfig $MeshGateway): self + public function setMeshGateway(null|MeshGatewayConfig $MeshGateway): self { $this->MeshGateway = $MeshGateway; return $this; } - public function getExpose(): ExposeConfig + public function getExpose(): null|ExposeConfig { return $this->Expose; } - public function setExpose(ExposeConfig $Expose): self + public function setExpose(null|ExposeConfig $Expose): self { $this->Expose = $Expose; return $this; } + + public function getAccessLogs(): null|AccessLogsConfig + { + return $this->AccessLogs; + } + + public function setAccessLogs(null|AccessLogsConfig $AccessLogs): self + { + $this->AccessLogs = $AccessLogs; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('EnvoyExtensions' === $k) { + foreach ($v as $vv) { + $n->EnvoyExtensions[] = EnvoyExtension::jsonUnserialize($vv); + } + } elseif ('Mode' === $k) { + $n->setMode($v); + } elseif ('TransparentProxy' === $k) { + $n->TransparentProxy = TransparentProxyConfig::jsonUnserialize($v); + } elseif ('Upstreams' === $k) { + foreach ($v as $vv) { + $n->Upstreams[] = Upstream::jsonUnserialize($vv); + } + } elseif ('MeshGateway' === $k) { + $n->MeshGateway = MeshGatewayConfig::jsonUnserialize($v); + } elseif ('Expose' === $k) { + $n->Expose = ExposeConfig::jsonUnserialize($v); + } elseif ('AccessLogs' === $k) { + $n->AccessLogs = null === $v ? null : AccessLogsConfig::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ([] !== $this->EnvoyExtensions) { + $out->EnvoyExtensions = $this->EnvoyExtensions; + } + if ('' !== $this->DestinationServiceName) { + $out->DestinationServiceName = $this->DestinationServiceName; + } + if ('' !== $this->DestinationServiceID) { + $out->DestinationServiceID = $this->DestinationServiceID; + } + if ('' !== $this->LocalServiceAddress) { + $out->LocalServiceAddress = $this->LocalServiceAddress; + } + if (0 !== $this->LocalServicePort) { + $out->LocalServicePort = $this->LocalServicePort; + } + if (null !== $this->Config) { + $out->Config = $this->Config; + } + if ('' !== $this->LocalServiceSocketPath) { + $out->LocalServiceSocketPath = $this->LocalServiceSocketPath; + } + if (ProxyMode::Default !== $this->Mode) { + $out->Mode = $this->Mode->value; + } + if (null !== $this->TransparentProxy) { + $out->TransparentProxy = $this->TransparentProxy; + } + if ([] !== $this->Upstreams) { + $out->Upstreams = $this->Upstreams; + } + if (null !== $this->MeshGateway) { + $out->MeshGateway = $this->MeshGateway; + } + if (null !== $this->Expose) { + $out->Expose = $this->Expose; + } + if (null !== $this->AccessLogs) { + $out->AccessLogs = $this->AccessLogs; + } + return $out; + } } diff --git a/src/Agent/AgentServiceRegistration.php b/src/Agent/AgentServiceRegistration.php index f565821b..e5d9772b 100644 --- a/src/Agent/AgentServiceRegistration.php +++ b/src/Agent/AgentServiceRegistration.php @@ -22,110 +22,99 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Catalog\ServiceAddress; -use DCarbone\PHPConsulAPI\HasSettableStringTags; -use DCarbone\PHPConsulAPI\HasStringTags; -use DCarbone\PHPConsulAPI\Transcoding; +use DCarbone\PHPConsulAPI\Peering\Locality; class AgentServiceRegistration extends AbstractModel { - use HasSettableStringTags; - use HasStringTags; - - protected const FIELDS = [ - self::FIELD_KIND => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_ID => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_NAME => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_PORT => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_ADDRESS => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_TAGGED_ADDRESSES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ServiceAddress::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_ENABLE_TAG_OVERRIDE => Transcoding::OMITEMPTY_BOOLEAN_FIELD, - self::FIELD_META => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::MIXED, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_WEIGHTS => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentWeights::class, - Transcoding::FIELD_NULLABLE => true, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_CHECK => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentServiceCheck::class, - Transcoding::FIELD_NULLABLE => true, - ], - self::FIELD_CHECKS => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => AgentServiceChecks::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - ], - self::FIELD_PROXY => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentServiceConnectProxyConfig::class, - Transcoding::FIELD_NULLABLE => true, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_CONNECT => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentServiceConnect::class, - Transcoding::FIELD_NULLABLE => true, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_KIND = 'Kind'; - private const FIELD_ID = 'ID'; - private const FIELD_NAME = 'Name'; - private const FIELD_PORT = 'Port'; - private const FIELD_ADDRESS = 'Address'; - private const FIELD_TAGGED_ADDRESSES = 'TaggedAddresses'; - private const FIELD_ENABLE_TAG_OVERRIDE = 'EnableTagOverride'; - private const FIELD_META = 'Meta'; - private const FIELD_WEIGHTS = 'Weights'; - private const FIELD_CHECK = 'Check'; - private const FIELD_CHECKS = 'Checks'; - private const FIELD_PROXY = 'Proxy'; - private const FIELD_CONNECT = 'Connect'; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $Kind = ''; - public string $ID = ''; - public string $Name = ''; - public int $Port = 0; - public string $Address = ''; - public array $TaggedAddresses = []; - public bool $EnableTagOverride = false; - public array $Meta = []; - public ?AgentWeights $Weights = null; - public ?AgentServiceCheck $Check = null; + public ServiceKind $Kind; + public string $ID; + public string $Name; + /** @var string[] */ + public array $Tags; + public int $Port; + public string $Address; + public null|\stdClass $TaggedAddresses; + public bool $EnableTagOverride; + public null|\stdClass $Meta; + public null|AgentWeights $Weights; + public null|AgentServiceCheck $Check; public AgentServiceChecks $Checks; - public ?AgentServiceConnectProxyConfig $Proxy = null; - public ?AgentServiceConnect $Connect = null; - public string $Namespace = ''; - - public function __construct(?array $data = []) - { - parent::__construct($data); - if (!isset($this->Checks)) { - $this->Checks = new AgentServiceChecks(null); + public null|AgentServiceConnectProxyConfig $Proxy; + public null|AgentServiceConnect $Connect; + public string $Namespace; + public string $Partition; + public null|Locality $Locality; + + /** + * @param array|null $data + * @param string|\DCarbone\PHPConsulAPI\Agent\ServiceKind $Kind + * @param string $ID + * @param string $Name + * @param iterable $Tags + * @param int $Port + * @param string $Address + * @param \stdClass|null $TaggedAddresses + * @param bool $EnableTagOverride + * @param \stdClass|null $Meta + * @param \DCarbone\PHPConsulAPI\Agent\AgentWeights|null $Weights + * @param \DCarbone\PHPConsulAPI\Agent\AgentServiceCheck|null $Check + * @param \DCarbone\PHPConsulAPI\Agent\AgentServiceChecks|null $Checks + * @param \DCarbone\PHPConsulAPI\Agent\AgentServiceConnectProxyConfig|null $Proxy + * @param \DCarbone\PHPConsulAPI\Agent\AgentServiceConnect|null $Connect + * @param string $Namespace + * @param string $Partition + * @param \DCarbone\PHPConsulAPI\Peering\Locality|null $Locality + */ + public function __construct( + null|array $data = null, + string|ServiceKind $Kind = ServiceKind::Typical, + string $ID = '', + string $Name = '', + iterable $Tags = [], + int $Port = 0, + string $Address = '', + null|\stdClass $TaggedAddresses = null, + bool $EnableTagOverride = false, + null|\stdClass $Meta = null, + null|AgentWeights $Weights = null, + null|AgentServiceCheck $Check = null, + null|AgentServiceChecks $Checks = null, + null|AgentServiceConnectProxyConfig $Proxy = null, + null|AgentServiceConnect $Connect = null, + string $Namespace = '', + string $Partition = '', + null|Locality $Locality = null, + ) { + $this->setKind($Kind); + $this->ID = $ID; + $this->Name = $Name; + $this->setTags(...$Tags); + $this->Port = $Port; + $this->Address = $Address; + $this->setTaggedAddresses($TaggedAddresses); + $this->EnableTagOverride = $EnableTagOverride; + $this->Meta = $Meta; + $this->Weights = $Weights; + $this->Check = $Check; + $this->Checks = $Checks ?? new AgentServiceChecks(); + $this->Proxy = $Proxy; + $this->Connect = $Connect; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + $this->Locality = $Locality; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } - public function getKind(): string + public function getKind(): ServiceKind { return $this->Kind; } - public function setKind(string $Kind): self + public function setKind(string|ServiceKind $Kind): self { - $this->Kind = $Kind; + $this->Kind = $Kind instanceof ServiceKind ? $Kind : ServiceKind::from($Kind); return $this; } @@ -151,6 +140,20 @@ public function setName(string $Name): self return $this; } + /** + * @return string[] + */ + public function getTags(): array + { + return $this->Tags; + } + + public function setTags(string ...$Tags): self + { + $this->Tags = $Tags; + return $this; + } + public function getPort(): int { return $this->Port; @@ -173,14 +176,21 @@ public function setAddress(string $Address): self return $this; } - public function getTaggedAddresses(): ?array + public function getTaggedAddresses(): \stdClass { return $this->TaggedAddresses; } - public function setTaggedAddresses(array $TaggedAddresses): self + public function setTaggedAddresses(null|\stdClass $TaggedAddresses): self { - $this->TaggedAddresses = $TaggedAddresses; + if (null === $TaggedAddresses) { + $this->TaggedAddresses = null; + return $this; + } + $this->TaggedAddresses = new \stdClass(); + foreach ($TaggedAddresses as $k => $v) { + $this->TaggedAddresses->{$k} = $v instanceof ServiceAddress ? $v : ServiceAddress::jsonUnserialize((object)$v); + } return $this; } @@ -195,34 +205,34 @@ public function setEnableTagOverride(bool $EnableTagOverride): self return $this; } - public function getMeta(): ?array + public function getMeta(): null|\stdClass { return $this->Meta; } - public function setMeta(array $Meta): self + public function setMeta(null|\stdClass $Meta): self { $this->Meta = $Meta; return $this; } - public function getWeights(): ?AgentWeights + public function getWeights(): null|AgentWeights { return $this->Weights; } - public function setWeights(?AgentWeights $Weights): self + public function setWeights(null|AgentWeights $Weights): self { $this->Weights = $Weights; return $this; } - public function getCheck(): ?AgentServiceCheck + public function getCheck(): null|AgentServiceCheck { return $this->Check; } - public function setCheck(?AgentServiceCheck $Check): self + public function setCheck(null|AgentServiceCheck $Check): self { $this->Check = $Check; return $this; @@ -239,23 +249,23 @@ public function setChecks(AgentServiceChecks $Checks): self return $this; } - public function getProxy(): ?AgentServiceConnectProxyConfig + public function getProxy(): null|AgentServiceConnectProxyConfig { return $this->Proxy; } - public function setProxy(?AgentServiceConnectProxyConfig $Proxy): self + public function setProxy(null|AgentServiceConnectProxyConfig $Proxy): self { $this->Proxy = $Proxy; return $this; } - public function getConnect(): ?AgentServiceConnect + public function getConnect(): null|AgentServiceConnect { return $this->Connect; } - public function setConnect(?AgentServiceConnect $Connect): self + public function setConnect(null|AgentServiceConnect $Connect): self { $this->Connect = $Connect; return $this; @@ -271,6 +281,114 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public function getLocality(): null|Locality + { + return $this->Locality; + } + + public function setLocality(null|Locality $Locality): self + { + $this->Locality = $Locality; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Kind' === $k) { + $n->setKind($v); + } elseif ('Tags' === $k) { + $n->setTags(...$v); + } elseif ('TaggedAddresses' === $k) { + $n->setTaggedAddresses($v); + } elseif ('Weights' === $k) { + $n->Weights = AgentWeights::jsonUnserialize($v); + } elseif ('Check' === $k) { + $n->Check = AgentServiceCheck::jsonUnserialize($v); + } elseif ('Checks' === $k) { + $n->Checks = AgentServiceChecks::jsonUnserialize($v); + } elseif ('Proxy' === $k) { + $n->Proxy = AgentServiceConnectProxyConfig::jsonUnserialize($v); + } elseif ('Connect' === $k) { + $n->Connect = AgentServiceConnect::jsonUnserialize($v); + } elseif ('Locality' === $k) { + $n->Locality = Locality::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ($this->Kind !== ServiceKind::Typical) { + $out->Kind = $this->Kind; + } + if ('' !== $this->ID) { + $out->ID = $this->ID; + } + if ('' !== $this->Name) { + $out->Name = $this->Name; + } + if ([] !== $this->Tags) { + $out->Tags = $this->Tags; + } + if (0 !== $this->Port) { + $out->Port = $this->Port; + } + if ('' !== $this->Address) { + $out->Address = $this->Address; + } + if (null !== $this->TaggedAddresses) { + $out->TaggedAddresses = $this->TaggedAddresses; + } + if ($this->EnableTagOverride) { + $out->EnableTagOverride = $this->EnableTagOverride; + } + if (null !== $this->Meta) { + $out->Meta = $this->Meta; + } + if (null !== $this->Weights) { + $out->Weights = $this->Weights; + } + $out->Check = $this->Check; + $out->Checks = $this->Checks; + if (null !== $this->Proxy) { + $out->Proxy = $this->Proxy; + } + if (null !== $this->Connect) { + $out->Connect = $this->Connect; + } + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + if (null !== $this->Locality) { + $out->Locality = $this->Locality; + } + return $out; + } + public function __toString(): string { return $this->Name; diff --git a/src/Agent/AgentServiceResponse.php b/src/Agent/AgentServiceResponse.php index 35e871ad..49d31f14 100644 --- a/src/Agent/AgentServiceResponse.php +++ b/src/Agent/AgentServiceResponse.php @@ -25,15 +25,19 @@ class AgentServiceResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?AgentService $Service = null; + public null|AgentService $Service = null; - public function getValue(): ?AgentService + public function getValue(): null|AgentService { return $this->Service; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->Service = new AgentService((array)$decodedData); + if (null === $decoded) { + $this->Service = null; + return; + } + $this->Service = AgentService::jsonUnserialize($decoded); } } diff --git a/src/Agent/AgentServicesResponse.php b/src/Agent/AgentServicesResponse.php index 2d559cbb..852a88bb 100644 --- a/src/Agent/AgentServicesResponse.php +++ b/src/Agent/AgentServicesResponse.php @@ -25,18 +25,22 @@ class AgentServicesResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?array $Services = null; + public null|\stdClass $Services = null; - public function getValue(): ?array + public function getValue(): null|\stdClass { return $this->Services; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->Services = []; - foreach ($decodedData as $k => $service) { - $this->Services[$k] = new AgentService($service); + if (null === $decoded) { + $this->Services = null; + return; + } + $this->Services = new \stdClass(); + foreach ($decoded as $k => $v) { + $this->Services->{$k} = AgentService::jsonUnserialize($v); } } } diff --git a/src/Agent/AgentToken.php b/src/Agent/AgentToken.php index 4f95dba6..b151fc35 100644 --- a/src/Agent/AgentToken.php +++ b/src/Agent/AgentToken.php @@ -24,7 +24,17 @@ class AgentToken extends AbstractModel { - public string $Token = ''; + public string $Token; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Token = '', + ) { + $this->Token = $Token; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getToken(): string { @@ -36,4 +46,23 @@ public function setToken(string $Token): self $this->Token = $Token; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Token = $this->Token; + return $out; + } } diff --git a/src/Agent/AgentWeights.php b/src/Agent/AgentWeights.php index 19dcb0b4..ecf7d2d9 100644 --- a/src/Agent/AgentWeights.php +++ b/src/Agent/AgentWeights.php @@ -24,8 +24,20 @@ class AgentWeights extends AbstractModel { - public int $Passing = 0; - public int $Warning = 0; + public int $Passing; + public int $Warning; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + int $Passing = 0, + int $Warning = 0, + ) { + $this->Passing = $Passing; + $this->Warning = $Warning; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getPassing(): int { @@ -36,4 +48,24 @@ public function getWarning(): int { return $this->Warning; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Passing = $this->Passing; + $out->Warning = $this->Warning; + return $out; + } } diff --git a/src/Agent/ConnectProxyConfig.php b/src/Agent/ConnectProxyConfig.php new file mode 100644 index 00000000..786ecd2b --- /dev/null +++ b/src/Agent/ConnectProxyConfig.php @@ -0,0 +1,164 @@ + */ + public array $Upstreams; + + /** + * @param array|null $data // Deprecated, will be removed. + * @param string $ProxyServiceID + * @param string $TargetServiceID + * @param string $TargetServiceName + * @param string $ContentHash + * @param \stdClass|null $Config + * @param array<\DCarbone\PHPConsulAPI\Agent\Upstream> $Upstreams + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ProxyServiceID = '', + string $TargetServiceID = '', + string $TargetServiceName = '', + string $ContentHash = '', + null|\stdClass $Config = null, + array $Upstreams = [], + ) { + $this->ProxyServiceID = $ProxyServiceID; + $this->TargetServiceID = $TargetServiceID; + $this->TargetServiceName = $TargetServiceName; + $this->ContentHash = $ContentHash; + $this->Config = $Config; + $this->setUpstreams(...$Upstreams); + + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } + + public function getProxyServiceID(): string + { + return $this->ProxyServiceID; + } + + public function setProxyServiceID(string $ProxyServiceID): self + { + $this->ProxyServiceID = $ProxyServiceID; + return $this; + } + + public function getTargetServiceID(): string + { + return $this->TargetServiceID; + } + + public function setTargetServiceID(string $TargetServiceID): self + { + $this->TargetServiceID = $TargetServiceID; + return $this; + } + + public function getTargetServiceName(): string + { + return $this->TargetServiceName; + } + + public function setTargetServiceName(string $TargetServiceName): self + { + $this->TargetServiceName = $TargetServiceName; + return $this; + } + + public function getContentHash(): string + { + return $this->ContentHash; + } + + public function setContentHash(string $ContentHash): self + { + $this->ContentHash = $ContentHash; + return $this; + } + + public function getConfig(): null|\stdClass + { + return $this->Config; + } + + public function setConfig(?\stdClass $Config): self + { + $this->Config = $Config; + return $this; + } + + /** + * @return \DCarbone\PHPConsulAPI\Agent\Upstream[] + */ + public function getUpstreams(): array + { + return $this->Upstreams; + } + + public function setUpstreams(Upstream ...$Upstreams): self + { + $this->Upstreams = $Upstreams; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Upstreams' === $k) { + $n->Upstreams = []; + foreach ($v as $vv) { + $n->Upstreams[] = Upstream::jsonUnserialize($vv); + } + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ProxyServiceID = $this->ProxyServiceID; + $out->TargetServiceID = $this->TargetServiceID; + $out->TargetServiceName = $this->TargetServiceName; + $out->ContentHash = $this->ContentHash; + $out->Config = $this->Config; + $out->Upstreams = $this->Upstreams; + return $out; + } +} diff --git a/src/Agent/GaugeValue.php b/src/Agent/GaugeValue.php index e1ec1a6b..89ce37d0 100644 --- a/src/Agent/GaugeValue.php +++ b/src/Agent/GaugeValue.php @@ -24,9 +24,29 @@ class GaugeValue extends AbstractModel { - public string $Name = ''; - public float $Value = 0.0; - public array $Labels = []; + public string $Name; + public float $Value; + public null|\stdClass $Labels; + + /** + * @param array|null $data + * @param string $Name + * @param float $Value + * @param \stdClass|null $Labels + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Name = '', + float $Value = 0.0, + null|\stdClass $Labels = null, + ) { + $this->Name = $Name; + $this->Value = $Value; + $this->Labels = $Labels; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getName(): string { @@ -50,14 +70,35 @@ public function setValue(float $value): self return $this; } - public function getLabels(): array + public function getLabels(): null|\stdClass { return $this->Labels; } - public function setLabels(array $labels): self + public function setLabels(null|\stdClass $Labels): self { - $this->Labels = $labels; + $this->Labels = $Labels; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + $out->Value = $this->Value; + $out->Labels = $this->Labels; + return $out; + } } diff --git a/src/Agent/MemberACLMode.php b/src/Agent/MemberACLMode.php new file mode 100644 index 00000000..0d0e9607 --- /dev/null +++ b/src/Agent/MemberACLMode.php @@ -0,0 +1,47 @@ +WAN = $WAN; + $this->Segment = $Segment; + $this->Filter = $Filter; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function isWAN(): bool { @@ -48,4 +63,31 @@ public function setSegment(string $segment): self $this->Segment = $segment; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ($this->WAN) { + $out->WAN = $this->WAN; + } + if ('' !== $this->Segment) { + $out->Segment = $this->Segment; + } + if ('' !== $this->Filter) { + $out->Filter = $this->Filter; + } + return $out; + } } diff --git a/src/Agent/MetricsInfo.php b/src/Agent/MetricsInfo.php index d580ab99..b65eecaa 100644 --- a/src/Agent/MetricsInfo.php +++ b/src/Agent/MetricsInfo.php @@ -21,43 +21,36 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class MetricsInfo extends AbstractModel { - protected const FIELDS = [ - self::FIELD_GAUGES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => GaugeValue::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - ], - self::FIELD_POINTS => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => PointValue::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - ], - self::FIELD_COUNTERS => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => SampledValue::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - ], - self::FIELD_SAMPLES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => SampledValue::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - ], - ]; - - private const FIELD_GAUGES = 'Gauges'; - private const FIELD_POINTS = 'Points'; - private const FIELD_COUNTERS = 'Counters'; - private const FIELD_SAMPLES = 'Samples'; - - public string $Timestamp = ''; - public array $Gauges = []; - public array $Points = []; - public array $Counters = []; - public array $Samples = []; + public string $Timestamp; + /** @var \DCarbone\PHPConsulAPI\Agent\GaugeValue[] */ + public array $Gauges; + /** @var \DCarbone\PHPConsulAPI\Agent\PointValue[] */ + public array $Points; + /** @var \DCarbone\PHPConsulAPI\Agent\SampledValue[] */ + public array $Counters; + /** @var \DCarbone\PHPConsulAPI\Agent\SampledValue[] */ + public array $Samples; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Timestamp = '', + iterable $Gauges = [], + iterable $Points = [], + iterable $Counters = [], + iterable $Samples = [], + ) { + $this->Timestamp = $Timestamp; + $this->setGauges(...$Gauges); + $this->setPoints(...$Points); + $this->setCounters(...$Counters); + $this->setSamples(...$Samples); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getTimestamp(): string { @@ -70,47 +63,100 @@ public function setTimestamp(string $timestamp): self return $this; } + /** + * @return \DCarbone\PHPConsulAPI\Agent\GaugeValue[] + */ public function getGauges(): array { return $this->Gauges; } - public function setGauges(array $gauges): self + public function setGauges(GaugeValue ...$gauges): self { $this->Gauges = $gauges; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\Agent\PointValue[] + */ public function getPoints(): array { return $this->Points; } - public function setPoints(array $points): self + public function setPoints(PointValue ...$points): self { $this->Points = $points; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\Agent\SampledValue[] + */ public function getCounters(): array { return $this->Counters; } - public function setCounters(array $counters): self + public function setCounters(SampledValue ...$counters): self { $this->Counters = $counters; return $this; } + /** + * @return \DCarbone\PHPConsulAPI\Agent\SampledValue[] + */ public function getSamples(): array { return $this->Samples; } - public function setSamples(array $samples): self + public function setSamples(SampledValue ...$samples): self { $this->Samples = $samples; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Gauges' === $k) { + foreach ($v as $vv) { + $n->Gauges[] = GaugeValue::jsonUnserialize($vv); + } + } elseif ('Points' === $k) { + foreach ($v as $vv) { + $n->Points[] = PointValue::jsonUnserialize($vv); + } + } elseif ('Counters' === $k) { + foreach ($v as $vv) { + $n->Counters[] = SampledValue::jsonUnserialize($vv); + } + } elseif ('Samples' === $k) { + foreach ($v as $vv) { + $n->Samples[] = SampledValue::jsonUnserialize($vv); + } + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Timestamp = $this->Timestamp; + $out->Gauges = $this->Gauges; + $out->Points = $this->Points; + $out->Counters = $this->Counters; + $out->Samples = $this->Samples; + return $out; + } } diff --git a/src/Agent/MetricsInfoResponse.php b/src/Agent/MetricsInfoResponse.php index da7e1ed9..82fbe9f7 100644 --- a/src/Agent/MetricsInfoResponse.php +++ b/src/Agent/MetricsInfoResponse.php @@ -25,15 +25,19 @@ class MetricsInfoResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?MetricsInfo $MetricsInfo = null; + public null|MetricsInfo $MetricsInfo = null; - public function getValue(): ?MetricsInfo + public function getValue(): null|MetricsInfo { return $this->MetricsInfo; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->MetricsInfo = new MetricsInfo((array)$decodedData); + if (null === $decoded) { + $this->MetricsInfo = null; + return; + } + $this->MetricsInfo = MetricsInfo::jsonUnserialize($decoded); } } diff --git a/src/Agent/PointValue.php b/src/Agent/PointValue.php index 00cd83fa..2b1d8948 100644 --- a/src/Agent/PointValue.php +++ b/src/Agent/PointValue.php @@ -24,8 +24,21 @@ class PointValue extends AbstractModel { - public string $Name = ''; - public array $Points = []; + public string $Name; + /** @var float[] */ + public array $Points; + + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Name = '', + iterable $Points = [], + ) { + $this->Name = $Name; + $this->setPoints(...$Points); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getName(): string { @@ -38,14 +51,37 @@ public function setName(string $name): self return $this; } + /** + * @return float[] + */ public function getPoints(): array { return $this->Points; } - public function setPoints(array $points): self + public function setPoints(float ...$points): self { $this->Points = $points; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + $out->Points = $this->Points; + return $out; + } } diff --git a/src/Agent/SampledValue.php b/src/Agent/SampledValue.php index 9c177c95..2e02725e 100644 --- a/src/Agent/SampledValue.php +++ b/src/Agent/SampledValue.php @@ -24,14 +24,49 @@ class SampledValue extends AbstractModel { - public string $Name = ''; - public int $Count = 0; - public float $Sum = 0.0; - public float $Min = 0.0; - public float $Max = 0.0; - public float $Mean = 0.0; - public float $Stddev = 0.0; - public array $Labels = []; + public string $Name; + public int $Count; + public float $Sum; + public float $Min; + public float $Max; + public float $Mean; + public float $Stddev; + public null|\stdClass $Labels; + + /** + * @param array|null $data Deprecated, will be removed. + * @param string $Name + * @param int $Count + * @param float $Sum + * @param float $Min + * @param float $Max + * @param float $Mean + * @param float $Stddev + * @param \stdClass|null $Labels + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Name = '', + int $Count = 0, + float $Sum = 0.0, + float $Min = 0.0, + float $Max = 0.0, + float $Mean = 0.0, + float $Stddev = 0.0, + null|\stdClass $Labels = null, + ) { + $this->Name = $Name; + $this->Count = $Count; + $this->Sum = $Sum; + $this->Min = $Min; + $this->Max = $Max; + $this->Mean = $Mean; + $this->Stddev = $Stddev; + $this->Labels = $Labels ?? new \stdClass(); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getName(): string { @@ -104,20 +139,46 @@ public function getStddev(): float return $this->Stddev; } - public function setStddev(float $Stddev): self + public function setStddev(float $stddev): self { - $this->Stddev = $Stddev; + $this->Stddev = $stddev; return $this; } - public function getLabels(): array + public function getLabels(): null|\stdClass { return $this->Labels; } - public function setLabels(array $labels): self + public function setLabels(null|\stdClass $labels): self { - $this->Labels = $labels; + $this->Labels = $labels ?? new \stdClass(); return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + $out->Count = $this->Count; + $out->Sum = $this->Sum; + $out->Min = $this->Min; + $out->Max = $this->Max; + $out->Mean = $this->Mean; + $out->Stddev = $this->Stddev; + $out->Labels = $this->Labels; + return $out; + } } diff --git a/src/Agent/ServiceKind.php b/src/Agent/ServiceKind.php new file mode 100644 index 00000000..08c57c6c --- /dev/null +++ b/src/Agent/ServiceKind.php @@ -0,0 +1,66 @@ +ReplaceExistingChecks = $ReplaceExistingChecks; + $this->Token = $Token; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function isReplaceExistingChecks(): bool { @@ -36,4 +49,35 @@ public function setReplaceExistingChecks(bool $replaceExistingChecks): self $this->ReplaceExistingChecks = $replaceExistingChecks; return $this; } + + public function getToken(): string + { + return $this->Token; + } + + public function setToken(string $Token): ServiceRegisterOpts + { + $this->Token = $Token; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ReplaceExistingChecks = $this->ReplaceExistingChecks; + $out->Token = $this->Token; + return $out; + } } diff --git a/src/Agent/Upstream.php b/src/Agent/Upstream.php index 96672596..122cfd53 100644 --- a/src/Agent/Upstream.php +++ b/src/Agent/Upstream.php @@ -22,61 +22,76 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\ConfigEntry\MeshGatewayConfig; -use DCarbone\PHPConsulAPI\Transcoding; class Upstream extends AbstractModel { - protected const FIELDS = [ - self::FIELD_DESTINATION_TYPE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_DESTINATION_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_DATACENTER => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_LOCAL_BIND_ADDRESS => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_LOCAL_BIND_PORT => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_CONFIG => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::MIXED, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_MESH_GATEWAY => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => MeshGatewayConfig::class, - Transcoding::FIELD_OMITEMPTY => true, - ], - ]; - - private const FIELD_DESTINATION_TYPE = 'DestinationType'; - private const FIELD_DESTINATION_NAMESPACE = 'DestinationNamespace'; - private const FIELD_DATACENTER = 'Datacenter'; - private const FIELD_LOCAL_BIND_ADDRESS = 'LocalBindAddress'; - private const FIELD_LOCAL_BIND_PORT = 'LocalBindPort'; - private const FIELD_CONFIG = 'Config'; - private const FIELD_MESH_GATEWAY = 'MeshGateway'; - - public string $DestinationType = ''; - public string $DestinationNamespace = ''; - public string $DestinationName = ''; - public string $Datacenter = ''; - public string $LocalBindAddress = ''; - public int $LocalBindPort = 0; - public array $Config = []; - public MeshGatewayConfig $MeshGatewayConfig; - - public function __construct(?array $data = []) - { - parent::__construct($data); - if (!isset($this->MeshGatewayConfig)) { - $this->MeshGatewayConfig = new MeshGatewayConfig(null); + public UpstreamDestType $DestinationType; + public string $DestinationPartition; + public string $DestinationNamespace; + public string $DestinationPeer; + public string $DestinationName; + public string $Datacenter; + public string $LocalBindAddress; + public int $LocalBindPort; + public string $LocalBindSocketPath; + public string $LocalBindSocketMode; + public null|\stdClass $Config; + public null|MeshGatewayConfig $MeshGateway; + public bool $CentrallyConfigured; + + public function __construct( + null|array $data = [], // Deprecated, will be removed. + string|UpstreamDestType $DestinationType = UpstreamDestType::UNDEFINED, + string $DestinationPartition = '', + string $DestinationNamespace = '', + string $DestinationPeer = '', + string $DestinationName = '', + string $Datacenter = '', + string $LocalBindAddress = '', + int $LocalBindPort = 0, + string $LocalBindSocketPath = '', + string $LocalBindSocketMode = '', + null|\stdClass $Config = null, + null|MeshGatewayConfig $MeshGateway = null, + bool $CentrallyConfigured = false, + ) { + $this->setDestinationType($DestinationType); + $this->DestinationPartition = $DestinationPartition; + $this->DestinationNamespace = $DestinationNamespace; + $this->DestinationPeer = $DestinationPeer; + $this->DestinationName = $DestinationName; + $this->Datacenter = $Datacenter; + $this->LocalBindAddress = $LocalBindAddress; + $this->LocalBindPort = $LocalBindPort; + $this->LocalBindSocketPath = $LocalBindSocketPath; + $this->LocalBindSocketMode = $LocalBindSocketMode; + $this->Config = $Config; + $this->MeshGateway = $MeshGateway; + $this->CentrallyConfigured = $CentrallyConfigured; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } - public function getDestinationType(): string + public function getDestinationType(): UpstreamDestType { return $this->DestinationType; } - public function setDestinationType(string $DestinationType): self + public function setDestinationType(string|UpstreamDestType $DestinationType): self + { + $this->DestinationType = $DestinationType instanceof UpstreamDestType ? $DestinationType : UpstreamDestType::from($DestinationType); + return $this; + } + + public function getDestinationPartition(): string + { + return $this->DestinationPartition; + } + + public function setDestinationPartition(string $DestinationPartition): self { - $this->DestinationType = $DestinationType; + $this->DestinationPartition = $DestinationPartition; return $this; } @@ -91,6 +106,17 @@ public function setDestinationNamespace(string $DestinationNamespace): self return $this; } + public function getDestinationPeer(): string + { + return $this->DestinationPeer; + } + + public function setDestinationPeer(string $DestinationPeer): self + { + $this->DestinationPeer = $DestinationPeer; + return $this; + } + public function getDestinationName(): string { return $this->DestinationName; @@ -135,25 +161,119 @@ public function setLocalBindPort(int $LocalBindPort): self return $this; } - public function getConfig(): array + public function getLocalBindSocketPath(): string + { + return $this->LocalBindSocketPath; + } + + public function setLocalBindSocketPath(string $LocalBindSocketPath): self + { + $this->LocalBindSocketPath = $LocalBindSocketPath; + return $this; + } + + public function getLocalBindSocketMode(): string + { + return $this->LocalBindSocketMode; + } + + public function setLocalBindSocketMode(string $LocalBindSocketMode): self + { + $this->LocalBindSocketMode = $LocalBindSocketMode; + return $this; + } + + public function getConfig(): null|\stdClass { return $this->Config; } - public function setConfig(array $Config): self + public function setConfig(null|\stdClass $Config): self { $this->Config = $Config; return $this; } - public function getMeshGatewayConfig(): MeshGatewayConfig + public function getMeshGateway(): null|MeshGatewayConfig + { + return $this->MeshGateway; + } + + public function setMeshGateway(null|MeshGatewayConfig $MeshGateway): self + { + $this->MeshGateway = $MeshGateway; + return $this; + } + + public function isCentrallyConfigured(): bool { - return $this->MeshGatewayConfig; + return $this->CentrallyConfigured; } - public function setMeshGatewayConfig(MeshGatewayConfig $MeshGatewayConfig): self + public function setCentrallyConfigured(bool $CentrallyConfigured): self { - $this->MeshGatewayConfig = $MeshGatewayConfig; + $this->CentrallyConfigured = $CentrallyConfigured; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('DestinationType' === $k) { + $n->setDestinationType($v); + } elseif ('MeshGateway' === $k) { + $n->MeshGateway = MeshGatewayConfig::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ($this->DestinationType !== UpstreamDestType::UNDEFINED) { + $out->DestinationType = $this->DestinationType; + } + if ('' !== $this->DestinationPartition) { + $out->DestinationPartition = $this->DestinationPartition; + } + if ('' !== $this->DestinationNamespace) { + $out->DestinationNamespace = $this->DestinationNamespace; + } + if ('' !== $this->DestinationPeer) { + $out->DestinationPeer = $this->DestinationPeer; + } + $out->DestinationName = $this->DestinationName; + if ('' !== $this->Datacenter) { + $out->Datacenter = $this->Datacenter; + } + if ('' !== $this->LocalBindAddress) { + $out->LocalBindAddress = $this->LocalBindAddress; + } + if (0 !== $this->LocalBindPort) { + $out->LocalBindPort = $this->LocalBindPort; + } + if ('' !== $this->LocalBindSocketPath) { + $out->LocalBindSocketPath = $this->LocalBindSocketPath; + } + if ('' !== $this->LocalBindSocketMode) { + $out->LocalBindSocketMode = $this->LocalBindSocketMode; + } + if (null !== $this->Config) { + $out->Config = $this->Config; + } + if (null !== $this->MeshGateway) { + $out->MeshGateway = $this->MeshGateway; + } + if ($this->CentrallyConfigured) { + $out->CentrallyConfigured = $this->CentrallyConfigured; + } + return $out; + } } diff --git a/src/Agent/TransparentProxyConfig.php b/src/Agent/UpstreamDestType.php similarity index 59% rename from src/Agent/TransparentProxyConfig.php rename to src/Agent/UpstreamDestType.php index eab35eb2..856ccef2 100644 --- a/src/Agent/TransparentProxyConfig.php +++ b/src/Agent/UpstreamDestType.php @@ -20,21 +20,15 @@ limitations under the License. */ -use DCarbone\PHPConsulAPI\AbstractModel; - -class TransparentProxyConfig extends AbstractModel +enum UpstreamDestType: string { - public int $OutboundListenerPort = 0; - public bool $DialedDirectly = false; - - public function getOutboundListenerPort(): int - { - return $this->OutboundListenerPort; - } - - public function setOutboundListenerPort(int $OutboundListenerPort): TransparentProxyConfig - { - $this->OutboundListenerPort = $OutboundListenerPort; - return $this; - } + // Service discovers instances via healthy service lookup. + case Service = 'service'; + + // PreparedQuery discovers instances via prepared query + // execution. + case PreparedQuery = 'prepared_query'; + + // Default case for when value is not set. + case UNDEFINED = ''; } diff --git a/src/Catalog/CatalogClient.php b/src/Catalog/CatalogClient.php index c778c499..8bce4c74 100644 --- a/src/Catalog/CatalogClient.php +++ b/src/Catalog/CatalogClient.php @@ -29,12 +29,12 @@ class CatalogClient extends AbstractClient { - public function Register(CatalogRegistration $catalogRegistration, ?WriteOptions $opts = null): WriteResponse + public function Register(CatalogRegistration $catalogRegistration, null|WriteOptions $opts = null): WriteResponse { return $this->_executePut('v1/catalog/register', $catalogRegistration, $opts); } - public function Deregister(CatalogDeregistration $catalogDeregistration, ?WriteOptions $opts = null): WriteResponse + public function Deregister(CatalogDeregistration $catalogDeregistration, null|WriteOptions $opts = null): WriteResponse { return $this->_executePut('v1/catalog/deregister', $catalogDeregistration, $opts); } @@ -47,7 +47,7 @@ public function Datacenters(): ValuedStringsResponse return $ret; } - public function Nodes(?QueryOptions $opts = null): NodesResponse + public function Nodes(null|QueryOptions $opts = null): NodesResponse { $resp = $this->_requireOK($this->_doGet('v1/catalog/nodes', $opts)); $ret = new NodesResponse(); @@ -55,7 +55,7 @@ public function Nodes(?QueryOptions $opts = null): NodesResponse return $ret; } - public function Services(?QueryOptions $opts = null): ValuedQueryStringsResponse + public function Services(null|QueryOptions $opts = null): ValuedQueryStringsResponse { $resp = $this->_requireOK($this->_doGet('v1/catalog/services', $opts)); $ret = new ValuedQueryStringsResponse(); @@ -63,7 +63,7 @@ public function Services(?QueryOptions $opts = null): ValuedQueryStringsResponse return $ret; } - public function NodeServicesList(string $node, ?QueryOptions $opts = null): CatalogNodeServicesListResponse + public function NodeServicesList(string $node, null|QueryOptions $opts = null): CatalogNodeServicesListResponse { $resp = $this->_requireOK($this->_doGet(sprintf('v1/catalog/node-services/%s', urlencode($node)), $opts)); $ret = new CatalogNodeServicesListResponse(); @@ -74,7 +74,7 @@ public function NodeServicesList(string $node, ?QueryOptions $opts = null): Cata public function ServiceMultipleTags( string $service, array $tags, - ?QueryOptions $opts = null + null|QueryOptions $opts = null ): CatalogServicesResponse { $r = $this->_newGetRequest(sprintf('v1/catalog/service/%s', $service), $opts); if ([] !== $tags) { @@ -86,12 +86,12 @@ public function ServiceMultipleTags( return $ret; } - public function Service(string $service, string $tag = '', ?QueryOptions $opts = null): CatalogServicesResponse + public function Service(string $service, string $tag = '', null|QueryOptions $opts = null): CatalogServicesResponse { return $this->ServiceMultipleTags($service, '' !== $tag ? [$tag] : [], $opts); } - public function Node(string $node, ?QueryOptions $opts = null): CatalogNodeResponse + public function Node(string $node, null|QueryOptions $opts = null): CatalogNodeResponse { $resp = $this->_requireOK($this->_doGet(sprintf('v1/catalog/node/%s', $node), $opts)); $ret = new CatalogNodeResponse(); @@ -99,7 +99,7 @@ public function Node(string $node, ?QueryOptions $opts = null): CatalogNodeRespo return $ret; } - public function GatewayServices(string $gateway, ?QueryOptions $opts = null): GatewayServicesResponse + public function GatewayServices(string $gateway, null|QueryOptions $opts = null): GatewayServicesResponse { $resp = $this->_requireOK($this->_doGet(sprintf('v1/catalog/gateway-services/%s', urlencode($gateway)), $opts)); $ret = new GatewayServicesResponse(); diff --git a/src/Catalog/CatalogDeregistration.php b/src/Catalog/CatalogDeregistration.php index 139008fc..42f51931 100644 --- a/src/Catalog/CatalogDeregistration.php +++ b/src/Catalog/CatalogDeregistration.php @@ -21,23 +21,48 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class CatalogDeregistration extends AbstractModel { - protected const FIELDS = [ - self::FIELD_ADDRESS => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_ADDRESS = 'Address'; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $Node = ''; - public string $Address = ''; - public string $Datacenter = ''; - public string $ServiceID = ''; - public string $CheckID = ''; + public string $Node; + public string $Address; + public string $Datacenter; + public string $ServiceID; + public string $CheckID; + public string $Namespace; + public string $Partition; + + /** + * @param array|null $data + * @param string $Node + * @param string $Address + * @param string $Datacenter + * @param string $ServiceID + * @param string $CheckID + * @param string $Namespace + * @param string $Partition + */ + public function __construct( + null|array $data = null, // Deprecated, do not use + string $Node = '', + string $Address = '', + string $Datacenter = '', + string $ServiceID = '', + string $CheckID = '', + string $Namespace = '', + string $Partition = '' + ) { + $this->Node = $Node; + $this->Address = $Address; + $this->Datacenter = $Datacenter; + $this->ServiceID = $ServiceID; + $this->CheckID = $CheckID; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getNode(): string { @@ -93,4 +118,57 @@ public function setCheckID(string $checkID): self $this->CheckID = $checkID; return $this; } + + public function getNamespace(): string + { + return $this->Namespace; + } + + public function setNamespace(string $Namespace): self + { + $this->Namespace = $Namespace; + return $this; + } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Node = $this->Node; + if ('' !== $this->Address) { + $out->Address = $this->Address; + } + $out->Datacenter = $this->Datacenter; + $out->ServiceID = $this->ServiceID; + $out->CheckID = $this->CheckID; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } } diff --git a/src/Catalog/CatalogNode.php b/src/Catalog/CatalogNode.php index 1f947d62..e5259866 100644 --- a/src/Catalog/CatalogNode.php +++ b/src/Catalog/CatalogNode.php @@ -22,29 +22,30 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Agent\AgentService; -use DCarbone\PHPConsulAPI\Transcoding; class CatalogNode extends AbstractModel { - protected const FIELDS = [ - self::FIELD_NODE => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => Node::class, - ], - self::FIELD_SERVICES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => AgentService::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - ], - ]; + public null|Node $Node; + public null|\stdClass $Services; - private const FIELD_NODE = 'Node'; - private const FIELD_SERVICES = 'Services'; - - public ?Node $Node = null; - public array $Services = []; + /** + * @param array|null $data + * @param \DCarbone\PHPConsulAPI\Catalog\Node|null $Node + * @param null|\stdClass $Services + */ + public function __construct( + null|array $data = null, // Deprecated, do not use, + null|Node $Node = null, + null|\stdClass $Services = null + ) { + $this->Node = $Node; + $this->setServices($Services); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } - public function getNode(): ?Node + public function getNode(): null|Node { return $this->Node; } @@ -55,14 +56,47 @@ public function setNode(?Node $Node): self return $this; } - public function getServices(): array + public function getServices(): null|\stdClass { return $this->Services; } - public function setServices(array $Services): self + public function setServices(null|\stdClass $Services): self { - $this->Services = $Services; + if (null === $Services) { + $this->Services = null; + return $this; + } + $this->Services = new \stdClass(); + foreach ($Services as $k => $v) { + $this->Services->{$k} = $v instanceof AgentService ? $v : AgentService::jsonUnserialize($v); + } return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Node' === $k) { + $n->Node = null === $v ? null : Node::jsonUnserialize($v); + } elseif ('Services' === $k) { + $n->setServices($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Node = $this->Node; + $out->Services = $this->Services; + return $out; + } } diff --git a/src/Catalog/CatalogNodeResponse.php b/src/Catalog/CatalogNodeResponse.php index b3095658..362f38e0 100644 --- a/src/Catalog/CatalogNodeResponse.php +++ b/src/Catalog/CatalogNodeResponse.php @@ -25,15 +25,19 @@ class CatalogNodeResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?CatalogNode $Node = null; + public null|CatalogNode $Node = null; - public function getValue(): ?CatalogNode + public function getValue(): null|CatalogNode { return $this->Node; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->Node = new CatalogNode((array)$decodedData); + if (null === $decoded) { + $this->Node = null; + return; + } + $this->Node = CatalogNode::jsonUnserialize($decoded); } } diff --git a/src/Catalog/CatalogNodeServiceList.php b/src/Catalog/CatalogNodeServiceList.php index abae0f3a..dc9c1398 100644 --- a/src/Catalog/CatalogNodeServiceList.php +++ b/src/Catalog/CatalogNodeServiceList.php @@ -22,47 +22,81 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Agent\AgentService; -use DCarbone\PHPConsulAPI\Transcoding; class CatalogNodeServiceList extends AbstractModel { - protected const FIELDS = [ - self::FIELD_NODE => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => Node::class, - ], - self::FIELD_SERVICES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => AgentService::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - ], - ]; + public null|Node $Node; + /** @var array<\DCarbone\PHPConsulAPI\Agent\AgentService> */ + public array $Services; - private const FIELD_NODE = 'Node'; - private const FIELD_SERVICES = 'Services'; - - public ?Node $Node = null; - public array $Services = []; + /** + * @param array|null $data + * @param \DCarbone\PHPConsulAPI\Catalog\Node|null $Node + * @param array<\DCarbone\PHPConsulAPI\Agent\AgentService> $Services + */ + public function __construct( + null|array $data = null, + null|Node $Node = null, + array $Services = [] + ) { + $this->Node = $Node; + $this->setServices(...$Services); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } - public function getNode(): ?Node + public function getNode(): null|Node { return $this->Node; } - public function setNode(?Node $Node): self + public function setNode(null|Node $Node): self { $this->Node = $Node; return $this; } + /** + * @return array<\DCarbone\PHPConsulAPI\Agent\AgentService> + */ public function getServices(): array { return $this->Services; } - public function setServices(array $Services): self + public function setServices(AgentService ...$Services): self { $this->Services = $Services; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Node' === $k) { + $n->Node = null === $v ? null : Node::jsonUnserialize($v); + } elseif ('Services' === $k) { + $n->Services = []; + foreach ($v as $vv) { + $n->Services[] = AgentService::jsonUnserialize($vv); + } + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Node = $this->Node; + $out->Services = $this->Services; + return $out; + } } diff --git a/src/Catalog/CatalogNodeServicesListResponse.php b/src/Catalog/CatalogNodeServicesListResponse.php index d7f712fd..30126820 100644 --- a/src/Catalog/CatalogNodeServicesListResponse.php +++ b/src/Catalog/CatalogNodeServicesListResponse.php @@ -25,15 +25,19 @@ class CatalogNodeServicesListResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?CatalogNodeServiceList $CatalogNodeServiceList = null; + public null|CatalogNodeServiceList $CatalogNodeServiceList = null; - public function getValue(): ?CatalogNodeServiceList + public function getValue(): null|CatalogNodeServiceList { return $this->CatalogNodeServiceList; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->CatalogNodeServiceList = new CatalogNodeServiceList((array)$decodedData); + if (null === $decoded) { + $this->CatalogNodeServiceList = null; + return; + } + $this->CatalogNodeServiceList = CatalogNodeServiceList::jsonUnserialize($decoded); } } diff --git a/src/Catalog/CatalogRegistration.php b/src/Catalog/CatalogRegistration.php index 5175edc2..a48c86cd 100644 --- a/src/Catalog/CatalogRegistration.php +++ b/src/Catalog/CatalogRegistration.php @@ -23,57 +23,68 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Agent\AgentCheck; use DCarbone\PHPConsulAPI\Agent\AgentService; -use DCarbone\PHPConsulAPI\FakeMap; use DCarbone\PHPConsulAPI\Health\HealthChecks; -use DCarbone\PHPConsulAPI\Transcoding; +use DCarbone\PHPConsulAPI\Peering\Locality; class CatalogRegistration extends AbstractModel { - protected const FIELDS = [ - self::FIELD_TAGGED_ADDRESSES => Transcoding::MAP_FIELD, - self::FIELD_NODE_META => Transcoding::MAP_FIELD, - self::FIELD_SERVICE => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentService::class, - ], - self::FIELD_CHECK => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentCheck::class, - ], - self::FIELD_CHECKS => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => HealthChecks::class, - ], - ]; - - private const FIELD_TAGGED_ADDRESSES = 'TaggedAddresses'; - private const FIELD_NODE_META = 'NodeMeta'; - private const FIELD_SERVICE = 'Service'; - private const FIELD_CHECK = 'Check'; - private const FIELD_CHECKS = 'Checks'; - - public string $ID = ''; - public string $Node = ''; - public string $Address = ''; - public FakeMap $TaggedAddresses; - public FakeMap $NodeMeta; - public string $Datacenter = ''; - public ?AgentService $Service = null; - public ?AgentCheck $Check = null; - public HealthChecks $Checks; - public bool $SkipNodeUpdate = false; - - public function __construct(?array $data = []) - { - parent::__construct($data); - if (!isset($this->Checks)) { - $this->Checks = new HealthChecks(null); - } - if (!isset($this->TaggedAddresses)) { - $this->TaggedAddresses = new FakeMap(null); - } - if (!isset($this->NodeMeta)) { - $this->NodeMeta = new FakeMap(null); + public string $ID; + public string $Node; + public string $Address; + public null|\stdClass $TaggedAddresses; + public null|\stdClass $NodeMeta; + public string $Datacenter; + public null|AgentService $Service; + public null|AgentCheck $Check; + public null|HealthChecks $Checks; + public bool $SkipNodeUpdate; + public string $Partition; + public null|Locality $Locality; + + /** + * @param array|null $data + * @param string $ID + * @param string $Node + * @param string $Address + * @param \stdClass|null $TaggedAddresses + * @param \stdClass|null $NodeMeta + * @param string $Datacenter + * @param \DCarbone\PHPConsulAPI\Agent\AgentService|null $Service + * @param \DCarbone\PHPConsulAPI\Agent\AgentCheck|null $Check + * @param \DCarbone\PHPConsulAPI\Health\HealthChecks|null $Checks + * @param bool $SkipNodeUpdate + * @param string $Partition + * @param \DCarbone\PHPConsulAPI\Peering\Locality|null $Locality + */ + public function __construct( + null|array $data = null, + string $ID = '', + string $Node = '', + string $Address = '', + null|\stdClass $TaggedAddresses = null, + null|\stdClass $NodeMeta = null, + string $Datacenter = '', + null|AgentService $Service = null, + null|AgentCheck $Check = null, + null|HealthChecks $Checks = null, + bool $SkipNodeUpdate = false, + string $Partition = '', + null|Locality $Locality = null, + ) { + $this->ID = $ID; + $this->Node = $Node; + $this->Address = $Address; + $this->TaggedAddresses = $TaggedAddresses; + $this->NodeMeta = $NodeMeta; + $this->Datacenter = $Datacenter; + $this->Service = $Service; + $this->Check = $Check; + $this->Checks = $Checks; + $this->SkipNodeUpdate = $SkipNodeUpdate; + $this->Partition = $Partition; + $this->Locality = $Locality; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -110,23 +121,23 @@ public function setAddress(string $Address): self return $this; } - public function getTaggedAddresses(): FakeMap + public function getTaggedAddresses(): null|\stdClass { return $this->TaggedAddresses; } - public function setTaggedAddresses(FakeMap $TaggedAddresses): self + public function setTaggedAddresses(null|\stdClass $TaggedAddresses): self { $this->TaggedAddresses = $TaggedAddresses; return $this; } - public function getNodeMeta(): FakeMap + public function getNodeMeta(): null|\stdClass { return $this->NodeMeta; } - public function setNodeMeta(FakeMap $NodeMeta): self + public function setNodeMeta(null|\stdClass $NodeMeta): self { $this->NodeMeta = $NodeMeta; return $this; @@ -186,4 +197,70 @@ public function setSkipNodeUpdate(bool $SkipNodeUpdate): self $this->SkipNodeUpdate = $SkipNodeUpdate; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public function getLocality(): null|Locality + { + return $this->Locality; + } + + public function setLocality(null|Locality $Locality): self + { + $this->Locality = $Locality; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('TaggedAddresses' === $k) { + $n->TaggedAddresses = null === $v ? null : (object)$v; + } elseif ('NodeMeta' === $k) { + $n->NodeMeta = null === $v ? null : (object)$v; + } elseif ('Service' === $k) { + $n->Service = null === $v ? null : AgentService::jsonUnserialize($v); + } elseif ('Check' === $k) { + $n->Check = null === $v ? null : AgentCheck::jsonUnserialize($v); + } elseif ('Checks' === $k) { + $n->Checks = null === $v ? null : HealthChecks::jsonUnserialize($v); + } elseif ('Locality' === $k) { + $n->Locality = null === $v ? null : Locality::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ID = $this->ID; + $out->Node = $this->Node; + $out->Address = $this->Address; + $out->TaggedAddresses = $this->TaggedAddresses; + $out->NodeMeta = $this->NodeMeta; + $out->Datacenter = $this->Datacenter; + $out->Service = $this->Service; + $out->Check = $this->Check; + $out->Checks = $this->Checks; + $out->SkipNodeUpdate = $this->SkipNodeUpdate; + $out->Partition = $this->Partition; + $out->Locality = $this->Locality; + return $out; + } } diff --git a/src/Catalog/CatalogService.php b/src/Catalog/CatalogService.php index deb51345..a5b0f741 100644 --- a/src/Catalog/CatalogService.php +++ b/src/Catalog/CatalogService.php @@ -23,57 +23,90 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Agent\AgentServiceConnectProxyConfig; use DCarbone\PHPConsulAPI\Health\HealthChecks; -use DCarbone\PHPConsulAPI\Transcoding; +use DCarbone\PHPConsulAPI\Peering\Locality; class CatalogService extends AbstractModel { - protected const FIELDS = [ - self::FIELD_SERVICE_TAGGED_ADDRESSES => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ServiceAddress::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - ], - self::FIELD_SERVICE_WEIGHTS => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => Weights::class, - ], - self::FIELD_SERVICE_PROXY => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => AgentServiceConnectProxyConfig::class, - Transcoding::FIELD_NULLABLE => true, - ], - self::FIELD_HEALTH_CHECKS => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => HealthChecks::class, - ], - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_SERVICE_TAGGED_ADDRESSES = 'ServiceTaggedAddresses'; - private const FIELD_SERVICE_WEIGHTS = 'ServiceWeights'; - private const FIELD_SERVICE_PROXY = 'ServiceProxy'; - private const FIELD_HEALTH_CHECKS = 'HealthChecks'; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $ID = ''; - public string $Node = ''; - public string $Address = ''; - public string $Datacenter = ''; - public array $TaggedAddresses = []; - public array $NodeMeta = []; - public string $ServiceID = ''; - public string $ServiceName = ''; - public string $ServiceAddress = ''; - public array $ServiceTaggedAddresses = []; - public array $ServiceTags = []; - public array $ServiceMeta = []; - public int $ServicePort = 0; + public string $ID; + public string $Node; + public string $Address; + public string $Datacenter; + public null|\stdClass $TaggedAddresses; + public null|\stdClass $NodeMeta; + public string $ServiceID; + public string $ServiceName; + public string $ServiceAddress; + public null|\stdClass $ServiceTaggedAddresses; + /** @var array */ + public array $ServiceTags; + public null|\stdClass $ServiceMeta; + public int $ServicePort; public Weights $ServiceWeights; - public bool $ServiceEnableTagOverride = false; - public int $CreateIndex = 0; - public ?AgentServiceConnectProxyConfig $ServiceProxy = null; - public int $ModifyIndex = 0; - public string $Namespace = ''; + public bool $ServiceEnableTagOverride; + public null|AgentServiceConnectProxyConfig $ServiceProxy; + public null|Locality $ServiceLocality; + public int $CreateIndex; + public HealthChecks $Checks; + public int $ModifyIndex; + public string $Namespace; + public string $Partition; + + /** + * @param array|null $data + * @param array $ServiceTags + */ + public function __construct( + null|array $data = null, // Deprecated, do not use. + string $ID = '', + string $Node = '', + string $Address = '', + string $Datacenter = '', + null|\stdclass $TaggedAddresses = null, + null|\stdclass $NodeMeta = null, + string $ServiceID = '', + string $ServiceName = '', + string $ServiceAddress = '', + null|\stdclass $ServiceTaggedAddresses = null, + array $ServiceTags = [], + null|\stdclass $ServiceMeta = null, + int $ServicePort = 0, + null|Weights $ServiceWeights = null, + bool $ServiceEnableTagOverride = false, + null|AgentServiceConnectProxyConfig $ServiceProxy = null, + null|Locality $ServiceLocality = null, + int $CreateIndex = 0, + int $ModifyIndex = 0, + null|HealthChecks $Checks = null, + string $Namespace = '', + string $Partition = '' + ) { + $this->ID = $ID; + $this->Node = $Node; + $this->Address = $Address; + $this->Datacenter = $Datacenter; + $this->TaggedAddresses = $TaggedAddresses; + $this->NodeMeta = $NodeMeta; + $this->ServiceID = $ServiceID; + $this->ServiceName = $ServiceName; + $this->ServiceAddress = $ServiceAddress; + $this->ServiceTaggedAddresses = $ServiceTaggedAddresses; + $this->setServiceTags(...$ServiceTags); + $this->setServiceTaggedAddresses($ServiceTaggedAddresses); + $this->ServiceMeta = $ServiceMeta; + $this->ServicePort = $ServicePort; + $this->ServiceWeights = $ServiceWeights ?? new Weights(); + $this->ServiceEnableTagOverride = $ServiceEnableTagOverride; + $this->ServiceProxy = $ServiceProxy; + $this->ServiceLocality = $ServiceLocality; + $this->CreateIndex = $CreateIndex; + $this->Checks = $Checks ?? new HealthChecks(); + $this->ModifyIndex = $ModifyIndex; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getID(): string { @@ -119,23 +152,23 @@ public function setDatacenter(string $Datacenter): self return $this; } - public function getTaggedAddresses(): array + public function getTaggedAddresses(): null|\stdClass { return $this->TaggedAddresses; } - public function setTaggedAddresses(array $TaggedAddresses): self + public function setTaggedAddresses(null|\stdClass $TaggedAddresses): self { $this->TaggedAddresses = $TaggedAddresses; return $this; } - public function getNodeMeta(): array + public function getNodeMeta(): \stdClass { return $this->NodeMeta; } - public function setNodeMeta(array $NodeMeta): self + public function setNodeMeta(null|\stdClass $NodeMeta): self { $this->NodeMeta = $NodeMeta; return $this; @@ -174,34 +207,48 @@ public function setServiceAddress(string $ServiceAddress): self return $this; } - public function getServiceTaggedAddresses(): array + public function getServiceTaggedAddresses(): \stdClass { return $this->ServiceTaggedAddresses; } - public function setServiceTaggedAddresses(array $ServiceTaggedAddresses): self - { - $this->ServiceTaggedAddresses = $ServiceTaggedAddresses; + public function setServiceTaggedAddresses(null|\stdClass $ServiceTaggedAddresses): self + { + if (null === $ServiceTaggedAddresses) { + $this->ServiceTaggedAddresses = null; + return $this; + } + $this->ServiceTaggedAddresses = new \stdClass(); + foreach ($ServiceTaggedAddresses as $k => $v) { + if ($v instanceof ServiceAddress) { + $this->ServiceTaggedAddresses->{$k} = $v; + } else { + $this->ServiceTaggedAddresses->{$k} = ServiceAddress::jsonUnserialize((object)$v); + } + } return $this; } + /** + * @return string[] + */ public function getServiceTags(): array { return $this->ServiceTags; } - public function setServiceTags(array $ServiceTags): self + public function setServiceTags(string ...$ServiceTags): self { $this->ServiceTags = $ServiceTags; return $this; } - public function getServiceMeta(): array + public function getServiceMeta(): \stdClass { return $this->ServiceMeta; } - public function setServiceMeta(array $ServiceMeta): self + public function setServiceMeta(null|\stdClass $ServiceMeta): self { $this->ServiceMeta = $ServiceMeta; return $this; @@ -240,6 +287,28 @@ public function setServiceEnableTagOverride(bool $ServiceEnableTagOverride): sel return $this; } + public function getServiceProxy(): null|AgentServiceConnectProxyConfig + { + return $this->ServiceProxy; + } + + public function setServiceProxy(null|AgentServiceConnectProxyConfig $ServiceProxy): self + { + $this->ServiceProxy = $ServiceProxy; + return $this; + } + + public function getServiceLocality(): null|Locality + { + return $this->ServiceLocality; + } + + public function setServiceLocality(null|Locality $ServiceLocality): self + { + $this->ServiceLocality = $ServiceLocality; + return $this; + } + public function getCreateIndex(): int { return $this->CreateIndex; @@ -251,14 +320,14 @@ public function setCreateIndex(int $CreateIndex): self return $this; } - public function getServiceProxy(): ?AgentServiceConnectProxyConfig + public function getChecks(): HealthChecks { - return $this->ServiceProxy; + return $this->Checks; } - public function setServiceProxy(?AgentServiceConnectProxyConfig $ServiceProxy): self + public function setChecks(HealthChecks $Checks): self { - $this->ServiceProxy = $ServiceProxy; + $this->Checks = $Checks; return $this; } @@ -273,14 +342,93 @@ public function setModifyIndex(int $ModifyIndex): self return $this; } - public function getNamespace(): ?string + public function getNamespace(): string { return $this->Namespace; } - public function setNamespace(?string $Namespace): self + public function setNamespace(string $Namespace): self { $this->Namespace = $Namespace; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('TaggedAddresses' === $k) { + $n->settaggedAddresses($v); + } elseif ('NodeMeta' === $k) { + $n->setnodemeta($v); + } elseif ('ServiceTaggedAddresses' === $k) { + $n->setservicetaggedaddresses($v); + } elseif ('Weights' === $k) { + $n->ServiceWeights = Weights::jsonUnserialize($v); + } elseif ('ServiceProxy' === $k) { + if (null !== $v) { + $n->ServiceProxy = AgentServiceConnectProxyConfig::jsonUnserialize($v); + } + } elseif ('ServiceLocality' === $k) { + if (null !== $v) { + $n->ServiceLocality = Locality::jsonUnserialize($v); + } + } elseif ('Checks' === $k) { + if (null !== $v) { + $n->Checks = HealthChecks::jsonUnserialize($v); + } + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ID = $this->ID; + $out->Node = $this->Node; + $out->Address = $this->Address; + $out->Datacenter = $this->Datacenter; + $out->TaggedAddresses = $this->TaggedAddresses; + $out->NodeMeta = $this->NodeMeta; + $out->ServiceID = $this->ServiceID; + $out->ServiceName = $this->ServiceName; + $out->ServiceAddress = $this->ServiceAddress; + $out->ServiceTaggedAddresses = $this->ServiceTaggedAddresses; + $out->ServiceTags = $this->ServiceTags; + $out->ServiceMeta = $this->ServiceMeta; + $out->ServicePort = $this->ServicePort; + $out->ServiceWeights = $this->ServiceWeights; + $out->ServiceEnableTagOverride = $this->ServiceEnableTagOverride; + $out->ServiceProxy = $this->ServiceProxy; + if (null !== $this->ServiceLocality) { + $out->ServiceLocality = $this->ServiceLocality; + } + $out->CreateIndex = $this->CreateIndex; + $out->Checks = $this->Checks; + $out->ModifyIndex = $this->ModifyIndex; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } } diff --git a/src/Catalog/CatalogServicesResponse.php b/src/Catalog/CatalogServicesResponse.php index 6cbbc8f1..6758043e 100644 --- a/src/Catalog/CatalogServicesResponse.php +++ b/src/Catalog/CatalogServicesResponse.php @@ -25,18 +25,22 @@ class CatalogServicesResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $Services = null; + /** @var array<\DCarbone\PHPConsulAPI\Catalog\CatalogService> */ + public array $Services = []; - public function getValue(): ?array + /** + * @return array<\DCarbone\PHPConsulAPI\Catalog\CatalogService> + */ + public function getValue(): array { return $this->Services; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->Services = []; - foreach ($decodedData as $node) { - $this->Services[] = new CatalogService($node); + foreach ($decoded as $node) { + $this->Services[] = CatalogService::jsonUnserialize($node); } } } diff --git a/src/Catalog/CompoundServiceName.php b/src/Catalog/CompoundServiceName.php index 31d32162..b2f45c98 100644 --- a/src/Catalog/CompoundServiceName.php +++ b/src/Catalog/CompoundServiceName.php @@ -21,18 +21,27 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class CompoundServiceName extends AbstractModel { - protected const FIELDS = [ - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; + public string $Name; + public string $Namespace; + public string $Partition; - private const FIELD_NAMESPACE = 'Namespace'; - - public string $Name = ''; - public string $Namespace = ''; + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Name = '', + string $Namespace = '', + string $Partition = '', + ) + { + $this->Name = $Name; + $this->Namespace = $Namespace; + $this->Partition = $Partition; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getName(): string { @@ -55,4 +64,40 @@ public function setNamespace(string $Namespace): self $this->Namespace = $Namespace; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + if ('' !== $this->Namespace) { + $out->Namespace = $this->Namespace; + } + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + return $out; + } } diff --git a/src/Catalog/GatewayService.php b/src/Catalog/GatewayService.php index 2a47bee2..569b509b 100644 --- a/src/Catalog/GatewayService.php +++ b/src/Catalog/GatewayService.php @@ -21,64 +21,51 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; +use DCarbone\PHPConsulAPI\Agent\ServiceKind; class GatewayService extends AbstractModel { - protected const FIELDS = [ - self::FIELD_GATEWAY => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => CompoundServiceName::class, - ], - self::FIELD_SERVICE => [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => CompoundServiceName::class, - ], - self::FIELD_PORT => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_PROTOCOL => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_HOSTS => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::STRING, - Transcoding::FIELD_OMITEMPTY => true, - ], - self::FIELD_CA_FILE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_CERT_FILE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_KEY_FILE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_SNI => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_FROM_WILDCARD => Transcoding::OMITEMPTY_BOOLEAN_FIELD, - ]; - - private const FIELD_GATEWAY = 'Gateway'; - private const FIELD_SERVICE = 'Service'; - private const FIELD_PORT = 'Port'; - private const FIELD_PROTOCOL = 'Protocol'; - private const FIELD_HOSTS = 'Hosts'; - private const FIELD_CA_FILE = 'CAFile'; - private const FIELD_CERT_FILE = 'CertFile'; - private const FIELD_KEY_FILE = 'KeyFile'; - private const FIELD_SNI = 'SNI'; - private const FIELD_FROM_WILDCARD = 'FromWildcard'; - public CompoundServiceName $Gateway; public CompoundServiceName $Service; - public string $GatewayKind = ''; - public int $Port = 0; - public string $Protocol = ''; - public array $Hosts = []; - public string $CAFile = ''; - public string $CertFile = ''; - public string $KeyFile = ''; - public string $SNI = ''; - public string $FromWildCard = ''; - - public function __construct(?array $data = []) - { - parent::__construct($data); - if (!isset($this->Gateway)) { - $this->Gateway = new CompoundServiceName(); - } - if (!isset($this->Service)) { - $this->Service = new CompoundServiceName(); + public ServiceKind $GatewayKind; + public int $Port; + public string $Protocol; + /** @var array */ + public array $Hosts; + public string $CAFile; + public string $CertFile; + public string $KeyFile; + public string $SNI; + public string $FromWildCard; + + public function __construct( + null|array $data = [], // Deprecated, will be removed. + null|CompoundServiceName $Gateway = null, + null|CompoundServiceName $Service = null, + string|ServiceKind $GatewayKind = '', + int $Port = 0, + string $Protocol = '', + array $Hosts = [], + string $CAFile = '', + string $CertFile = '', + string $KeyFile = '', + string $SNI = '', + string $FromWildCard = '' + ) + { + $this->Gateway = $Gateway ?? new CompoundServiceName(); + $this->Service = $Service ?? new CompoundServiceName(); + $this->GatewayKind = $GatewayKind instanceof ServiceKind ? $GatewayKind : ServiceKind::from($GatewayKind); + $this->Port = $Port; + $this->Protocol = $Protocol; + $this->setHosts(...$Hosts); + $this->CAFile = $CAFile; + $this->CertFile = $CertFile; + $this->KeyFile = $KeyFile; + $this->SNI = $SNI; + $this->FromWildCard = $FromWildCard; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -104,12 +91,12 @@ public function setService(CompoundServiceName $Service): self return $this; } - public function getGatewayKind(): string + public function getGatewayKind(): ServiceKind { return $this->GatewayKind; } - public function setGatewayKind(string $GatewayKind): self + public function setGatewayKind(ServiceKind $GatewayKind): self { $this->GatewayKind = $GatewayKind; return $this; @@ -137,12 +124,15 @@ public function setProtocol(string $Protocol): self return $this; } + /** + * @return array + */ public function getHosts(): array { return $this->Hosts; } - public function setHosts(array $Hosts): self + public function setHosts(string ...$Hosts): self { $this->Hosts = $Hosts; return $this; @@ -202,4 +192,60 @@ public function setFromWildCard(string $FromWildCard): self $this->FromWildCard = $FromWildCard; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Gateway' === $k) { + $n->Gateway = CompoundServiceName::jsonUnserialize($v); + } else if ('Service' === $k) { + $n->Service = CompoundServiceName::jsonUnserialize($v); + } else if ('GatewayKind' === $k) { + $n->GatewayKind = ServiceKind::from($v); + } else if ('Hosts' === $k) { + $n->setHosts(...$v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Gateway = $this->Gateway; + $out->Service = $this->Service; + $out->GatewayKind = $this->GatewayKind->value; + if (0 !== $this->Port) { + $out->Port = $this->Port; + } + if ('' !== $this->Protocol) { + $out->Protocol = $this->Protocol; + } + if ([] !== $this->Hosts) { + $out->Hosts = $this->Hosts; + } + if ('' !== $this->CAFile) { + $out->CAFile = $this->CAFile; + } + if ('' !== $this->CertFile) { + $out->CertFile = $this->CertFile; + } + if ('' !== $this->KeyFile) { + $out->KeyFile = $this->KeyFile; + } + if ('' !== $this->SNI) { + $out->SNI = $this->SNI; + } + if ('' !== $this->FromWildCard) { + $out->FromWildCard = $this->FromWildCard; + } + return $out; + } } diff --git a/src/Catalog/GatewayServicesResponse.php b/src/Catalog/GatewayServicesResponse.php index cbf9d620..127a92b9 100644 --- a/src/Catalog/GatewayServicesResponse.php +++ b/src/Catalog/GatewayServicesResponse.php @@ -25,18 +25,22 @@ class GatewayServicesResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $GatewayServices = null; + /** @var \DCarbone\PHPConsulAPI\Catalog\GatewayService[] */ + public array $GatewayServices = []; - public function getValue(): mixed + /** + * @return \DCarbone\PHPConsulAPI\Catalog\GatewayService[] + */ + public function getValue(): array { return $this->GatewayServices; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->GatewayServices = []; - foreach ($decodedData as $service) { - $this->GatewayServices[] = new GatewayService($service); + foreach ($decoded as $service) { + $this->GatewayServices[] = GatewayService::jsonUnserialize($service); } } } diff --git a/src/Catalog/Node.php b/src/Catalog/Node.php index 2a6d19fa..4f6968f1 100644 --- a/src/Catalog/Node.php +++ b/src/Catalog/Node.php @@ -21,33 +21,52 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\FakeMap; -use DCarbone\PHPConsulAPI\Transcoding; +use DCarbone\PHPConsulAPI\Peering\Locality; class Node extends AbstractModel { - protected const FIELDS = [ - self::FIELD_TAGGED_ADDRESSES => Transcoding::MAP_FIELD, - self::FIELD_META => Transcoding::MAP_FIELD, - ]; - - private const FIELD_TAGGED_ADDRESSES = 'TaggedAddresses'; - private const FIELD_META = 'Meta'; - - public string $ID = ''; - public string $Node = ''; - public string $Address = ''; - public string $Datacenter = ''; - public FakeMap $TaggedAddresses; - public FakeMap $Meta; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - - public function __construct(?array $data = []) - { - parent::__construct($data); - if (!isset($this->Meta)) { - $this->Meta = new FakeMap(null); + public string $ID; + public string $Node; + public string $Address; + public string $Datacenter; + public null|\stdClass $TaggedAddresses; + public null|\stdClass $Meta; + public int $CreateIndex; + public int $ModifyIndex; + public string $Partition; + public string $PeerName; + public null|Locality $Locality; + + /** + * @param array|null $data + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $ID = '', + string $Node = '', + string $Address = '', + string $Datacenter = '', + null|\stdClass $TaggedAddresses = null, + null|\stdClass $Meta = null, + int $CreateIndex = 0, + int $ModifyIndex = 0, + string $Partition = '', + string $PeerName = '', + null|Locality $Locality = null + ) { + $this->ID = $ID; + $this->Node = $Node; + $this->Address = $Address; + $this->Datacenter = $Datacenter; + $this->TaggedAddresses = $TaggedAddresses ?? new \stdClass(); + $this->Meta = $Meta ?? new \stdClass(); + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->Partition = $Partition; + $this->PeerName = $PeerName; + $this->Locality = $Locality; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -95,23 +114,23 @@ public function setDatacenter(string $Datacenter): self return $this; } - public function getTaggedAddresses(): FakeMap + public function getTaggedAddresses(): null|\stdClass { return $this->TaggedAddresses; } - public function setTaggedAddresses(FakeMap $TaggedAddresses): self + public function setTaggedAddresses(null|\stdClass $TaggedAddresses): self { $this->TaggedAddresses = $TaggedAddresses; return $this; } - public function getMeta(): FakeMap + public function getMeta(): null|\stdClass { return $this->Meta; } - public function setMeta(FakeMap $Meta): self + public function setMeta(null|\stdClass $Meta): self { $this->Meta = $Meta; return $this; @@ -138,4 +157,76 @@ public function setModifyIndex(int $ModifyIndex): self $this->ModifyIndex = $ModifyIndex; return $this; } + + public function getPartition(): string + { + return $this->Partition; + } + + public function setPartition(string $Partition): self + { + $this->Partition = $Partition; + return $this; + } + + public function getPeerName(): string + { + return $this->PeerName; + } + + public function setPeerName(string $PeerName): self + { + $this->PeerName = $PeerName; + return $this; + } + + public function getLocality(): null|Locality + { + return $this->Locality; + } + + public function setLocality(null|Locality $Locality): self + { + $this->Locality = $Locality; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Locality' === $k) { + $n->Locality = Locality::jsonUnserialize($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->ID = $this->ID; + $out->Node = $this->Node; + $out->Address = $this->Address; + $out->Datacenter = $this->Datacenter; + $out->TaggedAddresses = $this->TaggedAddresses; + $out->Meta = $this->Meta; + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + if ('' !== $this->PeerName) { + $out->PeerName = $this->PeerName; + } + if (null !== $this->Locality) { + $out->Locality = $this->Locality; + } + return $out; + } } diff --git a/src/Catalog/NodesResponse.php b/src/Catalog/NodesResponse.php index f38cddd9..a56b77bb 100644 --- a/src/Catalog/NodesResponse.php +++ b/src/Catalog/NodesResponse.php @@ -25,18 +25,22 @@ class NodesResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $Nodes = null; + /** @var \DCarbone\PHPConsulAPI\Catalog\Node[] */ + public array $Nodes = []; - public function getValue(): mixed + /** + * @return \DCarbone\PHPConsulAPI\Catalog\Node[] + */ + public function getValue(): array { return $this->Nodes; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->Nodes = []; - foreach ($decodedData as $node) { - $this->Nodes[] = new Node($node); + foreach ($decoded as $node) { + $this->Nodes[] = Node::jsonUnserialize($node); } } } diff --git a/src/Catalog/ServiceAddress.php b/src/Catalog/ServiceAddress.php index 27d1fb6b..cf02e047 100644 --- a/src/Catalog/ServiceAddress.php +++ b/src/Catalog/ServiceAddress.php @@ -24,8 +24,23 @@ class ServiceAddress extends AbstractModel { - public string $Address = ''; - public int $Port = 0; + public string $Address; + public int $Port; + + /** + * @param array|null $data + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $address = '', + int $port = 0, + ) { + $this->Address = $address; + $this->Port = $port; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getAddress(): string { @@ -48,4 +63,24 @@ public function setPort(int $port): self $this->Port = $port; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Address = $this->Address; + $out->Port = $this->Port; + return $out; + } } diff --git a/src/Catalog/Weights.php b/src/Catalog/Weights.php index 08021e75..0a237e98 100644 --- a/src/Catalog/Weights.php +++ b/src/Catalog/Weights.php @@ -24,8 +24,23 @@ class Weights extends AbstractModel { - public int $Passing = 0; - public int $Warning = 0; + public int $Passing; + public int $Warning; + + /** + * @param array|null $data + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + int $Passing = 0, + int $Warning = 0 + ) { + $this->Passing = $Passing; + $this->Warning = $Warning; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getPassing(): int { @@ -48,4 +63,24 @@ public function setWarning(int $Warning): self $this->Warning = $Warning; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Passing = $this->Passing; + $out->Warning = $this->Warning; + return $out; + } } diff --git a/src/Config.php b/src/Config.php index 7f652148..78bc515c 100644 --- a/src/Config.php +++ b/src/Config.php @@ -27,63 +27,38 @@ class Config { - use Unmarshaller; - public const DEFAULT_REQUEST_OPTIONS = [ RequestOptions::HTTP_ERRORS => false, RequestOptions::DECODE_CONTENT => false, ]; - protected const FIELDS = [ - self::FIELD_HTTP_AUTH => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => 'setHttpAuth', - ], - self::FIELD_WAIT_TIME => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_NULLABLE_DURATION, - ], - ]; + public const DEFAULT_ADDRESS = '127.0.0.1:8500'; + public const DEFAULT_SCHEME = 'http'; - private const FIELD_HTTP_AUTH = 'HttpAuth'; - private const FIELD_WAIT_TIME = 'WaitTime'; - private const FIELD_ADDRESS = 'Address'; - private const FIELD_SCHEME = 'Scheme'; - private const FIELD_JSON_ENCODE_OPTS = 'JSONEncodeOpts'; - private const FIELD_TOKEN = 'Token'; - private const FIELD_TOKEN_FILE = 'TokenFile'; - private const FIELD_CA_FILE = 'CAFile'; - private const FIELD_CERT_FILE = 'CertFile'; - private const FIELD_KEY_FILE = 'KeyFile'; - private const FIELD_INSECURE_SKIP_VERIFY = 'InsecureSkipVerify'; - - private const DEFAULT_CONFIG = [ - self::FIELD_ADDRESS => '127.0.0.1:8500', - self::FIELD_SCHEME => 'http', - self::FIELD_JSON_ENCODE_OPTS => \JSON_UNESCAPED_SLASHES, - ]; /** * The address, including port, of your Consul Agent * * @var string */ - public string $Address = ''; + public string $Address; - public string $Scheme = ''; + public string $Scheme; - public string $Datacenter = ''; + public string $Datacenter; - public string $Namespace = ''; + public string $Namespace; /** * HTTP authentication, if used * * @var \DCarbone\PHPConsulAPI\HttpAuth|null */ - public ?HttpAuth $HttpAuth = null; + public null|HttpAuth $HttpAuth; - public ?Time\Duration $WaitTime = null; + public null|Time\Duration $WaitTime; - public string $Token = ''; + public string $Token; /** * File containing the current token to use for this client. @@ -92,35 +67,63 @@ class Config * * @var string */ - public string $TokenFile = ''; + public string $TokenFile; - public string $CAFile = ''; + public string $CAFile; /** * Optional path to certificate. If set, KeyFile must also be set * * @var string */ - public string $CertFile = ''; + public string $CertFile; /** * Optional path to private key. If set, CertFile must also be set * * @var string */ - public string $KeyFile = ''; + public string $KeyFile; - public bool $InsecureSkipVerify = false; + public bool $InsecureSkipVerify; public ClientInterface $HttpClient; - public int $JSONEncodeOpts = 0; - - public function __construct(array $config = []) - { - foreach ($config + self::_getDefaultConfig() as $k => $v) { - $this->unmarshalField($k, $v); - } + public int $JSONEncodeOpts; + public int $JSONDecodeMaxDepth; + public int $JSONDecodeOpts; + + public function __construct( + string $Address = self::DEFAULT_ADDRESS, + string $Scheme = self::DEFAULT_SCHEME, + string $Datacenter = '', + string $Namespace = '', + null|string|HttpAuth $HttpAuth = null, + null|string|int|float|\DateInterval|Time\Duration $WaitTime = null, + string $Token = '', + string $TokenFile = '', + string $CAFile = '', + string $CertFile = '', + string $KeyFile = '', + bool $InsecureSkipVerify = false, + null|ClientInterface $HttpClient = null, + int $JSONEncodeOpts = JSON_UNESCAPED_SLASHES, + int $JSONDecodeMaxDepth = 512, + int $JSONDecodeOpts = 0, + ) { + $this->Address = self::_resolveValue($Address, Consul::HTTPAddrEnvName, self::DEFAULT_ADDRESS); + $this->setScheme(self::_resolveValue($Scheme, Consul::HTTPSSLEnvName, self::DEFAULT_SCHEME)); + $this->Datacenter = $Datacenter; + $this->Namespace = $Namespace; + $this->setHttpAuth(self::_resolveValue($HttpAuth, Consul::HTTPAuthEnvName, null)); + $this->setWaitTime($WaitTime); + $this->Token = self::_resolveValue($Token, Consul::HTTPTokenEnvName, ''); + $this->TokenFile = self::_resolveValue($TokenFile, Consul::HTTPTokenFileEnvName, ''); + $this->CAFile = self::_resolveValue($CAFile, Consul::HTTPCAFileEnvName, ''); + $this->CertFile = self::_resolveValue($CertFile, Consul::HTTPClientCertEnvName, ''); + $this->KeyFile = self::_resolveValue($KeyFile, Consul::HTTPClientKeyEnvName, ''); + $skipVerify = self::_resolveValue($InsecureSkipVerify, Consul::HTTPSSLVerifyEnvName, false); + $this->InsecureSkipVerify = is_string($skipVerify) ? strtolower($skipVerify) === 'true' : $skipVerify; // quick validation on key/cert combo $c = $this->CertFile; @@ -136,13 +139,14 @@ public function __construct(array $config = []) ); } - // if client hasn't been constructed, construct. - if (!isset($this->HttpClient)) { - $this->HttpClient = new Client(); - } + $this->HttpClient = $HttpClient ?? new Client(); + + $this->JSONEncodeOpts = $JSONEncodeOpts; + $this->JSONDecodeMaxDepth = $JSONDecodeMaxDepth; + $this->JSONDecodeOpts = $JSONDecodeOpts; } - public static function merge(?self $inc): self + public static function merge(null|Config $inc): Config { $actual = static::newDefaultConfig(); if (null === $inc) { @@ -190,12 +194,16 @@ public static function merge(?self $inc): self if (0 !== $inc->JSONEncodeOpts) { $actual->JSONEncodeOpts = $inc->JSONEncodeOpts; } + if (0 !== $inc->JSONDecodeMaxDepth) { + $actual->JSONDecodeMaxDepth = $inc->JSONDecodeMaxDepth; + } + $actual->JSONDecodeOpts = self::_resolveValue($inc->JSONDecodeOpts, '', $actual->JSONDecodeOpts); return $actual; } public static function newDefaultConfig(): self { - return new static(self::_getDefaultConfig()); + return new static(); } public function getAddress(): string @@ -214,9 +222,13 @@ public function getScheme(): string return $this->Scheme; } - public function setScheme(string $scheme): self + public function setScheme(bool|string $scheme): self { - $this->Scheme = $scheme; + $this->Scheme = match (is_string($scheme) ? strtolower($scheme) : $scheme) { + true, 'true', '1' => 'https', + false, 'false', '0' => 'http', + default => $scheme, + }; return $this; } @@ -246,7 +258,7 @@ public function getWaitTime(): Time\Duration return $this->WaitTime; } - public function setWaitTime(mixed $waitTime): self + public function setWaitTime(null|string|int|float|\DateInterval|Time\Duration $waitTime): self { $this->WaitTime = Time::Duration($waitTime); return $this; @@ -290,9 +302,14 @@ public function getHttpAuth(): HttpAuth return $this->HttpAuth; } - public function setHttpAuth(HttpAuth|string $httpAuth): self + public function setHttpAuth(null|string|HttpAuth $httpAuth): self { - if (\is_string($httpAuth)) { + if (null === $httpAuth) { + $this->HttpAuth = null; + return $this; + } + + if (is_string($httpAuth)) { $colon = strpos($httpAuth, ':'); if (false === $colon) { $username = $httpAuth; @@ -304,18 +321,8 @@ public function setHttpAuth(HttpAuth|string $httpAuth): self $httpAuth = new HttpAuth($username, $password); } - if ($httpAuth instanceof HttpAuth) { - $this->HttpAuth = $httpAuth; - return $this; - } - - throw new \InvalidArgumentException( - sprintf( - '%s::setHttpAuth - Value is expected to be string of "username:password" or instance of "\\DCarbone\\PHPConsulApi\\HttpAuth", %s seen.', - static::class, - \is_string($httpAuth) ? $httpAuth : \gettype($httpAuth) - ) - ); + $this->HttpAuth = $httpAuth; + return $this; } public function getCAFile(): string @@ -373,77 +380,44 @@ public function setJSONEncodeOpts(int $jsonEncodeOpts): self return $this; } - public static function getEnvironmentConfig(): array - { - $ret = []; - foreach ( - [ - Consul::HTTPAddrEnvName => static::_tryGetEnvParam(Consul::HTTPAddrEnvName), - Consul::HTTPTokenEnvName => static::_tryGetEnvParam(Consul::HTTPTokenEnvName), - Consul::HTTPTokenFileEnvName => static::_tryGetEnvParam(Consul::HTTPTokenFileEnvName), - Consul::HTTPAuthEnvName => static::_tryGetEnvParam(Consul::HTTPAuthEnvName), - Consul::HTTPCAFileEnvName => static::_tryGetEnvParam(Consul::HTTPCAFileEnvName), - Consul::HTTPClientCertEnvName => static::_tryGetEnvParam(Consul::HTTPClientCertEnvName), - Consul::HTTPClientKeyEnvName => static::_tryGetEnvParam(Consul::HTTPClientKeyEnvName), - Consul::HTTPSSLEnvName => static::_tryGetEnvParam(Consul::HTTPSSLEnvName), - Consul::HTTPSSLVerifyEnvName => static::_tryGetEnvParam(Consul::HTTPSSLVerifyEnvName), - ] as $k => $v - ) { - if (null !== $v) { - $ret[$k] = $v; - } - } - return $ret; + public function getJSONDecodeMaxDepth(): int + { + return $this->JSONDecodeMaxDepth; } - protected static function _tryGetEnvParam(string $param): ?string + public function setJSONDecodeMaxDepth(int $JSONDecodeMaxDepth): Config { - if (isset($_ENV[$param])) { - return $_ENV[$param]; - } + $this->JSONDecodeMaxDepth = $JSONDecodeMaxDepth; + return $this; + } - if (false !== ($value = getenv($param))) { - return $value; - } + public function getJSONDecodeOpts(): int + { + return $this->JSONDecodeOpts; + } - if (isset($_SERVER[$param])) { - return $_SERVER[$param]; + public function setJSONDecodeOpts(int $JSONDecodeOpts): Config + { + $this->JSONDecodeOpts = $JSONDecodeOpts; + return $this; + } + + protected static function _resolveValue(mixed $explicit, string $env, mixed $default): mixed + { + if ($explicit !== $default) { + return $explicit; } - return null; - } - - private static function _getDefaultConfig(): array - { - $conf = self::DEFAULT_CONFIG; - - // parse env vars - foreach (static::getEnvironmentConfig() as $k => $v) { - if (Consul::HTTPAddrEnvName === $k) { - $conf[self::FIELD_ADDRESS] = $v; - } elseif (Consul::HTTPTokenEnvName === $k) { - $conf[self::FIELD_TOKEN] = $v; - } elseif (Consul::HTTPTokenFileEnvName === $k) { - $conf[self::FIELD_TOKEN_FILE] = $v; - } elseif (Consul::HTTPAuthEnvName === $k) { - $conf[self::FIELD_HTTP_AUTH] = $v; - } elseif (Consul::HTTPCAFileEnvName === $k) { - $conf[self::FIELD_CA_FILE] = $v; - } elseif (Consul::HTTPClientCertEnvName === $k) { - $conf[self::FIELD_CERT_FILE] = $v; - } elseif (Consul::HTTPClientKeyEnvName === $k) { - $conf[self::FIELD_KEY_FILE] = $v; - } elseif (Consul::HTTPSSLEnvName === $k) { - if ((bool)$v) { - $conf[self::FIELD_SCHEME] = 'https'; - } - } elseif (Consul::HTTPSSLVerifyEnvName === $k) { - if ((bool)$v) { - $conf[self::FIELD_INSECURE_SKIP_VERIFY] = true; - } + if ($env !== '') { + if (isset($_ENV[$env])) { + return $_ENV[$env]; + } elseif (false !== ($value = getenv($env))) { + return $value; + } elseif (isset($_SERVER[$env])) { + return $_SERVER[$env]; } } - return $conf; + return $default; } } diff --git a/src/ConfigEntry/AccessLogsConfig.php b/src/ConfigEntry/AccessLogsConfig.php new file mode 100644 index 00000000..03563162 --- /dev/null +++ b/src/ConfigEntry/AccessLogsConfig.php @@ -0,0 +1,155 @@ +Enabled = $Enabled; + $this->DisableListenerLogs = $DisableListenerLogs; + $this->Type = $Type instanceof LogSinkType ? $Type : LogSinkType::from($Type); + $this->Path = $Path; + $this->JSONFormat = $JSONFormat; + $this->TextFormat = $TextFormat; + } + + public function isEnabled(): bool + { + return $this->Enabled; + } + + public function setEnabled(bool $Enabled): self + { + $this->Enabled = $Enabled; + return $this; + } + + public function isDisableListenerLogs(): bool + { + return $this->DisableListenerLogs; + } + + public function setDisableListenerLogs(bool $DisableListenerLogs): self + { + $this->DisableListenerLogs = $DisableListenerLogs; + return $this; + } + + public function getType(): LogSinkType + { + return $this->Type; + } + + public function setType(string|LogSinkType $Type): self + { + $this->Type = $Type instanceof LogSinkType ? $Type : LogSinkType::from($Type); + return $this; + } + + public function getPath(): string + { + return $this->Path; + } + + public function setPath(string $Path): self + { + $this->Path = $Path; + return $this; + } + + public function getJSONFormat(): string + { + return $this->JSONFormat; + } + + public function setJSONFormat(string $JSONFormat): self + { + $this->JSONFormat = $JSONFormat; + return $this; + } + + public function getTextFormat(): string + { + return $this->TextFormat; + } + + public function setTextFormat(string $TextFormat): self + { + $this->TextFormat = $TextFormat; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded): static + { + $n = new static(); + foreach ($decoded as $k => $v) { + if ('Type' === $k) { + $n->setType($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ($this->Enabled) { + $out->Enabled = $this->Enabled; + } + if ($this->DisableListenerLogs) { + $out->DisableListenerLogs = $this->DisableListenerLogs; + } + if ($this->Type !== LogSinkType::Default) { + $out->Type = $this->Type->value; + } + if ('' !== $this->Path) { + $out->Path = $this->Path; + } + if ('' !== $this->JSONFormat) { + $out->JSONFormat = $this->JSONFormat; + } + if ('' !== $this->TextFormat) { + $out->TextFormat = $this->TextFormat; + } + return $out; + } +} diff --git a/src/ConfigEntry/ConfigEntry.php b/src/ConfigEntry/ConfigEntry.php index 23789581..a8332bea 100644 --- a/src/ConfigEntry/ConfigEntry.php +++ b/src/ConfigEntry/ConfigEntry.php @@ -20,9 +20,6 @@ limitations under the License. */ -use DCarbone\PHPConsulAPI\FakeMap; -use DCarbone\PHPConsulAPI\Transcoding; - /** * Interface ConfigEntry * @@ -31,21 +28,13 @@ */ interface ConfigEntry { - public const INTERFACE_FIELDS = [ - self::FIELD_NAMESPACE => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_META => Transcoding::MAP_FIELD, - ]; - - public const FIELD_NAMESPACE = 'Namespace'; - public const FIELD_META = 'Meta'; - public function GetKind(): string; public function GetName(): string; public function GetNamespace(): string; - public function GetMeta(): ?FakeMap; + public function GetMeta(): \stdClass; public function GetCreateIndex(): int; diff --git a/src/ConfigEntry/ConfigEntryTrait.php b/src/ConfigEntry/ConfigEntryTrait.php index 3a302dc1..85b6c4f7 100644 --- a/src/ConfigEntry/ConfigEntryTrait.php +++ b/src/ConfigEntry/ConfigEntryTrait.php @@ -20,58 +20,32 @@ limitations under the License. */ -use DCarbone\PHPConsulAPI\FakeMap; - trait ConfigEntryTrait { - public string $Kind = ''; - public string $Name = ''; - public string $Namespace = ''; - public ?FakeMap $Meta = null; - public int $CreateIndex = 0; - public int $ModifyIndex = 0; - - public function getKind(): string - { - return $this->Kind; - } - - public function setKind(string $Kind): ConfigEntry - { - $this->Kind = $Kind; - return $this; - } - - public function getName(): string - { - return $this->Name; - } - - public function setName(string $Name): ConfigEntry - { - $this->Name = $Name; - return $this; - } + public string $Namespace; + public null|\stdClass $Meta; + public int $CreateIndex; + public int $ModifyIndex; public function getNamespace(): string { return $this->Namespace; } - public function setNamespace(string $Namespace): ConfigEntry + public function setNamespace(string $Namespace): self { $this->Namespace = $Namespace; return $this; } - public function getMeta(): ?FakeMap + public function getMeta(): null|\stdClass { return $this->Meta; } - public function setMeta(mixed $Meta): ProxyConfigEntry + public function setMeta(null|\stdClass $Meta): self { - $this->Meta = FakeMap::parse($Meta); + $this->Meta = $Meta; return $this; } @@ -80,7 +54,7 @@ public function getCreateIndex(): int return $this->CreateIndex; } - public function setCreateIndex(int $CreateIndex): ProxyConfigEntry + public function setCreateIndex(int $CreateIndex): self { $this->CreateIndex = $CreateIndex; return $this; @@ -91,7 +65,7 @@ public function getModifyIndex(): int return $this->ModifyIndex; } - public function setModifyIndex(int $ModifyIndex): ProxyConfigEntry + public function setModifyIndex(int $ModifyIndex): self { $this->ModifyIndex = $ModifyIndex; return $this; diff --git a/src/Agent/EnvoyExtension.php b/src/ConfigEntry/EnvoyExtension.php similarity index 51% rename from src/Agent/EnvoyExtension.php rename to src/ConfigEntry/EnvoyExtension.php index e433e843..1af3ec01 100644 --- a/src/Agent/EnvoyExtension.php +++ b/src/ConfigEntry/EnvoyExtension.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace DCarbone\PHPConsulAPI\Agent; +namespace DCarbone\PHPConsulAPI\ConfigEntry; /* Copyright 2016-2025 Daniel Carbone (daniel.p.carbone@gmail.com) @@ -21,28 +21,33 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\FakeMap; -use DCarbone\PHPConsulAPI\Transcoding; class EnvoyExtension extends AbstractModel { - protected const FIELDS = [ - self::FIELD_ARGUMENTS => Transcoding::MAP_FIELD, - ]; - - private const FIELD_ARGUMENTS = 'Arguments'; - - public string $Name = ''; - public bool $Required = false; - public FakeMap $Arguments; - public string $ConsulVersion = ''; - public string $EnvoyVersion = ''; - - public function __construct(?array $data = []) - { - parent::__construct($data); - if (!isset($this->Arguments)) { - $this->Arguments = new FakeMap(null); + public string $Name; + public bool $Required; + public null|\stdClass $Arguments; + public string $ConsulVersion; + public string $EnvoyVersion; + + /** + * @param array|null $data + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Name = '', + bool $Required = false, + null|\stdClass $Arguments = null, + string $ConsulVersion = '', + string $EnvoyVersion = '', + ) { + $this->Name = $Name; + $this->Required = $Required; + $this->Arguments = $Arguments; + $this->ConsulVersion = $ConsulVersion; + $this->EnvoyVersion = $EnvoyVersion; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); } } @@ -68,14 +73,14 @@ public function setRequired(bool $Required): self return $this; } - public function getArguments(): ?FakeMap + public function getArguments(): null|\stdClass { return $this->Arguments; } - public function setArguments(array|FakeMap|\stdClass|null $Arguments): self + public function setArguments(null|\stdClass $Arguments): self { - $this->Arguments = FakeMap::parse($Arguments); + $this->Arguments = $Arguments; return $this; } @@ -100,4 +105,27 @@ public function setEnvoyVersion(string $EnvoyVersion): self $this->EnvoyVersion = $EnvoyVersion; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Name = $this->Name; + $out->Required = $this->Required; + $out->Arguments = $this->Arguments; + $out->ConsulVersion = $this->ConsulVersion; + $out->EnvoyVersion = $this->EnvoyVersion; + return $out; + } } diff --git a/src/ConfigEntry/ExposeConfig.php b/src/ConfigEntry/ExposeConfig.php index de9d7867..9d05a783 100644 --- a/src/ConfigEntry/ExposeConfig.php +++ b/src/ConfigEntry/ExposeConfig.php @@ -21,25 +21,27 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ExposeConfig extends AbstractModel { - protected const FIELDS = [ - self::FIELD_CHECKS => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_PATHS => [ - Transcoding::FIELD_TYPE => Transcoding::ARRAY, - Transcoding::FIELD_CLASS => ExposePath::class, - Transcoding::FIELD_ARRAY_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_OMITEMPTY => true, - ], - ]; + public bool $Checks; + /** @var array<\DCarbone\PHPConsulAPI\ConfigEntry\ExposePath> */ + public array $Paths; - private const FIELD_CHECKS = 'Checks'; - private const FIELD_PATHS = 'Paths'; - - public bool $Checks = false; - public array $Paths = []; + /** + * @param array|null $data + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + bool $Checks = false, + array $Paths = [], + ) { + $this->Checks = $Checks; + $this->setPaths(...$Paths); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function isChecks(): bool { @@ -52,14 +54,47 @@ public function setChecks(bool $Checks): self return $this; } + /** + * @return \DCarbone\PHPConsulAPI\ConfigEntry\ExposePath[] + */ public function getPaths(): array { return $this->Paths; } - public function setPaths(array $Paths): self + public function setPaths(ExposePath ...$Paths): self { $this->Paths = $Paths; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $n = null): static + { + $n = $n ?? new self(); + foreach ($decoded as $k => $v) { + if ('Paths' === $k) { + foreach ($v as $vv) { + $n->Paths[] = ExposePath::jsonUnserialize($vv); + } + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ($this->Checks) { + $out->Checks = true; + } + if ([] !== $this->Paths) { + $out->Paths = $this->Paths; + } + return $out; + } } diff --git a/src/ConfigEntry/ExposePath.php b/src/ConfigEntry/ExposePath.php index 78d0ddb4..a60fdd6f 100644 --- a/src/ConfigEntry/ExposePath.php +++ b/src/ConfigEntry/ExposePath.php @@ -21,27 +21,35 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class ExposePath extends AbstractModel { - protected const FIELDS = [ - self::FIELD_LISTENER_PORT => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_PATH => Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_LOCAL_PORT_PATH => Transcoding::OMITEMPTY_INTEGER_FIELD, - self::FIELD_PROTOCOL => Transcoding::OMITEMPTY_STRING_FIELD, - ]; - - private const FIELD_LISTENER_PORT = 'ListenerPort'; - private const FIELD_PATH = 'Path'; - private const FIELD_LOCAL_PORT_PATH = 'LocalPortPath'; - private const FIELD_PROTOCOL = 'Protocol'; - - public int $ListenerPort = 0; - public string $Path = ''; - public int $LocalPathPort = 0; - public string $Protocol = ''; - public bool $ParsedFromCheck = false; + public int $ListenerPort; + public string $Path; + public int $LocalPathPort; + public string $Protocol; + public bool $ParsedFromCheck; + + /** + * @param array|null $data + */ + public function __construct( + null|array $data = null, // Deprecated, will be removed. + int $ListenerPort = 0, + string $Path = '', + int $LocalPathPort = 0, + string $Protocol = '', + bool $ParsedFromCheck = false + ) { + $this->ListenerPort = $ListenerPort; + $this->Path = $Path; + $this->LocalPathPort = $LocalPathPort; + $this->Protocol = $Protocol; + $this->ParsedFromCheck = $ParsedFromCheck; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getListenerPort(): int { @@ -97,4 +105,43 @@ public function setParsedFromCheck(bool $ParsedFromCheck): self $this->ParsedFromCheck = $ParsedFromCheck; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $n = null): static + { + $n = $n ?? new self(); + foreach ($decoded as $k => $v) { + if ('listener_port' === $k) { + $n->ListenerPort = $v; + } elseif ('local_path_port' === $k) { + $n->LocalPathPort = $v; + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if (0 !== $this->ListenerPort) { + $out->listener_port = $this->ListenerPort; + } + if ('' !== $this->Path) { + $out->Path = $this->Path; + } + if (0 !== $this->LocalPathPort) { + $out->local_path_port = $this->LocalPathPort; + } + if ('' !== $this->Protocol) { + $out->Protocol = $this->Protocol; + } + if ($this->ParsedFromCheck) { + $out->ParsedFromCheck = true; + } + return $out; + } } diff --git a/src/ConfigEntry/LogSinkType.php b/src/ConfigEntry/LogSinkType.php new file mode 100644 index 00000000..099d032a --- /dev/null +++ b/src/ConfigEntry/LogSinkType.php @@ -0,0 +1,29 @@ + [ - Transcoding::FIELD_TYPE => Transcoding::OBJECT, - Transcoding::FIELD_CLASS => TransparentProxyConfig::class, - Transcoding::FIELD_NULLABLE => false, - Transcoding::FIELD_OMITEMPTY => false, - ], - ]; + public string $Partition; + public TransparentProxyMeshConfig $TransparentProxy; + public bool $AllowEnablingPermissiveMutualTLS; + public null|MeshTLSConfig $TLS; + public null|MeshHTTPConfig $HTTP; + public null|PeeringMeshConfig $Peering; - private const FIELD_TRANSPARENT_PROXY = 'TransparentProxy'; + public function __construct( + null|array $data = null, // Deprecated, will be removed. + string $Partition = '', + string $Namespace = '', + null|TransparentProxyMeshConfig $TransparentProxy = null, + bool $AllowEnablingPermissiveMutualTLS = false, + null|MeshTLSConfig $TLS = null, + null|MeshHTTPConfig $HTTP = null, + null|PeeringMeshConfig $Peering = null, + null|\stdClass $Meta = null, + int $CreateIndex = 0, + int $ModifyIndex = 0 + ) { + $this->Partition = $Partition; + $this->Namespace = $Namespace; + $this->Meta = $Meta; + $this->CreateIndex = $CreateIndex; + $this->ModifyIndex = $ModifyIndex; + $this->TransparentProxy = $TransparentProxy; + $this->AllowEnablingPermissiveMutualTLS = $AllowEnablingPermissiveMutualTLS; + $this->TLS = $TLS; + $this->HTTP = $HTTP; + $this->Peering = $Peering; + + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } - public TransparentProxyConfig $TransparentProxy; + public function getKind(): string + { + return Consul::MeshConfig; + } - public function getTransparentProxy(): TransparentProxyConfig + public function getName(): string + { + return Consul::MeshConfigMesh; + } + + public function getTransparentProxy(): TransparentProxyMeshConfig { return $this->TransparentProxy; } - public function setTransparentProxy(TransparentProxyConfig $TransparentProxy): self + public function setTransparentProxy(TransparentProxyMeshConfig $TransparentProxy): self { $this->TransparentProxy = $TransparentProxy; return $this; } + + public function isAllowEnablingPermissiveMutualTLS(): bool + { + return $this->AllowEnablingPermissiveMutualTLS; + } + + public function setAllowEnablingPermissiveMutualTLS(bool $AllowEnablingPermissiveMutualTLS): self + { + $this->AllowEnablingPermissiveMutualTLS = $AllowEnablingPermissiveMutualTLS; + return $this; + } + + public function getTLS(): null|MeshTLSConfig + { + return $this->TLS; + } + + public function setTLS(null|MeshTLSConfig $TLS): self + { + $this->TLS = $TLS; + return $this; + } + + public function getHTTP(): null|MeshHTTPConfig + { + return $this->HTTP; + } + + public function setHTTP(null|MeshHTTPConfig $HTTP): self + { + $this->HTTP = $HTTP; + return $this; + } + + public function getPeering(): null|PeeringMeshConfig + { + return $this->Peering; + } + + public function setPeering(null|PeeringMeshConfig $Peering): self + { + $this->Peering = $Peering; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded, null|self $n = null): self + { + $n = $n ?? new self(); + foreach ($decoded as $k => $v) { + if ('TransparentProxy' === $k || 'transparent_proxy' === $k) { + $n->TransparentProxy = null === $v ? new TransparentProxyMeshConfig() : TransparentProxyMeshConfig::jsonUnserialize($v); + } elseif ('TLS' === $k) { + $n->TLS = null === $v ? null : MeshTLSConfig::jsonUnserialize($v); + } elseif ('HTTP' === $k) { + $n->HTTP = null === $v ? null : MeshHTTPConfig::jsonUnserialize($v); + } elseif ('Peering' === $k) { + $n->Peering = null === $v ? null : PeeringMeshConfig::jsonUnserialize($v); + } elseif ('allow_enabling_permissive_mutual_tls' === $k) { + $n->AllowEnablingPermissiveMutualTLS = $v; + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Kind = Consul::MeshConfigMesh; + if ('' !== $this->Partition) { + $out->Partition = $this->Partition; + } + $out->TransparentProxy = $this->TransparentProxy; + if ($this->AllowEnablingPermissiveMutualTLS) { + $out->allow_enabling_permissive_mutual_tls = true; + } + if (null !== $this->TLS) { + $out->TLS = $this->TLS; + } + if (null !== $this->HTTP) { + $out->HTTP = $this->HTTP; + } + if (null !== $this->Peering) { + $out->Peering = $this->Peering; + } + if (null !== $this->Meta) { + $out->Meta = $this->Meta; + } + $out->CreateIndex = $this->CreateIndex; + $out->ModifyIndex = $this->ModifyIndex; + return $out; + } } diff --git a/src/ConfigEntry/MeshDirectionalTLSConfig.php b/src/ConfigEntry/MeshDirectionalTLSConfig.php new file mode 100644 index 00000000..32e31311 --- /dev/null +++ b/src/ConfigEntry/MeshDirectionalTLSConfig.php @@ -0,0 +1,115 @@ + */ + public array $CipherSuites; + + /** + * @param array $CipherSuites + */ + public function __construct( + string $TLSMinVersion = '', + string $TLSMaxVersion = '', + array $CipherSuites = [], + ) { + $this->TLSMinVersion = $TLSMinVersion; + $this->TLSMaxVersion = $TLSMaxVersion; + $this->setCipherSuites(...$CipherSuites); + } + + public function getTLSMinVersion(): string + { + return $this->TLSMinVersion; + } + + public function setTLSMinVersion(string $TLSMinVersion): self + { + $this->TLSMinVersion = $TLSMinVersion; + return $this; + } + + public function getTLSMaxVersion(): string + { + return $this->TLSMaxVersion; + } + + public function setTLSMaxVersion(string $TLSMaxVersion): self + { + $this->TLSMaxVersion = $TLSMaxVersion; + return $this; + } + + /** + * @return array + */ + public function getCipherSuites(): array + { + return $this->CipherSuites; + } + + public function setCipherSuites(string ...$CipherSuites): self + { + $this->CipherSuites = $CipherSuites; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded): self + { + $n = new self(); + foreach ($decoded as $k => $v) { + if ('CipherSuites' === $k || 'cipher_suites' === $k) { + $n->setCipherSuites(...$v); + } elseif ('tls_min_version' === $k) { + $n->TLSMinVersion = $v; + } elseif ('tls_max_version' === $k) { + $n->TLSMaxVersion = $v; + } else { + $n->{$k} = (string)$v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if ('' !== $this->TLSMinVersion) { + $out->TLSMinVersion = $this->TLSMinVersion; + } + if ('' !== $this->TLSMaxVersion) { + $out->TLSMaxVersion = $this->TLSMaxVersion; + } + if ([] !== $this->CipherSuites) { + $out->CipherSuites = $this->CipherSuites; + } + return $out; + } +} \ No newline at end of file diff --git a/src/ConfigEntry/MeshGatewayConfig.php b/src/ConfigEntry/MeshGatewayConfig.php index 68074e57..94302e0d 100644 --- a/src/ConfigEntry/MeshGatewayConfig.php +++ b/src/ConfigEntry/MeshGatewayConfig.php @@ -21,26 +21,51 @@ */ use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Transcoding; class MeshGatewayConfig extends AbstractModel { - protected const FIELDS = [ - self::FIELD_MODE => Transcoding::OMITEMPTY_STRING_FIELD, - ]; + public MeshGatewayMode $Mode; - private const FIELD_MODE = 'Mode'; - - public string $Mode = ''; + public function __construct( + null|array $data = [], // Deprecated, will be removed. + string|MeshGatewayMode $mode = MeshGatewayMode::Default, + ) { + $this->setMode($mode); + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } - public function getMode(): string + public function getMode(): MeshGatewayMode { return $this->Mode; } - public function setMode(string $mode): self + public function setMode(string|MeshGatewayMode $Mode): self { - $this->Mode = $mode; + $this->Mode = $Mode instanceof MeshGatewayMode ? $Mode : MeshGatewayMode::from($Mode); return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Mode' === $k) { + $n->setMode($v); + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + return $out; + } } diff --git a/src/ConfigEntry/MeshGatewayMode.php b/src/ConfigEntry/MeshGatewayMode.php new file mode 100644 index 00000000..0f2f2311 --- /dev/null +++ b/src/ConfigEntry/MeshGatewayMode.php @@ -0,0 +1,46 @@ +SanitizeXForwardClientCert = $SanitizeXForwardClientCert; + } + + public function isSanitizeXForwardClientCert(): bool + { + return $this->SanitizeXForwardClientCert; + } + + public function setSanitizeXForwardClientCert(bool $SanitizeXForwardClientCert): self + { + $this->SanitizeXForwardClientCert = $SanitizeXForwardClientCert; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded): self + { + $n = new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->SanitizeXForwardClientCert = $this->SanitizeXForwardClientCert; + return $out; + } +} diff --git a/src/ConfigEntry/MeshTLSConfig.php b/src/ConfigEntry/MeshTLSConfig.php new file mode 100644 index 00000000..881a5131 --- /dev/null +++ b/src/ConfigEntry/MeshTLSConfig.php @@ -0,0 +1,88 @@ +Incoming = $Incoming; + $this->Outgoing = $Outgoing; + } + + public function getIncoming(): null|MeshDirectionalTLSConfig + { + return $this->Incoming; + } + public function setIncoming(null|MeshDirectionalTLSConfig $Incoming): self + { + $this->Incoming = $Incoming; + return $this; + } + + public function getOutgoing(): null|MeshDirectionalTLSConfig + { + return $this->Outgoing; + } + + public function setOutgoing(null|MeshDirectionalTLSConfig $Outgoing): self + { + $this->Outgoing = $Outgoing; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded): self + { + $n = new self(); + foreach ($decoded as $k => $V) { + if ('Incoming' === $k) { + $n->Incoming = null === $V ? null : MeshDirectionalTLSConfig::jsonUnserialize($V); + } elseif ('Outgoing' === $k) { + $n->Outgoing = null === $V ? null : MeshDirectionalTLSConfig::jsonUnserialize($V); + } else { + $n->{$k} = $V; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if (null !== $this->Incoming) { + $out->Incoming = $this->Incoming; + } + if (null !== $this->Outgoing) { + $out->Outgoing = $this->Outgoing; + } + return $out; + } +} diff --git a/src/ConfigEntry/MutualTLSMode.php b/src/ConfigEntry/MutualTLSMode.php new file mode 100644 index 00000000..c12604ca --- /dev/null +++ b/src/ConfigEntry/MutualTLSMode.php @@ -0,0 +1,39 @@ +PeerThroughMeshGateways = $PeerThroughMeshGateways; + } + + public function isPeerThroughMeshGateways(): bool + { + return $this->PeerThroughMeshGateways; + } + + public function setPeerThroughMeshGateways(bool $PeerThroughMeshGateways): self + { + $this->PeerThroughMeshGateways = $PeerThroughMeshGateways; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded): self + { + $n = new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->PeerThroughMeshGateways = $this->PeerThroughMeshGateways; + return $out; + } +} diff --git a/src/ConfigEntry/ProxyConfigEntry.php b/src/ConfigEntry/ProxyConfigEntry.php index d8896dd8..8d7c9d6e 100644 --- a/src/ConfigEntry/ProxyConfigEntry.php +++ b/src/ConfigEntry/ProxyConfigEntry.php @@ -55,7 +55,7 @@ class ProxyConfigEntry extends AbstractModel implements ConfigEntry private const FIELD_MESH_GATEWAY = 'MeshGateway'; private const FIELD_EXPOSE = 'Expose'; - public string $Mode = ''; + public string $Mode; public ?TransparentProxyConfig $TransparentProxy = null; public ?FakeMap $Config = null; public MeshGatewayConfig $MeshGateway; diff --git a/src/ConfigEntry/ProxyMode.php b/src/ConfigEntry/ProxyMode.php new file mode 100644 index 00000000..c416a423 --- /dev/null +++ b/src/ConfigEntry/ProxyMode.php @@ -0,0 +1,43 @@ + Transcoding::OMITEMPTY_STRING_FIELD, - self::FIELD_DIALED_DIRECTLY => Transcoding::OMITEMPTY_BOOLEAN_FIELD, - ]; + public int $OutboundListenerPort; + public bool $DialedDirectly; - private const FIELD_OUTBOUND_LISTENER_PORT = 'OutboundListenerPort'; - private const FIELD_DIALED_DIRECTLY = 'DialedDirectly'; - - public int $OutboundListenerPort = 0; - public bool $DialedDirectly = false; + public function __construct( + null|array $data = [], // Deprecated, will be removed. + int $OutboundListenerPort = 0, + bool $DialedDirectly = false + ) { + $this->OutboundListenerPort = $OutboundListenerPort; + $this->DialedDirectly = $DialedDirectly; + if (null !== $data && [] !== $data) { + self::jsonUnserialize((object)$data, $this); + } + } public function getOutboundListenerPort(): int { @@ -57,4 +60,28 @@ public function setDialedDirectly(bool $DialedDirectly): self $this->DialedDirectly = $DialedDirectly; return $this; } + + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + if (0 !== $this->OutboundListenerPort) { + $out->OutboundListenerPort = $this->OutboundListenerPort; + } + if ($this->DialedDirectly) { + $out->DialedDirectly = $this->DialedDirectly; + } + return $out; + } } diff --git a/src/ConfigEntry/TransparentProxyMeshConfig.php b/src/ConfigEntry/TransparentProxyMeshConfig.php new file mode 100644 index 00000000..9b1901eb --- /dev/null +++ b/src/ConfigEntry/TransparentProxyMeshConfig.php @@ -0,0 +1,64 @@ +MeshDestinationsOnly = $MeshDestinationsOnly; + } + + public function isMeshDestinationsOnly(): bool + { + return $this->MeshDestinationsOnly; + } + + public function setMeshDestinationsOnly(bool $MeshDestinationsOnly): self + { + $this->MeshDestinationsOnly = $MeshDestinationsOnly; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded): self + { + $n = new self(); + foreach ($decoded as $k => $v) { + if ('mesh_destinations_only' === $k) { + $n->MeshDestinationsOnly = $v; + } else { + $n->{$k} = $v; + } + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $o = new \stdClass(); + $o->MeshDestinationsOnly = $this->MeshDestinationsOnly; + return $o; + } +} diff --git a/src/ConfigEntry/UpstreamConfiguration.php b/src/ConfigEntry/UpstreamConfiguration.php index 7aa0b584..858b03eb 100644 --- a/src/ConfigEntry/UpstreamConfiguration.php +++ b/src/ConfigEntry/UpstreamConfiguration.php @@ -62,12 +62,12 @@ class UpstreamConfiguration extends AbstractModel private const FIELD_PASSIVE_HEALTH_CHECK = 'PassiveHealthCheck'; private const FIELD_MESH_GATEWAY = 'MeshGateway'; - public string $Name = ''; - public string $Namespace = ''; - public string $EnvoyListenerJSON = ''; - public string $EnvoyClusterJSON = ''; - public string $Protocol = ''; - public int $ConnectTimeoutMs = 0; + public string $Name; + public string $Namespace; + public string $EnvoyListenerJSON; + public string $EnvoyClusterJSON; + public string $Protocol; + public int $ConnectTimeoutMs; public ?UpstreamLimits $UpstreamLimits = null; public ?PassiveHealthCheck $PassiveHealthCheck = null; public ?MeshGatewayConfig $MeshGateway = null; diff --git a/src/Consul.php b/src/Consul.php index 0f1725fa..361ca0e9 100644 --- a/src/Consul.php +++ b/src/Consul.php @@ -73,43 +73,6 @@ class Consul public const SessionBehaviorRelease = 'release'; public const SessionBehaviorDelete = 'delete'; - public const ServiceKindTypical = ''; - public const ServiceKindConnectProxy = 'connect-proxy'; - public const ServiceKindMeshGateway = 'mesh-gateway'; - public const ServiceKindTerminatingGateway = 'terminating-gateway'; - public const ServiceKindIngressGateway = 'ingress-gateway'; - - public const UpstreamDestTypeService = 'service'; - public const UpstreamDestTypePreparedQuery = 'prepared_query'; - - public const AutopilotServerNone = 'none'; - public const AutopilotServerLeader = 'leader'; - public const AutopilotServerVoter = 'voter'; - public const AutopilotServerNonVoter = 'non-voter'; - public const AutopilotServerStaging = 'staging'; - - public const AutopilotTypeVoter = 'voter'; - public const AutopilotTypeReadReplica = 'read-replica'; - public const AutopilotTypeZoneVoter = 'zone-voter'; - public const AutopilotTypeZoneExtraVoter = 'zone-extra-voter'; - public const AutopilotTypeZoneStandby = 'zone-standby'; - - public const AutopilotUpgradeIdle = 'idle'; - public const AutopilotUpgradeAwaitNewVoters = 'await-new-voters'; - public const AutopilotUpgradePromoting = 'promoting'; - public const AutopilotUpgradeDemoting = 'demoting'; - public const AutopilotUpgradeLeaderTransfer = 'leader-transfer'; - public const AutopilotUpgradeAwaitNewServers = 'await-new-servers'; - public const AutopilotUpgradeAwaitServerRemoval = 'await-server-removal'; - public const AutopilotUpgradeDisabled = 'disabled'; - - public const BindingRuleBindTypeService = 'service'; - public const BindingRuleBindTypeRole = 'role'; - - public const MeshGatewayModeDefault = ''; - public const MeshGatewayModeNone = 'none'; - public const MeshGatewayModeLocal = 'local'; - public const MeshGatewayModeRemote = 'remote'; public const MemberTagKeyACLMode = 'acls'; public const MemberTagKeyRole = 'role'; @@ -123,14 +86,27 @@ class Consul public const MemberTagKeyReadReplica = 'read_replica'; public const MemberTagValueReadReplica = '1'; - public const ACLModeDisabled = '0'; - public const ACLModeEnabled = '1'; - public const ACLModeLegacy = '2'; - public const ACLModeUnknown = '3'; - - public const ProxyModeDefault = ''; - public const ProxyModeTransparent = 'transparent'; - public const ProxyModeDirect = 'direct'; + // config_entry.go + public const ServiceDefaults = 'service-defaults'; + public const ProxyDefaults = 'proxy-defaults'; + public const ServiceRouter = 'service-router'; + public const ServiceSplitter = 'service-splitter'; + public const ServiceResolver = 'service-resolver'; + public const IngressGateway = 'ingress-gateway'; + public const TerminatingGateway = 'terminating-gateway'; + public const ServiceIntentions = 'service-intentions'; + public const MeshConfig = 'mesh'; + public const ExportedServices = 'exported-services'; + public const SamenessGroup = 'sameness-group'; + public const RateLimitIPConfig = 'control-plane-request-limit'; + + public const ProxyConfigGlobal = 'global'; + public const MeshConfigMesh = 'mesh'; + public const APIGateway = "api-gateway"; + public const TCPRoute = "tcp-route"; + public const InlineCertificate = 'inline-certificate'; + public const HTTPRoute = 'http-route'; + public const JWTProvider = 'jwt-provider'; // "private" constants diff --git a/src/Coordinate/Coordinate.php b/src/Coordinate/Coordinate.php index 5ccb6a58..7898d6a3 100644 --- a/src/Coordinate/Coordinate.php +++ b/src/Coordinate/Coordinate.php @@ -37,7 +37,7 @@ class Coordinate extends AbstractModel public function __construct($data = []) { - if (\is_array($data)) { + if (is_array($data)) { parent::__construct($data); } elseif ($data instanceof CoordinateConfig) { $this->Vec = array_fill(0, $data->Dimensionality, 0.0); @@ -50,7 +50,7 @@ public function __construct($data = []) '%s::__construct - Argument 1 must be array of values or instance of %s, %s seen', static::class, CoordinateConfig::class, - \is_object($data) ? \get_class($data) : \gettype($data) + is_object($data) ? get_class($data) : gettype($data) ) ); } @@ -98,7 +98,7 @@ public function IsValid(): bool public function IsCompatibleWith(self $other): bool { - return \count($this->Vec) === \count($other->Vec); + return count($this->Vec) === count($other->Vec); } public function ApplyForce(CoordinateConfig $config, float $force, self $other): self diff --git a/src/Coordinate/CoordinateClient.php b/src/Coordinate/CoordinateClient.php index 42aed10e..4a443303 100644 --- a/src/Coordinate/CoordinateClient.php +++ b/src/Coordinate/CoordinateClient.php @@ -36,7 +36,7 @@ public function Datacenters(): CoordinateDatacentersResponse return $ret; } - public function Nodes(?QueryOptions $opts = null): CoordinateEntriesResponse + public function Nodes(null|QueryOptions $opts = null): CoordinateEntriesResponse { $resp = $this->_requireOK($this->_doGet('v1/coordinate/nodes', $opts)); $ret = new CoordinateEntriesResponse(); @@ -44,12 +44,12 @@ public function Nodes(?QueryOptions $opts = null): CoordinateEntriesResponse return $ret; } - public function Update(CoordinateEntry $coordinateEntry, ?WriteOptions $opts = null): WriteResponse + public function Update(CoordinateEntry $coordinateEntry, null|WriteOptions $opts = null): WriteResponse { return $this->_executePut('v1/coordinate/update', $coordinateEntry, $opts); } - public function Node(string $node, ?QueryOptions $opts = null): CoordinateEntriesResponse + public function Node(string $node, null|QueryOptions $opts = null): CoordinateEntriesResponse { $resp = $this->_requireOK($this->_doGet(sprintf('v1/coordinate/node/%s', $node), $opts)); $ret = new CoordinateEntriesResponse(); diff --git a/src/Coordinate/CoordinateDatacentersResponse.php b/src/Coordinate/CoordinateDatacentersResponse.php index 7953d3b4..031fc260 100644 --- a/src/Coordinate/CoordinateDatacentersResponse.php +++ b/src/Coordinate/CoordinateDatacentersResponse.php @@ -25,18 +25,22 @@ class CoordinateDatacentersResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?array $DatacenterMap = null; + /** @var \DCarbone\PHPConsulAPI\Coordinate\CoordinateDatacenterMap[] */ + public array $DatacenterMap = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Coordinate\CoordinateDatacenterMap[] + */ + public function getValue(): array { return $this->DatacenterMap; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->DatacenterMap = []; - foreach ($decodedData as $item) { - $this->DatacenterMap[] = new CoordinateDatacenterMap($item); + foreach ($decoded as $item) { + $this->DatacenterMap[] = CoordinateDatacenterMap::jsonUnserialize($item); } } } diff --git a/src/Coordinate/CoordinateEntriesResponse.php b/src/Coordinate/CoordinateEntriesResponse.php index af95e426..8ecefa28 100644 --- a/src/Coordinate/CoordinateEntriesResponse.php +++ b/src/Coordinate/CoordinateEntriesResponse.php @@ -25,18 +25,22 @@ class CoordinateEntriesResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $Nodes = null; + /** @var \DCarbone\PHPConsulAPI\Coordinate\CoordinateEntry[] */ + public array $Nodes = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Coordinate\CoordinateEntry[] + */ + public function getValue(): array { return $this->Nodes; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->Nodes = []; - foreach ($decodedData as $node) { - $this->Nodes[] = new CoordinateEntry($node); + foreach ($decoded as $node) { + $this->Nodes[] = CoordinateEntry::jsonUnserialize($node); } } } diff --git a/src/Coordinate/funcs.php b/src/Coordinate/funcs.php index 88d0eadd..9f0a90b2 100644 --- a/src/Coordinate/funcs.php +++ b/src/Coordinate/funcs.php @@ -48,7 +48,7 @@ function unitVectorAt(array $vec1, array $vec2): array return [mul($ret, 1.0 / $mag), 0.0]; } - $ret = array_fill(0, \count($ret), 0.0); + $ret = array_fill(0, count($ret), 0.0); $ret[0] = 1.0; return $ret; } diff --git a/src/DecodedBody.php b/src/DecodedBody.php index da120b52..068a2ac0 100644 --- a/src/DecodedBody.php +++ b/src/DecodedBody.php @@ -26,7 +26,7 @@ final class DecodedBody public mixed $Decoded = null; - public function __construct(mixed $decoded, ?Error $err) + public function __construct(mixed $decoded, null|Error $err) { $this->Decoded = $decoded; $this->Err = $err; diff --git a/src/Error.php b/src/Error.php index ce2cd9d8..d84620aa 100644 --- a/src/Error.php +++ b/src/Error.php @@ -29,9 +29,6 @@ */ class Error implements \JsonSerializable { - private const FIELD_MESSAGE = 'message'; - private const FIELD_TIMESTAMP = 'timestamp'; - private Time\Time $time; private string $message; @@ -67,8 +64,8 @@ public function getMessage(): string public function jsonSerialize(): array { return [ - self::FIELD_MESSAGE => $this->message, - self::FIELD_TIMESTAMP => $this->time, + 'message' => $this->message, + 'timestamp' => $this->time, ]; } diff --git a/src/ErrorContainer.php b/src/ErrorContainer.php index 0eb20750..bfd17fbf 100644 --- a/src/ErrorContainer.php +++ b/src/ErrorContainer.php @@ -22,9 +22,9 @@ trait ErrorContainer { - public ?Error $Err = null; + public null|Error $Err = null; - public function getErr(): ?Error + public function getErr(): null|Error { return $this->Err; } diff --git a/src/Event/EventClient.php b/src/Event/EventClient.php index aa76bed0..aa322324 100644 --- a/src/Event/EventClient.php +++ b/src/Event/EventClient.php @@ -26,7 +26,7 @@ class EventClient extends AbstractClient { - public function Fire(UserEvent $event, ?WriteOptions $opts = null): UserEventResponse + public function Fire(UserEvent $event, null|WriteOptions $opts = null): UserEventResponse { $r = $this->_newPutRequest(sprintf('v1/event/fire/%s', $event->Name), '' !== $event->Payload ? $event->Payload : null, $opts); if ('' !== ($nf = $event->NodeFilter)) { @@ -44,7 +44,7 @@ public function Fire(UserEvent $event, ?WriteOptions $opts = null): UserEventRes return $ret; } - public function List(string $name = '', ?QueryOptions $opts = null): UserEventsResponse + public function List(string $name = '', null|QueryOptions $opts = null): UserEventsResponse { $r = $this->_newGetRequest('v1/event/list', $opts); if ('' !== $name) { @@ -58,17 +58,17 @@ public function List(string $name = '', ?QueryOptions $opts = null): UserEventsR public function IDToIndex(string $uuid): int { - if (36 !== \strlen($uuid)) { + if (36 !== strlen($uuid)) { throw new \InvalidArgumentException("{$uuid} is not a valid UUID"); } $lower = substr($uuid, 0, 8) + substr($uuid, 9, 4) + substr($uuid, 14, 4); $upper = substr($uuid, 19, 4) + substr($uuid, 24, 12); - $lowVal = \intval($lower, 10); + $lowVal = intval($lower, 10); if (0 >= $lowVal) { throw new \InvalidArgumentException("{$lower} is not greater than 0"); } - $highVal = \intval($upper, 10); + $highVal = intval($upper, 10); if (0 >= $highVal) { throw new \InvalidArgumentException("{$upper} is not greater than 0"); } diff --git a/src/Event/UserEventResponse.php b/src/Event/UserEventResponse.php index 1b854d71..a71a354e 100644 --- a/src/Event/UserEventResponse.php +++ b/src/Event/UserEventResponse.php @@ -25,15 +25,19 @@ class UserEventResponse extends AbstractValuedWriteResponse implements UnmarshalledResponseInterface { - public ?UserEvent $UserEvent = null; + public null|UserEvent $UserEvent = null; - public function getValue(): ?UserEvent + public function getValue(): null|UserEvent { return $this->UserEvent; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->UserEvent = new UserEvent((array)$decodedData); + if (null === $decoded) { + $this->UserEvent = null; + return; + } + $this->UserEvent = UserEvent::jsonUnserialize($decoded); } } diff --git a/src/Event/UserEventsResponse.php b/src/Event/UserEventsResponse.php index b9eb5f61..d3c56eca 100644 --- a/src/Event/UserEventsResponse.php +++ b/src/Event/UserEventsResponse.php @@ -25,18 +25,22 @@ class UserEventsResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $UserEvents = null; + /** @var \DCarbone\PHPConsulAPI\Event\UserEvent[] */ + public array $UserEvents = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Event\UserEvent[] + */ + public function getValue(): array { return $this->UserEvents; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->UserEvents = []; - foreach ($decodedData as $datum) { - $this->UserEvents[] = new UserEvent($datum); + foreach ($decoded as $datum) { + $this->UserEvents[] = UserEvent::jsonUnserialize($datum); } } } diff --git a/src/FakeMap.php b/src/FakeMap.php deleted file mode 100644 index 5376a1b2..00000000 --- a/src/FakeMap.php +++ /dev/null @@ -1,108 +0,0 @@ -_map = $data; - } - - public static function parse(array|FakeMap|\stdClass|null $input): ?self - { - if (null === $input) { - return null; - } - if (\is_object($input)) { - if ($input instanceof self) { - return $input; - } - return new self((array)$input); - } - if (\is_array($input)) { - return new self($input); - } - throw new \InvalidArgumentException( - sprintf('Cannot parse input of type %s to %s', \gettype($input), self::class) - ); - } - - public function current(): mixed - { - return current($this->_map); - } - - public function next(): void - { - next($this->_map); - } - - public function key(): int|string|null - { - return key($this->_map); - } - - public function valid(): bool - { - return null !== key($this->_map); - } - - public function rewind(): void - { - reset($this->_map); - } - - public function offsetExists(mixed $offset): bool - { - return isset($this->_map[$offset]) || \array_key_exists($offset, $this->_map); - } - - public function offsetGet(mixed $offset): mixed - { - return $this->_map[$offset] ?? null; - } - - public function offsetSet(mixed $offset, mixed $value): void - { - $this->_map[$offset] = $value; - } - - public function offsetUnset(mixed $offset): void - { - unset($this->_map[$offset]); - } - - public function count(): int - { - return \count($this->_map); - } - - public function jsonSerialize(): object - { - return (object)$this->getArrayCopy(); - } -} diff --git a/src/FakeSlice.php b/src/FakeSlice.php deleted file mode 100644 index 255bdf4d..00000000 --- a/src/FakeSlice.php +++ /dev/null @@ -1,188 +0,0 @@ -containedClass)) { - throw new \DomainException( - sprintf( - 'Class "%s" must define $containedClass', - static::class - ) - ); - } - // fastpath for "empty" - if (null === $children || [] === $children) { - return; - } - foreach ($children as $child) { - $this->append($child); - } - } - - public function append(array|AbstractModel|null $value): void - { - // validate provided value is either null or instance of allowed child class - $value = $this->_validateValue($value); - - // set offset to current value of _size, and iterate size by 1 - $offset = $this->_size++; - - // if value is passed, clone then set. - $this->_list[$offset] = $value; - } - - public function current(): bool|AbstractModel - { - return current($this->_list); - } - - public function next(): void - { - next($this->_list); - } - - public function key(): ?int - { - return key($this->_list); - } - - public function valid(): bool - { - return null !== key($this->_list); - } - - public function rewind(): void - { - reset($this->_list); - } - - public function offsetExists(mixed $offset): bool - { - return \is_int($offset) && isset($this->_list[$offset]); - } - - public function offsetGet(mixed $offset): ?AbstractModel - { - $this->_validateOffset($offset); - return $this->_list[$offset]; - } - - public function offsetSet(mixed $offset, mixed $value): void - { - // if incoming offset is null, assume [] (append) operation. - if (null === $offset) { - $this->append($value); - return; - } - - // validate provided offset value - $this->_validateOffset($offset); - - // validate value input and set - $this->_list[$offset] = $this->_validateValue($value); - } - - public function offsetUnset(mixed $offset): void - { - // validate provided offset value - $this->_validateOffset($offset); - - // null out value in list - $this->_list[$offset] = null; - } - - public function count(): int - { - return $this->_size; - } - - public function jsonSerialize(): array - { - if (0 === $this->_size) { - return []; - } - - $out = []; - foreach ($this->_list as $i => $item) { - if (null === $item) { - $out[$i] = null; - } else { - $out[$i] = clone $item; - } - } - return $out; - } - - abstract protected function newChild(array $data): AbstractModel; - - private function _validateOffset(mixed $offset): void - { - if (!\is_int($offset)) { - throw new \InvalidArgumentException( - sprintf( - 'Cannot use offset of type "%s" with "%s"', - \gettype($offset), - static::class - ) - ); - } - if (0 > $offset || $offset >= $this->_size) { - throw new \OutOfRangeException(sprintf('Offset %d does not exist in this list', $offset)); - } - } - - private function _validateValue(mixed $value): ?AbstractModel - { - // fast path for null values - if (null === $value) { - return null; - } - - // if instance of contained class, clone and move on - if ($value instanceof $this->containedClass) { - return clone $value; - } - - // if array, construct new child - if (\is_array($value)) { - return $this->newChild($value); - } - - // if we make it down here, fail. - throw new \InvalidArgumentException( - sprintf( - '%s accepts only objects of type %s, null, or associative array definition as values', - static::class, - $this->containedClass, - ) - ); - } -} diff --git a/src/Health/HealthCheckDefinition.php b/src/Health/HealthCheckDefinition.php index 1c6a1e1e..75983ca4 100644 --- a/src/Health/HealthCheckDefinition.php +++ b/src/Health/HealthCheckDefinition.php @@ -21,95 +21,43 @@ */ use DCarbone\Go\Time; -use DCarbone\Go\Time\Duration; use DCarbone\PHPConsulAPI\AbstractModel; -use DCarbone\PHPConsulAPI\Operator\ReadableDuration; -use DCarbone\PHPConsulAPI\Transcoding; class HealthCheckDefinition extends AbstractModel implements \JsonSerializable { - protected const FIELDS = [ - self::FIELD_INTERVAL_DURATION => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_DURATION, - Transcoding::FIELD_SKIP => true, - ], - self::FIELD_TIMEOUT_DURATION => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_DURATION, - Transcoding::FIELD_SKIP => true, - ], - self::FIELD_DEREGISTER_CRITICAL_SERVICE_AFTER_DURATION => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_DURATION, - Transcoding::FIELD_SKIP => true, - ], - self::FIELD_TIMEOUT => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => [ReadableDuration::class, 'unmarshalJSON'], - ], - self::FIELD_INTERVAL => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => [ReadableDuration::class, 'unmarshalJSON'], - ], - self::FIELD_DEREGISTER_CRITICAL_SERVICE_AFTER => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => [ReadableDuration::class, 'unmarshalJSON'], - ], - ]; - - private const FIELD_HTTP = 'HTTP'; - private const FIELD_HEADER = 'Header'; - private const FIELD_METHOD = 'Method'; - private const FIELD_BODY = 'Body'; - private const FIELD_TLS_SKIP_VERIFY = 'TLSSkipVerify'; - private const FIELD_TCP = 'TCP'; - private const FIELD_INTERVAL_DURATION = 'IntervalDuration'; - private const FIELD_TIMEOUT_DURATION = 'TimeoutDuration'; - private const FIELD_DEREGISTER_CRITICAL_SERVICE_AFTER_DURATION = 'DeregisterCriticalServiceAfterDuration'; - private const FIELD_INTERVAL = 'Interval'; - private const FIELD_TIMEOUT = 'Timeout'; - private const FIELD_DEREGISTER_CRITICAL_SERVICE_AFTER = 'DeregisterCriticalServiceAfter'; - - public string $HTTP = ''; - public array $Header = []; - public string $Method = ''; - public string $Body = ''; - public bool $TLSSkipVerify = false; - public string $TCP = ''; - public Duration $IntervalDuration; - public Duration $TimeoutDuration; - public Duration $DeregisterCriticalServiceAfterDuration; - - public ReadableDuration $Interval; - public ReadableDuration $Timeout; - public ReadableDuration $DeregisterCriticalServiceAfter; - - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!isset($this->Interval)) { - $this->Interval = new ReadableDuration(); - } - if (!isset($this->Timeout)) { - $this->Timeout = new ReadableDuration(); - } - if (!isset($this->DeregisterCriticalServiceAfter)) { - $this->DeregisterCriticalServiceAfter = new ReadableDuration(); - } - - if (!isset($this->IntervalDuration)) { - $this->IntervalDuration = Time::ParseDuration((string)$this->Interval); - } else { - $this->Interval = ReadableDuration::fromDuration((string)$this->IntervalDuration); - } - if (!isset($this->TimeoutDuration)) { - $this->TimeoutDuration = Time::ParseDuration((string)$this->Timeout); - } else { - $this->Timeout = ReadableDuration::fromDuration((string)$this->TimeoutDuration); - } - if (!isset($this->DeregisterCriticalServiceAfterDuration)) { - $this->DeregisterCriticalServiceAfterDuration = Time::ParseDuration( - (string)$this->DeregisterCriticalServiceAfter - ); - } else { - $this->DeregisterCriticalServiceAfter = ReadableDuration::fromDuration( - (string)$this->DeregisterCriticalServiceAfterDuration - ); + public string $HTTP; + public array $Header; + public string $Method; + public string $Body; + public bool $TLSSkipVerify; + public string $TCP; + public Time\Duration $IntervalDuration; + public Time\Duration $TimeoutDuration; + public Time\Duration $DeregisterCriticalServiceAfterDuration; + + public function __construct( + null|array $data = null, + string $HTTP = '', + iterable $Header = [], + string $Method = '', + string $Body = '', + bool $TLSSkipVerify = false, + string $TCP = '', + null|int|float|string|\DateInterval|Time\Duration $IntervalDuration = null, + null|int|float|string|\DateInterval|Time\Duration $TimeoutDuration = null, + null|int|float|string|\DateInterval|Time\Duration $DeregisterCriticalServiceAfterDuration = null, + ) { + $this->HTTP = $HTTP; + $this->setHeader(...$Header); + $this->Method = $Method; + $this->Body = $Body; + $this->TLSSkipVerify = $TLSSkipVerify; + $this->TCP = $TCP; + $this->setIntervalDuration($IntervalDuration); + $this->setTimeoutDuration($TimeoutDuration); + $this->setDeregisterCriticalServiceAfterDuration($DeregisterCriticalServiceAfterDuration); + if (null !== $data && [] !== $data) { + static::jsonUnserialize((object)$data, $this); } } @@ -118,16 +66,34 @@ public function getHTTP(): string return $this->HTTP; } + public function setHTTP(string $HTTP): self + { + $this->HTTP = $HTTP; + return $this; + } + public function getHeader(): array { return $this->Header; } + public function setHeader(string ...$Header): self + { + $this->Header = $Header; + return $this; + } + public function getMethod(): string { return $this->Method; } + public function setMethod(string $Method): self + { + $this->Method = $Method; + return $this; + } + public function getBody(): string { return $this->Body; @@ -144,75 +110,91 @@ public function isTLSSkipVerify(): bool return $this->TLSSkipVerify; } + public function setTLSSkipVerify(bool $TLSSkipVerify): self + { + $this->TLSSkipVerify = $TLSSkipVerify; + return $this; + } + public function getTCP(): string { return $this->TCP; } - public function getIntervalDuration(): ?Duration + public function setTCP(string $TCP): self { - return $this->IntervalDuration; + $this->TCP = $TCP; + return $this; } - public function getTimeoutDuration(): ?Duration + public function getIntervalDuration(): Time\Duration { - return $this->TimeoutDuration; + return $this->IntervalDuration; } - public function getDeregisterCriticalServiceAfterDuration(): ?Duration - { - return $this->DeregisterCriticalServiceAfterDuration; + public function setIntervalDuration( + null|int|float|string|\DateInterval|Time\Duration $IntervalDuration + ): self { + $this->IntervalDuration = Time::Duration($IntervalDuration); + return $this; } - public function getInterval(): ?ReadableDuration + public function getTimeoutDuration(): Time\Duration { - return $this->Interval; + return $this->TimeoutDuration; } - public function getTimeout(): ?ReadableDuration - { - return $this->Timeout; + public function setTimeoutDuration( + null|int|float|string|\DateInterval|Time\Duration $TimeoutDuration + ): self { + $this->TimeoutDuration = Time::Duration($TimeoutDuration); + return $this; } - public function getDeregisterCriticalServiceAfter(): ?ReadableDuration + public function getDeregisterCriticalServiceAfterDuration(): Time\Duration { - return $this->DeregisterCriticalServiceAfter; + return $this->DeregisterCriticalServiceAfterDuration; } - public function jsonSerialize(): array - { - // prepare base definition - $prep = [ - self::FIELD_HTTP => $this->HTTP, - self::FIELD_HEADER => $this->Header, - self::FIELD_METHOD => $this->Method, - self::FIELD_BODY => $this->Body, - self::FIELD_TLS_SKIP_VERIFY => $this->TLSSkipVerify, - self::FIELD_TCP => $this->TCP, + public function setDeregisterCriticalServiceAfterDuration( + null|int|float|string|\DateInterval|Time\Duration $DeregisterCriticalServiceAfterDuration + ): self { + $this->DeregisterCriticalServiceAfterDuration = Time::Duration($DeregisterCriticalServiceAfterDuration); + return $this; + } - ]; - if (0 !== $this->IntervalDuration->Nanoseconds()) { - $prep[self::FIELD_INTERVAL] = (string)$this->IntervalDuration; - } elseif (0 !== $this->Interval->Nanoseconds()) { - $prep[self::FIELD_INTERVAL] = (string)$this->Interval; - } - if (0 !== $this->TimeoutDuration->Nanoseconds()) { - $prep[self::FIELD_TIMEOUT] = (string)$this->TimeoutDuration; - } elseif (0 !== $this->Timeout->Nanoseconds()) { - $prep[self::FIELD_TIMEOUT] = (string)$this->Timeout; - } - if (0 !== $this->DeregisterCriticalServiceAfterDuration->Nanoseconds()) { - $prep[self::FIELD_DEREGISTER_CRITICAL_SERVICE_AFTER] = (string)$this->DeregisterCriticalServiceAfterDuration; - } elseif (0 !== $this->DeregisterCriticalServiceAfter->Nanoseconds()) { - $prep[self::FIELD_DEREGISTER_CRITICAL_SERVICE_AFTER] = (string)$this->DeregisterCriticalServiceAfter; + public static function jsonUnserialize(\stdClass $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $k => $v) { + if ('Interval' === $k || 'IntervalDuration' === $k) { + $n->IntervalDuration = Time::Duration($v); + } elseif ('Timeout' === $k || 'TimeoutDuration' === $k) { + $n->TimeoutDuration = Time::Duration($v); + } elseif ('DeregisterCriticalServiceAfter' === $k || 'DeregisterCriticalServiceAfterDuration' === $k) { + $n->DeregisterCriticalServiceAfterDuration = Time::Duration($v); + } else { + $n->{$k} = $v; + } } + return $n; + } - // handle per-field marshalling - $out = []; - foreach ($prep as $field => $value) { - $this->marshalField($out, $field, $value); + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; } - + $out->HTTP = $this->HTTP; + $out->Header = $this->Header; + $out->Method = $this->Method; + $out->Body = $this->Body; + $out->TLSSkipVerify = $this->TLSSkipVerify; + $out->TCP = $this->TCP; + $out->Interval = (string)$this->IntervalDuration; + $out->Timeout = (string)$this->TimeoutDuration; + $out->DeregisterCriticalServiceAfter = (string)$this->DeregisterCriticalServiceAfterDuration; return $out; } } diff --git a/src/Health/HealthChecks.php b/src/Health/HealthChecks.php index f764dd26..e60860c4 100644 --- a/src/Health/HealthChecks.php +++ b/src/Health/HealthChecks.php @@ -22,17 +22,26 @@ use DCarbone\PHPConsulAPI\AbstractModel; use DCarbone\PHPConsulAPI\Consul; -use DCarbone\PHPConsulAPI\FakeSlice; -class HealthChecks extends FakeSlice +/** + * @implements \ArrayAccess + * @implements \IteratorAggregate + */ +class HealthChecks extends AbstractModel implements \IteratorAggregate, \Countable, \ArrayAccess { - protected string $containedClass = HealthCheck::class; + /** @var \DCarbone\PHPConsulAPI\Health\HealthCheck[] */ + protected array $Checks = []; + + public function __construct(HealthCheck ...$Checks) + { + $this->Checks = $Checks; + } public function AggregatedStatus(): string { $passing = $warning = $critical = $maintenance = false; - foreach ($this as $check) { - if (Consul::NodeMaint === $check->CheckID || 0 === strpos($check->CheckID, Consul::ServiceMaintPrefix)) { + foreach ($this->Checks as $check) { + if (Consul::NodeMaint === $check->CheckID || str_starts_with($check->CheckID, Consul::ServiceMaintPrefix)) { // TODO: Maybe just return maintenance right now...? $maintenance = true; continue; @@ -68,8 +77,66 @@ public function AggregatedStatus(): string return Consul::HealthPassing; } - protected function newChild(array $data): AbstractModel + public function getIterator(): \Traversable + { + return new \ArrayIterator($this->Checks); + } + + public function count(): int + { + return count($this->Checks); + } + + public function offsetExists($offset): bool + { + return is_int($offset) && isset($this->Checks[$offset]); + } + + public function offsetGet($offset): null|HealthCheck + { + if (!isset($this->Checks[$offset])) { + throw new \OutOfRangeException("Offset $offset does not exist"); + } + return $this->Checks[$offset]; + } + + public function offsetSet($offset, $value): void + { + if (!$value instanceof HealthCheck) { + throw new \InvalidArgumentException(sprintf("Value must be an instance of %s", HealthCheck::class)); + } + if (null === $offset) { + $this->Checks[] = $value; + } else { + if (!is_int($offset)) { + throw new \InvalidArgumentException('Offset must be an integer'); + } + $this->Checks[$offset] = $value; + } + } + + public function offsetUnset($offset): void + { + unset($this->Checks[$offset]); + } + + /** + * @param array<\stdClass> $decoded + */ + public static function jsonUnserialize(array $decoded, null|self $into = null): static + { + $n = $into ?? new self(); + foreach ($decoded as $d) { + $n->Checks[] = HealthCheck::jsonUnserialize($d); + } + return $n; + } + + /** + * @return \DCarbone\PHPConsulAPI\Health\HealthCheck[] + */ + public function jsonSerialize(): array { - return new HealthCheck($data); + return $this->Checks; } } diff --git a/src/Health/HealthChecksResponse.php b/src/Health/HealthChecksResponse.php index 54852a40..14081f1e 100644 --- a/src/Health/HealthChecksResponse.php +++ b/src/Health/HealthChecksResponse.php @@ -25,15 +25,24 @@ class HealthChecksResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?HealthChecks $HealthChecks = null; + public HealthChecks $HealthChecks; - public function getValue(): ?HealthChecks + public function __construct() + { + $this->HealthChecks = new HealthChecks(); + } + + public function getValue(): HealthChecks { return $this->HealthChecks; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->HealthChecks = new HealthChecks((array)$decodedData); + if (null === $decoded) { + $this->HealthChecks = new HealthChecks(); + return; + } + $this->HealthChecks = HealthChecks::jsonUnserialize($decoded); } } diff --git a/src/Health/HealthClient.php b/src/Health/HealthClient.php index b7ff2704..82cf7370 100644 --- a/src/Health/HealthClient.php +++ b/src/Health/HealthClient.php @@ -30,12 +30,12 @@ class HealthClient extends AbstractClient private const connectHealth = 'connect'; private const ingressHealth = 'ingress'; - public function Node(string $node, ?QueryOptions $opts = null): HealthChecksResponse + public function Node(string $node, null|QueryOptions $opts = null): HealthChecksResponse { return $this->_getHealthChecks(sprintf('v1/health/node/%s', $node), $opts); } - public function Checks(string $service, ?QueryOptions $opts = null): HealthChecksResponse + public function Checks(string $service, null|QueryOptions $opts = null): HealthChecksResponse { return $this->_getHealthChecks(sprintf('v1/health/checks/%s', $service), $opts); } @@ -44,7 +44,7 @@ public function ServiceMultipleTags( string $service, array $tags = [], bool $passingOnly = false, - ?QueryOptions $opts = null + null|QueryOptions $opts = null ): ServiceEntriesResponse { return $this->_getServiceEntries($service, $tags, $passingOnly, $opts, self::serviceHealth); } @@ -53,7 +53,7 @@ public function Service( string $service, string $tag = '', bool $passingOnly = false, - ?QueryOptions $opts = null + null|QueryOptions $opts = null ): ServiceEntriesResponse { return $this->ServiceMultipleTags($service, '' !== $tag ? [$tag] : [], $passingOnly, $opts); } @@ -62,7 +62,7 @@ public function IngressMultipleTags( string $service, array $tags = [], bool $passingOnly = false, - ?QueryOptions $opts = null + null|QueryOptions $opts = null ): ServiceEntriesResponse { return $this->_getServiceEntries($service, $tags, $passingOnly, $opts, self::ingressHealth); } @@ -71,7 +71,7 @@ public function Ingress( string $service, string $tag = '', bool $passingOnly = false, - ?QueryOptions $opts = null + null|QueryOptions $opts = null ): ServiceEntriesResponse { return $this->IngressMultipleTags($service, '' !== $tag ? [$tag] : [], $passingOnly, $opts); } @@ -80,7 +80,7 @@ public function ConnectMultipleTags( string $service, array $tags = [], bool $passingOnly = false, - ?QueryOptions $opts = null + null|QueryOptions $opts = null ): ServiceEntriesResponse { return $this->_getServiceEntries($service, $tags, $passingOnly, $opts, self::connectHealth); } @@ -89,16 +89,16 @@ public function Connect( string $service, string $tag = '', bool $passingOnly = false, - ?QueryOptions $opts = null + null|QueryOptions $opts = null ): ServiceEntriesResponse { return $this->ConnectMultipleTags($service, '' !== $tag ? [$tag] : [], $passingOnly, $opts); } - public function State(string $state, ?QueryOptions $opts = null): HealthChecksResponse + public function State(string $state, null|QueryOptions $opts = null): HealthChecksResponse { static $validStates = ['any', 'warning', 'critical', 'passing', 'unknown']; - if (!\in_array($state, $validStates, true)) { + if (!in_array($state, $validStates, true)) { $ret = new HealthChecksResponse(); $ret->Err = new Error( sprintf( @@ -114,7 +114,7 @@ public function State(string $state, ?QueryOptions $opts = null): HealthChecksRe return $this->_getHealthChecks(sprintf('v1/health/state/%s', $state), $opts); } - protected function _getHealthChecks(string $path, ?QueryOptions $opts): HealthChecksResponse + protected function _getHealthChecks(string $path, null|QueryOptions $opts): HealthChecksResponse { $resp = $this->_requireOK($this->_doGet($path, $opts)); $ret = new HealthChecksResponse(); @@ -126,7 +126,7 @@ private function _getServiceEntries( string $service, array $tags, bool $passingOnly, - ?QueryOptions $opts, + null|QueryOptions $opts, string $healthType ): ServiceEntriesResponse { $uri = match ($healthType) { diff --git a/src/Health/ServiceEntriesResponse.php b/src/Health/ServiceEntriesResponse.php index 5ed674ea..9223803b 100644 --- a/src/Health/ServiceEntriesResponse.php +++ b/src/Health/ServiceEntriesResponse.php @@ -25,18 +25,22 @@ class ServiceEntriesResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $ServiceEntries = null; + /** @var \DCarbone\PHPConsulAPI\Health\ServiceEntry[] */ + public array $ServiceEntries = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Health\ServiceEntry[] + */ + public function getValue(): array { return $this->ServiceEntries; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->ServiceEntries = []; - foreach ($decodedData as $entry) { - $this->ServiceEntries[] = new ServiceEntry($entry); + foreach ($decoded as $entry) { + $this->ServiceEntries[] = ServiceEntry::jsonUnserialize($entry); } } } diff --git a/src/HttpAuth.php b/src/HttpAuth.php index 0e26216f..97057e30 100644 --- a/src/HttpAuth.php +++ b/src/HttpAuth.php @@ -22,11 +22,8 @@ class HttpAuth implements \JsonSerializable { - private const FIELD_USERNAME = 'username'; - private const FIELD_PASSWORD = 'password'; - - public string $username = ''; - public string $password = ''; + public string $username; + public string $password; public function __construct(string $username = '', string $password = '') { @@ -49,18 +46,23 @@ public function compileAuthString(): string return (string)$this; } - public function jsonSerialize(): array + public function jsonSerialize(): \stdClass { - return [self::FIELD_USERNAME => $this->username, self::FIELD_PASSWORD => $this->password]; + $out = new \stdClass(); + $out->username = $this->username; + if ('' !== $this->password) { + $out->password = $this->password; + } + return $out; } public function __debugInfo(): array { - return [self::FIELD_USERNAME => $this->username]; + return ['username' => $this->username]; } public function __toString(): string { - return trim(sprintf('%s:%s', $this->username, $this->password), ':'); + return $this->password !== '' ? "{$this->username}:{$this->password}" : $this->username; } } diff --git a/src/KV/KVClient.php b/src/KV/KVClient.php index 2fb51783..8adcd094 100644 --- a/src/KV/KVClient.php +++ b/src/KV/KVClient.php @@ -31,7 +31,7 @@ class KVClient extends AbstractClient { - public function Get(string $key, ?QueryOptions $opts = null): KVPairResponse + public function Get(string $key, null|QueryOptions $opts = null): KVPairResponse { $resp = $this->_doGet(sprintf('v1/kv/%s', $key), $opts); $ret = new KVPairResponse(); @@ -59,7 +59,7 @@ public function Get(string $key, ?QueryOptions $opts = null): KVPairResponse return $ret; } - public function Put(KVPair $p, ?WriteOptions $opts = null): WriteResponse + public function Put(KVPair $p, null|WriteOptions $opts = null): WriteResponse { $r = $this->_newPutRequest(sprintf('v1/kv/%s', $p->Key), $p->Value, $opts); if (0 !== $p->Flags) { @@ -71,12 +71,12 @@ public function Put(KVPair $p, ?WriteOptions $opts = null): WriteResponse return $ret; } - public function Delete(string $key, ?WriteOptions $opts = null): WriteResponse + public function Delete(string $key, null|WriteOptions $opts = null): WriteResponse { return $this->_executeDelete(sprintf('v1/kv/%s', $key), $opts); } - public function List(string $prefix = '', ?QueryOptions $opts = null): KVPairsResponse + public function List(string $prefix = '', null|QueryOptions $opts = null): KVPairsResponse { $r = $this->_newGetRequest(sprintf('v1/kv/%s', $prefix), $opts); $r->params->set('recurse', ''); @@ -86,7 +86,7 @@ public function List(string $prefix = '', ?QueryOptions $opts = null): KVPairsRe return $ret; } - public function Keys(string $prefix = '', ?QueryOptions $opts = null): ValuedQueryStringsResponse + public function Keys(string $prefix = '', null|QueryOptions $opts = null): ValuedQueryStringsResponse { $r = $this->_newGetRequest(sprintf('v1/kv/%s', $prefix), $opts); $r->params->set('keys', ''); @@ -96,7 +96,7 @@ public function Keys(string $prefix = '', ?QueryOptions $opts = null): ValuedQue return $ret; } - public function CAS(KVPair $p, ?WriteOptions $opts = null): ValuedWriteBoolResponse + public function CAS(KVPair $p, null|WriteOptions $opts = null): ValuedWriteBoolResponse { $r = $this->_newPutRequest(sprintf('v1/kv/%s', $p->Key), $p->Value, $opts); $r->params->set('cas', (string)$p->ModifyIndex); @@ -109,7 +109,7 @@ public function CAS(KVPair $p, ?WriteOptions $opts = null): ValuedWriteBoolRespo return $ret; } - public function Acquire(KVPair $p, ?WriteOptions $opts = null): WriteResponse + public function Acquire(KVPair $p, null|WriteOptions $opts = null): WriteResponse { $r = $this->_newPutRequest(sprintf('v1/kv/%s', $p->Key), $p->Value, $opts); $r->params->set('acquire', $p->Session); @@ -122,7 +122,7 @@ public function Acquire(KVPair $p, ?WriteOptions $opts = null): WriteResponse return $ret; } - public function DeleteCAS(KVPair $p, ?WriteOptions $opts = null): ValuedWriteBoolResponse + public function DeleteCAS(KVPair $p, null|WriteOptions $opts = null): ValuedWriteBoolResponse { $r = $this->_newDeleteRequest(sprintf('v1/kv/%s', ltrim($p->Key, '/')), $opts); $r->params['cas'] = (string)$p->ModifyIndex; @@ -132,7 +132,7 @@ public function DeleteCAS(KVPair $p, ?WriteOptions $opts = null): ValuedWriteBoo return $ret; } - public function Release(KVPair $p, ?WriteOptions $opts = null): WriteResponse + public function Release(KVPair $p, null|WriteOptions $opts = null): WriteResponse { $r = $this->_newPutRequest(sprintf('v1/kv/%s', $p->Key), $p->Value, $opts); $r->params->set('release', $p->Session); @@ -145,7 +145,7 @@ public function Release(KVPair $p, ?WriteOptions $opts = null): WriteResponse return $ret; } - public function DeleteTree(string $prefix, ?WriteOptions $opts = null): WriteResponse + public function DeleteTree(string $prefix, null|WriteOptions $opts = null): WriteResponse { $r = $this->_newDeleteRequest(sprintf('v1/kv/%s', $prefix), $opts); $r->params['recurse'] = ''; @@ -155,7 +155,7 @@ public function DeleteTree(string $prefix, ?WriteOptions $opts = null): WriteRes return $ret; } - public function Txn(KVTxnOps $txn, ?QueryOptions $opts = null): KVTxnAPIResponse + public function Txn(KVTxnOps $txn, null|QueryOptions $opts = null): KVTxnAPIResponse { $txnOps = new KVTxnOps(); foreach ($txn as $op) { @@ -206,7 +206,7 @@ public function Txn(KVTxnOps $txn, ?QueryOptions $opts = null): KVTxnAPIResponse * @var \DCarbone\PHPConsulAPI\Error|null error, if any * ) */ - public function Tree(string $prefix = '', ?QueryOptions $opts = null): array + public function Tree(string $prefix = '', null|QueryOptions $opts = null): array { [$valueList, $_, $err] = $this->List($prefix, $opts); diff --git a/src/KV/KVPairResponse.php b/src/KV/KVPairResponse.php index f6abca82..89d95eb9 100644 --- a/src/KV/KVPairResponse.php +++ b/src/KV/KVPairResponse.php @@ -25,15 +25,19 @@ class KVPairResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?KVPair $KVPair = null; + public null|KVPair $KVPair = null; - public function getValue(): ?KVPair + public function getValue(): null|KVPair { return $this->KVPair; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->KVPair = new KVPair((array)$decodedData, true); + if (null === $decoded) { + $this->KVPair = null; + return; + } + $this->KVPair = KVPair::jsonUnserialize($decoded); } } diff --git a/src/KV/KVPairsResponse.php b/src/KV/KVPairsResponse.php index 2c5a1a65..ddd34cdb 100644 --- a/src/KV/KVPairsResponse.php +++ b/src/KV/KVPairsResponse.php @@ -25,15 +25,24 @@ class KVPairsResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?KVPairs $KVPairs = null; + public KVPairs $KVPairs; - public function getValue(): ?KVPairs + public function __construct() + { + $this->KVPairs = new KVPairs(); + } + + public function getValue(): null|KVPairs { return $this->KVPairs; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->KVPairs = new KVPairs((array)$decodedData); + if (null === $decoded) { + $this->KVPairs = new KVPairs(); + return; + } + $this->KVPairs = KVPairs::jsonUnserialize($decoded); } } diff --git a/src/KV/KVTree.php b/src/KV/KVTree.php index ecfd21e9..ff493e58 100644 --- a/src/KV/KVTree.php +++ b/src/KV/KVTree.php @@ -79,12 +79,12 @@ public function getChildren(): \RecursiveIterator|KVTree|KVPair public function count(): int { - return \count($this->_children); + return count($this->_children); } public function offsetExists(mixed $offset): bool { - if (\is_string($offset)) { + if (is_string($offset)) { $subPath = str_replace($this->_prefix, '', $offset); $cnt = substr_count($subPath, '/'); @@ -96,12 +96,12 @@ public function offsetExists(mixed $offset): bool } } - return isset($this->_children[$offset]) || \array_key_exists($offset, $this->_children); + return isset($this->_children[$offset]) || array_key_exists($offset, $this->_children); } public function offsetGet(mixed $offset): KVTree|KVPair|null { - if (\is_string($offset)) { + if (is_string($offset)) { $subPath = str_replace($this->_prefix, '', $offset); $cnt = substr_count($subPath, '/'); if (1 < $cnt || (1 === $cnt && '/' !== substr($subPath, -1))) { @@ -130,7 +130,7 @@ public function offsetGet(mixed $offset): KVTree|KVPair|null public function offsetSet(mixed $offset, mixed $value): void { - if ('string' === \gettype($offset)) { + if ('string' === gettype($offset)) { $subPath = str_replace($this->_prefix, '', $offset); $cnt = substr_count($subPath, '/'); diff --git a/src/KV/KVTxnAPIResponse.php b/src/KV/KVTxnAPIResponse.php index d64b2515..05221fe1 100644 --- a/src/KV/KVTxnAPIResponse.php +++ b/src/KV/KVTxnAPIResponse.php @@ -29,14 +29,14 @@ class KVTxnAPIResponse use ErrorContainer; public bool $OK = false; - public ?KVTxnResponse $KVTxnResponse = null; + public null|KVTxnResponse $KVTxnResponse = null; public function isOK(): bool { return $this->OK; } - public function getKVTxnResponse(): ?KVTxnResponse + public function getKVTxnResponse(): null|KVTxnResponse { return $this->KVTxnResponse; } diff --git a/src/MapResponse.php b/src/MapResponse.php index cecfec0f..4425a4f1 100644 --- a/src/MapResponse.php +++ b/src/MapResponse.php @@ -22,15 +22,15 @@ class MapResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?array $Map = null; + public null|\stdClass $Map = null; - public function getValue(): ?array + public function getValue(): null|\stdClass { return $this->Map; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->Map = $decodedData; + $this->Map = $decoded; } } diff --git a/src/Marshaller.php b/src/Marshaller.php deleted file mode 100644 index bc9b5ce0..00000000 --- a/src/Marshaller.php +++ /dev/null @@ -1,152 +0,0 @@ - (string)$value, - Transcoding::INTEGER => (int)$value, - Transcoding::DOUBLE => (float)$value, - Transcoding::BOOLEAN => (bool)$value, - default => throw new \InvalidArgumentException( - sprintf('Unable to handle serializing to %s', $def[Transcoding::FIELD_MARSHAL_AS]) - ), - }; - } - - // if this field is NOT explicitly marked as "omitempty", set and move on. - if (!isset($def[Transcoding::FIELD_OMITEMPTY]) || true !== $def[Transcoding::FIELD_OMITEMPTY]) { - $output[$field] = $value; - return; - } - - // otherwise, handle value setting on a per-type basis - - $type = \gettype($value); - - // strings must be non empty - if (Transcoding::STRING === $type) { - if ('' !== $value) { - $output[$field] = $value; - } - return; - } - - // integers must be non-zero (negatives are ok) - if (Transcoding::INTEGER === $type) { - if (0 !== $value) { - $output[$field] = $value; - } - return; - } - - // floats must be non-zero (negatives are ok) - if (Transcoding::DOUBLE === $type) { - if (0.0 !== $value) { - $output[$field] = $value; - } - return; - } - - // bools must be true - if (Transcoding::BOOLEAN === $type) { - if ($value) { - $output[$field] = $value; - } - return; - } - - // object "non-zero" calculations require a bit more finesse... - if (Transcoding::OBJECT === $type) { - // AbstractModels are collections, and are non-zero if they contain at least 1 entry - if ($value instanceof FakeSlice || $value instanceof FakeMap) { - if (0 < \count($value)) { - $output[$field] = $value; - } - return; - } - - // Time\Duration types are non-zero if their internal value is > 0 - if ($value instanceof Time\Duration) { - if (0 < $value->Nanoseconds()) { - $output[$field] = $value; - } - return; - } - - // Time\Time values are non-zero if they are anything greater than epoch - if ($value instanceof Time\Time) { - if (!$value->IsZero()) { - $output[$field] = $value; - } - return; - } - - // otherwise, by being defined it is non-zero, so add it. - $output[$field] = $value; - return; - } - - // arrays must have at least 1 value - if (Transcoding::ARRAY === $type) { - if ([] !== $value) { - $output[$field] = $value; - } - return; - } - - // todo: be more better about resources - if (Transcoding::RESOURCE === $type) { - $output[$field] = $value; - return; - } - - // once we get here the only possible value type is "NULL", which are always considered "empty". thus, do not - // set any value. - } -} diff --git a/src/Operator/ReadableDuration.php b/src/Operator/AutopilotServerStatus.php similarity index 56% rename from src/Operator/ReadableDuration.php rename to src/Operator/AutopilotServerStatus.php index 303c6720..b732d9e3 100644 --- a/src/Operator/ReadableDuration.php +++ b/src/Operator/AutopilotServerStatus.php @@ -20,23 +20,11 @@ limitations under the License. */ -use DCarbone\Go\Time; -use DCarbone\PHPConsulAPI\ScalarType; - -class ReadableDuration extends Time\Duration implements \JsonSerializable, ScalarType +enum AutopilotServerStatus: string { - public static function unmarshalJSON(object $instance, string $field, mixed $value): void - { - $instance->{$field} = new self(\intval($value, 10)); - } - - public static function fromDuration(string $s): self - { - return new self(Time::ParseDuration($s)->Nanoseconds()); - } - - public function jsonSerialize(): string - { - return (string)$this; - } + case None = 'none'; + case Leader = 'leader'; + case Voter = 'voter'; + case NonVoter = 'non-voter'; + case Staging = 'staging'; } diff --git a/src/Operator/AutopilotServerType.php b/src/Operator/AutopilotServerType.php new file mode 100644 index 00000000..70107e96 --- /dev/null +++ b/src/Operator/AutopilotServerType.php @@ -0,0 +1,30 @@ +AutopilotState; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->AutopilotState = new AutopilotState($decodedData); + $this->AutopilotState = AutopilotState::jsonUnserialize($decoded); } } diff --git a/src/Operator/AutopilotUpgradeStatus.php b/src/Operator/AutopilotUpgradeStatus.php new file mode 100644 index 00000000..1c40f86f --- /dev/null +++ b/src/Operator/AutopilotUpgradeStatus.php @@ -0,0 +1,33 @@ +AreaJoinResponses; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->AreaJoinResponses = []; - foreach ($decodedData as $area) { - $this->AreaJoinResponses[] = new AreaJoinResponse($area); + foreach ($decoded as $area) { + $this->AreaJoinResponses[] = AreaJoinResponse::jsonUnserialize($area); } } } diff --git a/src/Operator/OperatorAreasResponse.php b/src/Operator/OperatorAreasResponse.php index 9e7417a4..928e3fba 100644 --- a/src/Operator/OperatorAreasResponse.php +++ b/src/Operator/OperatorAreasResponse.php @@ -25,18 +25,22 @@ class OperatorAreasResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $Areas = null; + /** @var \DCarbone\PHPConsulAPI\Operator\Area[] */ + public array $Areas = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Operator\Area[] + */ + public function getValue(): array { return $this->Areas; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->Areas = []; - foreach ($decodedData as $area) { - $this->Areas[] = new Area($area); + foreach ($decoded as $area) { + $this->Areas[] = Area::jsonUnserialize($area); } } } diff --git a/src/Operator/OperatorAutopilotConfigurationResponse.php b/src/Operator/OperatorAutopilotConfigurationResponse.php index 1bbe27ab..30ad276a 100644 --- a/src/Operator/OperatorAutopilotConfigurationResponse.php +++ b/src/Operator/OperatorAutopilotConfigurationResponse.php @@ -25,15 +25,15 @@ class OperatorAutopilotConfigurationResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?AutopilotConfiguration $AutopilotConfiguration = null; + public null|AutopilotConfiguration $AutopilotConfiguration = null; - public function getValue(): ?AutopilotConfiguration + public function getValue(): null|AutopilotConfiguration { return $this->AutopilotConfiguration; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->AutopilotConfiguration = new AutopilotConfiguration((array)$decodedData); + $this->AutopilotConfiguration = AutopilotConfiguration::jsonUnserialize($decoded); } } diff --git a/src/Operator/OperatorClient.php b/src/Operator/OperatorClient.php index f4ccf63c..3d477621 100644 --- a/src/Operator/OperatorClient.php +++ b/src/Operator/OperatorClient.php @@ -31,19 +31,19 @@ class OperatorClient extends AbstractClient { - public function AreaCreate(Area $area, ?WriteOptions $opts = null): ValuedWriteStringResponse + public function AreaCreate(Area $area, null|WriteOptions $opts = null): ValuedWriteStringResponse { return $this->_writeIDResponse($this->_requireOK($this->_doPost('v1/operator/area', $area, $opts))); } - public function AreaUpdate(string $areaID, Area $area, ?WriteOptions $opts = null): ValuedWriteStringResponse + public function AreaUpdate(string $areaID, Area $area, null|WriteOptions $opts = null): ValuedWriteStringResponse { return $this->_writeIDResponse( $this->_requireOK($this->_doPut(sprintf('v1/operator/area/%s', $areaID), $area, $opts)) ); } - public function AreaGet(string $areaID, ?QueryOptions $opts = null): OperatorAreasResponse + public function AreaGet(string $areaID, null|QueryOptions $opts = null): OperatorAreasResponse { $resp = $this->_requireOK($this->_doGet(sprintf('v1/operator/area/%s', urlencode($areaID)), $opts)); $ret = new OperatorAreasResponse(); @@ -51,7 +51,7 @@ public function AreaGet(string $areaID, ?QueryOptions $opts = null): OperatorAre return $ret; } - public function AreaList(?QueryOptions $opts = null): OperatorAreasResponse + public function AreaList(null|QueryOptions $opts = null): OperatorAreasResponse { $resp = $this->_requireOK($this->_doGet('v1/operator/area', $opts)); $ret = new OperatorAreasResponse(); @@ -59,12 +59,12 @@ public function AreaList(?QueryOptions $opts = null): OperatorAreasResponse return $ret; } - public function AreaDelete(string $areaID, ?WriteOptions $opts = null): WriteResponse + public function AreaDelete(string $areaID, null|WriteOptions $opts = null): WriteResponse { return $this->_executeDelete(sprintf('v1/operator/area/%s', $areaID), $opts); } - public function AreaJoin(string $areaID, array $addresses, ?WriteOptions $opts = null): OperatorAreaJoinResponse + public function AreaJoin(string $areaID, array $addresses, null|WriteOptions $opts = null): OperatorAreaJoinResponse { $resp = $this->_requireOK($this->_doPut(sprintf('v1/operator/area/%s/join', $areaID), $addresses, $opts)); $ret = new OperatorAreaJoinResponse(); @@ -72,7 +72,7 @@ public function AreaJoin(string $areaID, array $addresses, ?WriteOptions $opts = return $ret; } - public function AreaMembers(string $areaID, ?QueryOptions $opts = null): OperatorSerfMembersResponse + public function AreaMembers(string $areaID, null|QueryOptions $opts = null): OperatorSerfMembersResponse { $resp = $this->_requireOK($this->_doGet(sprintf('v1/operator/area/%s/members', $areaID), $opts)); $ret = new OperatorSerfMembersResponse(); @@ -80,7 +80,7 @@ public function AreaMembers(string $areaID, ?QueryOptions $opts = null): Operato return $ret; } - public function AutopilotGetConfiguration(?QueryOptions $opts = null): OperatorAutopilotConfigurationResponse + public function AutopilotGetConfiguration(null|QueryOptions $opts = null): OperatorAutopilotConfigurationResponse { $resp = $this->_requireOK($this->_doGet('v1/operator/autopilot/configuration', $opts)); $ret = new OperatorAutopilotConfigurationResponse(); @@ -88,14 +88,14 @@ public function AutopilotGetConfiguration(?QueryOptions $opts = null): OperatorA return $ret; } - public function AutopilotSetConfiguration(AutopilotConfiguration $conf, ?WriteOptions $opts = null): ?Error + public function AutopilotSetConfiguration(AutopilotConfiguration $conf, null|WriteOptions $opts = null): ?Error { return $this->_requireOK($this->_doPut('v1/operator/autopilot/configuration', $conf, $opts))->Err; } public function AutopilotCASConfiguration( AutopilotConfiguration $conf, - ?WriteOptions $opts = null + null|WriteOptions $opts = null ): ValuedBoolResponse { $resp = $this->_requireOK($this->_doPut('v1/operator/autopilot/configuration', $conf, $opts)); $ret = new ValuedBoolResponse(); @@ -103,7 +103,7 @@ public function AutopilotCASConfiguration( return $ret; } - public function AutopilotServerHealth(?QueryOptions $opts = null): OperatorHealthReplyResponse + public function AutopilotServerHealth(null|QueryOptions $opts = null): OperatorHealthReplyResponse { $resp = $this->_requireOK($this->_doGet('v1/operator/autopilot/health', $opts)); $ret = new OperatorHealthReplyResponse(); @@ -111,7 +111,7 @@ public function AutopilotServerHealth(?QueryOptions $opts = null): OperatorHealt return $ret; } - public function AutopilotState(?QueryOptions $opts = null): AutopilotStateResponse + public function AutopilotState(null|QueryOptions $opts = null): AutopilotStateResponse { $resp = $this->_requireOK($this->_doGet('v1/operator/autopilot/state', $opts)); $ret = new AutopilotStateResponse(); @@ -119,7 +119,7 @@ public function AutopilotState(?QueryOptions $opts = null): AutopilotStateRespon return $ret; } - public function RaftGetConfiguration(?QueryOptions $opts = null): OperatorRaftConfigurationResponse + public function RaftGetConfiguration(null|QueryOptions $opts = null): OperatorRaftConfigurationResponse { $resp = $this->_requireOK($this->_doGet('v1/operator/raft/configuration', $opts)); $ret = new OperatorRaftConfigurationResponse(); @@ -127,7 +127,7 @@ public function RaftGetConfiguration(?QueryOptions $opts = null): OperatorRaftCo return $ret; } - public function RaftRemovePeerByAddress(string $address, ?WriteOptions $opts = null): ?Error + public function RaftRemovePeerByAddress(string $address, null|WriteOptions $opts = null): ?Error { $r = $this->_newDeleteRequest('v1/operator/raft/peer', $opts); $r->applyOptions($opts); diff --git a/src/Operator/OperatorHealthReplyResponse.php b/src/Operator/OperatorHealthReplyResponse.php index 1a6446cc..deccc502 100644 --- a/src/Operator/OperatorHealthReplyResponse.php +++ b/src/Operator/OperatorHealthReplyResponse.php @@ -25,15 +25,15 @@ class OperatorHealthReplyResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?OperatorHealthReply $OperatorHealthReply = null; + public null|OperatorHealthReply $OperatorHealthReply = null; - public function getValue(): mixed + public function getValue(): null|OperatorHealthReply { return $this->OperatorHealthReply; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->OperatorHealthReply = new OperatorHealthReply((array)$decodedData); + $this->OperatorHealthReply = OperatorHealthReply::jsonUnserialize($decoded); } } diff --git a/src/Operator/OperatorRaftConfigurationResponse.php b/src/Operator/OperatorRaftConfigurationResponse.php index 114410be..89b700df 100644 --- a/src/Operator/OperatorRaftConfigurationResponse.php +++ b/src/Operator/OperatorRaftConfigurationResponse.php @@ -25,15 +25,15 @@ class OperatorRaftConfigurationResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?RaftConfiguration $RaftConfiguration = null; + public null|RaftConfiguration $RaftConfiguration = null; - public function getValue(): ?RaftConfiguration + public function getValue(): null|RaftConfiguration { return $this->RaftConfiguration; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->RaftConfiguration = new RaftConfiguration($decodedData); + $this->RaftConfiguration = RaftConfiguration::jsonUnserialize($decoded); } } diff --git a/src/Operator/OperatorSerfMembersResponse.php b/src/Operator/OperatorSerfMembersResponse.php index 5c875222..33688ac6 100644 --- a/src/Operator/OperatorSerfMembersResponse.php +++ b/src/Operator/OperatorSerfMembersResponse.php @@ -25,18 +25,22 @@ class OperatorSerfMembersResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $SerfMembers = null; + /** @var \DCarbone\PHPConsulAPI\Operator\SerfMember[] */ + public array $SerfMembers = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Operator\SerfMember[] + */ + public function getValue(): array { return $this->SerfMembers; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->SerfMembers = []; - foreach ($decodedData as $datum) { - $this->SerfMembers[] = new SerfMember($datum); + foreach ($decoded as $datum) { + $this->SerfMembers[] = SerfMember::jsonUnserialize($datum); } } } diff --git a/src/Operator/OperatorServerHealthsResponse.php b/src/Operator/OperatorServerHealthsResponse.php index c1010a68..9c1fdc21 100644 --- a/src/Operator/OperatorServerHealthsResponse.php +++ b/src/Operator/OperatorServerHealthsResponse.php @@ -25,18 +25,22 @@ class OperatorServerHealthsResponse extends AbstractValuedResponse implements UnmarshalledResponseInterface { - public ?array $ServerHealths = null; + /** @var \DCarbone\PHPConsulAPI\Operator\ServerHealth[] */ + public array $ServerHealths = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Operator\ServerHealth[] + */ + public function getValue(): array { return $this->ServerHealths; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->ServerHealths = []; - foreach ($decodedData as $datum) { - $this->ServerHealths[] = new ServerHealth($datum); + foreach ($decoded as $datum) { + $this->ServerHealths[] = ServerHealth::jsonUnserialize($datum); } } } diff --git a/src/Peering/Locality.php b/src/Peering/Locality.php new file mode 100644 index 00000000..061487ff --- /dev/null +++ b/src/Peering/Locality.php @@ -0,0 +1,77 @@ +Region = $Region; + $this->Zone = $Zone; + } + + public function getRegion(): string + { + return $this->Region; + } + + public function setRegion(string $Region): self + { + $this->Region = $Region; + return $this; + } + + public function getZone(): string + { + return $this->Zone; + } + + public function setZone(string $Zone): self + { + $this->Zone = $Zone; + return $this; + } + + public static function jsonUnserialize(\stdClass $decoded): static + { + $n = new static(); + foreach ($decoded as $k => $v) { + $n->{$k} = $v; + } + return $n; + } + + public function jsonSerialize(): \stdClass + { + $out = new \stdClass(); + foreach ($this->_getDynamicFields() as $k => $v) { + $out->{$k} = $v; + } + $out->Region = $this->Region; + $out->Zone = $this->Zone; + return $out; + } +} diff --git a/src/PreparedQuery/PreparedQueryClient.php b/src/PreparedQuery/PreparedQueryClient.php index e35585c7..27e3d187 100644 --- a/src/PreparedQuery/PreparedQueryClient.php +++ b/src/PreparedQuery/PreparedQueryClient.php @@ -28,7 +28,7 @@ class PreparedQueryClient extends AbstractClient { - public function Create(PreparedQueryDefinition $query, ?WriteOptions $opts = null): ValuedWriteStringResponse + public function Create(PreparedQueryDefinition $query, null|WriteOptions $opts = null): ValuedWriteStringResponse { $resp = $this->_requireOK($this->_doPost('v1/query', $query, $opts)); $ret = new ValuedWriteStringResponse(); @@ -36,12 +36,12 @@ public function Create(PreparedQueryDefinition $query, ?WriteOptions $opts = nul return $ret; } - public function Update(PreparedQueryDefinition $query, ?WriteOptions $opts = null): WriteResponse + public function Update(PreparedQueryDefinition $query, null|WriteOptions $opts = null): WriteResponse { return $this->_executePut('v1/query', $query, $opts); } - public function List(?QueryOptions $opts = null): PreparedQueryDefinitionsResponse + public function List(null|QueryOptions $opts = null): PreparedQueryDefinitionsResponse { $resp = $this->_doGet('v1/query', $opts); $ret = new PreparedQueryDefinitionsResponse(); @@ -49,7 +49,7 @@ public function List(?QueryOptions $opts = null): PreparedQueryDefinitionsRespon return $ret; } - public function Get(string $queryID, ?QueryOptions $opts = null): PreparedQueryDefinitionsResponse + public function Get(string $queryID, null|QueryOptions $opts = null): PreparedQueryDefinitionsResponse { $resp = $this->_doGet(sprintf('v1/query/%s', $queryID), $opts); $ret = new PreparedQueryDefinitionsResponse(); @@ -57,12 +57,12 @@ public function Get(string $queryID, ?QueryOptions $opts = null): PreparedQueryD return $ret; } - public function Delete(string $queryID, ?WriteOptions $opts = null): WriteResponse + public function Delete(string $queryID, null|WriteOptions $opts = null): WriteResponse { return $this->_executeDelete(sprintf('v1/query/%s', $queryID), $opts); } - public function Execute(string $queryIDOrName, ?QueryOptions $opts = null): PreparedQueryExecuteResponseResponse + public function Execute(string $queryIDOrName, null|QueryOptions $opts = null): PreparedQueryExecuteResponseResponse { $resp = $this->_doGet(sprintf('v1/query/%s/execute', $queryIDOrName), $opts); $ret = new PreparedQueryExecuteResponseResponse(); diff --git a/src/PreparedQuery/PreparedQueryDefinitionsResponse.php b/src/PreparedQuery/PreparedQueryDefinitionsResponse.php index eb04548e..595e93f6 100644 --- a/src/PreparedQuery/PreparedQueryDefinitionsResponse.php +++ b/src/PreparedQuery/PreparedQueryDefinitionsResponse.php @@ -25,18 +25,22 @@ class PreparedQueryDefinitionsResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $PreparedQueryDefinitions = null; + /** @var \DCarbone\PHPConsulAPI\PreparedQuery\PreparedQueryDefinition[] */ + public array $PreparedQueryDefinitions = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\PreparedQuery\PreparedQueryDefinition[] + */ + public function getValue(): array { return $this->PreparedQueryDefinitions; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->PreparedQueryDefinitions = []; - foreach ($decodedData as $datum) { - $this->PreparedQueryDefinitions[] = new PreparedQueryDefinition($datum); + foreach ($decoded as $datum) { + $this->PreparedQueryDefinitions[] = PreparedQueryDefinition::jsonUnserialize($datum); } } } diff --git a/src/PreparedQuery/PreparedQueryExecuteResponseResponse.php b/src/PreparedQuery/PreparedQueryExecuteResponseResponse.php index c5f66b20..3fe9b80c 100644 --- a/src/PreparedQuery/PreparedQueryExecuteResponseResponse.php +++ b/src/PreparedQuery/PreparedQueryExecuteResponseResponse.php @@ -32,8 +32,8 @@ public function getValue(): ?PreparedQueryExecuteResponse return $this->PreparedQueryExecuteResponse; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->PreparedQueryExecuteResponse = new PreparedQueryExecuteResponse((array)$decodedData); + $this->PreparedQueryExecuteResponse = new PreparedQueryExecuteResponse((array)$decoded); } } diff --git a/src/QueryMeta.php b/src/QueryMeta.php index ea23adef..96d3760b 100644 --- a/src/QueryMeta.php +++ b/src/QueryMeta.php @@ -24,15 +24,38 @@ class QueryMeta { - public string $RequestUrl = ''; - public int $LastIndex = 0; - public string $LastContentHash = ''; - public int $LastContact = 0; - public bool $KnownLeader = false; - public ?Time\Duration $RequestTime = null; - public bool $AddressTranslationEnabled = false; - public bool $CacheHit = false; - public ?Time\Duration $CacheAge = null; + public string $RequestUrl; + public int $LastIndex; + public string $LastContentHash; + public int $LastContact; + public bool $KnownLeader; + public Time\Duration $RequestTime; + public bool $AddressTranslationEnabled; + public bool $CacheHit; + public Time\Duration $CacheAge; + + public function __construct( + string $RequestUrl, + null|Time\Duration $RequestTime, + int $LastIndex = 0, + string $LastContentHash = '', + int $LastContact = 0, + bool $KnownLeader = false, + bool $AddressTranslationEnabled = false, + bool $CacheHit = false, + null|Time\Duration $CacheAge = null + ) { + $this->RequestUrl = $RequestUrl; + $this->RequestTime = Time::Duration($RequestTime); + + $this->LastIndex = $LastIndex; + $this->LastContentHash = $LastContentHash; + $this->LastContact = $LastContact; + $this->KnownLeader = $KnownLeader; + $this->AddressTranslationEnabled = $AddressTranslationEnabled; + $this->CacheHit = $CacheHit; + $this->CacheAge = Time::Duration($CacheAge); + } public function getRequestUrl(): string { @@ -59,7 +82,7 @@ public function isKnownLeader(): bool return $this->KnownLeader; } - public function getRequestTime(): ?Time\Duration + public function getRequestTime(): Time\Duration { return $this->RequestTime; } @@ -74,7 +97,7 @@ public function isCacheHit(): bool return $this->CacheHit; } - public function getCacheAge(): ?Time\Duration + public function getCacheAge(): Time\Duration { return $this->CacheAge; } diff --git a/src/QueryMetaContainer.php b/src/QueryMetaContainer.php index 57bcc958..8c513435 100644 --- a/src/QueryMetaContainer.php +++ b/src/QueryMetaContainer.php @@ -22,9 +22,9 @@ trait QueryMetaContainer { - public ?QueryMeta $QueryMeta = null; + public null|QueryMeta $QueryMeta = null; - public function getQueryMeta(): ?QueryMeta + public function getQueryMeta(): null|QueryMeta { return $this->QueryMeta; } diff --git a/src/QueryOptions.php b/src/QueryOptions.php index cf6fff29..7360de01 100644 --- a/src/QueryOptions.php +++ b/src/QueryOptions.php @@ -22,64 +22,73 @@ use DCarbone\Go\Time; -class QueryOptions extends AbstractModel implements RequestOptions +class QueryOptions implements RequestOptions { - protected const FIELDS = [ - self::FIELD_MAX_AGE => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_NULLABLE_DURATION, - ], - self::FIELD_STALE_IF_ERROR => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_NULLABLE_DURATION, - ], - self::FIELD_WAIT_TIME => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_NULLABLE_DURATION, - ], - self::FIELD_TIMEOUT => [ - Transcoding::FIELD_UNMARSHAL_CALLBACK => Transcoding::UNMARSHAL_NULLABLE_DURATION, - ], - ]; - - private const FIELD_MAX_AGE = 'MaxAge'; - private const FIELD_STALE_IF_ERROR = 'StaleIfError'; - private const FIELD_WAIT_TIME = 'WaitTime'; - private const FIELD_TIMEOUT = 'Timeout'; - - public string $Namespace = ''; - public string $Datacenter = ''; - public bool $AllowStale = false; - public bool $RequireConsistent = false; - public bool $UseCache = false; - public ?Time\Duration $MaxAge = null; - public ?Time\Duration $StaleIfError = null; - public int $WaitIndex = 0; - public string $WaitHash = ''; - public ?Time\Duration $WaitTime = null; - public string $Token = ''; - public string $Near = ''; - public string $Filter = ''; - public array $NodeMeta = []; - public int $RelayFactor = 0; - public bool $LocalOnly = false; - public bool $Connect = false; - - public ?Time\Duration $Timeout = null; - - public bool $Pretty = false; - - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!($this->MaxAge instanceof Time\Duration)) { - $this->MaxAge = Time::Duration($this->MaxAge); - } - if (!($this->StaleIfError instanceof Time\Duration)) { - $this->StaleIfError = Time::Duration($this->StaleIfError); - } - if (!($this->WaitTime instanceof Time\Duration)) { - $this->WaitTime = Time::Duration($this->WaitTime); - } - if (!($this->Timeout instanceof Time\Duration)) { - $this->Timeout = Time::Duration($this->Timeout); + public string $Namespace; + public string $Datacenter; + public bool $AllowStale; + public bool $RequireConsistent; + public bool $UseCache; + public Time\Duration $MaxAge; + public Time\Duration $StaleIfError; + public int $WaitIndex; + public string $WaitHash; + public Time\Duration $WaitTime; + public string $Token; + public string $Near; + public string $Filter; + public null|\stdClass $NodeMeta; + public int $RelayFactor; + public bool $LocalOnly; + public bool $Connect; + + public Time\Duration $Timeout; + + public bool $Pretty; + + public function __construct( + null|array $data = null, // Deprecated do not use. + string $Namespace = '', + string $Datacenter = '', + bool $AllowStale = false, + bool $RequireConsistent = false, + bool $UseCache = false, + null|int|float|string|\DateInterval|Time\Duration $MaxAge = null, + null|int|float|string|\DateInterval|Time\Duration $StaleIfError = null, + int $WaitIndex = 0, + string $WaitHash = '', + null|int|float|string|\DateInterval|Time\Duration $WaitTime = null, + string $Token = '', + string $Near = '', + string $Filter = '', + null|\stdClass $NodeMeta = null, + int $RelayFactor = 0, + bool $LocalOnly = false, + bool $Connect = false, + null|int|float|string|\DateInterval|Time\Duration $Timeout = null, + bool $Pretty = false, + ) { + $this->Namespace = $Namespace; + $this->Datacenter = $Datacenter; + $this->AllowStale = $AllowStale; + $this->RequireConsistent = $RequireConsistent; + $this->UseCache = $UseCache; + $this->MaxAge = Time::Duration($MaxAge); + $this->StaleIfError = Time::Duration($StaleIfError); + $this->WaitIndex = $WaitIndex; + $this->WaitHash = $WaitHash; + $this->WaitTime = Time::Duration($WaitTime); + $this->Token = $Token; + $this->Near = $Near; + $this->Filter = $Filter; + $this->NodeMeta = $NodeMeta; + $this->RelayFactor = $RelayFactor; + $this->LocalOnly = $LocalOnly; + $this->Connect = $Connect; + $this->Timeout = Time::Duration($Timeout); + $this->Pretty = $Pretty; + if (null !== $data && [] !== $data) { + $this->_fromMap((object)$data); } } @@ -138,7 +147,7 @@ public function getMaxAge(): Time\Duration return $this->MaxAge; } - public function setMaxAge(float|int|string|Time\Duration|null $maxAge): void + public function setMaxAge(null|int|float|string|\DateInterval|Time\Duration $maxAge): void { $this->MaxAge = Time::Duration($maxAge); } @@ -148,7 +157,7 @@ public function getStaleIfError(): Time\Duration return $this->StaleIfError; } - public function setStaleIfError(float|int|string|Time\Duration|null $staleIfError): void + public function setStaleIfError(null|int|float|string|\DateInterval|Time\Duration $staleIfError): void { $this->StaleIfError = Time::Duration($staleIfError); } @@ -168,7 +177,7 @@ public function getWaitTime(): Time\Duration return $this->WaitTime; } - public function setWaitTime(mixed $waitTime): void + public function setWaitTime(null|int|float|string|\DateInterval|Time\Duration $waitTime): void { $this->WaitTime = Time::Duration($waitTime); } @@ -213,12 +222,12 @@ public function setFilter(string $filter): void $this->Filter = $filter; } - public function getNodeMeta(): array + public function getNodeMeta(): null|\stdClass { return $this->NodeMeta; } - public function setNodeMeta(array $nodeMeta): void + public function setNodeMeta(null|\stdClass $nodeMeta): void { $this->NodeMeta = $nodeMeta; } @@ -253,12 +262,12 @@ public function setConnect(bool $connect): void $this->Connect = $connect; } - public function getTimeout(): ?Time\Duration + public function getTimeout(): Time\Duration { return $this->Timeout; } - public function setTimeout(float|int|string|Time\Duration|null $timeout): void + public function setTimeout(null|int|float|string|\DateInterval|Time\Duration $timeout): void { $this->Timeout = Time::Duration($timeout); } @@ -288,9 +297,9 @@ public function apply(Request $r): void $r->params->set('consistent', ''); } if (0 !== $this->WaitIndex) { - $r->params->set('index', (string) $this->WaitIndex); + $r->params->set('index', (string)$this->WaitIndex); } - if (isset($this->WaitTime) && 0 < $this->WaitTime->Microseconds()) { + if (0 < $this->WaitTime->Microseconds()) { $r->params->set('wait', dur_to_millisecond($this->WaitTime)); } if ('' !== $this->WaitHash) { @@ -305,13 +314,13 @@ public function apply(Request $r): void if ('' !== $this->Filter) { $r->params->set('filter', $this->Filter); } - if (isset($this->NodeMeta) && [] !== $this->NodeMeta) { + if (null !== $this->NodeMeta) { foreach ($this->NodeMeta as $k => $v) { $r->params->add('node-meta', "{$k}:{$v}"); } } if (0 !== $this->RelayFactor) { - $r->params->set('relay-factor', (string) $this->RelayFactor); + $r->params->set('relay-factor', (string)$this->RelayFactor); } if ($this->LocalOnly) { $r->params->set('local-only', 'true'); @@ -335,7 +344,7 @@ public function apply(Request $r): void } } - if (null !== $this->Timeout) { + if (0 < $this->Timeout->Nanoseconds()) { $r->timeout = $this->Timeout; } @@ -343,4 +352,25 @@ public function apply(Request $r): void $r->params->set('pretty', ''); } } + + /** + * @param \stdClass $data + * @deprecated This is only here to support construction with map. It will be removed in a future version. + */ + private function _fromMap(\stdClass $data): void + { + foreach ($data as $k => $v) { + if ('MaxAge' === $k) { + $this->MaxAge = Time::Duration($v); + } elseif ('StaleIfError' === $k) { + $this->StaleIfError = Time::Duration($v); + } elseif ('WaitTime' === $k) { + $this->WaitTime = Time::Duration($v); + } elseif ('Timeout' === $k) { + $this->Timeout = Time::Duration($v); + } else { + $this->{$k} = $v; + } + } + } } diff --git a/src/HasStringTags.php b/src/QueryResponseInterface.php similarity index 84% rename from src/HasStringTags.php rename to src/QueryResponseInterface.php index 9546a477..389a2e26 100644 --- a/src/HasStringTags.php +++ b/src/QueryResponseInterface.php @@ -20,12 +20,7 @@ limitations under the License. */ -trait HasStringTags +interface QueryResponseInterface { - public array $Tags = []; - - public function getTags(): array - { - return $this->Tags; - } + public function getQueryMeta(): null|QueryMeta; } diff --git a/src/Request.php b/src/Request.php index bae97388..10c6e199 100644 --- a/src/Request.php +++ b/src/Request.php @@ -112,7 +112,7 @@ public function filterQuery(string $filter): void public function getUri(): UriInterface { $uri = "{$this->scheme}://{$this->address}/{$this->path}"; - if (0 < \count($this->params)) { + if (0 < count($this->params)) { $uri .= "?{$this->params}"; } return new Uri($uri); diff --git a/src/RequestResponse.php b/src/RequestResponse.php index 00b3a2e3..29dfe33e 100644 --- a/src/RequestResponse.php +++ b/src/RequestResponse.php @@ -27,10 +27,10 @@ final class RequestResponse { public RequestMeta $RequestMeta; public Time\Duration $Duration; - public ?ResponseInterface $Response; - public ?Error $Err; + public null|ResponseInterface $Response; + public null|Error $Err; - public function __construct(RequestMeta $meta, Time\Duration $dur, ?ResponseInterface $resp, ?Error $err) + public function __construct(RequestMeta $meta, Time\Duration $dur, null|ResponseInterface $resp, null|Error $err) { $this->RequestMeta = $meta; $this->Duration = $dur; @@ -48,24 +48,23 @@ public function getDuration(): Time\Duration return $this->Duration; } - public function getResponse(): ?ResponseInterface + public function getResponse(): null|ResponseInterface { return $this->Response; } - public function getErr(): ?Error + public function getErr(): null|Error { return $this->Err; } public function buildQueryMeta(): QueryMeta { - // init class - $qm = new QueryMeta(); - // set some always-defined values - $qm->RequestTime = $this->Duration; - $qm->RequestUrl = (string)$this->RequestMeta->uri; + $qm = new QueryMeta( + RequestUrl: (string)$this->RequestMeta->uri, + RequestTime: $this->Duration, + ); // if there was no response, return as-is // note: should never see this in the wild. @@ -95,7 +94,7 @@ public function buildQueryMeta(): QueryMeta } if ('' !== ($h = $this->Response->getHeaderLine(Consul::_headerCache))) { - $qm->CacheAge = Time::Duration(\intval($h, 10) * Time::Second); + $qm->CacheAge = Time::Duration((int)$h * Time::Second); } return $qm; @@ -103,8 +102,6 @@ public function buildQueryMeta(): QueryMeta public function buildWriteMeta(): WriteMeta { - $wm = new WriteMeta(); - $wm->RequestTime = $this->Duration; - return $wm; + return new WriteMeta($this->Duration); } } diff --git a/src/ResponseValueBoolTrait.php b/src/ResponseValueBoolTrait.php index e4a7c401..8741df78 100644 --- a/src/ResponseValueBoolTrait.php +++ b/src/ResponseValueBoolTrait.php @@ -29,21 +29,21 @@ public function getValue(): bool return $this->Value; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - if (\is_bool($decodedData)) { - $this->Value = $decodedData; + if (is_bool($decoded)) { + $this->Value = $decoded; return; } - if (\is_string($decodedData)) { - $this->Value = Transcoding::TRUE === strtolower(trim($decodedData)); + if (is_string($decoded)) { + $this->Value = 'true' === strtolower(trim($decoded)); return; } - $this->Value = (bool)$decodedData; + $this->Value = (bool)$decoded; } public function __toString(): string { - return $this->Value ? Transcoding::TRUE : Transcoding::FALSE; + return $this->Value ? 'true' : 'false'; } } diff --git a/src/ResponseValueStringTrait.php b/src/ResponseValueStringTrait.php index 804c3f74..bfdbf8ac 100644 --- a/src/ResponseValueStringTrait.php +++ b/src/ResponseValueStringTrait.php @@ -29,9 +29,9 @@ public function getValue(): string return $this->Value; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->Value = (string)$decodedData; + $this->Value = (string)$decoded; } public function __toString(): string diff --git a/src/ResponseValueStringsTrait.php b/src/ResponseValueStringsTrait.php index 83e78a96..f996b53c 100644 --- a/src/ResponseValueStringsTrait.php +++ b/src/ResponseValueStringsTrait.php @@ -29,8 +29,8 @@ public function getValue(): ?array return $this->Value; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { - $this->Value = (array)$decodedData; + $this->Value = (array)$decoded; } } diff --git a/src/Session/SessionClient.php b/src/Session/SessionClient.php index 3c997a0c..00e51fe1 100644 --- a/src/Session/SessionClient.php +++ b/src/Session/SessionClient.php @@ -30,7 +30,7 @@ class SessionClient extends AbstractClient { - public function CreateNoChecks(?SessionEntry $sessionEntry = null, ?WriteOptions $opts = null): ValuedWriteStringResponse + public function CreateNoChecks(?SessionEntry $sessionEntry = null, null|WriteOptions $opts = null): ValuedWriteStringResponse { if (null === $sessionEntry) { $body = new SessionEntry(); @@ -45,17 +45,17 @@ public function CreateNoChecks(?SessionEntry $sessionEntry = null, ?WriteOptions return $this->_create('v1/session/create', $body, $opts); } - public function Create(?SessionEntry $sessionEntry = null, ?WriteOptions $opts = null): ValuedWriteStringResponse + public function Create(?SessionEntry $sessionEntry = null, null|WriteOptions $opts = null): ValuedWriteStringResponse { return $this->_create('v1/session/create', $sessionEntry, $opts); } - public function Destroy(string $id, ?WriteOptions $opts = null): WriteResponse + public function Destroy(string $id, null|WriteOptions $opts = null): WriteResponse { return $this->_executePut(sprintf('v1/session/destroy/%s', $id), null, $opts); } - public function Renew(string $id, ?WriteOptions $opts = null): SessionEntriesWriteResponse + public function Renew(string $id, null|WriteOptions $opts = null): SessionEntriesWriteResponse { $ret = new SessionEntriesWriteResponse(); @@ -87,22 +87,22 @@ public function Renew(string $id, ?WriteOptions $opts = null): SessionEntriesWri return $ret; } - public function Info(string $id, ?QueryOptions $opts = null): SessionEntriesQueryResponse + public function Info(string $id, null|QueryOptions $opts = null): SessionEntriesQueryResponse { return $this->_get(sprintf('v1/session/info/%s', $id), $opts); } - public function Node(string $node, ?QueryOptions $opts = null): SessionEntriesQueryResponse + public function Node(string $node, null|QueryOptions $opts = null): SessionEntriesQueryResponse { return $this->_get(sprintf('v1/session/node/%s', $node), $opts); } - public function List(?QueryOptions $opts = null): SessionEntriesQueryResponse + public function List(null|QueryOptions $opts = null): SessionEntriesQueryResponse { return $this->_get('v1/session/list', $opts); } - private function _get(string $path, ?QueryOptions $opts): SessionEntriesQueryResponse + private function _get(string $path, null|QueryOptions $opts): SessionEntriesQueryResponse { $resp = $this->_requireOK($this->_doGet($path, $opts)); $ret = new SessionEntriesQueryResponse(); @@ -110,7 +110,7 @@ private function _get(string $path, ?QueryOptions $opts): SessionEntriesQueryRes return $ret; } - private function _create(string $path, SessionEntry $entry, ?WriteOptions $opts): ValuedWriteStringResponse + private function _create(string $path, SessionEntry $entry, null|WriteOptions $opts): ValuedWriteStringResponse { $resp = $this->_requireOK($this->_doPut($path, $entry->_toAPIPayload(), $opts)); $ret = new ValuedWriteStringResponse(); diff --git a/src/Session/SessionEntriesQueryResponse.php b/src/Session/SessionEntriesQueryResponse.php index 6ebeda8b..08a25a10 100644 --- a/src/Session/SessionEntriesQueryResponse.php +++ b/src/Session/SessionEntriesQueryResponse.php @@ -25,18 +25,22 @@ class SessionEntriesQueryResponse extends AbstractValuedQueryResponse implements UnmarshalledResponseInterface { - public ?array $SessionEntries = []; + /** @var \DCarbone\PHPConsulAPI\Session\SessionEntry[] */ + public array $SessionEntries = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Session\SessionEntry[] + */ + public function getValue(): array { return $this->SessionEntries; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->SessionEntries = []; - foreach ($decodedData as $datum) { - $this->SessionEntries[] = new SessionEntry($datum); + foreach ($decoded as $datum) { + $this->SessionEntries[] = SessionEntry::jsonUnserialize($datum); } } } diff --git a/src/Session/SessionEntriesWriteResponse.php b/src/Session/SessionEntriesWriteResponse.php index b5ce2916..4e7f13a9 100644 --- a/src/Session/SessionEntriesWriteResponse.php +++ b/src/Session/SessionEntriesWriteResponse.php @@ -25,18 +25,22 @@ class SessionEntriesWriteResponse extends AbstractValuedWriteResponse implements UnmarshalledResponseInterface { - public ?array $SessionEntries = null; + /** @var \DCarbone\PHPConsulAPI\Session\SessionEntry[] */ + public array $SessionEntries = []; - public function getValue(): ?array + /** + * @return \DCarbone\PHPConsulAPI\Session\SessionEntry[] + */ + public function getValue(): array { return $this->SessionEntries; } - public function unmarshalValue(mixed $decodedData): void + public function unmarshalValue(mixed $decoded): void { $this->SessionEntries = []; - foreach ($decodedData as $datum) { - $this->SessionEntries[] = new SessionEntry($datum); + foreach ($decoded as $datum) { + $this->SessionEntries[] = SessionEntry::jsonUnserialize($datum); } } } diff --git a/src/Status/StatusClient.php b/src/Status/StatusClient.php index e66e6532..6659c958 100644 --- a/src/Status/StatusClient.php +++ b/src/Status/StatusClient.php @@ -27,7 +27,7 @@ class StatusClient extends AbstractClient { - public function LeaderWithQueryOptions(?QueryOptions $opts): ValuedStringResponse + public function LeaderWithQueryOptions(null|QueryOptions $opts): ValuedStringResponse { $resp = $this->_requireOK($this->_doGet('v1/status/leader', $opts)); $ret = new ValuedStringResponse(); @@ -40,7 +40,7 @@ public function Leader(): ValuedStringResponse return $this->LeaderWithQueryOptions(null); } - public function PeersWithQueryOptions(?QueryOptions $opts): ValuedStringsResponse + public function PeersWithQueryOptions(null|QueryOptions $opts): ValuedStringsResponse { $resp = $this->_requireOK($this->_doGet('v1/status/peers', $opts)); $ret = new ValuedStringsResponse(); diff --git a/src/Transcoding.php b/src/Transcoding.php deleted file mode 100644 index e19c92ac..00000000 --- a/src/Transcoding.php +++ /dev/null @@ -1,130 +0,0 @@ - self::OBJECT, self::FIELD_CLASS => FakeMap::class]; - public const DURATION_FIELD = [ - self::FIELD_TYPE => self::OBJECT, - self::FIELD_CLASS => Time\Duration::class, - ] + self::UNMARSHAL_DURATION; - - //-- common field type definitions with omitempty - - public const OMITEMPTY_FIELD = [self::FIELD_OMITEMPTY => true]; - - public const OMITEMPTY_STRING_FIELD = [self::FIELD_TYPE => self::STRING] + self::OMITEMPTY_FIELD; - public const OMITEMPTY_INTEGER_FIELD = [self::FIELD_TYPE => self::INTEGER] + self::OMITEMPTY_FIELD; - public const OMITEMPTY_DOUBLE_FIELD = [self::FIELD_TYPE => self::DOUBLE] + self::OMITEMPTY_FIELD; - public const OMITEMPTY_BOOLEAN_FIELD = [self::FIELD_TYPE => self::BOOLEAN] + self::OMITEMPTY_FIELD; - public const OMITEMPTY_STRING_ARRAY_FIELD = [ - self::FIELD_TYPE => self::ARRAY, - self::FIELD_ARRAY_TYPE => self::STRING, - ] + self::OMITEMPTY_FIELD; - public const OMITEMPTY_INTEGER_ARRAY_FIELD = [ - self::FIELD_TYPE => self::ARRAY, - self::FIELD_ARRAY_TYPE => self::INTEGER, - ] + self::OMITEMPTY_FIELD; - public const OMITEMPTY_MAP_FIELD = self::MAP_FIELD + self::OMITEMPTY_FIELD; - - public static function isScalar(string $type): bool - { - return \in_array($type, self::SCALAR, true); - } - - public static function unmarshalTime(object $instance, string $field, Time\Time|string $value): void - { - if ($value instanceof Time\Time) { - $instance->{$field} = clone $value; - return; - } - $instance->{$field} = Time\Time::createFromFormat(\DATE_RFC3339, $value); - } - - public static function unmarshalNullableTime(object $instance, string $field, Time\Time|string|null $value): void - { - if (null === $value) { - $instance->{$field} = null; - return; - } - self::unmarshalTime($instance, $field, $value); - } - - /** - * This accepts a multitude of $value types. See Time::Duration for implementation details. - * - * @param object $instance - * @param string $field - * @param mixed $value - */ - public static function unmarshalDuration(object $instance, string $field, mixed $value): void - { - $instance->{$field} = Time::Duration($value); - } - - public static function unmarshalNullableDuration(object $instance, string $field, mixed $value): void - { - if (null === $value) { - $instance->{$field} = null; - return; - } - self::unmarshalDuration($instance, $field, $value); - } -} diff --git a/src/UnmarshalledResponseInterface.php b/src/UnmarshalledResponseInterface.php index 4c1e616d..c379cf6f 100644 --- a/src/UnmarshalledResponseInterface.php +++ b/src/UnmarshalledResponseInterface.php @@ -22,5 +22,5 @@ interface UnmarshalledResponseInterface { - public function unmarshalValue(mixed $decodedData): void; + public function unmarshalValue(mixed $decoded): void; } diff --git a/src/Unmarshaller.php b/src/Unmarshaller.php deleted file mode 100644 index 5b55c234..00000000 --- a/src/Unmarshaller.php +++ /dev/null @@ -1,277 +0,0 @@ -unmarshalComplex($field, $value, static::FIELDS[$field]); - } elseif (!property_exists($this, $field)) { - // if the field isn't explicitly defined on the implementing class, just set it to whatever the incoming - // value is - $this->{$field} = $value; - } elseif (null !== $value) { - // at this point, value must be non-null to be operable - if (isset($this->{$field}) && is_scalar($this->{$field})) { - // if the property has a scalar default value, unmarshal it as such. - $this->unmarshalScalar($field, $value, false); - } else { - // if we fall down here, try to set the value as-is. if this barfs, it indicates we have a bug to be - // squished. - // todo: should this be an exception? - $this->{$field} = $value; - } - } - - // if the value is null at this point, ignore and move on. - // note: this is not checked prior to the property_exists call as if the field is not explicitly defined but - // is seen with a null value, we still want to define it as null on the implementing type. - } - - protected function fieldIsNullable(array $fieldDef): bool - { - // todo: make sure this key is always a bool... - return $fieldDef[Transcoding::FIELD_NULLABLE] ?? false; - } - - protected static function scalarZeroVal(string $type): float|bool|int|string|null - { - return match ($type) { - Transcoding::STRING => '', - Transcoding::INTEGER => 0, - Transcoding::DOUBLE => 0.0, - Transcoding::BOOLEAN => false, - default => null, - }; - } - - private function buildScalarValue(string $field, mixed $value, string $type, bool $nullable): float|bool|int|string|null - { - if (null === $value) { - return $nullable ? null : self::scalarZeroVal($type); - } - - return match ($type) { - Transcoding::STRING => (string)$value, - Transcoding::INTEGER => \intval($value, 10), - Transcoding::DOUBLE => (float)$value, - Transcoding::BOOLEAN => (bool)$value, - - // if we fall down to here, default to try to set the value to whatever it happens to be. - default => $value, - }; - } - - private function buildObjectValue(string $field, null|object|array $value, string $class, bool $nullable): ?object - { - // if the incoming value is null... - if (null === $value) { - return $nullable ? null : new $class([]); - } - // if the incoming value is already an instance of the class, clone it and return - if ($value instanceof $class) { - return clone $value; - } - // otherwise, attempt to cast whatever was provided as an array and construct a new instance of $class - if (KVPair::class === $class || KVTxnOp::class === $class || UserEvent::class === $class) { - // special case for KVPair and KVTxnOp - // todo: find cleaner way to do this... - return new $class((array)$value, true); - } - return new $class((array)$value); - } - - private function unmarshalScalar(string $field, mixed $value, bool $nullable): void - { - $this->{$field} = $this->buildScalarValue( - $field, - $value, - isset($this->{$field}) ? \gettype($this->{$field}) : Transcoding::MIXED, - $nullable - ); - } - - private function unmarshalComplex(string $field, mixed $value, array $def): void - { - // check if a callable has been defined - if (isset($def[Transcoding::FIELD_UNMARSHAL_CALLBACK])) { - $cb = $def[Transcoding::FIELD_UNMARSHAL_CALLBACK]; - // allow for using a "setter" method - if (\is_string($cb) && method_exists($this, $cb)) { - $this->{$cb}($value); - return; - } - // handle all other callable input - $err = \call_user_func($def[Transcoding::FIELD_UNMARSHAL_CALLBACK], $this, $field, $value); - if (false === $err) { - throw new \RuntimeException( - sprintf( - 'Error calling hydration callback "%s" for field "%s" on class "%s"', - var_export($def[Transcoding::FIELD_UNMARSHAL_CALLBACK], true), - $field, - static::class - ) - ); - } - return; - } - - // try to determine field type by first looking up the field in the definition map, then by inspecting the - // the field's default value. - // - // objects _must_ have an entry in the map, as they are either un-initialized at class instantiation time or - // set to "NULL", at which point we cannot automatically determine the value type. - - if (isset($def[Transcoding::FIELD_TYPE])) { - // if the field has a FIELD_TYPE value in the definition map - $fieldType = $def[Transcoding::FIELD_TYPE]; - } elseif (isset($this->{$field})) { - // if the field is set and non-null - $fieldType = \gettype($this->{$field}); - } else { - throw new \LogicException( - sprintf( - 'Field "%s" on type "%s" is missing a FIELD_TYPE hydration entry: %s', - $field, - static::class, - var_export($def, true) - ) - ); - } - - if (Transcoding::OBJECT === $fieldType) { - $this->unmarshalObject($field, $value, $def); - return; - } - - if (Transcoding::ARRAY === $fieldType) { - $this->unmarshalArray($field, $value, $def); - return; - } - - // at this point, assume scalar - // todo: handle non-scalar types here - $this->unmarshalScalar($field, $value, self::fieldIsNullable($def)); - } - - private function unmarshalObject(string $field, mixed $value, array $def): void - { - if (!isset($def[Transcoding::FIELD_CLASS])) { - throw new \LogicException( - sprintf( - 'Field "%s" on type "%s" is missing FIELD_CLASS hydration entry: %s', - $field, - static::class, - var_export($def, true) - ) - ); - } - - $this->{$field} = $this->buildObjectValue( - $field, - $value, - $def[Transcoding::FIELD_CLASS], - self::fieldIsNullable($def) - ); - } - - private function unmarshalArray(string $field, mixed $value, array $def): void - { - // attempt to extract the two possible keys - $type = $def[Transcoding::FIELD_ARRAY_TYPE] ?? null; - $class = $def[Transcoding::FIELD_CLASS] ?? null; - - // type is required - if (null === $type) { - throw new \DomainException( - sprintf( - 'Field "%s" on type "%s" definition is missing FIELD_ARRAY_TYPE value: %s', - $field, - static::class, - var_export($def, true) - ) - ); - } - - // is the incoming value null? - if (null === $value) { - // if this value can be null'd, allow it. - if (static::fieldIsNullable($def)) { - $this->{$field} = null; - } - return; - } - - // by the time we get here, $value must be an array - if (!\is_array($value)) { - throw new \RuntimeException( - sprintf( - 'Field "%s" on type "%s" is an array but provided value is "%s"', - $field, - static::class, - \gettype($value) - ) - ); - } - - // currently the only supported array types are scalar or objects. everything else will require - // a custom callback for hydration purposes. - - if (Transcoding::OBJECT === $type) { - if (null === $class) { - throw new \DomainException( - sprintf( - 'Field "%s" on type "%s" definition is missing FIELD_CLASS value: %s', - $field, - static::class, - var_export($def, true) - ) - ); - } - - foreach ($value as $k => $v) { - // short circuit to prevent additional func call - if (null === $v) { - $this->{$field}[$k] = null; - } else { - $this->{$field}[$k] = $this->buildObjectValue($field, $v, $class, false); - } - } - } else { - // in all other cases, just set as-is - foreach ($value as $k => $v) { - // short circuit to prevent additional func call - if (null === $v) { - $this->{$field}[$k] = null; - } else { - $this->{$field}[$k] = $this->buildScalarValue($field, $v, $type, false); - } - } - } - } -} diff --git a/src/Values.php b/src/Values.php index e43fdc08..3d2b60fb 100644 --- a/src/Values.php +++ b/src/Values.php @@ -20,7 +20,7 @@ limitations under the License. */ -class Values implements \Iterator, \ArrayAccess, \Countable, \JsonSerializable +class Values implements \ArrayAccess, \Countable, \JsonSerializable { private array $values = []; @@ -63,7 +63,7 @@ public function delete(string $key): void public function count(): int { - return \count($this->values); + return count($this->values); } public function toPsr7Array(): array @@ -71,47 +71,30 @@ public function toPsr7Array(): array return $this->values; } - public function current(): array + public function getIterator(): iterable { - return current($this->values); - } - - public function next(): void - { - next($this->values); - } - - public function key(): ?string - { - return key($this->values); - } - - public function valid(): bool - { - return null !== key($this->values); - } - - public function rewind(): void - { - reset($this->values); + if ([] === $this->values) { + return new \EmptyIterator(); + } + return new \ArrayIterator($this->values); } public function offsetExists(mixed $offset): bool { - return isset($this->values[$offset]); + return array_key_exists($offset, $this->values); } - public function offsetGet($offset): string + public function offsetGet(mixed $offset): string { return $this->get($offset); } - public function offsetSet($offset, $value): void + public function offsetSet(mixed $offset, mixed $value): void { $this->set($offset, $value); } - public function offsetUnset($offset): void + public function offsetUnset(mixed $offset): void { $this->delete($offset); } @@ -137,7 +120,7 @@ public function __toString(): string if ('' === $v) { $str .= $k; } else { - $str .= sprintf('%s=%s', $k, $this->encode($v)); + $str .= "{$k}={$this->encode($v)}"; } } } diff --git a/src/WriteMeta.php b/src/WriteMeta.php index 326960ec..d911ecca 100644 --- a/src/WriteMeta.php +++ b/src/WriteMeta.php @@ -24,9 +24,14 @@ class WriteMeta { - public ?Time\Duration $RequestTime = null; + public Time\Duration $RequestTime; - public function getRequestTime(): ?Time\Duration + public function __construct(Time\Duration $RequestTime) + { + $this->RequestTime = $RequestTime; + } + + public function getRequestTime(): Time\Duration { return $this->RequestTime; } diff --git a/src/WriteMetaContainer.php b/src/WriteMetaContainer.php index 76c5d857..0c13ba78 100644 --- a/src/WriteMetaContainer.php +++ b/src/WriteMetaContainer.php @@ -22,9 +22,9 @@ trait WriteMetaContainer { - public ?WriteMeta $WriteMeta = null; + public null|WriteMeta $WriteMeta = null; - public function getWriteMeta(): ?WriteMeta + public function getWriteMeta(): null|WriteMeta { return $this->WriteMeta; } diff --git a/src/WriteOptions.php b/src/WriteOptions.php index 6b750702..f659b0ad 100644 --- a/src/WriteOptions.php +++ b/src/WriteOptions.php @@ -22,20 +22,30 @@ use DCarbone\Go\Time; -class WriteOptions extends AbstractModel implements RequestOptions +class WriteOptions implements RequestOptions { - public string $Namespace = ''; - public string $Datacenter = ''; - public string $Token = ''; - public int $RelayFactor = 0; - - public ?Time\Duration $Timeout = null; - - public function __construct(?array $data = null) - { - parent::__construct($data); - if (!($this->Timeout instanceof Time\Duration)) { - $this->Timeout = Time::Duration($this->Timeout); + public string $Namespace; + public string $Datacenter; + public string $Token; + public int $RelayFactor; + + public Time\Duration $Timeout; + + public function __construct( + null|array $data = null, // Deprecated do not use. + string $Namespace = '', + string $Datacenter = '', + string $Token = '', + int $RelayFactor = 0, + null|int|float|string|\DateInterval|Time\Duration $Timeout = null, + ) { + $this->Namespace = $Namespace; + $this->Datacenter = $Datacenter; + $this->Token = $Token; + $this->RelayFactor = $RelayFactor; + $this->Timeout = Time::Duration($Timeout); + if (null !== $data && [] !== $data) { + $this->_fromMap((object)$data); } } @@ -84,7 +94,7 @@ public function getTimeout(): ?Time\Duration return $this->Timeout; } - public function setTimeout(float|int|string|Time\Duration|null $timeout): void + public function setTimeout(null|int|float|string|\DateInterval|Time\Duration $timeout): void { $this->Timeout = Time::Duration($timeout); } @@ -101,11 +111,26 @@ public function apply(Request $r): void $r->header->set('X-Consul-Token', $this->Token); } if (0 !== $this->RelayFactor) { - $r->params->set('relay-factor', (string) $this->RelayFactor); + $r->params->set('relay-factor', (string)$this->RelayFactor); } - if (null !== $this->Timeout) { + if (0 < $this->Timeout->Nanoseconds()) { $r->timeout = $this->Timeout; } } + + /** + * @param \stdClass $data + * @deprecated This is only here to support construction with map. It will be removed in a future version. + */ + private function _fromMap(\stdClass $data): void + { + foreach ($data as $k => $v) { + if ('Timeout' === $k) { + $this->Timeout = Time::Duration($v); + } else { + $this->{$k} = $v; + } + } + } } diff --git a/src/WriteResponse.php b/src/WriteResponse.php index c6fa61db..592e7586 100644 --- a/src/WriteResponse.php +++ b/src/WriteResponse.php @@ -20,14 +20,14 @@ limitations under the License. */ -class WriteResponse extends AbstractResponse +class WriteResponse extends AbstractResponse implements WriteResponseInterface { use WriteMetaContainer; use ErrorContainer; public function offsetExists(mixed $offset): bool { - return \is_int($offset) && 0 <= $offset && $offset < 2; + return is_int($offset) && 0 <= $offset && $offset < 2; } public function offsetGet(mixed $offset): Error|null|WriteMeta diff --git a/src/ScalarType.php b/src/WriteResponseInterface.php similarity index 77% rename from src/ScalarType.php rename to src/WriteResponseInterface.php index 3dc28b72..c3218f94 100644 --- a/src/ScalarType.php +++ b/src/WriteResponseInterface.php @@ -20,12 +20,7 @@ limitations under the License. */ -/** - * This is a quick hack to allow for classes to be non-null during definition testing, yet still provide - * go-like functionality in practice. - * - * Interface ScalarType - */ -interface ScalarType +interface WriteResponseInterface { + public function getWriteMeta(): null|WriteMeta; } diff --git a/tests/ConsulManager.php b/tests/ConsulManager.php index f34ebb03..bc315102 100644 --- a/tests/ConsulManager.php +++ b/tests/ConsulManager.php @@ -40,14 +40,14 @@ final class ConsulManager */ public static function startSingle(string $flags): void { - if (\file_exists(self::PID_FILE)) { + if (file_exists(self::PID_FILE)) { self::stopSingle(); } - \shell_exec(self::START_SINGLE_CMD . " {$flags}"); + shell_exec(self::START_SINGLE_CMD . " {$flags}"); // sleep to allow consul to setup - \sleep(3); + sleep(3); } /** @@ -63,12 +63,12 @@ public static function startSingleDev(): void */ public static function stopSingle(): void { - if (\file_exists(self::PID_FILE)) { - \shell_exec(self::STOP_SINGLE_CMD); - if (\file_exists(self::PID_FILE)) { - \unlink(self::PID_FILE); + if (file_exists(self::PID_FILE)) { + shell_exec(self::STOP_SINGLE_CMD); + if (file_exists(self::PID_FILE)) { + unlink(self::PID_FILE); } - \sleep(1); + sleep(1); } } diff --git a/tests/Usage/ACL/ACLClientTest.php b/tests/Usage/ACL/ACLClientTest.php index f16501ea..5cb48d94 100644 --- a/tests/Usage/ACL/ACLClientTest.php +++ b/tests/Usage/ACL/ACLClientTest.php @@ -24,22 +24,18 @@ use DCarbone\PHPConsulAPITests\ConsulManager; use DCarbone\PHPConsulAPITests\Usage\AbstractUsageTests; -/** - * Class ACLClientTest - * - * @internal - */ + final class ACLClientTest extends AbstractUsageTests { /** @var string */ - protected $bootstrappedACL; + protected string $bootstrappedACL; /** * @return string */ public function testCanBootstrapACL() { - ConsulManager::startSingleDev('-bind="127.0.0.1"'); + ConsulManager::startSingleDev(); $client = new ACLClient(ConsulManager::testConfig()); @@ -60,9 +56,9 @@ public function testCanGetBootstrappedACL(string $aclID): void $client = new ACLClient(ConsulManager::testConfig()); [$acls, $qm, $err] = $client->Info($aclID); - self::assertNull($err, 'ACL::info() return error: ' . $err); + self::assertNull($err, 'ACL::Info() return error: ' . $err); self::assertInstanceOf(QueryMeta::class, $qm); self::assertIsArray($acls); - \var_dump($acls); + var_dump($acls); } } diff --git a/tests/Usage/Agent/AgentClientTest.php b/tests/Usage/Agent/AgentClientTest.php index 40c8ce03..a7040052 100644 --- a/tests/Usage/Agent/AgentClientTest.php +++ b/tests/Usage/Agent/AgentClientTest.php @@ -54,11 +54,11 @@ public function testCanGetSelf(): void [$self, $err] = $client->Self(); self::assertNull($err); - self::assertIsArray( + self::assertIsObject( $self, - \sprintf( + sprintf( 'Expected AgentClient::self to return array, saw "%s"', - \gettype($self) + gettype($self) ) ); } @@ -70,7 +70,7 @@ public function testCanReloadSelf(): void { $client = new AgentClient(ConsulManager::testConfig()); $err = $client->Reload(); - self::assertNull($err, \sprintf('AgentClient::reload returned error: %s', $err)); + self::assertNull($err, sprintf('AgentClient::reload returned error: %s', $err)); } /** @@ -81,10 +81,10 @@ public function testCanGetNodeName(): void $client = new AgentClient(ConsulManager::testConfig()); [$nodeName, $err] = $client->NodeName(); - self::assertNull($err, \sprintf('Unable to get agent node name: %s', $err)); + self::assertNull($err, sprintf('Unable to get agent node name: %s', $err)); self::assertIsString( $nodeName, - \sprintf('node name expected to be string, %s seen', \gettype($nodeName)) + sprintf('node name expected to be string, %s seen', gettype($nodeName)) ); self::assertNotEmpty($nodeName, 'NodeName was empty!'); } @@ -97,7 +97,7 @@ public function testCanGeMembers(): void $client = new AgentClient(ConsulManager::testConfig()); [$members, $err] = $client->Members(); - self::assertNull($err, \sprintf('AgentClient::members returned error: %s', $err)); + self::assertNull($err, sprintf('AgentClient::members returned error: %s', $err)); self::assertIsArray($members); self::assertContainsOnlyInstancesOf(AgentMember::class, $members); self::assertCount(1, $members); @@ -117,7 +117,7 @@ public function testCanRegisterServiceNoChecks(): void ->setPort(1234); $err = $client->ServiceRegister($svc); - self::assertNull($err, \sprintf('AgentClient::serviceRegister returned error: %s', $err)); + self::assertNull($err, sprintf('AgentClient::serviceRegister returned error: %s', $err)); } /** @@ -132,12 +132,12 @@ public function testCanRegisterServiceWithOneCheck(): void ->setName(self::Service2Name) ->setAddress('127.0.0.1') ->setPort(4321) - ->setCheck(new AgentServiceCheck([ - 'TTL' => '5s', - ])); + ->setCheck(new AgentServiceCheck( + TTL: '5s', + )); $err = $client->ServiceRegister($svc); - self::assertNull($err, \sprintf('AgentClient::serviceRegister returned error: %s', $err)); + self::assertNull($err, sprintf('AgentClient::serviceRegister returned error: %s', $err)); } /** @@ -152,15 +152,15 @@ public function testCanGetServiceList(): void [$svcs, $err] = $client->Services(); try { - self::assertNull($err, \sprintf('AgentClient::services return error: %s', $err)); - self::assertIsArray($svcs); - self::assertContainsOnlyInstancesOf(AgentService::class, $svcs); + self::assertNull($err, sprintf('AgentClient::services return error: %s', $err)); + self::assertIsObject($svcs); + self::assertContainsOnlyInstancesOf(AgentService::class, (array)$svcs); // NOTE: will always contain "consul" service - self::assertCount(2, $svcs); + self::assertCount(2, (array)$svcs); } catch (AssertionFailedError $e) { echo "\nservices list:\n"; - \var_dump($svcs); + var_dump($svcs); echo "\n"; throw $e; @@ -175,18 +175,18 @@ public function testCanDeregisterService(): void $client = new AgentClient(ConsulManager::testConfig()); $err = $client->ServiceDeregister(self::Service1Name); - self::assertNull($err, \sprintf('AgentClient::serviceDeregister returned error: %s', $err)); + self::assertNull($err, sprintf('AgentClient::serviceDeregister returned error: %s', $err)); [$svcs, $err] = $client->Services(); try { - self::assertNull($err, \sprintf('AgentClient::services returned error: %s', $err)); - self::assertIsArray($svcs); - self::assertContainsOnlyInstancesOf(AgentService::class, $svcs); - self::assertCount(1, $svcs); + self::assertNull($err, sprintf('AgentClient::services returned error: %s', $err)); + self::assertIsObject($svcs); + self::assertContainsOnlyInstancesOf(AgentService::class, (array)$svcs); + self::assertCount(1, (array)$svcs); } catch (AssertionFailedError $e) { echo "\nservices list:\n"; - \var_dump($svcs); + var_dump($svcs); echo "\n"; throw $e; @@ -205,32 +205,32 @@ public function testCanRegisterServiceWithCheck(): void ->setName(self::Service1Name) ->setPort(1234) ->setAddress('127.0.0.1') - ->setCheck(new AgentServiceCheck([ - 'TCP' => '127.0.0.1', - 'Interval' => '30s', - ])); + ->setCheck(Check: new AgentServiceCheck( + Interval: '30s', + TCP: '127.0.0.1', + )); $err = $client->ServiceRegister($svc); - self::assertNull($err, \sprintf('Error registering service with check: %s', $err)); + self::assertNull($err, sprintf('Error registering service with check: %s', $err)); - \sleep(2); + sleep(2); [$svcs, $err] = $client->Services(); try { - self::assertNull($err, \sprintf('AgentClient::services returned error: %s', $err)); - self::assertIsArray($svcs); - self::assertContainsOnlyInstancesOf(AgentService::class, $svcs); - self::assertCount(2, $svcs); + self::assertNull($err, sprintf('AgentClient::services returned error: %s', $err)); + self::assertIsObject($svcs); + self::assertContainsOnlyInstancesOf(AgentService::class, (array)$svcs); + self::assertCount(2, (array)$svcs); } catch (AssertionFailedError $e) { echo "\nservices list:\n"; - \var_dump($svcs); + var_dump($svcs); echo "\n"; throw $e; } $err = $client->ServiceDeregister(self::Service1Name); - self::assertNull($err, \sprintf('Error deregistering service: %s', $err)); + self::assertNull($err, sprintf('Error deregistering service: %s', $err)); } } diff --git a/tests/Usage/Agent/AgentServiceConnectProxyConfigTest.php b/tests/Usage/Agent/AgentServiceConnectProxyConfigTest.php index e0d5fea7..89f38180 100644 --- a/tests/Usage/Agent/AgentServiceConnectProxyConfigTest.php +++ b/tests/Usage/Agent/AgentServiceConnectProxyConfigTest.php @@ -20,29 +20,28 @@ */ use DCarbone\PHPConsulAPI\Agent\AgentServiceConnectProxyConfig; -use DCarbone\PHPConsulAPI\FakeMap; use DCarbone\PHPConsulAPITests\Usage\AbstractUsageTests; class AgentServiceConnectProxyConfigTest extends AbstractUsageTests { public function test_construct_givenConfig_willUnmarshalConfigValuesSuccessfully() { - $config = new AgentServiceConnectProxyConfig([ - 'Config' => [ + $config = new AgentServiceConnectProxyConfig( + Config: (object)[ 'envoy_prometheus_bind_addr' => '0.0.0.0:12345', 'handshake_timeout_ms' => 10000, 'local_connect_timeout_ms' => 1000, 'local_request_timeout_ms' => 0, 'protocol' => 'http', ], - ]); + ); - $this->assertEquals(new FakeMap([ + $this->assertEquals((object)[ 'envoy_prometheus_bind_addr' => '0.0.0.0:12345', 'handshake_timeout_ms' => 10000, 'local_connect_timeout_ms' => 1000, 'local_request_timeout_ms' => 0, 'protocol' => 'http', - ]), $config->Config); + ], $config->Config); } } \ No newline at end of file diff --git a/tests/Usage/Catalog/CatalogClientTest.php b/tests/Usage/Catalog/CatalogClientTest.php index e0111b9a..47cbd31f 100644 --- a/tests/Usage/Catalog/CatalogClientTest.php +++ b/tests/Usage/Catalog/CatalogClientTest.php @@ -89,7 +89,7 @@ public function testCanGetService(): void self::assertInstanceOf(QueryMeta::class, $qm); self::assertIsArray($service); self::assertCount(1, $service); - self::assertInstanceOf(CatalogService::class, \reset($service)); + self::assertInstanceOf(CatalogService::class, reset($service)); } /** @@ -132,7 +132,7 @@ public function testCanGetListOfService(): void self::assertInstanceOf(CatalogService::class, $s); } } catch (AssertionFailedError $e) { - \var_dump($service); + var_dump($service); throw $e; } } @@ -153,7 +153,7 @@ public function testCanGetListOfServices(): void self::assertCount(2, $services); self::assertContainsOnly('array', $services); } catch (AssertionFailedError $e) { - \var_dump($services); + var_dump($services); throw $e; } } @@ -176,7 +176,7 @@ public function testCanDeregisterService(): void self::assertNull($err, 'CatalogClient::service returned error: ' . $err); self::assertInstanceOf(QueryMeta::class, $qm); self::assertCount(1, $service); - self::assertInstanceOf(CatalogService::class, \reset($service)); + self::assertInstanceOf(CatalogService::class, reset($service)); } /** @@ -196,7 +196,7 @@ public function testCanGetDatacenters(): void self::assertCount(1, $dcs); self::assertSame('dc1', $dcs[0]); } catch (AssertionFailedError $e) { - \var_dump($dcs); + var_dump($dcs); throw $e; } } @@ -217,7 +217,7 @@ public function testCanGetListOfNodes(): void self::assertCount(2, $nodes); self::assertContainsOnlyInstancesOf(Node::class, $nodes); } catch (AssertionFailedError $e) { - \var_dump($nodes); + var_dump($nodes); throw $e; } } @@ -245,7 +245,7 @@ public function testCanGetNode(): void self::assertNotNull($id, 'Unable to get node with ID'); } catch (AssertionFailedError $e) { - \var_dump($nodes); + var_dump($nodes); throw $e; } @@ -255,7 +255,7 @@ public function testCanGetNode(): void self::assertInstanceOf(QueryMeta::class, $qm); self::assertInstanceOf(CatalogNode::class, $node); } catch (AssertionFailedError $e) { - \var_dump($node); + var_dump($node); throw $e; } } diff --git a/tests/Usage/Coordinate/CoordinateClientTest.php b/tests/Usage/Coordinate/CoordinateClientTest.php index 1d615539..2440e5fa 100644 --- a/tests/Usage/Coordinate/CoordinateClientTest.php +++ b/tests/Usage/Coordinate/CoordinateClientTest.php @@ -47,9 +47,9 @@ public function testDatacenters(): void $client = new CoordinateClient(ConsulManager::testConfig()); [$dcs, $err] = $client->Datacenters(); - self::assertNull($err, \sprintf('CoordinateClient::datacenters() - %s', $err)); + self::assertNull($err, sprintf('CoordinateClient::datacenters() - %s', $err)); self::assertIsArray($dcs); - self::assertGreaterThan(0, \count($dcs), 'Expected at least 1 datacenter'); + self::assertGreaterThan(0, count($dcs), 'Expected at least 1 datacenter'); } /** @@ -60,7 +60,7 @@ public function testNodes(): void $client = new CoordinateClient(ConsulManager::testConfig()); [$nodes, $qm, $err] = $client->Nodes(); - self::assertNull($err, \sprintf('CoordinateClient::nodes() - %s', $err)); + self::assertNull($err, sprintf('CoordinateClient::nodes() - %s', $err)); self::assertInstanceOf(QueryMeta::class, $qm); self::assertIsArray($nodes); } diff --git a/tests/Usage/Coordinate/CoordinateUsageTest.php b/tests/Usage/Coordinate/CoordinateUsageTest.php index 0ed2b1a5..b4c91268 100644 --- a/tests/Usage/Coordinate/CoordinateUsageTest.php +++ b/tests/Usage/Coordinate/CoordinateUsageTest.php @@ -178,7 +178,7 @@ public function testApplyForce(): void $this->verifyEqualFloats($c->Height, $config->HeightMin); $bad = clone $c; - $bad->Vec = \array_fill(0, \count($c->Vec) + 1, 0.0); + $bad->Vec = array_fill(0, count($c->Vec) + 1, 0.0); $c->ApplyForce($config, 1.0, $bad); } @@ -212,7 +212,7 @@ public function testDistanceTo(): void $this->verifyEqualFloats($c1->DistanceTo($c2)->Seconds(), 4.104875150354758 + 0.3 + 0.8); $bad = clone $c1; - $bad->Vec = \array_fill(0, \count($c1->Vec) + 1, 0.0); + $bad->Vec = array_fill(0, count($c1->Vec) + 1, 0.0); $c1->DistanceTo($bad); } @@ -224,8 +224,8 @@ protected function verifyEqualFloats(float $f1, float $f2): void { self::assertLessThanOrEqual( self::ZeroThreshold, - \abs($f1 - $f2), - \sprintf('equal assertion fail, %.6f != %.6f', $f1, $f2) + abs($f1 - $f2), + sprintf('equal assertion fail, %.6f != %.6f', $f1, $f2) ); } @@ -241,7 +241,7 @@ protected function verifyEqualVectors(array $vec1, array $vec2): void $this->verifyEqualFloats($v, $vec2[$k]); } } catch (AssertionFailedError $e) { - \var_dump($vec1, $vec2); + var_dump($vec1, $vec2); throw $e; } } diff --git a/tests/Usage/KV/KVCRUDTest.php b/tests/Usage/KV/KVCRUDTest.php index ae1cebd9..4c038b47 100644 --- a/tests/Usage/KV/KVCRUDTest.php +++ b/tests/Usage/KV/KVCRUDTest.php @@ -55,7 +55,7 @@ public function testCanPutKey(): void $client = new KVClient(ConsulManager::testConfig()); [$wm, $err] = $client->Put(new KVPair(['Key' => self::KVKey1, 'Value' => self::KVValue1])); - self::assertNull($err, \sprintf('Unable to set kvp: %s', (string)$err)); + self::assertNull($err, sprintf('Unable to set kvp: %s', (string)$err)); self::assertInstanceOf(WriteMeta::class, $wm); } @@ -68,7 +68,7 @@ public function testCanGetKey(): void $client->Put(new KVPair(['Key' => self::KVKey1, 'Value' => self::KVValue1])); [$kv, $qm, $err] = $client->Get(self::KVKey1); - self::assertNull($err, \sprintf('KV::get returned error: %s', (string)$err)); + self::assertNull($err, sprintf('KV::get returned error: %s', (string)$err)); self::assertInstanceOf(QueryMeta::class, $qm); self::assertInstanceOf(KVPair::class, $kv); self::assertSame(self::KVKey1, $kv->Key); @@ -84,14 +84,14 @@ public function testCanDeleteKey(): void $client->Put(new KVPair(['Key' => self::KVKey1, 'Value' => self::KVValue1])); [$wm, $err] = $client->Delete(self::KVKey1); - self::assertNull($err, \sprintf('KV::delete returned error: %s', $err)); + self::assertNull($err, sprintf('KV::delete returned error: %s', $err)); self::assertInstanceOf( WriteMeta::class, $wm, - \sprintf( + sprintf( 'expected "%s", saw "%s"', WriteMeta::class, - \is_object($wm) ? \get_class($wm) : \gettype($wm) + is_object($wm) ? get_class($wm) : gettype($wm) ) ); } @@ -103,10 +103,10 @@ public function testListReturnsErrorWithInvalidPrefix(): void self::assertInstanceOf( Error::class, $err, - \sprintf( + sprintf( 'Expected $err to be instanceof "%s", saw "%s"', Error::class, - \is_object($err) ? \get_class($err) : \gettype($err) + is_object($err) ? get_class($err) : gettype($err) ) ); } @@ -126,7 +126,7 @@ public function testCanGetNoPrefixList(): void /** @noinspection PhpUnhandledExceptionInspection */ [$list, $qm, $err] = $client->List(); - self::assertNull($err, \sprintf('KV::valueList returned error: %s', $err)); + self::assertNull($err, sprintf('KV::valueList returned error: %s', $err)); try { self::assertInstanceOf(KVPairs::class, $list); @@ -152,7 +152,7 @@ public function testCanGetNoPrefixList(): void self::assertTrue($key3found, 'Key3 not found in list!'); } catch (AssertionFailedError $e) { echo "\nno prefix \$list value:\n"; - \var_dump($list); + var_dump($list); echo "\n"; throw $e; @@ -173,7 +173,7 @@ public function testCanGetPrefixList(): void $client->Put(new KVPair(['Key' => self::KVPrefix . '/' . self::KVKey3, 'Value' => self::KVValue3])); [$list, $qm, $err] = $client->List(self::KVPrefix); - self::assertNull($err, \sprintf('KV::valueList returned error: %s', $err)); + self::assertNull($err, sprintf('KV::valueList returned error: %s', $err)); self::assertInstanceOf(QueryMeta::class, $qm); try { @@ -200,7 +200,7 @@ public function testCanGetPrefixList(): void self::assertTrue($key3found, 'Key3 not found in list!'); } catch (AssertionFailedError $e) { echo "\nprefix \$list value:\n"; - \var_dump($list); + var_dump($list); echo "\n"; throw $e; @@ -214,10 +214,10 @@ public function testKeysReturnsErrorWithInvalidPrefix(): void self::assertInstanceOf( Error::class, $err, - \sprintf( + sprintf( 'Expected $err to be "%s", saw "%s"', Error::class, - \is_object($err) ? \get_class($err) : \gettype($err) + is_object($err) ? get_class($err) : gettype($err) ) ); } @@ -236,7 +236,7 @@ public function testCanGetNoPrefixKeys(): void $client->Put(new KVPair(['Key' => self::KVKey3, 'Value' => self::KVValue3])); [$list, $qm, $err] = $client->Keys(); - self::assertNull($err, \sprintf('KV::keys returned error: %s', $err)); + self::assertNull($err, sprintf('KV::keys returned error: %s', $err)); self::assertInstanceOf(QueryMeta::class, $qm); try { @@ -263,7 +263,7 @@ public function testCanGetNoPrefixKeys(): void self::assertTrue($key3found, 'Key3 not found in list!'); } catch (AssertionFailedError $e) { echo "\nprefix \$list value:\n"; - \var_dump($list); + var_dump($list); echo "\n"; throw $e; diff --git a/tests/Usage/KV/KVClientCASTest.php b/tests/Usage/KV/KVClientCASTest.php index d212e6c2..ecfc4a5c 100644 --- a/tests/Usage/KV/KVClientCASTest.php +++ b/tests/Usage/KV/KVClientCASTest.php @@ -29,10 +29,10 @@ public function testKVWithCAS(): void $client = new KVClient(ConsulManager::testConfig()); [$_, $err] = $client->Put(new KVPair(['Key' => self::KVKey1, 'Value' => self::KVOriginalValue])); - self::assertNull($err, \sprintf('Unable to put KV: %s', $err)); + self::assertNull($err, sprintf('Unable to put KV: %s', $err)); [$kv, $_, $err] = $client->Get(self::KVKey1); - self::assertNull($err, \sprintf('Unable to get KV: %s', $err)); + self::assertNull($err, sprintf('Unable to get KV: %s', $err)); self::assertInstanceOf(KVPair::class, $kv); self::assertSame(self::KVOriginalValue, $kv->Value); @@ -41,27 +41,27 @@ public function testKVWithCAS(): void $kv->Value = self::KVUpdatedValue; [$ok, $_, $err] = $client->CAS($kv); - self::assertNull($err, \sprintf('Unable to update kv value: %s', $err)); + self::assertNull($err, sprintf('Unable to update kv value: %s', $err)); self::assertTrue($ok); $kv->Value = self::KVUpdatedValue2; [$ok, $_, $err] = $client->CAS($kv); - self::assertNull($err, \sprintf('Error updating kv with old cas: %s', $err)); + self::assertNull($err, sprintf('Error updating kv with old cas: %s', $err)); self::assertFalse($ok, 'Expected false when trying to update key with old cas'); [$ok, $_, $err] = $client->DeleteCAS($kv); - self::assertNull($err, \sprintf('Error deleting kv with old cas: %s', $err)); + self::assertNull($err, sprintf('Error deleting kv with old cas: %s', $err)); self::assertFalse($ok, 'Expected false when trying to delete key with old cas'); [$kv, $_, $err] = $client->Get(self::KVKey1); - self::assertNull($err, \sprintf('Error retrieving updated key: %s', $err)); + self::assertNull($err, sprintf('Error retrieving updated key: %s', $err)); self::assertInstanceOf(KVPair::class, $kv); self::assertNotSame($omi, $kv->ModifyIndex, 'Expected ModifyIndex to be different'); self::assertSame(self::KVUpdatedValue, $kv->Value, 'KV Value was not actually updated'); [$ok, $_, $err] = $client->DeleteCAS($kv); - self::assertNull($err, \sprintf('Error deleting key: %s', $err)); + self::assertNull($err, sprintf('Error deleting key: %s', $err)); self::assertTrue($ok, 'Expected true when deleting key with updated cas'); } } diff --git a/tests/Usage/KV/KVClientLockTest.php b/tests/Usage/KV/KVClientLockTest.php index 615455d2..2d5abfbd 100644 --- a/tests/Usage/KV/KVClientLockTest.php +++ b/tests/Usage/KV/KVClientLockTest.php @@ -41,15 +41,15 @@ public function testAcquireAndRelease(): void ] ) ); - self::assertNull($err, \sprintf('Error creating session: %s', $err)); + self::assertNull($err, sprintf('Error creating session: %s', $err)); $kv = new KVPair(['Key' => $key, 'Value' => 'whatever', 'Session' => $id]); [$wm, $err] = $kvClient->Acquire($kv); - self::assertNull($err, \sprintf('Error acquiring lock: %s', $err)); + self::assertNull($err, sprintf('Error acquiring lock: %s', $err)); self::assertInstanceOf(WriteMeta::class, $wm); [$kv, $_, $err] = $kvClient->Get($key); - self::assertNull($err, \sprintf('Error retrieving key: %s', $err)); + self::assertNull($err, sprintf('Error retrieving key: %s', $err)); self::assertInstanceOf(KVPair::class, $kv); self::assertSame($id, $kv->Session); self::assertSame('whatever', $kv->Value); diff --git a/tests/Usage/Operator/OperatorAutopilotTest.php b/tests/Usage/Operator/OperatorAutopilotTest.php index e77a82fb..6fd456ac 100644 --- a/tests/Usage/Operator/OperatorAutopilotTest.php +++ b/tests/Usage/Operator/OperatorAutopilotTest.php @@ -39,11 +39,11 @@ public function testCanGetAutopilotConfiguration(): void $client = new OperatorClient(ConsulManager::testConfig()); [$conf, $err] = $client->AutopilotGetConfiguration(); - self::assertNull($err, \sprintf('Unable to list autopilot configuration: %s', $err)); + self::assertNull($err, sprintf('Unable to list autopilot configuration: %s', $err)); self::assertInstanceOf( AutopilotConfiguration::class, $conf, - \sprintf('Expected instance of %s, saw: %s', AutopilotConfiguration::class, \json_encode($conf)) + sprintf('Expected instance of %s, saw: %s', AutopilotConfiguration::class, json_encode($conf)) ); } diff --git a/tests/Usage/Operator/ReadableDurationTest.php b/tests/Usage/Operator/ReadableDurationTest.php index 53db8ae9..c6abb929 100644 --- a/tests/Usage/Operator/ReadableDurationTest.php +++ b/tests/Usage/Operator/ReadableDurationTest.php @@ -31,7 +31,7 @@ final class ReadableDurationTest extends TestCase { public function testReadableJsonEncoding(): void { - $rd = new ReadableDuration(\time() * Time::Second); - self::assertSame('"' . (string)$rd . '"', \json_encode($rd)); + $rd = new ReadableDuration(time() * Time::Second); + self::assertSame('"' . (string)$rd . '"', json_encode($rd)); } } diff --git a/tests/Usage/RequestUsageTest.php b/tests/Usage/RequestUsageTest.php index 2e0bc48a..35c04223 100644 --- a/tests/Usage/RequestUsageTest.php +++ b/tests/Usage/RequestUsageTest.php @@ -79,7 +79,7 @@ public function testCanCreatePsr7Request(): void public function testCanSetQueryOptions(): void { $r = new Request('GET', 'kv', ConsulManager::testConfig(), null); - $r->applyOptions(new QueryOptions(['Pretty' => true])); + $r->applyOptions(new QueryOptions(Pretty: true)); $psr7 = $r->toPsrRequest(); $uri = $psr7->getUri(); @@ -92,7 +92,7 @@ public function testCanSetQueryOptions(): void public function testCanSetWriteOptions(): void { $r = new Request('GET', 'kv', ConsulManager::testConfig(), null); - $r->applyOptions(new WriteOptions(['Datacenter' => 'dc1'])); + $r->applyOptions(new WriteOptions(Datacenter: 'dc1')); $psr7 = $r->toPsrRequest(); $uri = $psr7->getUri(); diff --git a/tests/Usage/Session/SessionClientUsageTest.php b/tests/Usage/Session/SessionClientUsageTest.php index 47cdeca3..f51d07ea 100644 --- a/tests/Usage/Session/SessionClientUsageTest.php +++ b/tests/Usage/Session/SessionClientUsageTest.php @@ -36,12 +36,12 @@ public function testNoChecksLifecycle(): void 'Behavior' => Consul::SessionBehaviorDelete, 'TTL' => $ttl, ])); - self::assertNull($err, \sprintf('Error creating session: %s', $err)); + self::assertNull($err, sprintf('Error creating session: %s', $err)); self::assertInstanceOf(WriteMeta::class, $wm); self::assertIsString($id, 'Expected ID to be string'); [$sessions, $qm, $err] = $client->Info($id); - self::assertNull($err, \sprintf('Error getting %s info: %s', $id, $err)); + self::assertNull($err, sprintf('Error getting %s info: %s', $id, $err)); self::assertInstanceOf(QueryMeta::class, $qm); self::assertIsArray($sessions); self::assertCount(1, $sessions); @@ -58,17 +58,17 @@ public function testNoChecksLifecycle(): void self::assertSame(15 * Time::Second, $session->LockDelay->Nanoseconds()); [$sessions, $wm, $err] = $client->Renew($id); - self::assertNull($err, \sprintf('Error renewing session: %s', $err)); + self::assertNull($err, sprintf('Error renewing session: %s', $err)); self::assertInstanceOf(WriteMeta::class, $wm); self::assertIsArray($sessions); self::assertCount(1, $sessions); self::assertContainsOnlyInstancesOf(SessionEntry::class, $sessions); [$_, $err] = $client->Destroy($id); - self::assertNull($err, \sprintf('Error destroying session: %s', $err)); + self::assertNull($err, sprintf('Error destroying session: %s', $err)); [$sessions, $_, $err] = $client->Info($id); - self::assertNull($err, \sprintf('Error getting list after expected expiration: %s', $err)); + self::assertNull($err, sprintf('Error getting list after expected expiration: %s', $err)); self::assertIsArray($sessions, 'Expected $sessions to be an array'); self::assertCount(0, $sessions, 'Expected $sessions to be empty'); } diff --git a/tests/consul.hcl b/tests/consul.hcl new file mode 100644 index 00000000..a348735d --- /dev/null +++ b/tests/consul.hcl @@ -0,0 +1,7 @@ +acl { + enabled = true + default_policy = "allow" + tokens { + default = "123456" + } +} \ No newline at end of file diff --git a/tests/funcs.php b/tests/funcs.php index a7102800..83429fff 100644 --- a/tests/funcs.php +++ b/tests/funcs.php @@ -50,7 +50,7 @@ function determine_param_hint(Compound $compoundHint): array $others[] = $hint; } } - if (1 === \count($others)) { + if (1 === count($others)) { $out[1] = $others[0]; } return $out; diff --git a/tools/php-cs-fixer/composer.lock b/tools/php-cs-fixer/composer.lock index 3df88f8b..312dd7fe 100644 --- a/tools/php-cs-fixer/composer.lock +++ b/tools/php-cs-fixer/composer.lock @@ -451,16 +451,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.74.0", + "version": "v3.75.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "6b7cb12a6cf592fd9a2b46a2d5d4c3b44003973d" + "reference": "399a128ff2fdaf4281e4e79b755693286cdf325c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/6b7cb12a6cf592fd9a2b46a2d5d4c3b44003973d", - "reference": "6b7cb12a6cf592fd9a2b46a2d5d4c3b44003973d", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c", + "reference": "399a128ff2fdaf4281e4e79b755693286cdf325c", "shasum": "" }, "require": { @@ -543,7 +543,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.74.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0" }, "funding": [ { @@ -551,7 +551,7 @@ "type": "github" } ], - "time": "2025-03-27T22:31:30+00:00" + "time": "2025-03-31T18:40:42+00:00" }, { "name": "psr/container", @@ -1234,29 +1234,29 @@ }, { "name": "sebastian/diff", - "version": "7.0.0", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7ab1ea946c012266ca32390913653d844ecd085f" + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", - "reference": "7ab1ea946c012266ca32390913653d844ecd085f", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0", - "symfony/process": "^7.2" + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1289,7 +1289,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" }, "funding": [ { @@ -1297,50 +1297,51 @@ "type": "github" } ], - "time": "2025-02-07T04:55:46+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "symfony/console", - "version": "v7.2.1", + "version": "v6.4.20", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" + "reference": "2e4af9c952617cc3f9559ff706aee420a8464c36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "url": "https://api.github.com/repos/symfony/console/zipball/2e4af9c952617cc3f9559ff706aee420a8464c36", + "reference": "2e4af9c952617cc3f9559ff706aee420a8464c36", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" + "symfony/string": "^5.4|^6.0|^7.0" }, "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -1374,7 +1375,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.1" + "source": "https://github.com/symfony/console/tree/v6.4.20" }, "funding": [ { @@ -1390,7 +1391,7 @@ "type": "tidelift" } ], - "time": "2024-12-11T03:49:26+00:00" + "time": "2025-03-03T17:16:38+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1461,24 +1462,24 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.2.0", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", + "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<6.4", + "symfony/dependency-injection": "<5.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -1487,13 +1488,13 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/error-handler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0" + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -1521,7 +1522,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.13" }, "funding": [ { @@ -1537,7 +1538,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2024-09-25T14:18:03+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -1617,25 +1618,25 @@ }, { "name": "symfony/filesystem", - "version": "v7.2.0", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", - "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/4856c9cf585d5a0313d8d35afd681a526f038dd3", + "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^6.4|^7.0" + "symfony/process": "^5.4|^6.4|^7.0" }, "type": "library", "autoload": { @@ -1663,7 +1664,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + "source": "https://github.com/symfony/filesystem/tree/v6.4.13" }, "funding": [ { @@ -1679,27 +1680,27 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:15:23+00:00" + "time": "2024-10-25T15:07:50+00:00" }, { "name": "symfony/finder", - "version": "v7.2.2", + "version": "v6.4.17", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb" + "reference": "1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb", + "url": "https://api.github.com/repos/symfony/finder/zipball/1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7", + "reference": "1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "require-dev": { - "symfony/filesystem": "^6.4|^7.0" + "symfony/filesystem": "^6.0|^7.0" }, "type": "library", "autoload": { @@ -1727,7 +1728,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.2.2" + "source": "https://github.com/symfony/finder/tree/v6.4.17" }, "funding": [ { @@ -1743,24 +1744,24 @@ "type": "tidelift" } ], - "time": "2024-12-30T19:00:17+00:00" + "time": "2024-12-29T13:51:37+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.2.0", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" + "reference": "368128ad168f20e22c32159b9f761e456cec0c78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", - "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/368128ad168f20e22c32159b9f761e456cec0c78", + "reference": "368128ad168f20e22c32159b9f761e456cec0c78", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", @@ -1794,7 +1795,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" + "source": "https://github.com/symfony/options-resolver/tree/v6.4.16" }, "funding": [ { @@ -1810,7 +1811,7 @@ "type": "tidelift" } ], - "time": "2024-11-20T11:17:29+00:00" + "time": "2024-11-20T10:57:02+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2288,20 +2289,20 @@ }, { "name": "symfony/process", - "version": "v7.2.4", + "version": "v6.4.20", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf" + "reference": "e2a61c16af36c9a07e5c9906498b73e091949a20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf", - "reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf", + "url": "https://api.github.com/repos/symfony/process/zipball/e2a61c16af36c9a07e5c9906498b73e091949a20", + "reference": "e2a61c16af36c9a07e5c9906498b73e091949a20", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1" }, "type": "library", "autoload": { @@ -2329,7 +2330,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.2.4" + "source": "https://github.com/symfony/process/tree/v6.4.20" }, "funding": [ { @@ -2345,7 +2346,7 @@ "type": "tidelift" } ], - "time": "2025-02-05T08:33:46+00:00" + "time": "2025-03-10T17:11:00+00:00" }, { "name": "symfony/service-contracts", @@ -2432,20 +2433,20 @@ }, { "name": "symfony/stopwatch", - "version": "v7.2.4", + "version": "v6.4.19", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" + "reference": "dfe1481c12c06266d0c3d58c0cb4b09bd497ab9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", - "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/dfe1481c12c06266d0c3d58c0cb4b09bd497ab9c", + "reference": "dfe1481c12c06266d0c3d58c0cb4b09bd497ab9c", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", "symfony/service-contracts": "^2.5|^3" }, "type": "library", @@ -2474,7 +2475,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.2.4" + "source": "https://github.com/symfony/stopwatch/tree/v6.4.19" }, "funding": [ { @@ -2490,24 +2491,24 @@ "type": "tidelift" } ], - "time": "2025-02-24T10:49:57+00:00" + "time": "2025-02-21T10:06:30+00:00" }, { "name": "symfony/string", - "version": "v7.2.0", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -2517,12 +2518,11 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/emoji": "^7.1", - "symfony/error-handler": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -2561,7 +2561,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.0" + "source": "https://github.com/symfony/string/tree/v6.4.15" }, "funding": [ { @@ -2577,7 +2577,7 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:26+00:00" + "time": "2024-11-13T13:31:12+00:00" } ], "packages-dev": [], diff --git a/tools/php-cs-fixer/php-consul-api-rules.php_cs b/tools/php-cs-fixer/php-consul-api-rules.php_cs index 1db0153f..854b38db 100644 --- a/tools/php-cs-fixer/php-consul-api-rules.php_cs +++ b/tools/php-cs-fixer/php-consul-api-rules.php_cs @@ -1,17 +1,17 @@ -setUsingCache(false) - ->setRiskyAllowed(true) +// ->setRiskyAllowed(true) ->setLineEnding("\n") ->setIndent(' ') ->registerCustomFixers( @@ -20,9 +20,10 @@ $config ] ) ->setRules( - (new PSR12Set())->getRules() + - (new PSR12RiskySet())->getRules() + [ + '@PSR12' => true, +// 'PSR12Risky', + // custom rules 'AdamWojs/phpdoc_force_fqcn_fixer' => true,