From 7b3006f12cd728537b8f4b4a2236f0aa1b68d102 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 2 Oct 2023 14:31:55 -0700 Subject: [PATCH 1/9] chore: fix Longrunning client namespace (and add alias for BC) --- LongRunning/.OwlBot.yaml | 2 +- LongRunning/owlbot.py | 28 ++----------- .../ApiCore/LongRunning/OperationsClient.php | 39 +++++-------------- .../Gapic/OperationsGapicClient.php | 2 +- .../src/LongRunning/OperationsClient.php | 36 +++++++++++++++++ .../LongRunning/gapic_metadata.json | 0 .../resources/operations_client_config.json | 0 .../operations_descriptor_config.php | 0 .../operations_rest_client_config.php | 0 .../tests/Unit/OperationsClientTest.php | 4 +- 10 files changed, 54 insertions(+), 57 deletions(-) rename LongRunning/src/{ApiCore => }/LongRunning/Gapic/OperationsGapicClient.php (99%) create mode 100644 LongRunning/src/LongRunning/OperationsClient.php rename LongRunning/src/{ApiCore => }/LongRunning/gapic_metadata.json (100%) rename LongRunning/src/{ApiCore => }/LongRunning/resources/operations_client_config.json (100%) rename LongRunning/src/{ApiCore => }/LongRunning/resources/operations_descriptor_config.php (100%) rename LongRunning/src/{ApiCore => }/LongRunning/resources/operations_rest_client_config.php (100%) diff --git a/LongRunning/.OwlBot.yaml b/LongRunning/.OwlBot.yaml index f4f00e2f4ade..50fa62ef7164 100644 --- a/LongRunning/.OwlBot.yaml +++ b/LongRunning/.OwlBot.yaml @@ -1,6 +1,6 @@ deep-copy-regex: - source: /google/longrunning/.*-php/src/(.*) - dest: /owl-bot-staging/LongRunning/src/ApiCore/LongRunning/$1 + dest: /owl-bot-staging/LongRunning/src/LongRunning/$1 - source: /google/longrunning/.*-php/tests/(.*) dest: /owl-bot-staging/LongRunning/tests/$1 - source: /google/longrunning/.*-php/proto/src/(.*) diff --git a/LongRunning/owlbot.py b/LongRunning/owlbot.py index fc547a8a4251..4e10110256f7 100644 --- a/LongRunning/owlbot.py +++ b/LongRunning/owlbot.py @@ -41,31 +41,11 @@ version_string="longrunning", ) -# Fix namespace for LongRunning GAPIC (ApiCore) -# This is defined in longrunning_gapic.yaml, but not being used by -# gapic-generator-php +# Add an alias for the previous namespace s.replace( - "src/ApiCore/**/*.php", - r"^namespace Google\\LongRunning(.*);$", - r"namespace Google\\ApiCore\\LongRunning\1;") -s.replace( - "src/ApiCore/LongRunning/OperationsClient.php", - r"^use Google\\LongRunning\\Gapic\\OperationsGapicClient;$", - r"use Google\\ApiCore\\LongRunning\\Gapic\\OperationsGapicClient;") -s.replace( - "tests/**/*.php", - r"\\Google\\LongRunning\\OperationsClient", - r"\\Google\\ApiCore\\LongRunning\\OperationsClient") - -# remove class_alias code -s.replace( - "src/**/*.php", - r"^// Adding a class alias for backwards compatibility with the previous class name.$" - + "\n" - + r"^class_alias\(.*\);$" - + "\n", - '') - + "src/LongRunning/OperationsClient.php", + r"^}$\n", + r"}\n\nclass_alias('Google\\LongRunning\\OperationsClient', 'Google\\ApiCore\\LongRunning\\OperationsClient');\n") ### [START] protoc backwards compatibility fixes diff --git a/LongRunning/src/ApiCore/LongRunning/OperationsClient.php b/LongRunning/src/ApiCore/LongRunning/OperationsClient.php index be3d8e56be5d..ccd47095efef 100644 --- a/LongRunning/src/ApiCore/LongRunning/OperationsClient.php +++ b/LongRunning/src/ApiCore/LongRunning/OperationsClient.php @@ -1,34 +1,15 @@ getMockBuilder(CredentialsWrapper::class)->disableOriginalConstructor()->getMock(); } - /** @return \Google\ApiCore\LongRunning\OperationsClient */ + /** @return \Google\LongRunning\OperationsClient */ private function createClient(array $options = []) { $options += [ 'credentials' => $this->createCredentials(), ]; - return new \Google\ApiCore\LongRunning\OperationsClient($options); + return new \Google\LongRunning\OperationsClient($options); } /** @test */ From b45e2057f5cdbc9b02570f516642da6d96227b2a Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Fri, 6 Oct 2023 17:00:31 -0700 Subject: [PATCH 2/9] try to trick breaking change detector --- .../LongRunning/Gapic/OperationsGapicClient.php | 15 +++++++++++++++ .../src/ApiCore/LongRunning/OperationsClient.php | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php diff --git a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php new file mode 100644 index 000000000000..19c82d67efc3 --- /dev/null +++ b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php @@ -0,0 +1,15 @@ + Date: Tue, 10 Oct 2023 10:35:37 -0700 Subject: [PATCH 3/9] exclude BC file from snippet list --- Core/src/Testing/Snippet/Coverage/Coverage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/Testing/Snippet/Coverage/Coverage.php b/Core/src/Testing/Snippet/Coverage/Coverage.php index 2fd7b2a6e902..5c793c19bc51 100644 --- a/Core/src/Testing/Snippet/Coverage/Coverage.php +++ b/Core/src/Testing/Snippet/Coverage/Coverage.php @@ -34,6 +34,7 @@ class Coverage '/\\\Google\\\Cloud\\\Translate\\\TranslateClient/', '/\\\Google\\\Cloud\\\Translate\\\Connection\\\Rest/', '/\\\Google\\\Cloud\\\Translate\\\Connection\\\ConnectionInterface/', + '/\\\Google\\\ApiCore\\\LongRunning\\\Gapic\\\OperationsGapicClient/', ]; /** From abd577cb6c2e681903239599bf248167bbea983a Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 10 Apr 2024 21:43:39 +0000 Subject: [PATCH 4/9] updates from owlbot --- .../metadata/Longrunning/Operations.php | Bin 2587 -> 2587 bytes .../Gapic/OperationsGapicClient.php | 10 +- .../LongRunning/CancelOperationRequest.php | 13 + .../LongRunning/Client/OperationsClient.php | 335 ++++++++++++++ .../LongRunning/DeleteOperationRequest.php | 13 + .../Gapic/OperationsGapicClient.php | 11 +- .../src/LongRunning/GetOperationRequest.php | 13 + .../src/LongRunning/ListOperationsRequest.php | 15 + .../operations_descriptor_config.php | 50 +++ .../Unit/Client/OperationsClientTest.php | 417 ++++++++++++++++++ 10 files changed, 873 insertions(+), 4 deletions(-) create mode 100644 LongRunning/src/LongRunning/Client/OperationsClient.php create mode 100644 LongRunning/tests/Unit/Client/OperationsClientTest.php diff --git a/LongRunning/metadata/Longrunning/Operations.php b/LongRunning/metadata/Longrunning/Operations.php index 1757fcc8c7844b18c510a75f2a97ffa5b1a5149a..2ed35d91878de9e1a9f899893fad9fbb1a18793b 100644 GIT binary patch delta 78 zcmbO&GFxQB4>rDAj@)^Pxv4s7nK>n?MU#K9$xc>gk72*%$O00cT+gmBc^P{Yj6aD( TVX`_0oIAOZLu>OUj!Z@XXa^g1 delta 107 zcmbO&GFxQB4>pdb%TFdVi3^ENp1>i(Uwg}uJ1;ReRVOVorzEv#vNC%NM1ho$1W`_n&EmR40j;P5U99l4in>TS}G6Db`x+Q-A diff --git a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php index 079c5a7f466b..0d2c79ca295b 100644 --- a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php +++ b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php @@ -9,9 +9,13 @@ * This class is deprecated. Use Google\LongRunning\OperationsClient instead. * @deprecated */ - class OperationsGapicClient extends OperationsGapicClient {} + class OperationsGapicClient extends OperationsGapicClient + { + } } // Autoload the class and its alias class_exists('\Google\LongRunning\Gapic\OperationsGapicClient'); -@trigger_error('Google\LongRunning\ApiCore\OperationsGapicClient is deprecated and will be removed in the next major release. Use Google\LongRunning\OperationsClient instead', E_USER_DEPRECATED); - +@trigger_error( + 'Google\LongRunning\ApiCore\OperationsGapicClient is deprecated and will be removed in the next major release. Use Google\LongRunning\OperationsClient instead', + E_USER_DEPRECATED +); diff --git a/LongRunning/src/LongRunning/CancelOperationRequest.php b/LongRunning/src/LongRunning/CancelOperationRequest.php index 48b68f41d976..d596e8a8048a 100644 --- a/LongRunning/src/LongRunning/CancelOperationRequest.php +++ b/LongRunning/src/LongRunning/CancelOperationRequest.php @@ -22,6 +22,19 @@ class CancelOperationRequest extends \Google\Protobuf\Internal\Message */ private $name = ''; + /** + * @param string $name The name of the operation resource to be cancelled. + * + * @return \Google\LongRunning\CancelOperationRequest + * + * @experimental + */ + public static function build(string $name): self + { + return (new self()) + ->setName($name); + } + /** * Constructor. * diff --git a/LongRunning/src/LongRunning/Client/OperationsClient.php b/LongRunning/src/LongRunning/Client/OperationsClient.php new file mode 100644 index 000000000000..d3697fc93b40 --- /dev/null +++ b/LongRunning/src/LongRunning/Client/OperationsClient.php @@ -0,0 +1,335 @@ + self::SERVICE_NAME, + 'apiEndpoint' => self::SERVICE_ADDRESS . ':' . self::DEFAULT_SERVICE_PORT, + 'clientConfig' => __DIR__ . '/../resources/operations_client_config.json', + 'descriptorsConfigPath' => __DIR__ . '/../resources/operations_descriptor_config.php', + 'gcpApiConfigPath' => __DIR__ . '/../resources/operations_grpc_config.json', + 'credentialsConfig' => [ + 'defaultScopes' => self::$serviceScopes, + ], + 'transportConfig' => [ + 'rest' => [ + 'restClientConfigPath' => __DIR__ . '/../resources/operations_rest_client_config.php', + ], + ], + ]; + } + + /** + * Constructor. + * + * @param array $options { + * Optional. Options for configuring the service API wrapper. + * + * @type string $apiEndpoint + * The address of the API remote host. May optionally include the port, formatted + * as ":". Default 'longrunning.googleapis.com:443'. + * @type string|array|FetchAuthTokenInterface|CredentialsWrapper $credentials + * The credentials to be used by the client to authorize API calls. This option + * accepts either a path to a credentials file, or a decoded credentials file as a + * PHP array. + * *Advanced usage*: In addition, this option can also accept a pre-constructed + * {@see \Google\Auth\FetchAuthTokenInterface} object or + * {@see \Google\ApiCore\CredentialsWrapper} object. Note that when one of these + * objects are provided, any settings in $credentialsConfig will be ignored. + * @type array $credentialsConfig + * Options used to configure credentials, including auth token caching, for the + * client. For a full list of supporting configuration options, see + * {@see \Google\ApiCore\CredentialsWrapper::build()} . + * @type bool $disableRetries + * Determines whether or not retries defined by the client configuration should be + * disabled. Defaults to `false`. + * @type string|array $clientConfig + * Client method configuration, including retry settings. This option can be either + * a path to a JSON file, or a PHP array containing the decoded JSON data. By + * default this settings points to the default client config file, which is + * provided in the resources folder. + * @type string|TransportInterface $transport + * The transport used for executing network requests. May be either the string + * `rest` or `grpc`. Defaults to `grpc` if gRPC support is detected on the system. + * *Advanced usage*: Additionally, it is possible to pass in an already + * instantiated {@see \Google\ApiCore\Transport\TransportInterface} object. Note + * that when this object is provided, any settings in $transportConfig, and any + * $apiEndpoint setting, will be ignored. + * @type array $transportConfig + * Configuration options that will be used to construct the transport. Options for + * each supported transport type should be passed in a key for that transport. For + * example: + * $transportConfig = [ + * 'grpc' => [...], + * 'rest' => [...], + * ]; + * See the {@see \Google\ApiCore\Transport\GrpcTransport::build()} and + * {@see \Google\ApiCore\Transport\RestTransport::build()} methods for the + * supported options. + * @type callable $clientCertSource + * A callable which returns the client cert as a string. This can be used to + * provide a certificate and private key to the transport layer for mTLS. + * } + * + * @throws ValidationException + */ + public function __construct(array $options = []) + { + $clientOptions = $this->buildClientOptions($options); + $this->setClientOptions($clientOptions); + } + + /** Handles execution of the async variants for each documented method. */ + public function __call($method, $args) + { + if (substr($method, -5) !== 'Async') { + trigger_error('Call to undefined method ' . __CLASS__ . "::$method()", E_USER_ERROR); + } + + array_unshift($args, substr($method, 0, -5)); + return call_user_func_array([$this, 'startAsyncCall'], $args); + } + + /** + * Starts asynchronous cancellation on a long-running operation. The server + * makes a best effort to cancel the operation, but success is not + * guaranteed. If the server doesn't support this method, it returns + * `google.rpc.Code.UNIMPLEMENTED`. Clients can use + * [Operations.GetOperation][google.longrunning.Operations.GetOperation] or + * other methods to check whether the cancellation succeeded or whether the + * operation completed despite cancellation. On successful cancellation, + * the operation is not deleted; instead, it becomes an operation with + * an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, + * corresponding to `Code.CANCELLED`. + * + * The async variant is {@see OperationsClient::cancelOperationAsync()} . + * + * @example samples/OperationsClient/cancel_operation.php + * + * @param CancelOperationRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @throws ApiException Thrown if the API call fails. + */ + public function cancelOperation(CancelOperationRequest $request, array $callOptions = []): void + { + $this->startApiCall('CancelOperation', $request, $callOptions)->wait(); + } + + /** + * Deletes a long-running operation. This method indicates that the client is + * no longer interested in the operation result. It does not cancel the + * operation. If the server doesn't support this method, it returns + * `google.rpc.Code.UNIMPLEMENTED`. + * + * The async variant is {@see OperationsClient::deleteOperationAsync()} . + * + * @example samples/OperationsClient/delete_operation.php + * + * @param DeleteOperationRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @throws ApiException Thrown if the API call fails. + */ + public function deleteOperation(DeleteOperationRequest $request, array $callOptions = []): void + { + $this->startApiCall('DeleteOperation', $request, $callOptions)->wait(); + } + + /** + * Gets the latest state of a long-running operation. Clients can use this + * method to poll the operation result at intervals as recommended by the API + * service. + * + * The async variant is {@see OperationsClient::getOperationAsync()} . + * + * @example samples/OperationsClient/get_operation.php + * + * @param GetOperationRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @return Operation + * + * @throws ApiException Thrown if the API call fails. + */ + public function getOperation(GetOperationRequest $request, array $callOptions = []): Operation + { + return $this->startApiCall('GetOperation', $request, $callOptions)->wait(); + } + + /** + * Lists operations that match the specified filter in the request. If the + * server doesn't support this method, it returns `UNIMPLEMENTED`. + * + * NOTE: the `name` binding allows API services to override the binding + * to use different resource name schemes, such as `users/*/operations`. To + * override the binding, API services can add a binding such as + * `"/v1/{name=users/*}/operations"` to their service configuration. + * For backwards compatibility, the default name includes the operations + * collection id, however overriding users must ensure the name binding + * is the parent resource, without the operations collection id. + * + * The async variant is {@see OperationsClient::listOperationsAsync()} . + * + * @example samples/OperationsClient/list_operations.php + * + * @param ListOperationsRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @return PagedListResponse + * + * @throws ApiException Thrown if the API call fails. + */ + public function listOperations(ListOperationsRequest $request, array $callOptions = []): PagedListResponse + { + return $this->startApiCall('ListOperations', $request, $callOptions); + } + + /** + * Waits until the specified long-running operation is done or reaches at most + * a specified timeout, returning the latest state. If the operation is + * already done, the latest state is immediately returned. If the timeout + * specified is greater than the default HTTP/RPC timeout, the HTTP/RPC + * timeout is used. If the server does not support this method, it returns + * `google.rpc.Code.UNIMPLEMENTED`. + * Note that this method is on a best-effort basis. It may return the latest + * state before the specified timeout (including immediately), meaning even an + * immediate response is no guarantee that the operation is done. + * + * The async variant is {@see OperationsClient::waitOperationAsync()} . + * + * @example samples/OperationsClient/wait_operation.php + * + * @param WaitOperationRequest $request A request to house fields associated with the call. + * @param array $callOptions { + * Optional. + * + * @type RetrySettings|array $retrySettings + * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an + * associative array of retry settings parameters. See the documentation on + * {@see RetrySettings} for example usage. + * } + * + * @return Operation + * + * @throws ApiException Thrown if the API call fails. + */ + public function waitOperation(WaitOperationRequest $request, array $callOptions = []): Operation + { + return $this->startApiCall('WaitOperation', $request, $callOptions)->wait(); + } +} diff --git a/LongRunning/src/LongRunning/DeleteOperationRequest.php b/LongRunning/src/LongRunning/DeleteOperationRequest.php index 8fce867db98d..943a6498c743 100644 --- a/LongRunning/src/LongRunning/DeleteOperationRequest.php +++ b/LongRunning/src/LongRunning/DeleteOperationRequest.php @@ -22,6 +22,19 @@ class DeleteOperationRequest extends \Google\Protobuf\Internal\Message */ private $name = ''; + /** + * @param string $name The name of the operation resource to be deleted. + * + * @return \Google\LongRunning\DeleteOperationRequest + * + * @experimental + */ + public static function build(string $name): self + { + return (new self()) + ->setName($name); + } + /** * Constructor. * diff --git a/LongRunning/src/LongRunning/Gapic/OperationsGapicClient.php b/LongRunning/src/LongRunning/Gapic/OperationsGapicClient.php index 454b9c14c315..c0de812aef7a 100644 --- a/LongRunning/src/LongRunning/Gapic/OperationsGapicClient.php +++ b/LongRunning/src/LongRunning/Gapic/OperationsGapicClient.php @@ -65,6 +65,8 @@ * $operationsClient->close(); * } * ``` + * + * @deprecated Please use the new service client {@see \Google\LongRunning\Client\OperationsClient}. */ class OperationsGapicClient { @@ -73,9 +75,16 @@ class OperationsGapicClient /** The name of the service. */ const SERVICE_NAME = 'google.longrunning.Operations'; - /** The default address of the service. */ + /** + * The default address of the service. + * + * @deprecated SERVICE_ADDRESS_TEMPLATE should be used instead. + */ const SERVICE_ADDRESS = 'longrunning.googleapis.com'; + /** The address template of the service. */ + private const SERVICE_ADDRESS_TEMPLATE = 'longrunning.UNIVERSE_DOMAIN'; + /** The default port of the service. */ const DEFAULT_SERVICE_PORT = 443; diff --git a/LongRunning/src/LongRunning/GetOperationRequest.php b/LongRunning/src/LongRunning/GetOperationRequest.php index 061a192a4b37..d89d75cc6240 100644 --- a/LongRunning/src/LongRunning/GetOperationRequest.php +++ b/LongRunning/src/LongRunning/GetOperationRequest.php @@ -22,6 +22,19 @@ class GetOperationRequest extends \Google\Protobuf\Internal\Message */ private $name = ''; + /** + * @param string $name The name of the operation resource. + * + * @return \Google\LongRunning\GetOperationRequest + * + * @experimental + */ + public static function build(string $name): self + { + return (new self()) + ->setName($name); + } + /** * Constructor. * diff --git a/LongRunning/src/LongRunning/ListOperationsRequest.php b/LongRunning/src/LongRunning/ListOperationsRequest.php index 75b65eceaf90..3ad0bebe826d 100644 --- a/LongRunning/src/LongRunning/ListOperationsRequest.php +++ b/LongRunning/src/LongRunning/ListOperationsRequest.php @@ -40,6 +40,21 @@ class ListOperationsRequest extends \Google\Protobuf\Internal\Message */ private $page_token = ''; + /** + * @param string $name The name of the operation's parent resource. + * @param string $filter The standard list filter. + * + * @return \Google\LongRunning\ListOperationsRequest + * + * @experimental + */ + public static function build(string $name, string $filter): self + { + return (new self()) + ->setName($name) + ->setFilter($filter); + } + /** * Constructor. * diff --git a/LongRunning/src/LongRunning/resources/operations_descriptor_config.php b/LongRunning/src/LongRunning/resources/operations_descriptor_config.php index 886339d2d0e9..d46a3426ef91 100644 --- a/LongRunning/src/LongRunning/resources/operations_descriptor_config.php +++ b/LongRunning/src/LongRunning/resources/operations_descriptor_config.php @@ -3,6 +3,42 @@ return [ 'interfaces' => [ 'google.longrunning.Operations' => [ + 'CancelOperation' => [ + 'callType' => \Google\ApiCore\Call::UNARY_CALL, + 'responseType' => 'Google\Protobuf\GPBEmpty', + 'headerParams' => [ + [ + 'keyName' => 'name', + 'fieldAccessors' => [ + 'getName', + ], + ], + ], + ], + 'DeleteOperation' => [ + 'callType' => \Google\ApiCore\Call::UNARY_CALL, + 'responseType' => 'Google\Protobuf\GPBEmpty', + 'headerParams' => [ + [ + 'keyName' => 'name', + 'fieldAccessors' => [ + 'getName', + ], + ], + ], + ], + 'GetOperation' => [ + 'callType' => \Google\ApiCore\Call::UNARY_CALL, + 'responseType' => 'Google\LongRunning\Operation', + 'headerParams' => [ + [ + 'keyName' => 'name', + 'fieldAccessors' => [ + 'getName', + ], + ], + ], + ], 'ListOperations' => [ 'pageStreaming' => [ 'requestPageTokenGetMethod' => 'getPageToken', @@ -12,6 +48,20 @@ 'responsePageTokenGetMethod' => 'getNextPageToken', 'resourcesGetMethod' => 'getOperations', ], + 'callType' => \Google\ApiCore\Call::PAGINATED_CALL, + 'responseType' => 'Google\LongRunning\ListOperationsResponse', + 'headerParams' => [ + [ + 'keyName' => 'name', + 'fieldAccessors' => [ + 'getName', + ], + ], + ], + ], + 'WaitOperation' => [ + 'callType' => \Google\ApiCore\Call::UNARY_CALL, + 'responseType' => 'Google\LongRunning\Operation', ], ], ], diff --git a/LongRunning/tests/Unit/Client/OperationsClientTest.php b/LongRunning/tests/Unit/Client/OperationsClientTest.php new file mode 100644 index 000000000000..9bfb9671abca --- /dev/null +++ b/LongRunning/tests/Unit/Client/OperationsClientTest.php @@ -0,0 +1,417 @@ +getMockBuilder(CredentialsWrapper::class)->disableOriginalConstructor()->getMock(); + } + + /** @return \Google\LongRunning\Client\OperationsClient */ + private function createClient(array $options = []) + { + $options += [ + 'credentials' => $this->createCredentials(), + ]; + return new \Google\LongRunning\Client\OperationsClient($options); + } + + /** @test */ + public function cancelOperationTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $expectedResponse = new GPBEmpty(); + $transport->addResponse($expectedResponse); + // Mock request + $name = 'name3373707'; + $request = (new CancelOperationRequest()) + ->setName($name); + $gapicClient->cancelOperation($request); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.longrunning.Operations/CancelOperation', $actualFuncCall); + $actualValue = $actualRequestObject->getName(); + $this->assertProtobufEquals($name, $actualValue); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function cancelOperationExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + // Mock request + $name = 'name3373707'; + $request = (new CancelOperationRequest()) + ->setName($name); + try { + $gapicClient->cancelOperation($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function deleteOperationTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $expectedResponse = new GPBEmpty(); + $transport->addResponse($expectedResponse); + // Mock request + $name = 'name3373707'; + $request = (new DeleteOperationRequest()) + ->setName($name); + $gapicClient->deleteOperation($request); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.longrunning.Operations/DeleteOperation', $actualFuncCall); + $actualValue = $actualRequestObject->getName(); + $this->assertProtobufEquals($name, $actualValue); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function deleteOperationExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + // Mock request + $name = 'name3373707'; + $request = (new DeleteOperationRequest()) + ->setName($name); + try { + $gapicClient->deleteOperation($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function getOperationTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $name2 = 'name2-1052831874'; + $done = true; + $expectedResponse = new Operation(); + $expectedResponse->setName($name2); + $expectedResponse->setDone($done); + $transport->addResponse($expectedResponse); + // Mock request + $name = 'name3373707'; + $request = (new GetOperationRequest()) + ->setName($name); + $response = $gapicClient->getOperation($request); + $this->assertEquals($expectedResponse, $response); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.longrunning.Operations/GetOperation', $actualFuncCall); + $actualValue = $actualRequestObject->getName(); + $this->assertProtobufEquals($name, $actualValue); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function getOperationExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + // Mock request + $name = 'name3373707'; + $request = (new GetOperationRequest()) + ->setName($name); + try { + $gapicClient->getOperation($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function listOperationsTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $nextPageToken = ''; + $operationsElement = new Operation(); + $operations = [ + $operationsElement, + ]; + $expectedResponse = new ListOperationsResponse(); + $expectedResponse->setNextPageToken($nextPageToken); + $expectedResponse->setOperations($operations); + $transport->addResponse($expectedResponse); + // Mock request + $name = 'name3373707'; + $filter = 'filter-1274492040'; + $request = (new ListOperationsRequest()) + ->setName($name) + ->setFilter($filter); + $response = $gapicClient->listOperations($request); + $this->assertEquals($expectedResponse, $response->getPage()->getResponseObject()); + $resources = iterator_to_array($response->iterateAllElements()); + $this->assertSame(1, count($resources)); + $this->assertEquals($expectedResponse->getOperations()[0], $resources[0]); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.longrunning.Operations/ListOperations', $actualFuncCall); + $actualValue = $actualRequestObject->getName(); + $this->assertProtobufEquals($name, $actualValue); + $actualValue = $actualRequestObject->getFilter(); + $this->assertProtobufEquals($filter, $actualValue); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function listOperationsExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + // Mock request + $name = 'name3373707'; + $filter = 'filter-1274492040'; + $request = (new ListOperationsRequest()) + ->setName($name) + ->setFilter($filter); + try { + $gapicClient->listOperations($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function waitOperationTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $name2 = 'name2-1052831874'; + $done = true; + $expectedResponse = new Operation(); + $expectedResponse->setName($name2); + $expectedResponse->setDone($done); + $transport->addResponse($expectedResponse); + $request = new WaitOperationRequest(); + $response = $gapicClient->waitOperation($request); + $this->assertEquals($expectedResponse, $response); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.longrunning.Operations/WaitOperation', $actualFuncCall); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function waitOperationExceptionTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + $status = new stdClass(); + $status->code = Code::DATA_LOSS; + $status->details = 'internal error'; + $expectedExceptionMessage = json_encode([ + 'message' => 'internal error', + 'code' => Code::DATA_LOSS, + 'status' => 'DATA_LOSS', + 'details' => [], + ], JSON_PRETTY_PRINT); + $transport->addResponse(null, $status); + $request = new WaitOperationRequest(); + try { + $gapicClient->waitOperation($request); + // If the $gapicClient method call did not throw, fail the test + $this->fail('Expected an ApiException, but no exception was thrown.'); + } catch (ApiException $ex) { + $this->assertEquals($status->code, $ex->getCode()); + $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); + } + // Call popReceivedCalls to ensure the stub is exhausted + $transport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + } + + /** @test */ + public function cancelOperationAsyncTest() + { + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + ]); + $this->assertTrue($transport->isExhausted()); + // Mock response + $expectedResponse = new GPBEmpty(); + $transport->addResponse($expectedResponse); + // Mock request + $name = 'name3373707'; + $request = (new CancelOperationRequest()) + ->setName($name); + $gapicClient->cancelOperationAsync($request)->wait(); + $actualRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($actualRequests)); + $actualFuncCall = $actualRequests[0]->getFuncCall(); + $actualRequestObject = $actualRequests[0]->getRequestObject(); + $this->assertSame('/google.longrunning.Operations/CancelOperation', $actualFuncCall); + $actualValue = $actualRequestObject->getName(); + $this->assertProtobufEquals($name, $actualValue); + $this->assertTrue($transport->isExhausted()); + } +} From 4cd9e1baa99a32efc6d741a055347bff5a92c352 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 10 Apr 2024 21:51:09 +0000 Subject: [PATCH 5/9] exclude operations client --- Core/src/Testing/Snippet/Coverage/Coverage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/Testing/Snippet/Coverage/Coverage.php b/Core/src/Testing/Snippet/Coverage/Coverage.php index 5c793c19bc51..4268e15facf4 100644 --- a/Core/src/Testing/Snippet/Coverage/Coverage.php +++ b/Core/src/Testing/Snippet/Coverage/Coverage.php @@ -35,6 +35,7 @@ class Coverage '/\\\Google\\\Cloud\\\Translate\\\Connection\\\Rest/', '/\\\Google\\\Cloud\\\Translate\\\Connection\\\ConnectionInterface/', '/\\\Google\\\ApiCore\\\LongRunning\\\Gapic\\\OperationsGapicClient/', + '/\\\Google\\\LongRunning\\\Client\\\OperationsClient/', ]; /** From d77c0c69749139d853b71336b144030988e9cf74 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 10 Apr 2024 15:10:23 -0700 Subject: [PATCH 6/9] fix static analysis --- .../src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php | 4 +--- LongRunning/src/ApiCore/LongRunning/OperationsClient.php | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php index 0d2c79ca295b..d1c2410bed06 100644 --- a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php +++ b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php @@ -2,14 +2,12 @@ namespace Google\ApiCore\LongRunning\Gapic; -use Google\ApiCore\LongRunning\Gapic\OperationsGapicClient; - if (false) { /** * This class is deprecated. Use Google\LongRunning\OperationsClient instead. * @deprecated */ - class OperationsGapicClient extends OperationsGapicClient + class OperationsGapicClient extends \Google\LongRunning\Client\OperationsClient { } } diff --git a/LongRunning/src/ApiCore/LongRunning/OperationsClient.php b/LongRunning/src/ApiCore/LongRunning/OperationsClient.php index ed88a7ba1f5b..888ea5269238 100644 --- a/LongRunning/src/ApiCore/LongRunning/OperationsClient.php +++ b/LongRunning/src/ApiCore/LongRunning/OperationsClient.php @@ -2,12 +2,14 @@ namespace Google\ApiCore\LongRunning; +use Google\ApiCore\LongRunning\Gapic\OperationsGapicClient; + if (false) { /** * This class is deprecated. Use Google\LongRunning\OperationsClient instead. * @deprecated */ - class OperationsClient extends \Google\LongRunning\OperationsClient {} + class OperationsClient extends OperationsGapicClient {} } // Autoload the class and its alias class_exists('\Google\LongRunning\OperationsClient'); From cfb43ff1fe37b21831b6c5667c4b6e28b8ac0cf9 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 10 Apr 2024 15:21:23 -0700 Subject: [PATCH 7/9] exclude Longrunning from snippets in the proper place --- Core/src/Testing/Snippet/Coverage/Coverage.php | 2 -- Core/src/Testing/TestHelpers.php | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Core/src/Testing/Snippet/Coverage/Coverage.php b/Core/src/Testing/Snippet/Coverage/Coverage.php index 4268e15facf4..2fd7b2a6e902 100644 --- a/Core/src/Testing/Snippet/Coverage/Coverage.php +++ b/Core/src/Testing/Snippet/Coverage/Coverage.php @@ -34,8 +34,6 @@ class Coverage '/\\\Google\\\Cloud\\\Translate\\\TranslateClient/', '/\\\Google\\\Cloud\\\Translate\\\Connection\\\Rest/', '/\\\Google\\\Cloud\\\Translate\\\Connection\\\ConnectionInterface/', - '/\\\Google\\\ApiCore\\\LongRunning\\\Gapic\\\OperationsGapicClient/', - '/\\\Google\\\LongRunning\\\Client\\\OperationsClient/', ]; /** diff --git a/Core/src/Testing/TestHelpers.php b/Core/src/Testing/TestHelpers.php index 2e832559bb34..e2050d6356ff 100644 --- a/Core/src/Testing/TestHelpers.php +++ b/Core/src/Testing/TestHelpers.php @@ -113,7 +113,8 @@ public static function snippetBootstrap() '/vendor/', '/dev/', new RegexFileFilter('/\w{0,}\/vendor\//'), - new RegexFileFilter('/\w{0,}\/V\d{1,}\w{0,}\//') + new RegexFileFilter('/\w{0,}\/V\d{1,}\w{0,}\//'), + 'LongRunning/', // LongRunning doesn't match the GAPIC regex, but should still be excluded ]); $coverage = new Coverage($scanner); $coverage->buildListToCover(); From 90f829b4f1815ffd27f052990e4e6a2b46469fe2 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 10 Apr 2024 15:37:48 -0700 Subject: [PATCH 8/9] remove trigger error for previous LongRunning classes --- .../src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php | 4 ---- LongRunning/src/ApiCore/LongRunning/OperationsClient.php | 2 -- 2 files changed, 6 deletions(-) diff --git a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php index d1c2410bed06..d1eacaa61fc4 100644 --- a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php +++ b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php @@ -13,7 +13,3 @@ class OperationsGapicClient extends \Google\LongRunning\Client\OperationsClient } // Autoload the class and its alias class_exists('\Google\LongRunning\Gapic\OperationsGapicClient'); -@trigger_error( - 'Google\LongRunning\ApiCore\OperationsGapicClient is deprecated and will be removed in the next major release. Use Google\LongRunning\OperationsClient instead', - E_USER_DEPRECATED -); diff --git a/LongRunning/src/ApiCore/LongRunning/OperationsClient.php b/LongRunning/src/ApiCore/LongRunning/OperationsClient.php index 888ea5269238..44310a55f51a 100644 --- a/LongRunning/src/ApiCore/LongRunning/OperationsClient.php +++ b/LongRunning/src/ApiCore/LongRunning/OperationsClient.php @@ -13,5 +13,3 @@ class OperationsClient extends OperationsGapicClient {} } // Autoload the class and its alias class_exists('\Google\LongRunning\OperationsClient'); -@trigger_error('Google\LongRunning\ApiCore\OperationsClient is deprecated and will be removed in the next major release. Use Google\LongRunning\OperationsClient instead', E_USER_DEPRECATED); - From 55d554b9265fdd89cf5740f562f96e12ce33648e Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 10 Apr 2024 22:48:54 +0000 Subject: [PATCH 9/9] style fix from owlbot --- .../src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php index d1eacaa61fc4..617c15470267 100644 --- a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php +++ b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php @@ -7,7 +7,8 @@ * This class is deprecated. Use Google\LongRunning\OperationsClient instead. * @deprecated */ - class OperationsGapicClient extends \Google\LongRunning\Client\OperationsClient + class OperationsGapicClient extends + \Google\LongRunning\Client\OperationsClient { } }