-
Notifications
You must be signed in to change notification settings - Fork 438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support customer managed instance configurations #5523
Changes from all commits
3c4275f
80b646f
e137583
2dd8290
d72866b
f65ea62
56aa92e
68b4301
9715cc6
4a60e5d
0cf42b0
e843239
077f21c
3b78a7a
91d1c73
80b4e14
236b612
6879a40
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,9 +36,12 @@ | |
use Google\Cloud\Spanner\Admin\Database\V1\RestoreDatabaseEncryptionConfig; | ||
use Google\Cloud\Spanner\Admin\Database\V1\RestoreDatabaseMetadata; | ||
use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseDdlMetadata; | ||
use Google\Cloud\Spanner\Admin\Instance\V1\CreateInstanceConfigMetadata; | ||
use Google\Cloud\Spanner\Admin\Instance\V1\CreateInstanceMetadata; | ||
use Google\Cloud\Spanner\Admin\Instance\V1\Instance; | ||
use Google\Cloud\Spanner\Admin\Instance\V1\InstanceAdminClient; | ||
use Google\Cloud\Spanner\Admin\Instance\V1\InstanceConfig; | ||
use Google\Cloud\Spanner\Admin\Instance\V1\UpdateInstanceConfigMetadata; | ||
use Google\Cloud\Spanner\Admin\Instance\V1\UpdateInstanceMetadata; | ||
use Google\Cloud\Spanner\Operation; | ||
use Google\Cloud\Spanner\SpannerClient as ManualSpannerClient; | ||
|
@@ -131,6 +134,14 @@ class Grpc implements ConnectionInterface | |
'method' => 'createDatabase', | ||
'typeUrl' => 'type.googleapis.com/google.spanner.admin.database.v1.CreateDatabaseMetadata', | ||
'message' => CreateDatabaseMetadata::class | ||
], [ | ||
'method' => 'createInstanceConfig', | ||
'typeUrl' => 'type.googleapis.com/google.spanner.admin.instance.v1.CreateInstanceConfigMetadata', | ||
'message' => CreateInstanceConfigMetadata::class | ||
], [ | ||
'method' => 'updateInstanceConfig', | ||
'typeUrl' => 'type.googleapis.com/google.spanner.admin.instance.v1.UpdateInstanceConfigMetadata', | ||
'message' => UpdateInstanceConfigMetadata::class | ||
], [ | ||
'method' => 'createInstance', | ||
'typeUrl' => 'type.googleapis.com/google.spanner.admin.instance.v1.CreateInstanceMetadata', | ||
|
@@ -163,6 +174,14 @@ class Grpc implements ConnectionInterface | |
'method' => 'createDatabase', | ||
'typeUrl' => 'type.googleapis.com/google.spanner.admin.database.v1.Database', | ||
'message' => Database::class | ||
], [ | ||
'method' => 'createInstanceConfig', | ||
'typeUrl' => 'type.googleapis.com/google.spanner.admin.instance.v1.InstanceConfig', | ||
'message' => InstanceConfig::class | ||
], [ | ||
'method' => 'updateInstanceConfig', | ||
'typeUrl' => 'type.googleapis.com/google.spanner.admin.instance.v1.InstanceConfig', | ||
'message' => InstanceConfig::class | ||
], [ | ||
'method' => 'createInstance', | ||
'typeUrl' => 'type.googleapis.com/google.spanner.admin.instance.v1.Instance', | ||
|
@@ -275,6 +294,74 @@ public function getInstanceConfig(array $args) | |
]); | ||
} | ||
|
||
/** | ||
* @param array $args | ||
*/ | ||
public function createInstanceConfig(array $args) | ||
{ | ||
$instanceConfigName = $args['name']; | ||
|
||
$instanceConfig = $this->instanceConfigObject($args, true); | ||
$res = $this->send([$this->getInstanceAdminClient(), 'createInstanceConfig'], [ | ||
$this->pluck('projectName', $args), | ||
$this->pluck('instanceConfigId', $args), | ||
$instanceConfig, | ||
$this->addResourcePrefixHeader($args, $instanceConfigName) | ||
]); | ||
|
||
return $this->operationToArray($res, $this->serializer, $this->lroResponseMappers); | ||
} | ||
|
||
/** | ||
* @param array $args | ||
*/ | ||
public function updateInstanceConfig(array $args) | ||
{ | ||
$instanceConfigName = $args['name']; | ||
|
||
$instanceConfigArray = $this->instanceConfigArray($args); | ||
|
||
$fieldMask = $this->fieldMask($instanceConfigArray); | ||
|
||
$instanceConfigObject = $this->serializer->decodeMessage(new InstanceConfig(), $instanceConfigArray); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because:
This function is following the same structure as the existing method for |
||
|
||
$res = $this->send([$this->getInstanceAdminClient(), 'updateInstanceConfig'], [ | ||
$instanceConfigObject, | ||
$fieldMask, | ||
$this->addResourcePrefixHeader($args, $instanceConfigName) | ||
]); | ||
|
||
return $this->operationToArray($res, $this->serializer, $this->lroResponseMappers); | ||
} | ||
|
||
/** | ||
* @param array $args | ||
*/ | ||
public function deleteInstanceConfig(array $args) | ||
{ | ||
$instanceConfigName = $this->pluck('name', $args); | ||
return $this->send([$this->getInstanceAdminClient(), 'deleteInstanceConfig'], [ | ||
$instanceConfigName, | ||
$this->addResourcePrefixHeader($args, $instanceConfigName) | ||
]); | ||
} | ||
|
||
/** | ||
* @param array $args | ||
*/ | ||
public function listInstanceConfigOperations(array $args) | ||
{ | ||
$projectName = $this->pluck('projectName', $args); | ||
$result = $this->send([$this->getInstanceAdminClient(), 'listInstanceConfigOperations'], [ | ||
$projectName, | ||
$this->addResourcePrefixHeader($args, $projectName) | ||
]); | ||
foreach ($result['operations'] as $index => $operation) { | ||
$result['operations'][$index] = $this->deserializeOperationArray($operation); | ||
} | ||
return $result; | ||
} | ||
|
||
/** | ||
* @param array $args | ||
*/ | ||
|
@@ -1227,6 +1314,45 @@ private function createTransactionSelector(array &$args) | |
return $selector; | ||
} | ||
|
||
/** | ||
* Converts a PHP array to an InstanceConfig proto message. | ||
* | ||
* @param array $args | ||
saranshdhingra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @param bool $required | ||
* @return InstanceConfig | ||
*/ | ||
private function instanceConfigObject(array &$args, $required = false) | ||
{ | ||
return $this->serializer->decodeMessage( | ||
new InstanceConfig(), | ||
$this->instanceConfigArray($args, $required) | ||
); | ||
} | ||
|
||
/** | ||
* Creates a PHP array with only the fields that are relevant for an InstanceConfig. | ||
* | ||
* @param array $args | ||
saranshdhingra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @param bool $required | ||
* @return array | ||
*/ | ||
private function instanceConfigArray(array &$args, $required = false) | ||
{ | ||
$argsCopy = $args; | ||
return array_intersect_key([ | ||
'name' => $this->pluck('name', $args, $required), | ||
'baseConfig' => $this->pluck('baseConfig', $args, $required), | ||
'displayName' => $this->pluck('displayName', $args, $required), | ||
'configType' => $this->pluck('configType', $args, $required), | ||
'replicas' => $this->pluck('replicas', $args, $required), | ||
'optionalReplicas' => $this->pluck('optionalReplicas', $args, $required), | ||
'leaderOptions' => $this->pluck('leaderOptions', $args, $required), | ||
'reconciling' => $this->pluck('reconciling', $args, $required), | ||
'state' => $this->pluck('state', $args, $required), | ||
'labels' => $this->pluck('labels', $args, $required), | ||
], $argsCopy); | ||
} | ||
|
||
/** | ||
* @param array $args | ||
* @param bool $required | ||
|
@@ -1276,7 +1402,9 @@ private function fieldMask($instanceArray) | |
{ | ||
$mask = []; | ||
foreach (array_keys($instanceArray) as $key) { | ||
$mask[] = Serializer::toSnakeCase($key); | ||
if ($key !== 'name') { | ||
$mask[] = Serializer::toSnakeCase($key); | ||
} | ||
} | ||
return $this->serializer->decodeMessage(new FieldMask(), ['paths' => $mask]); | ||
} | ||
|
@@ -1385,7 +1513,6 @@ private function getInstanceAdminClient() | |
return $this->instanceAdminClient; | ||
} | ||
//@codeCoverageIgnoreEnd | ||
|
||
$this->instanceAdminClient = $this->constructGapic(InstanceAdminClient::class, $this->grpcConfig); | ||
|
||
return $this->instanceAdminClient; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I found in local testing, I think the
name
key needs to be removed before sending it to thefieldMask
method.Let me know if you think that's not the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I've changed that.
Are there any plans for running the integration tests on real Cloud Spanner for PRs in this repository? Or is there any way that they can be kicked off manually? I guess that would have caught this earlier, as it is probably a case of making a small change after having executed all the integration tests, and then forgetting to run them all once more after this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The integration tests run as a continuous job but not on PRs.
You can test them manually by running
phpunit -c phpunit-system.xml.dist --verbose tests/System/AdminTest
.Optionally you could use the
--filter
argument if you don't want other tests to run. It accepts a regex.