diff --git a/Spanner/metadata/Admin/Database/V1/SpannerDatabaseAdmin.php b/Spanner/metadata/Admin/Database/V1/SpannerDatabaseAdmin.php index d308205faad2..2fa9c381d1f1 100644 Binary files a/Spanner/metadata/Admin/Database/V1/SpannerDatabaseAdmin.php and b/Spanner/metadata/Admin/Database/V1/SpannerDatabaseAdmin.php differ diff --git a/Spanner/src/Admin/Database/V1/Database.php b/Spanner/src/Admin/Database/V1/Database.php index 212cdb4f6f68..909b3417f042 100644 --- a/Spanner/src/Admin/Database/V1/Database.php +++ b/Spanner/src/Admin/Database/V1/Database.php @@ -101,6 +101,18 @@ class Database extends \Google\Protobuf\Internal\Message * Generated from protobuf field .google.spanner.admin.database.v1.DatabaseDialect database_dialect = 10 [(.google.api.field_behavior) = OUTPUT_ONLY]; */ private $database_dialect = 0; + /** + * Whether drop protection is enabled for this database. Defaults to false, if not set. + * + * Generated from protobuf field bool enable_drop_protection = 11; + */ + private $enable_drop_protection = false; + /** + * If true, the database is being updated. If false, there are no ongoing update operations for the database. + * + * Generated from protobuf field bool reconciling = 12 [(.google.api.field_behavior) = OUTPUT_ONLY]; + */ + private $reconciling = false; /** * Constructor. @@ -154,6 +166,10 @@ class Database extends \Google\Protobuf\Internal\Message * DatabaseAdmin.UpdateDatabaseDdl. If not explicitly set, this is empty. * @type int $database_dialect * Output only. The dialect of the Cloud Spanner Database. + * @type bool $enable_drop_protection + * Whether drop protection is enabled for this database. Defaults to false, if not set. + * @type bool $reconciling + * If true, the database is being updated. If false, there are no ongoing update operations for the database. * } */ public function __construct($data = NULL) { @@ -513,5 +529,57 @@ public function setDatabaseDialect($var) return $this; } + /** + * Whether drop protection is enabled for this database. Defaults to false, if not set. + * + * Generated from protobuf field bool enable_drop_protection = 11; + * @return bool + */ + public function getEnableDropProtection() + { + return $this->enable_drop_protection; + } + + /** + * Whether drop protection is enabled for this database. Defaults to false, if not set. + * + * Generated from protobuf field bool enable_drop_protection = 11; + * @param bool $var + * @return $this + */ + public function setEnableDropProtection($var) + { + GPBUtil::checkBool($var); + $this->enable_drop_protection = $var; + + return $this; + } + + /** + * If true, the database is being updated. If false, there are no ongoing update operations for the database. + * + * Generated from protobuf field bool reconciling = 12 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * @return bool + */ + public function getReconciling() + { + return $this->reconciling; + } + + /** + * If true, the database is being updated. If false, there are no ongoing update operations for the database. + * + * Generated from protobuf field bool reconciling = 12 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * @param bool $var + * @return $this + */ + public function setReconciling($var) + { + GPBUtil::checkBool($var); + $this->reconciling = $var; + + return $this; + } + } diff --git a/Spanner/src/Admin/Database/V1/DatabaseAdminGrpcClient.php b/Spanner/src/Admin/Database/V1/DatabaseAdminGrpcClient.php index 6ce01e23b16a..63fc3c82e218 100644 --- a/Spanner/src/Admin/Database/V1/DatabaseAdminGrpcClient.php +++ b/Spanner/src/Admin/Database/V1/DatabaseAdminGrpcClient.php @@ -90,6 +90,20 @@ public function GetDatabase(\Google\Cloud\Spanner\Admin\Database\V1\GetDatabaseR $metadata, $options); } + /** + * @param \Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseRequest $argument input argument + * @param array $metadata metadata + * @param array $options call options + * @return \Grpc\UnaryCall + */ + public function UpdateDatabase(\Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseRequest $argument, + $metadata = [], $options = []) { + return $this->_simpleRequest('/google.spanner.admin.database.v1.DatabaseAdmin/UpdateDatabase', + $argument, + ['\Google\LongRunning\Operation', 'decode'], + $metadata, $options); + } + /** * Updates the schema of a Cloud Spanner database by * creating/altering/dropping tables, columns, indexes, etc. The returned diff --git a/Spanner/src/Admin/Database/V1/Gapic/DatabaseAdminGapicClient.php b/Spanner/src/Admin/Database/V1/Gapic/DatabaseAdminGapicClient.php index cc96835d3bf5..96bd44f31342 100644 --- a/Spanner/src/Admin/Database/V1/Gapic/DatabaseAdminGapicClient.php +++ b/Spanner/src/Admin/Database/V1/Gapic/DatabaseAdminGapicClient.php @@ -74,6 +74,7 @@ use Google\Cloud\Spanner\Admin\Database\V1\UpdateBackupRequest; use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseDdlMetadata; use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseDdlRequest; +use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseRequest; use Google\LongRunning\Operation; use Google\Protobuf\FieldMask; use Google\Protobuf\GPBEmpty; @@ -2016,6 +2017,87 @@ public function updateBackup($backup, $updateMask, array $optionalArgs = []) )->wait(); } + /** + * + * Sample code: + * ``` + * $databaseAdminClient = new DatabaseAdminClient(); + * try { + * $database = new Database(); + * $updateMask = new FieldMask(); + * $operationResponse = $databaseAdminClient->updateDatabase($database, $updateMask); + * $operationResponse->pollUntilComplete(); + * if ($operationResponse->operationSucceeded()) { + * $result = $operationResponse->getResult(); + * // doSomethingWith($result) + * } else { + * $error = $operationResponse->getError(); + * // handleError($error) + * } + * // Alternatively: + * // start the operation, keep the operation name, and resume later + * $operationResponse = $databaseAdminClient->updateDatabase($database, $updateMask); + * $operationName = $operationResponse->getName(); + * // ... do other work + * $newOperationResponse = $databaseAdminClient->resumeOperation($operationName, 'updateDatabase'); + * while (!$newOperationResponse->isDone()) { + * // ... do other work + * $newOperationResponse->reload(); + * } + * if ($newOperationResponse->operationSucceeded()) { + * $result = $newOperationResponse->getResult(); + * // doSomethingWith($result) + * } else { + * $error = $newOperationResponse->getError(); + * // handleError($error) + * } + * } finally { + * $databaseAdminClient->close(); + * } + * ``` + * + * @param Database $database Required. The database to update. + * The `name` field of the database is of the form + * `projects//instances//databases/`. + * @param FieldMask $updateMask Required. The list of fields to update. Currently, only + * `enable_drop_protection` field can be updated. + * @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\ApiCore\OperationResponse + * + * @throws ApiException if the remote call fails + */ + public function updateDatabase( + $database, + $updateMask, + array $optionalArgs = [] + ) { + $request = new UpdateDatabaseRequest(); + $requestParamHeaders = []; + $request->setDatabase($database); + $request->setUpdateMask($updateMask); + $requestParamHeaders['database.name'] = $database->getName(); + $requestParams = new RequestParamsHeaderDescriptor( + $requestParamHeaders + ); + $optionalArgs['headers'] = isset($optionalArgs['headers']) + ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) + : $requestParams->getHeader(); + return $this->startOperationsCall( + 'UpdateDatabase', + $optionalArgs, + $request, + $this->getOperationsClient() + )->wait(); + } + /** * Updates the schema of a Cloud Spanner database by * creating/altering/dropping tables, columns, indexes, etc. The returned diff --git a/Spanner/src/Admin/Database/V1/UpdateDatabaseMetadata.php b/Spanner/src/Admin/Database/V1/UpdateDatabaseMetadata.php new file mode 100644 index 000000000000..2ca78f6017ec --- /dev/null +++ b/Spanner/src/Admin/Database/V1/UpdateDatabaseMetadata.php @@ -0,0 +1,174 @@ +google.spanner.admin.database.v1.UpdateDatabaseMetadata + */ +class UpdateDatabaseMetadata extends \Google\Protobuf\Internal\Message +{ + /** + * The request for [UpdateDatabase][DatabaseAdmin.UpdateDatabase]. + * + * Generated from protobuf field .google.spanner.admin.database.v1.UpdateDatabaseRequest request = 1; + */ + private $request = null; + /** + * The progress of the [UpdateDatabase][DatabaseAdmin.UpdateDatabase] + * operation. + * + * Generated from protobuf field .google.spanner.admin.database.v1.OperationProgress progress = 2; + */ + private $progress = null; + /** + * The time at which this operation was cancelled. If set, this operation is + * in the process of undoing itself (which is best-effort). + * + * Generated from protobuf field .google.protobuf.Timestamp cancel_time = 3; + */ + private $cancel_time = null; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseRequest $request + * The request for [UpdateDatabase][DatabaseAdmin.UpdateDatabase]. + * @type \Google\Cloud\Spanner\Admin\Database\V1\OperationProgress $progress + * The progress of the [UpdateDatabase][DatabaseAdmin.UpdateDatabase] + * operation. + * @type \Google\Protobuf\Timestamp $cancel_time + * The time at which this operation was cancelled. If set, this operation is + * in the process of undoing itself (which is best-effort). + * } + */ + public function __construct($data = NULL) { + \GPBMetadata\Google\Spanner\Admin\Database\V1\SpannerDatabaseAdmin::initOnce(); + parent::__construct($data); + } + + /** + * The request for [UpdateDatabase][DatabaseAdmin.UpdateDatabase]. + * + * Generated from protobuf field .google.spanner.admin.database.v1.UpdateDatabaseRequest request = 1; + * @return \Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseRequest|null + */ + public function getRequest() + { + return $this->request; + } + + public function hasRequest() + { + return isset($this->request); + } + + public function clearRequest() + { + unset($this->request); + } + + /** + * The request for [UpdateDatabase][DatabaseAdmin.UpdateDatabase]. + * + * Generated from protobuf field .google.spanner.admin.database.v1.UpdateDatabaseRequest request = 1; + * @param \Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseRequest $var + * @return $this + */ + public function setRequest($var) + { + GPBUtil::checkMessage($var, \Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseRequest::class); + $this->request = $var; + + return $this; + } + + /** + * The progress of the [UpdateDatabase][DatabaseAdmin.UpdateDatabase] + * operation. + * + * Generated from protobuf field .google.spanner.admin.database.v1.OperationProgress progress = 2; + * @return \Google\Cloud\Spanner\Admin\Database\V1\OperationProgress|null + */ + public function getProgress() + { + return $this->progress; + } + + public function hasProgress() + { + return isset($this->progress); + } + + public function clearProgress() + { + unset($this->progress); + } + + /** + * The progress of the [UpdateDatabase][DatabaseAdmin.UpdateDatabase] + * operation. + * + * Generated from protobuf field .google.spanner.admin.database.v1.OperationProgress progress = 2; + * @param \Google\Cloud\Spanner\Admin\Database\V1\OperationProgress $var + * @return $this + */ + public function setProgress($var) + { + GPBUtil::checkMessage($var, \Google\Cloud\Spanner\Admin\Database\V1\OperationProgress::class); + $this->progress = $var; + + return $this; + } + + /** + * The time at which this operation was cancelled. If set, this operation is + * in the process of undoing itself (which is best-effort). + * + * Generated from protobuf field .google.protobuf.Timestamp cancel_time = 3; + * @return \Google\Protobuf\Timestamp|null + */ + public function getCancelTime() + { + return $this->cancel_time; + } + + public function hasCancelTime() + { + return isset($this->cancel_time); + } + + public function clearCancelTime() + { + unset($this->cancel_time); + } + + /** + * The time at which this operation was cancelled. If set, this operation is + * in the process of undoing itself (which is best-effort). + * + * Generated from protobuf field .google.protobuf.Timestamp cancel_time = 3; + * @param \Google\Protobuf\Timestamp $var + * @return $this + */ + public function setCancelTime($var) + { + GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); + $this->cancel_time = $var; + + return $this; + } + +} + diff --git a/Spanner/src/Admin/Database/V1/UpdateDatabaseRequest.php b/Spanner/src/Admin/Database/V1/UpdateDatabaseRequest.php new file mode 100644 index 000000000000..d21415d7a02b --- /dev/null +++ b/Spanner/src/Admin/Database/V1/UpdateDatabaseRequest.php @@ -0,0 +1,133 @@ +google.spanner.admin.database.v1.UpdateDatabaseRequest + */ +class UpdateDatabaseRequest extends \Google\Protobuf\Internal\Message +{ + /** + * Required. The database to update. + * The `name` field of the database is of the form + * `projects//instances//databases/`. + * + * Generated from protobuf field .google.spanner.admin.database.v1.Database database = 1 [(.google.api.field_behavior) = REQUIRED]; + */ + private $database = null; + /** + * Required. The list of fields to update. Currently, only + * `enable_drop_protection` field can be updated. + * + * Generated from protobuf field .google.protobuf.FieldMask update_mask = 2 [(.google.api.field_behavior) = REQUIRED]; + */ + private $update_mask = null; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Cloud\Spanner\Admin\Database\V1\Database $database + * Required. The database to update. + * The `name` field of the database is of the form + * `projects//instances//databases/`. + * @type \Google\Protobuf\FieldMask $update_mask + * Required. The list of fields to update. Currently, only + * `enable_drop_protection` field can be updated. + * } + */ + public function __construct($data = NULL) { + \GPBMetadata\Google\Spanner\Admin\Database\V1\SpannerDatabaseAdmin::initOnce(); + parent::__construct($data); + } + + /** + * Required. The database to update. + * The `name` field of the database is of the form + * `projects//instances//databases/`. + * + * Generated from protobuf field .google.spanner.admin.database.v1.Database database = 1 [(.google.api.field_behavior) = REQUIRED]; + * @return \Google\Cloud\Spanner\Admin\Database\V1\Database|null + */ + public function getDatabase() + { + return $this->database; + } + + public function hasDatabase() + { + return isset($this->database); + } + + public function clearDatabase() + { + unset($this->database); + } + + /** + * Required. The database to update. + * The `name` field of the database is of the form + * `projects//instances//databases/`. + * + * Generated from protobuf field .google.spanner.admin.database.v1.Database database = 1 [(.google.api.field_behavior) = REQUIRED]; + * @param \Google\Cloud\Spanner\Admin\Database\V1\Database $var + * @return $this + */ + public function setDatabase($var) + { + GPBUtil::checkMessage($var, \Google\Cloud\Spanner\Admin\Database\V1\Database::class); + $this->database = $var; + + return $this; + } + + /** + * Required. The list of fields to update. Currently, only + * `enable_drop_protection` field can be updated. + * + * Generated from protobuf field .google.protobuf.FieldMask update_mask = 2 [(.google.api.field_behavior) = REQUIRED]; + * @return \Google\Protobuf\FieldMask|null + */ + public function getUpdateMask() + { + return $this->update_mask; + } + + public function hasUpdateMask() + { + return isset($this->update_mask); + } + + public function clearUpdateMask() + { + unset($this->update_mask); + } + + /** + * Required. The list of fields to update. Currently, only + * `enable_drop_protection` field can be updated. + * + * Generated from protobuf field .google.protobuf.FieldMask update_mask = 2 [(.google.api.field_behavior) = REQUIRED]; + * @param \Google\Protobuf\FieldMask $var + * @return $this + */ + public function setUpdateMask($var) + { + GPBUtil::checkMessage($var, \Google\Protobuf\FieldMask::class); + $this->update_mask = $var; + + return $this; + } + +} + diff --git a/Spanner/src/Admin/Database/V1/resources/database_admin_client_config.json b/Spanner/src/Admin/Database/V1/resources/database_admin_client_config.json index 5389af80866c..ca8f1d556f1a 100644 --- a/Spanner/src/Admin/Database/V1/resources/database_admin_client_config.json +++ b/Spanner/src/Admin/Database/V1/resources/database_admin_client_config.json @@ -152,6 +152,11 @@ "retry_codes_name": "retry_policy_1_codes", "retry_params_name": "retry_policy_1_params" }, + "UpdateDatabase": { + "timeout_millis": 3600000, + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params" + }, "UpdateDatabaseDdl": { "timeout_millis": 3600000, "retry_codes_name": "retry_policy_1_codes", diff --git a/Spanner/src/Admin/Database/V1/resources/database_admin_descriptor_config.php b/Spanner/src/Admin/Database/V1/resources/database_admin_descriptor_config.php index 2e8b023771cf..932c0b19731b 100644 --- a/Spanner/src/Admin/Database/V1/resources/database_admin_descriptor_config.php +++ b/Spanner/src/Admin/Database/V1/resources/database_admin_descriptor_config.php @@ -43,6 +43,16 @@ 'totalPollTimeoutMillis' => '86400000', ], ], + 'UpdateDatabase' => [ + 'longRunning' => [ + 'operationReturnType' => '\Google\Cloud\Spanner\Admin\Database\V1\Database', + 'metadataReturnType' => '\Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseMetadata', + 'initialPollDelayMillis' => '20000', + 'pollDelayMultiplier' => '1.5', + 'maxPollDelayMillis' => '45000', + 'totalPollTimeoutMillis' => '86400000', + ], + ], 'UpdateDatabaseDdl' => [ 'longRunning' => [ 'operationReturnType' => '\Google\Protobuf\GPBEmpty', diff --git a/Spanner/src/Admin/Database/V1/resources/database_admin_rest_client_config.php b/Spanner/src/Admin/Database/V1/resources/database_admin_rest_client_config.php index debb0420d4f9..b14247ff4156 100644 --- a/Spanner/src/Admin/Database/V1/resources/database_admin_rest_client_config.php +++ b/Spanner/src/Admin/Database/V1/resources/database_admin_rest_client_config.php @@ -344,6 +344,22 @@ 'update_mask', ], ], + 'UpdateDatabase' => [ + 'method' => 'patch', + 'uriTemplate' => '/v1/{database.name=projects/*/instances/*/databases/*}', + 'body' => 'database', + 'placeholders' => [ + 'database.name' => [ + 'getters' => [ + 'getDatabase', + 'getName', + ], + ], + ], + 'queryParams' => [ + 'update_mask', + ], + ], 'UpdateDatabaseDdl' => [ 'method' => 'patch', 'uriTemplate' => '/v1/{database=projects/*/instances/*/databases/*}/ddl', diff --git a/Spanner/tests/Unit/Admin/Database/V1/DatabaseAdminClientTest.php b/Spanner/tests/Unit/Admin/Database/V1/DatabaseAdminClientTest.php index 1da2a28464bd..248bab56f04d 100644 --- a/Spanner/tests/Unit/Admin/Database/V1/DatabaseAdminClientTest.php +++ b/Spanner/tests/Unit/Admin/Database/V1/DatabaseAdminClientTest.php @@ -366,10 +366,14 @@ public function createDatabaseTest() $name = 'name3373707'; $versionRetentionPeriod = 'versionRetentionPeriod907249289'; $defaultLeader = 'defaultLeader1941180615'; + $enableDropProtection = false; + $reconciling = false; $expectedResponse = new Database(); $expectedResponse->setName($name); $expectedResponse->setVersionRetentionPeriod($versionRetentionPeriod); $expectedResponse->setDefaultLeader($defaultLeader); + $expectedResponse->setEnableDropProtection($enableDropProtection); + $expectedResponse->setReconciling($reconciling); $anyResponse = new Any(); $anyResponse->setValue($expectedResponse->serializeToString()); $completeOperation = new Operation(); @@ -659,10 +663,14 @@ public function getDatabaseTest() $name2 = 'name2-1052831874'; $versionRetentionPeriod = 'versionRetentionPeriod907249289'; $defaultLeader = 'defaultLeader1941180615'; + $enableDropProtection = false; + $reconciling = false; $expectedResponse = new Database(); $expectedResponse->setName($name2); $expectedResponse->setVersionRetentionPeriod($versionRetentionPeriod); $expectedResponse->setDefaultLeader($defaultLeader); + $expectedResponse->setEnableDropProtection($enableDropProtection); + $expectedResponse->setReconciling($reconciling); $transport->addResponse($expectedResponse); // Mock request $formattedName = $gapicClient->databaseName('[PROJECT]', '[INSTANCE]', '[DATABASE]'); @@ -1195,10 +1203,14 @@ public function restoreDatabaseTest() $name = 'name3373707'; $versionRetentionPeriod = 'versionRetentionPeriod907249289'; $defaultLeader = 'defaultLeader1941180615'; + $enableDropProtection = false; + $reconciling = false; $expectedResponse = new Database(); $expectedResponse->setName($name); $expectedResponse->setVersionRetentionPeriod($versionRetentionPeriod); $expectedResponse->setDefaultLeader($defaultLeader); + $expectedResponse->setEnableDropProtection($enableDropProtection); + $expectedResponse->setReconciling($reconciling); $anyResponse = new Any(); $anyResponse->setValue($expectedResponse->serializeToString()); $completeOperation = new Operation(); @@ -1494,6 +1506,141 @@ public function updateBackupExceptionTest() $this->assertTrue($transport->isExhausted()); } + /** @test */ + public function updateDatabaseTest() + { + $operationsTransport = $this->createTransport(); + $operationsClient = new OperationsClient([ + 'apiEndpoint' => '', + 'transport' => $operationsTransport, + 'credentials' => $this->createCredentials(), + ]); + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + 'operationsClient' => $operationsClient, + ]); + $this->assertTrue($transport->isExhausted()); + $this->assertTrue($operationsTransport->isExhausted()); + // Mock response + $incompleteOperation = new Operation(); + $incompleteOperation->setName('operations/updateDatabaseTest'); + $incompleteOperation->setDone(false); + $transport->addResponse($incompleteOperation); + $name = 'name3373707'; + $versionRetentionPeriod = 'versionRetentionPeriod907249289'; + $defaultLeader = 'defaultLeader1941180615'; + $enableDropProtection = false; + $reconciling = false; + $expectedResponse = new Database(); + $expectedResponse->setName($name); + $expectedResponse->setVersionRetentionPeriod($versionRetentionPeriod); + $expectedResponse->setDefaultLeader($defaultLeader); + $expectedResponse->setEnableDropProtection($enableDropProtection); + $expectedResponse->setReconciling($reconciling); + $anyResponse = new Any(); + $anyResponse->setValue($expectedResponse->serializeToString()); + $completeOperation = new Operation(); + $completeOperation->setName('operations/updateDatabaseTest'); + $completeOperation->setDone(true); + $completeOperation->setResponse($anyResponse); + $operationsTransport->addResponse($completeOperation); + // Mock request + $database = new Database(); + $databaseName = 'databaseName-459093338'; + $database->setName($databaseName); + $updateMask = new FieldMask(); + $response = $gapicClient->updateDatabase($database, $updateMask); + $this->assertFalse($response->isDone()); + $this->assertNull($response->getResult()); + $apiRequests = $transport->popReceivedCalls(); + $this->assertSame(1, count($apiRequests)); + $operationsRequestsEmpty = $operationsTransport->popReceivedCalls(); + $this->assertSame(0, count($operationsRequestsEmpty)); + $actualApiFuncCall = $apiRequests[0]->getFuncCall(); + $actualApiRequestObject = $apiRequests[0]->getRequestObject(); + $this->assertSame('/google.spanner.admin.database.v1.DatabaseAdmin/UpdateDatabase', $actualApiFuncCall); + $actualValue = $actualApiRequestObject->getDatabase(); + $this->assertProtobufEquals($database, $actualValue); + $actualValue = $actualApiRequestObject->getUpdateMask(); + $this->assertProtobufEquals($updateMask, $actualValue); + $expectedOperationsRequestObject = new GetOperationRequest(); + $expectedOperationsRequestObject->setName('operations/updateDatabaseTest'); + $response->pollUntilComplete([ + 'initialPollDelayMillis' => 1, + ]); + $this->assertTrue($response->isDone()); + $this->assertEquals($expectedResponse, $response->getResult()); + $apiRequestsEmpty = $transport->popReceivedCalls(); + $this->assertSame(0, count($apiRequestsEmpty)); + $operationsRequests = $operationsTransport->popReceivedCalls(); + $this->assertSame(1, count($operationsRequests)); + $actualOperationsFuncCall = $operationsRequests[0]->getFuncCall(); + $actualOperationsRequestObject = $operationsRequests[0]->getRequestObject(); + $this->assertSame('/google.longrunning.Operations/GetOperation', $actualOperationsFuncCall); + $this->assertEquals($expectedOperationsRequestObject, $actualOperationsRequestObject); + $this->assertTrue($transport->isExhausted()); + $this->assertTrue($operationsTransport->isExhausted()); + } + + /** @test */ + public function updateDatabaseExceptionTest() + { + $operationsTransport = $this->createTransport(); + $operationsClient = new OperationsClient([ + 'apiEndpoint' => '', + 'transport' => $operationsTransport, + 'credentials' => $this->createCredentials(), + ]); + $transport = $this->createTransport(); + $gapicClient = $this->createClient([ + 'transport' => $transport, + 'operationsClient' => $operationsClient, + ]); + $this->assertTrue($transport->isExhausted()); + $this->assertTrue($operationsTransport->isExhausted()); + // Mock response + $incompleteOperation = new Operation(); + $incompleteOperation->setName('operations/updateDatabaseTest'); + $incompleteOperation->setDone(false); + $transport->addResponse($incompleteOperation); + $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); + $operationsTransport->addResponse(null, $status); + // Mock request + $database = new Database(); + $databaseName = 'databaseName-459093338'; + $database->setName($databaseName); + $updateMask = new FieldMask(); + $response = $gapicClient->updateDatabase($database, $updateMask); + $this->assertFalse($response->isDone()); + $this->assertNull($response->getResult()); + $expectedOperationsRequestObject = new GetOperationRequest(); + $expectedOperationsRequestObject->setName('operations/updateDatabaseTest'); + try { + $response->pollUntilComplete([ + 'initialPollDelayMillis' => 1, + ]); + // If the pollUntilComplete() 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 stubs are exhausted + $transport->popReceivedCalls(); + $operationsTransport->popReceivedCalls(); + $this->assertTrue($transport->isExhausted()); + $this->assertTrue($operationsTransport->isExhausted()); + } + /** @test */ public function updateDatabaseDdlTest() { diff --git a/generate-gapic-services.sh b/generate-gapic-services.sh new file mode 100755 index 000000000000..2acee9a1699a --- /dev/null +++ b/generate-gapic-services.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +COMPONENT_NAME="" +if [ "$#" -eq 1 ]; then + COMPONENT_NAME=" -name $1 " +elif [ "$#" -ne 0 ]; then + echo "usage: generate-gapic-services.sh [COMPONENT]" + exit 1; +fi + +GOOGLE_CLOUD_PHP=~/github/google-cloud-php +GOOGLEAPIS_GEN=~/github/googleapis-gen +IMAGE="gcr.io/cloud-devrel-public-resources/owlbot-php:latest" +find $GOOGLE_CLOUD_PHP -mindepth 1 -maxdepth 1 -type d -name '*Spanner*' -printf '%f\n' | grep '^[A-Z]' | sort | while read DIR +do + echo "Running Owlbot in $DIR"; + + docker run --rm --user $(id -u):$(id -g) \ + -v $GOOGLE_CLOUD_PHP:/repo -v $GOOGLEAPIS_GEN:/googleapis-gen -w /repo \ + --env HOME=/tmp \ + gcr.io/cloud-devrel-public-resources/owlbot-cli:latest copy-code \ + --source-repo=/googleapis-gen \ + --config-file=$DIR/.OwlBot.yaml + + + docker run --rm --user $(id -u):$(id -g) \ + -v $GOOGLE_CLOUD_PHP:/repo \ + -v $GOOGLEAPIS_GEN/bazel-bin:/bazel-bin \ + gcr.io/cloud-devrel-public-resources/owlbot-cli:latest copy-bazel-bin \ + --config-file=$DIR/.OwlBot.yaml \ + --source-dir /bazel-bin --dest /repo +done + +echo "Run owlbot post processing for all generated files" + +docker pull $IMAGE +docker run --user $(id -u):$(id -g) --rm -v $(pwd):/repo -w /repo $IMAGE