From f4bd25cc1bebeca54af7e354d210d040ab0a6ff5 Mon Sep 17 00:00:00 2001 From: David Supplee Date: Fri, 17 Nov 2017 12:08:14 -0500 Subject: [PATCH] clarify gRPC dependencies (#750) --- src/Core/ClientTrait.php | 31 +++++++++++++++++++++++++---- src/Firestore/FirestoreClient.php | 18 ++++++++++------- src/Firestore/composer.json | 5 +++-- src/Spanner/SpannerClient.php | 7 +++++-- tests/unit/Core/ClientTraitTest.php | 24 +++++++++++++++++++++- 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/src/Core/ClientTrait.php b/src/Core/ClientTrait.php index 33d322f9a770..e168eb8a670b 100644 --- a/src/Core/ClientTrait.php +++ b/src/Core/ClientTrait.php @@ -46,7 +46,7 @@ trait ClientTrait */ private function getConnectionType(array $config) { - $isGrpcExtensionLoaded = $this->getGrpcDependencyStatus(); + $isGrpcExtensionLoaded = $this->isGrpcLoaded(); $defaultTransport = $isGrpcExtensionLoaded ? 'grpc' : 'rest'; $transport = isset($config['transport']) ? strtolower($config['transport']) @@ -56,8 +56,7 @@ private function getConnectionType(array $config) if (!$isGrpcExtensionLoaded) { throw new GoogleException( 'gRPC support has been requested but required dependencies ' . - 'have not been found. Please make sure to run the following ' . - 'from the command line: pecl install grpc' + 'have not been found. ' . $this->getGrpcInstallationMessage() ); } } @@ -65,6 +64,30 @@ private function getConnectionType(array $config) return $transport; } + /** + * Throw an exception if the gRPC extension is not loaded. + * + * @throws GoogleException + */ + private function requireGrpc() + { + if (!$this->isGrpcLoaded()) { + throw new GoogleException( + 'The requested client requires the gRPC extension. ' . + $this->getGrpcInstallationMessage() + ); + } + } + + /** + * @return string + */ + private function getGrpcInstallationMessage() + { + return 'Please see https://cloud.google.com/php/grpc for installation ' . + 'instructions.'; + } + /** * Fetch and validate the keyfile and set the project ID. * @@ -208,7 +231,7 @@ protected function getMetaData() * @codeCoverageIgnore * @return bool */ - protected function getGrpcDependencyStatus() + protected function isGrpcLoaded() { return extension_loaded('grpc'); } diff --git a/src/Firestore/FirestoreClient.php b/src/Firestore/FirestoreClient.php index 85d2bb850559..861bad0d40bb 100644 --- a/src/Firestore/FirestoreClient.php +++ b/src/Firestore/FirestoreClient.php @@ -17,16 +17,17 @@ namespace Google\Cloud\Firestore; -use Google\Cloud\Core\Blob; -use Google\Cloud\Core\Retry; -use Google\Cloud\Core\GeoPoint; use Google\Cloud\Core\ArrayTrait; +use Google\Cloud\Core\Blob; use Google\Cloud\Core\ClientTrait; -use Google\Cloud\Core\ValidateTrait; -use Google\Cloud\Firestore\Connection\Grpc; +use Google\Cloud\Core\Exception\AbortedException; +use Google\Cloud\Core\Exception\GoogleException; +use Google\Cloud\Core\GeoPoint; use Google\Cloud\Core\Iterator\ItemIterator; use Google\Cloud\Core\Iterator\PageIterator; -use Google\Cloud\Core\Exception\AbortedException; +use Google\Cloud\Core\Retry; +use Google\Cloud\Core\ValidateTrait; +use Google\Cloud\Firestore\Connection\Grpc; /** * Cloud Firestore is a flexible, scalable, realtime database for mobile, web, and server development. @@ -68,7 +69,8 @@ class FirestoreClient private $valueMapper; /** - * Create a Firestore client. + * Create a Firestore client. Please note that this client requires + * [the gRPC extension](https://cloud.google.com/php/grpc). * * @param array $config [optional] { * Configuration Options. @@ -96,9 +98,11 @@ class FirestoreClient * platform compatibility. **Defaults to** false. * } * @throws \InvalidArgumentException + * @throws GoogleException */ public function __construct(array $config = []) { + $this->requireGrpc(); $config += [ 'returnInt64AsObject' => false, 'scopes' => [self::FULL_CONTROL_SCOPE], diff --git a/src/Firestore/composer.json b/src/Firestore/composer.json index 48a20e977673..61c1bb723ab9 100644 --- a/src/Firestore/composer.json +++ b/src/Firestore/composer.json @@ -4,9 +4,10 @@ "license": "Apache-2.0", "minimum-stability": "stable", "require": { + "ext-grpc": "*", "google/cloud-core": "^1.0", - "google/gax": "^0.25", - "google/proto-client": "^0.25", + "google/gax": "^0.26", + "google/proto-client": "^0.26", "ramsey/uuid": "~3" }, "extra": { diff --git a/src/Spanner/SpannerClient.php b/src/Spanner/SpannerClient.php index 142211197feb..5ec92d2c5e8a 100644 --- a/src/Spanner/SpannerClient.php +++ b/src/Spanner/SpannerClient.php @@ -19,6 +19,7 @@ use Google\Cloud\Core\ArrayTrait; use Google\Cloud\Core\ClientTrait; +use Google\Cloud\Core\Exception\GoogleException; use Google\Cloud\Core\Exception\NotFoundException; use Google\Cloud\Core\Int64; use Google\Cloud\Core\Iterator\ItemIterator; @@ -80,7 +81,8 @@ class SpannerClient private $returnInt64AsObject; /** - * Create a Spanner client. + * Create a Spanner client. Please note that this client requires + * [the gRPC extension](https://cloud.google.com/php/grpc). * * @param array $config [optional] { * Configuration Options. @@ -108,10 +110,11 @@ class SpannerClient * returned as a {@see Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * } - * @throws Google\Cloud\Core\Exception\GoogleException + * @throws GoogleException */ public function __construct(array $config = []) { + $this->requireGrpc(); $config += [ 'scopes' => [ self::FULL_CONTROL_SCOPE, diff --git a/tests/unit/Core/ClientTraitTest.php b/tests/unit/Core/ClientTraitTest.php index 9d6338f23ef2..b9f98ae6f42f 100644 --- a/tests/unit/Core/ClientTraitTest.php +++ b/tests/unit/Core/ClientTraitTest.php @@ -89,6 +89,23 @@ public function dependencyStatusProvider() ]; } + public function testRequireGrpcPassesWithGrpc() + { + $this->assertNull( + (new ClientTraitStubGrpcDependencyChecks(true)) + ->runRequireGrpc() + ); + } + + /** + * @expectedException Google\Cloud\Core\Exception\GoogleException + */ + public function testRequireGrpcThrowsExceptionWithoutGrpc() + { + (new ClientTraitStubGrpcDependencyChecks(false)) + ->runRequireGrpc(); + } + public function testConfigureAuthentication() { $keyFilePath = __DIR__ . '/../fixtures/json-key-fixture.json'; @@ -252,6 +269,11 @@ public function runDetectProjectId($config) { return $this->detectProjectId($config); } + + public function runRequireGrpc() + { + return $this->requireGrpc(); + } } class ClientTraitStubOnGce extends ClientTraitStub @@ -287,7 +309,7 @@ public function __construct($dependencyStatus) $this->dependencyStatus = $dependencyStatus; } - protected function getGrpcDependencyStatus() + protected function isGrpcLoaded() { return $this->dependencyStatus; }