From 4d2844fdaaf12072f5be57c8451aa5b24dfc059e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=85=B4=E9=A1=BA?= <250915790@qq.com> Date: Thu, 14 Jan 2021 16:07:12 +0800 Subject: [PATCH 1/6] =?UTF-8?q?Add=20Apollo=E9=85=8D=E7=BD=AE=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E6=B7=BB=E5=8A=A0=20`secret`=20=E5=AF=86=E9=92=A5?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config-apollo/publish/apollo.php | 1 + src/config-apollo/src/Client.php | 69 ++++++++++++++++++++----- src/config-apollo/src/ClientFactory.php | 7 ++- src/config-apollo/src/Option.php | 29 ++++++++--- src/config-apollo/tests/ClientTest.php | 3 +- 5 files changed, 86 insertions(+), 23 deletions(-) diff --git a/src/config-apollo/publish/apollo.php b/src/config-apollo/publish/apollo.php index 66e0ed1b9..81e65aa6a 100644 --- a/src/config-apollo/publish/apollo.php +++ b/src/config-apollo/publish/apollo.php @@ -20,4 +20,5 @@ return [ ], 'interval' => 5, 'strict_mode' => false, + 'secret' => '', ]; diff --git a/src/config-apollo/src/Client.php b/src/config-apollo/src/Client.php index d942f504a..784825522 100644 --- a/src/config-apollo/src/Client.php +++ b/src/config-apollo/src/Client.php @@ -9,9 +9,11 @@ declare(strict_types=1); * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ + namespace Hyperf\ConfigApollo; use Closure; +use GuzzleHttp\Exception\ClientException; use Hyperf\Contract\ConfigInterface; use Hyperf\Utils\Coroutine; use Hyperf\Utils\Parallel; @@ -43,7 +45,8 @@ class Client implements ClientInterface array $callbacks = [], Closure $httpClientFactory, ?ConfigInterface $config = null - ) { + ) + { $this->option = $option; $this->callbacks = $callbacks; $this->httpClientFactory = $httpClientFactory; @@ -52,7 +55,7 @@ class Client implements ClientInterface public function pull(array $namespaces, array $callbacks = []): void { - if (! $namespaces) { + if (!$namespaces) { return; } if (Coroutine::inCoroutine()) { @@ -86,6 +89,28 @@ class Client implements ClientInterface return $this->option; } + private function hasSecret() + { + return !empty($this->option->getSecret()); + } + + private function getTimestamp() + { + list($usec, $sec) = explode(" ", microtime()); + return sprintf('%.0f', (floatval($usec) + floatval($sec)) * 1000); + } + + private function getAuthorization($timestamp, $path_with_query) + { + if (!$this->hasSecret()) { + return ''; + } + $to_signature = $timestamp . "\n" . $path_with_query; + $signature = base64_encode(hash_hmac('sha1', $to_signature, $this->option->getSecret(), true)); + return sprintf('Apollo %s:%s', $this->option->getAppid(), $signature); + } + + private function coroutinePull(array $namespaces): array { $option = $this->option; @@ -94,18 +119,26 @@ class Client implements ClientInterface foreach ($namespaces as $namespace) { $parallel->add(function () use ($option, $httpClientFactory, $namespace) { $client = $httpClientFactory(); - if (! $client instanceof \GuzzleHttp\Client) { + if (!$client instanceof \GuzzleHttp\Client) { throw new \RuntimeException('Invalid http client.'); } $releaseKey = ReleaseKey::get($option->buildCacheKey($namespace), null); + $query = [ + 'ip' => $option->getClientIp(), + 'releaseKey' => $releaseKey, + ]; + $timestamp = $this->getTimestamp(); + $headers = [ + 'Authorization' => $this->getAuthorization($timestamp, parse_url($option->buildBaseUrl(), PHP_URL_PATH) . $namespace . '?' . http_build_query($query)), + 'Timestamp' => $timestamp, + ]; + $response = $client->get($option->buildBaseUrl() . $namespace, [ - 'query' => [ - 'ip' => $option->getClientIp(), - 'releaseKey' => $releaseKey, - ], + 'query' => $query, + 'headers' => $headers, ]); if ($response->getStatusCode() === 200 && strpos($response->getHeaderLine('Content-Type'), 'application/json') !== false) { - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string)$response->getBody(), true); $result = [ 'configurations' => $body['configurations'] ?? [], 'releaseKey' => $body['releaseKey'] ?? '', @@ -128,18 +161,26 @@ class Client implements ClientInterface $httpClientFactory = $this->httpClientFactory; foreach ($namespaces as $namespace) { $client = $httpClientFactory(); - if (! $client instanceof \GuzzleHttp\Client) { + if (!$client instanceof \GuzzleHttp\Client) { throw new \RuntimeException('Invalid http client.'); } $releaseKey = ReleaseKey::get($this->option->buildCacheKey($namespace), null); + $query = [ + 'ip' => $this->option->getClientIp(), + 'releaseKey' => $releaseKey, + ]; + $timestamp = $this->getTimestamp(); + $headers = [ + 'Authorization' => $this->getAuthorization($timestamp, parse_url($url, PHP_URL_PATH) . $namespace . '?' . http_build_query($query)), + 'Timestamp' => $timestamp, + ]; + $response = $client->get($url . $namespace, [ - 'query' => [ - 'ip' => $this->option->getClientIp(), - 'releaseKey' => $releaseKey, - ], + 'query' => $query, + 'headers' => $headers, ]); if ($response->getStatusCode() === 200 && strpos($response->getHeaderLine('Content-Type'), 'application/json') !== false) { - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string)$response->getBody(), true); $result[$namespace] = [ 'configurations' => $body['configurations'] ?? [], 'releaseKey' => $body['releaseKey'] ?? '', diff --git a/src/config-apollo/src/ClientFactory.php b/src/config-apollo/src/ClientFactory.php index 1136ff7d1..b30279004 100644 --- a/src/config-apollo/src/ClientFactory.php +++ b/src/config-apollo/src/ClientFactory.php @@ -9,6 +9,7 @@ declare(strict_types=1); * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ + namespace Hyperf\ConfigApollo; use Hyperf\Contract\ConfigInterface; @@ -27,12 +28,14 @@ class ClientFactory ->setCluster($config->get('apollo.cluster', '')) ->setClientIp($config->get('apollo.client_ip', current(swoole_get_local_ip()))) ->setPullTimeout($config->get('apollo.pull_timeout', 10)) - ->setIntervalTimeout($config->get('apollo.interval_timeout', 60)); + ->setIntervalTimeout($config->get('apollo.interval_timeout', 60)) + ->setSecret($config->get('apollo.secret')); + $namespaces = $config->get('apollo.namespaces', []); $callbacks = []; foreach ($namespaces as $namespace => $callable) { // If does not exist a user-defined callback, then delegate to the dafault callback. - if (! is_numeric($namespace) && is_callable($callable)) { + if (!is_numeric($namespace) && is_callable($callable)) { $callbacks[$namespace] = $callable; } } diff --git a/src/config-apollo/src/Option.php b/src/config-apollo/src/Option.php index b883e2694..7283418d2 100644 --- a/src/config-apollo/src/Option.php +++ b/src/config-apollo/src/Option.php @@ -9,6 +9,7 @@ declare(strict_types=1); * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ + namespace Hyperf\ConfigApollo; use Hyperf\Utils\Str; @@ -50,14 +51,19 @@ class Option */ private $intervalTimeout = 60; + /** + * @var string + */ + private $secret; + public function buildBaseUrl(): string { return implode('/', [ - $this->getServer(), - 'configs', - $this->getAppid(), - $this->getCluster(), - ]) . '/'; + $this->getServer(), + 'configs', + $this->getAppid(), + $this->getCluster(), + ]) . '/'; } public function buildCacheKey(string $namespace): string @@ -72,7 +78,7 @@ class Option public function setServer(string $server): self { - if (! Str::startsWith($server, 'http://')) { + if (!Str::startsWith($server, 'http://')) { $server = 'http://' . $server; } $this->server = $server; @@ -144,4 +150,15 @@ class Option $this->intervalTimeout = $intervalTimeout; return $this; } + + public function setSecret(string $secret): self + { + $this->secret = $secret; + return $this; + } + + public function getSecret(): string + { + return $this->secret; + } } diff --git a/src/config-apollo/tests/ClientTest.php b/src/config-apollo/tests/ClientTest.php index c6316b7ae..34e39547a 100644 --- a/src/config-apollo/tests/ClientTest.php +++ b/src/config-apollo/tests/ClientTest.php @@ -30,7 +30,8 @@ class ClientTest extends TestCase public function testPull() { $option = new Option(); - $option->setServer('http://127.0.0.1:8080')->setAppid('test')->setCluster('default')->setClientIp('127.0.0.1'); + $option->setServer('http://127.0.0.1:8080')->setAppid('test')->setCluster('default')->setClientIp('127.0.0.1') + ->setSecret('b0224a48805442ebacceb0431d98b2bf'); $container = Mockery::mock(ContainerInterface::class); $configInstance = new Config([]); $configInstance->set('apollo.test-key', 'pre-value'); From f01ccd71ac5c779916c357ab29e08d69db1680ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=85=B4=E9=A1=BA?= <250915790@qq.com> Date: Thu, 14 Jan 2021 20:07:06 +0800 Subject: [PATCH 2/6] =?UTF-8?q?Changed=20=E4=BF=AE=E6=94=B9=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config-apollo/src/Client.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config-apollo/src/Client.php b/src/config-apollo/src/Client.php index 784825522..0e85026cc 100644 --- a/src/config-apollo/src/Client.php +++ b/src/config-apollo/src/Client.php @@ -100,13 +100,13 @@ class Client implements ClientInterface return sprintf('%.0f', (floatval($usec) + floatval($sec)) * 1000); } - private function getAuthorization($timestamp, $path_with_query) + private function getAuthorization($timestamp, $pathWithQuery) { if (!$this->hasSecret()) { return ''; } - $to_signature = $timestamp . "\n" . $path_with_query; - $signature = base64_encode(hash_hmac('sha1', $to_signature, $this->option->getSecret(), true)); + $toSignature = $timestamp . "\n" . $pathWithQuery; + $signature = base64_encode(hash_hmac('sha1', $toSignature, $this->option->getSecret(), true)); return sprintf('Apollo %s:%s', $this->option->getAppid(), $signature); } From 9e9edef3ec3507bfccc79163f413f8555e38830a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=85=B4=E9=A1=BA?= <250915790@qq.com> Date: Mon, 18 Jan 2021 17:41:41 +0800 Subject: [PATCH 3/6] =?UTF-8?q?Bugfix=20=E6=9C=AA=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=AF=86=E9=92=A5=E6=97=B6=E6=8A=A5=E7=B1=BB=E5=9E=8B=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config-apollo/src/ClientFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config-apollo/src/ClientFactory.php b/src/config-apollo/src/ClientFactory.php index b30279004..3cb9312e5 100644 --- a/src/config-apollo/src/ClientFactory.php +++ b/src/config-apollo/src/ClientFactory.php @@ -29,7 +29,7 @@ class ClientFactory ->setClientIp($config->get('apollo.client_ip', current(swoole_get_local_ip()))) ->setPullTimeout($config->get('apollo.pull_timeout', 10)) ->setIntervalTimeout($config->get('apollo.interval_timeout', 60)) - ->setSecret($config->get('apollo.secret')); + ->setSecret($config->get('apollo.secret', '')); $namespaces = $config->get('apollo.namespaces', []); $callbacks = []; From 0b06fdd0824126cbe2379b98259e3323e1d4d6ba Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Wed, 23 Jun 2021 13:28:15 +0800 Subject: [PATCH 4/6] Remove apollo.php config file --- src/config-apollo/publish/apollo.php | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 src/config-apollo/publish/apollo.php diff --git a/src/config-apollo/publish/apollo.php b/src/config-apollo/publish/apollo.php deleted file mode 100644 index 81e65aa6a..000000000 --- a/src/config-apollo/publish/apollo.php +++ /dev/null @@ -1,24 +0,0 @@ - false, - 'use_standalone_process' => true, - 'server' => 'http://localhost:8080', - 'appid' => 'test', - 'cluster' => 'default', - 'namespaces' => [ - 'application', - ], - 'interval' => 5, - 'strict_mode' => false, - 'secret' => '', -]; From 2dafafd573db862145c789648f99890496f13d01 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Wed, 23 Jun 2021 13:35:59 +0800 Subject: [PATCH 5/6] Update ClientTest.php --- src/config-apollo/tests/ClientTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/config-apollo/tests/ClientTest.php b/src/config-apollo/tests/ClientTest.php index 34e39547a..c6316b7ae 100644 --- a/src/config-apollo/tests/ClientTest.php +++ b/src/config-apollo/tests/ClientTest.php @@ -30,8 +30,7 @@ class ClientTest extends TestCase public function testPull() { $option = new Option(); - $option->setServer('http://127.0.0.1:8080')->setAppid('test')->setCluster('default')->setClientIp('127.0.0.1') - ->setSecret('b0224a48805442ebacceb0431d98b2bf'); + $option->setServer('http://127.0.0.1:8080')->setAppid('test')->setCluster('default')->setClientIp('127.0.0.1'); $container = Mockery::mock(ContainerInterface::class); $configInstance = new Config([]); $configInstance->set('apollo.test-key', 'pre-value'); From 94d117fa9da49e33b55f8baa714f87e4a38524cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=93=AD=E6=98=95?= <715557344@qq.com> Date: Wed, 23 Jun 2021 15:11:58 +0800 Subject: [PATCH 6/6] Format --- CHANGELOG-2.2.md | 1 + src/config-apollo/src/Client.php | 18 +++++++----------- src/config-apollo/src/ClientFactory.php | 1 - src/config-apollo/src/Option.php | 13 ++++++------- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/CHANGELOG-2.2.md b/CHANGELOG-2.2.md index d29888de5..0d52bc87e 100644 --- a/CHANGELOG-2.2.md +++ b/CHANGELOG-2.2.md @@ -52,6 +52,7 @@ - [#3698](https://github.com/hyperf/hyperf/pull/3698) Support PHP8 Attribute which can replace doctrine annotations. - [#3714](https://github.com/hyperf/hyperf/pull/3714) Added ide-helper component. - [#3722](https://github.com/hyperf/hyperf/pull/3722) Added config-center component. +- [#3728](https://github.com/hyperf/hyperf/pull/3728) Added support for `secret` of Apollo. ## Optimized diff --git a/src/config-apollo/src/Client.php b/src/config-apollo/src/Client.php index dd0f36784..c78edb53d 100644 --- a/src/config-apollo/src/Client.php +++ b/src/config-apollo/src/Client.php @@ -9,11 +9,9 @@ declare(strict_types=1); * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ - namespace Hyperf\ConfigApollo; use Closure; -use GuzzleHttp\Exception\ClientException; use Hyperf\Contract\ConfigInterface; use Hyperf\Utils\Coroutine; use Hyperf\Utils\Parallel; @@ -46,8 +44,7 @@ class Client implements ClientInterface array $callbacks, Closure $httpClientFactory, ?ConfigInterface $config = null - ) - { + ) { $this->option = $option; $this->callbacks = $callbacks; $this->httpClientFactory = $httpClientFactory; @@ -56,7 +53,7 @@ class Client implements ClientInterface public function pull(array $namespaces, array $callbacks = []): void { - if (!$namespaces) { + if (! $namespaces) { return; } if (Coroutine::inCoroutine()) { @@ -92,18 +89,18 @@ class Client implements ClientInterface private function hasSecret(): bool { - return !empty($this->option->getSecret()); + return ! empty($this->option->getSecret()); } private function getTimestamp(): string { - list($usec, $sec) = explode(" ", microtime()); + [$usec, $sec] = explode(' ', microtime()); return sprintf('%.0f', (floatval($usec) + floatval($sec)) * 1000); } private function getAuthorization(string $timestamp, string $pathWithQuery): string { - if (!$this->hasSecret()) { + if (! $this->hasSecret()) { return ''; } $toSignature = $timestamp . "\n" . $pathWithQuery; @@ -111,7 +108,6 @@ class Client implements ClientInterface return sprintf('Apollo %s:%s', $this->option->getAppid(), $signature); } - private function coroutinePull(array $namespaces): array { $option = $this->option; @@ -139,7 +135,7 @@ class Client implements ClientInterface 'headers' => $headers, ]); if ($response->getStatusCode() === 200 && strpos($response->getHeaderLine('Content-Type'), 'application/json') !== false) { - $body = json_decode((string)$response->getBody(), true); + $body = json_decode((string) $response->getBody(), true); $result = [ 'configurations' => $body['configurations'] ?? [], 'releaseKey' => $body['releaseKey'] ?? '', @@ -181,7 +177,7 @@ class Client implements ClientInterface 'headers' => $headers, ]); if ($response->getStatusCode() === 200 && strpos($response->getHeaderLine('Content-Type'), 'application/json') !== false) { - $body = json_decode((string)$response->getBody(), true); + $body = json_decode((string) $response->getBody(), true); $result[$namespace] = [ 'configurations' => $body['configurations'] ?? [], 'releaseKey' => $body['releaseKey'] ?? '', diff --git a/src/config-apollo/src/ClientFactory.php b/src/config-apollo/src/ClientFactory.php index 7c4a47549..0954524cd 100644 --- a/src/config-apollo/src/ClientFactory.php +++ b/src/config-apollo/src/ClientFactory.php @@ -9,7 +9,6 @@ declare(strict_types=1); * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ - namespace Hyperf\ConfigApollo; use Hyperf\Contract\ConfigInterface; diff --git a/src/config-apollo/src/Option.php b/src/config-apollo/src/Option.php index 7283418d2..46701496d 100644 --- a/src/config-apollo/src/Option.php +++ b/src/config-apollo/src/Option.php @@ -9,7 +9,6 @@ declare(strict_types=1); * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ - namespace Hyperf\ConfigApollo; use Hyperf\Utils\Str; @@ -59,11 +58,11 @@ class Option public function buildBaseUrl(): string { return implode('/', [ - $this->getServer(), - 'configs', - $this->getAppid(), - $this->getCluster(), - ]) . '/'; + $this->getServer(), + 'configs', + $this->getAppid(), + $this->getCluster(), + ]) . '/'; } public function buildCacheKey(string $namespace): string @@ -78,7 +77,7 @@ class Option public function setServer(string $server): self { - if (!Str::startsWith($server, 'http://')) { + if (! Str::startsWith($server, 'http://')) { $server = 'http://' . $server; } $this->server = $server;