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(); 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/metadata/Longrunning/Operations.php b/LongRunning/metadata/Longrunning/Operations.php index 1757fcc8c784..2ed35d91878d 100644 Binary files a/LongRunning/metadata/Longrunning/Operations.php and b/LongRunning/metadata/Longrunning/Operations.php differ 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/Gapic/OperationsGapicClient.php b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php index b0b7f1356c5e..617c15470267 100644 --- a/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php +++ b/LongRunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php @@ -1,483 +1,16 @@ cancelOperation($name); - * } finally { - * $operationsClient->close(); - * } - * ``` - * - * @deprecated This class will be removed in the next major version update. - */ -class OperationsGapicClient -{ - use GapicClientTrait; - - /** The name of the service. */ - const SERVICE_NAME = 'google.longrunning.Operations'; - - /** - * 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; - - /** The name of the code generator, to be included in the agent header. */ - const CODEGEN_NAME = 'gapic'; - - /** The default scopes required by the service. */ - public static $serviceScopes = []; - - private static function getClientDefaults() - { - return [ - 'serviceName' => 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', - ], - ], - ]; - } - +if (false) { /** - * 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 + * This class is deprecated. Use Google\LongRunning\OperationsClient instead. + * @deprecated */ - public function __construct(array $options = []) + class OperationsGapicClient extends + \Google\LongRunning\Client\OperationsClient { - $clientOptions = $this->buildClientOptions($options); - $this->setClientOptions($clientOptions); - } - - /** - * 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`. - * - * Sample code: - * ``` - * $operationsClient = new OperationsClient(); - * try { - * $name = 'name'; - * $operationsClient->cancelOperation($name); - * } finally { - * $operationsClient->close(); - * } - * ``` - * - * @param string $name The name of the operation resource to be cancelled. - * @param array $optionalArgs { - * 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 if the remote call fails - */ - public function cancelOperation($name, array $optionalArgs = []) - { - $request = new CancelOperationRequest(); - $requestParamHeaders = []; - $request->setName($name); - $requestParamHeaders['name'] = $name; - $requestParams = new RequestParamsHeaderDescriptor( - $requestParamHeaders - ); - $optionalArgs['headers'] = isset($optionalArgs['headers']) - ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) - : $requestParams->getHeader(); - return $this->startCall( - 'CancelOperation', - GPBEmpty::class, - $optionalArgs, - $request - )->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`. - * - * Sample code: - * ``` - * $operationsClient = new OperationsClient(); - * try { - * $name = 'name'; - * $operationsClient->deleteOperation($name); - * } finally { - * $operationsClient->close(); - * } - * ``` - * - * @param string $name The name of the operation resource to be deleted. - * @param array $optionalArgs { - * 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 if the remote call fails - */ - public function deleteOperation($name, array $optionalArgs = []) - { - $request = new DeleteOperationRequest(); - $requestParamHeaders = []; - $request->setName($name); - $requestParamHeaders['name'] = $name; - $requestParams = new RequestParamsHeaderDescriptor( - $requestParamHeaders - ); - $optionalArgs['headers'] = isset($optionalArgs['headers']) - ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) - : $requestParams->getHeader(); - return $this->startCall( - 'DeleteOperation', - GPBEmpty::class, - $optionalArgs, - $request - )->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. - * - * Sample code: - * ``` - * $operationsClient = new OperationsClient(); - * try { - * $name = 'name'; - * $response = $operationsClient->getOperation($name); - * } finally { - * $operationsClient->close(); - * } - * ``` - * - * @param string $name The name of the operation resource. - * @param array $optionalArgs { - * 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 \Google\LongRunning\Operation - * - * @throws ApiException if the remote call fails - */ - public function getOperation($name, array $optionalArgs = []) - { - $request = new GetOperationRequest(); - $requestParamHeaders = []; - $request->setName($name); - $requestParamHeaders['name'] = $name; - $requestParams = new RequestParamsHeaderDescriptor( - $requestParamHeaders - ); - $optionalArgs['headers'] = isset($optionalArgs['headers']) - ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) - : $requestParams->getHeader(); - return $this->startCall( - 'GetOperation', - Operation::class, - $optionalArgs, - $request - )->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. - * - * Sample code: - * ``` - * $operationsClient = new OperationsClient(); - * try { - * $name = 'name'; - * $filter = 'filter'; - * // Iterate over pages of elements - * $pagedResponse = $operationsClient->listOperations($name, $filter); - * foreach ($pagedResponse->iteratePages() as $page) { - * foreach ($page as $element) { - * // doSomethingWith($element); - * } - * } - * // Alternatively: - * // Iterate through all elements - * $pagedResponse = $operationsClient->listOperations($name, $filter); - * foreach ($pagedResponse->iterateAllElements() as $element) { - * // doSomethingWith($element); - * } - * } finally { - * $operationsClient->close(); - * } - * ``` - * - * @param string $name The name of the operation's parent resource. - * @param string $filter The standard list filter. - * @param array $optionalArgs { - * Optional. - * - * @type int $pageSize - * The maximum number of resources contained in the underlying API - * response. The API may return fewer values in a page, even if - * there are additional values to be retrieved. - * @type string $pageToken - * A page token is used to specify a page of values to be returned. - * If no page token is specified (the default), the first page - * of values will be returned. Any page token used here must have - * been generated by a previous call to the API. - * @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 \Google\ApiCore\PagedListResponse - * - * @throws ApiException if the remote call fails - */ - public function listOperations($name, $filter, array $optionalArgs = []) - { - $request = new ListOperationsRequest(); - $requestParamHeaders = []; - $request->setName($name); - $request->setFilter($filter); - $requestParamHeaders['name'] = $name; - if (isset($optionalArgs['pageSize'])) { - $request->setPageSize($optionalArgs['pageSize']); - } - - if (isset($optionalArgs['pageToken'])) { - $request->setPageToken($optionalArgs['pageToken']); - } - - $requestParams = new RequestParamsHeaderDescriptor( - $requestParamHeaders - ); - $optionalArgs['headers'] = isset($optionalArgs['headers']) - ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) - : $requestParams->getHeader(); - return $this->getPagedListResponse( - 'ListOperations', - $optionalArgs, - ListOperationsResponse::class, - $request - ); - } - - /** - * 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. - * - * Sample code: - * ``` - * $operationsClient = new OperationsClient(); - * try { - * $response = $operationsClient->waitOperation(); - * } finally { - * $operationsClient->close(); - * } - * ``` - * - * @param array $optionalArgs { - * Optional. - * - * @type string $name - * The name of the operation resource to wait on. - * @type Duration $timeout - * The maximum duration to wait before timing out. If left blank, the wait - * will be at most the time permitted by the underlying HTTP/RPC protocol. - * If RPC context deadline is also specified, the shorter one will be used. - * @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 \Google\LongRunning\Operation - * - * @throws ApiException if the remote call fails - */ - public function waitOperation(array $optionalArgs = []) - { - $request = new WaitOperationRequest(); - if (isset($optionalArgs['name'])) { - $request->setName($optionalArgs['name']); - } - - if (isset($optionalArgs['timeout'])) { - $request->setTimeout($optionalArgs['timeout']); - } - - return $this->startCall( - 'WaitOperation', - Operation::class, - $optionalArgs, - $request - )->wait(); } } +// Autoload the class and its alias +class_exists('\Google\LongRunning\Gapic\OperationsGapicClient'); diff --git a/LongRunning/src/ApiCore/LongRunning/OperationsClient.php b/LongRunning/src/ApiCore/LongRunning/OperationsClient.php index be3d8e56be5d..44310a55f51a 100644 --- a/LongRunning/src/ApiCore/LongRunning/OperationsClient.php +++ b/LongRunning/src/ApiCore/LongRunning/OperationsClient.php @@ -1,34 +1,15 @@ [ - 'google.longrunning.Operations' => [ - 'ListOperations' => [ - 'pageStreaming' => [ - 'requestPageTokenGetMethod' => 'getPageToken', - 'requestPageTokenSetMethod' => 'setPageToken', - 'requestPageSizeGetMethod' => 'getPageSize', - 'requestPageSizeSetMethod' => 'setPageSize', - 'responsePageTokenGetMethod' => 'getNextPageToken', - 'resourcesGetMethod' => 'getOperations', - ], - ], - ], - ], -]; 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 new file mode 100644 index 000000000000..c0de812aef7a --- /dev/null +++ b/LongRunning/src/LongRunning/Gapic/OperationsGapicClient.php @@ -0,0 +1,483 @@ +cancelOperation($name); + * } finally { + * $operationsClient->close(); + * } + * ``` + * + * @deprecated Please use the new service client {@see \Google\LongRunning\Client\OperationsClient}. + */ +class OperationsGapicClient +{ + use GapicClientTrait; + + /** The name of the service. */ + const SERVICE_NAME = 'google.longrunning.Operations'; + + /** + * 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; + + /** The name of the code generator, to be included in the agent header. */ + const CODEGEN_NAME = 'gapic'; + + /** The default scopes required by the service. */ + public static $serviceScopes = []; + + private static function getClientDefaults() + { + return [ + 'serviceName' => 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); + } + + /** + * 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`. + * + * Sample code: + * ``` + * $operationsClient = new OperationsClient(); + * try { + * $name = 'name'; + * $operationsClient->cancelOperation($name); + * } finally { + * $operationsClient->close(); + * } + * ``` + * + * @param string $name The name of the operation resource to be cancelled. + * @param array $optionalArgs { + * 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 if the remote call fails + */ + public function cancelOperation($name, array $optionalArgs = []) + { + $request = new CancelOperationRequest(); + $requestParamHeaders = []; + $request->setName($name); + $requestParamHeaders['name'] = $name; + $requestParams = new RequestParamsHeaderDescriptor( + $requestParamHeaders + ); + $optionalArgs['headers'] = isset($optionalArgs['headers']) + ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) + : $requestParams->getHeader(); + return $this->startCall( + 'CancelOperation', + GPBEmpty::class, + $optionalArgs, + $request + )->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`. + * + * Sample code: + * ``` + * $operationsClient = new OperationsClient(); + * try { + * $name = 'name'; + * $operationsClient->deleteOperation($name); + * } finally { + * $operationsClient->close(); + * } + * ``` + * + * @param string $name The name of the operation resource to be deleted. + * @param array $optionalArgs { + * 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 if the remote call fails + */ + public function deleteOperation($name, array $optionalArgs = []) + { + $request = new DeleteOperationRequest(); + $requestParamHeaders = []; + $request->setName($name); + $requestParamHeaders['name'] = $name; + $requestParams = new RequestParamsHeaderDescriptor( + $requestParamHeaders + ); + $optionalArgs['headers'] = isset($optionalArgs['headers']) + ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) + : $requestParams->getHeader(); + return $this->startCall( + 'DeleteOperation', + GPBEmpty::class, + $optionalArgs, + $request + )->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. + * + * Sample code: + * ``` + * $operationsClient = new OperationsClient(); + * try { + * $name = 'name'; + * $response = $operationsClient->getOperation($name); + * } finally { + * $operationsClient->close(); + * } + * ``` + * + * @param string $name The name of the operation resource. + * @param array $optionalArgs { + * 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 \Google\LongRunning\Operation + * + * @throws ApiException if the remote call fails + */ + public function getOperation($name, array $optionalArgs = []) + { + $request = new GetOperationRequest(); + $requestParamHeaders = []; + $request->setName($name); + $requestParamHeaders['name'] = $name; + $requestParams = new RequestParamsHeaderDescriptor( + $requestParamHeaders + ); + $optionalArgs['headers'] = isset($optionalArgs['headers']) + ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) + : $requestParams->getHeader(); + return $this->startCall( + 'GetOperation', + Operation::class, + $optionalArgs, + $request + )->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. + * + * Sample code: + * ``` + * $operationsClient = new OperationsClient(); + * try { + * $name = 'name'; + * $filter = 'filter'; + * // Iterate over pages of elements + * $pagedResponse = $operationsClient->listOperations($name, $filter); + * foreach ($pagedResponse->iteratePages() as $page) { + * foreach ($page as $element) { + * // doSomethingWith($element); + * } + * } + * // Alternatively: + * // Iterate through all elements + * $pagedResponse = $operationsClient->listOperations($name, $filter); + * foreach ($pagedResponse->iterateAllElements() as $element) { + * // doSomethingWith($element); + * } + * } finally { + * $operationsClient->close(); + * } + * ``` + * + * @param string $name The name of the operation's parent resource. + * @param string $filter The standard list filter. + * @param array $optionalArgs { + * Optional. + * + * @type int $pageSize + * The maximum number of resources contained in the underlying API + * response. The API may return fewer values in a page, even if + * there are additional values to be retrieved. + * @type string $pageToken + * A page token is used to specify a page of values to be returned. + * If no page token is specified (the default), the first page + * of values will be returned. Any page token used here must have + * been generated by a previous call to the API. + * @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 \Google\ApiCore\PagedListResponse + * + * @throws ApiException if the remote call fails + */ + public function listOperations($name, $filter, array $optionalArgs = []) + { + $request = new ListOperationsRequest(); + $requestParamHeaders = []; + $request->setName($name); + $request->setFilter($filter); + $requestParamHeaders['name'] = $name; + if (isset($optionalArgs['pageSize'])) { + $request->setPageSize($optionalArgs['pageSize']); + } + + if (isset($optionalArgs['pageToken'])) { + $request->setPageToken($optionalArgs['pageToken']); + } + + $requestParams = new RequestParamsHeaderDescriptor( + $requestParamHeaders + ); + $optionalArgs['headers'] = isset($optionalArgs['headers']) + ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) + : $requestParams->getHeader(); + return $this->getPagedListResponse( + 'ListOperations', + $optionalArgs, + ListOperationsResponse::class, + $request + ); + } + + /** + * 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. + * + * Sample code: + * ``` + * $operationsClient = new OperationsClient(); + * try { + * $response = $operationsClient->waitOperation(); + * } finally { + * $operationsClient->close(); + * } + * ``` + * + * @param array $optionalArgs { + * Optional. + * + * @type string $name + * The name of the operation resource to wait on. + * @type Duration $timeout + * The maximum duration to wait before timing out. If left blank, the wait + * will be at most the time permitted by the underlying HTTP/RPC protocol. + * If RPC context deadline is also specified, the shorter one will be used. + * @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 \Google\LongRunning\Operation + * + * @throws ApiException if the remote call fails + */ + public function waitOperation(array $optionalArgs = []) + { + $request = new WaitOperationRequest(); + if (isset($optionalArgs['name'])) { + $request->setName($optionalArgs['name']); + } + + if (isset($optionalArgs['timeout'])) { + $request->setTimeout($optionalArgs['timeout']); + } + + return $this->startCall( + 'WaitOperation', + Operation::class, + $optionalArgs, + $request + )->wait(); + } +} 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/OperationsClient.php b/LongRunning/src/LongRunning/OperationsClient.php new file mode 100644 index 000000000000..04e271747a37 --- /dev/null +++ b/LongRunning/src/LongRunning/OperationsClient.php @@ -0,0 +1,36 @@ + [ + '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', + 'requestPageTokenSetMethod' => 'setPageToken', + 'requestPageSizeGetMethod' => 'getPageSize', + 'requestPageSizeSetMethod' => 'setPageSize', + '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/src/ApiCore/LongRunning/resources/operations_rest_client_config.php b/LongRunning/src/LongRunning/resources/operations_rest_client_config.php similarity index 100% rename from LongRunning/src/ApiCore/LongRunning/resources/operations_rest_client_config.php rename to LongRunning/src/LongRunning/resources/operations_rest_client_config.php 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()); + } +} diff --git a/LongRunning/tests/Unit/OperationsClientTest.php b/LongRunning/tests/Unit/OperationsClientTest.php index 0da33f5bc555..828e560a19c1 100644 --- a/LongRunning/tests/Unit/OperationsClientTest.php +++ b/LongRunning/tests/Unit/OperationsClientTest.php @@ -51,13 +51,13 @@ private function createCredentials() return $this->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 */