Skip to content
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(Core): add RequestHandler and supporting classes #6871

Merged
merged 25 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ef252d7
feat: Add request handler and a GapicRequestWrapper (#6807)
saranshdhingra Dec 13, 2023
f1cec73
Added tests for ApiHelpersTrait
saranshdhingra Dec 13, 2023
7a09351
Marked the classes as internal
saranshdhingra Dec 13, 2023
510b562
Added missed use statements
saranshdhingra Dec 13, 2023
739ac5c
Update RequestHandler to accept only GAPIC classes and not objects
saranshdhingra Dec 18, 2023
4e2fcb7
Fix lint issues
saranshdhingra Dec 19, 2023
3597b40
Addressed PR comments
saranshdhingra Jan 2, 2024
7b639be
Fixed Unit tests for the latest changes
saranshdhingra Jan 2, 2024
ec21e82
Fixed return type for constructGapic
saranshdhingra Jan 2, 2024
be3a5b0
Removed setSerialzer from RequestHandler
saranshdhingra Jan 2, 2024
8eef4dd
Removed mixed type declerations
saranshdhingra Jan 2, 2024
33fd1ec
Removed mixed types from argument declerations
saranshdhingra Jan 2, 2024
7e32839
Merged RequestHandler and RequestCallerTrait
saranshdhingra Jan 3, 2024
4a9c090
Removed incompatible changes in ApiHelpersTrait
saranshdhingra Jan 8, 2024
4a9d03c
Removed getSerializer from RequestHandler
saranshdhingra Jan 8, 2024
d7a1c85
Removed trailing comas
saranshdhingra Jan 8, 2024
04ed254
Merged RequestHandler and GapicRequestWrapper
saranshdhingra Jan 16, 2024
a046bb6
Fixed tests
saranshdhingra Jan 16, 2024
85a088a
Fixed segmentation faults in tests with protobuf enabled
saranshdhingra Jan 22, 2024
c72ae30
Removed calls to reveal() in RequestHandler
saranshdhingra Jan 22, 2024
c394634
Merge branch 'main' into add-request-handler
saranshdhingra Jan 22, 2024
4147a9d
Added client related changes
saranshdhingra Jan 24, 2024
265fbc0
Updated version for gax in Core
saranshdhingra Jan 24, 2024
4806e22
Addressed PR comments
saranshdhingra Jan 26, 2024
8aaa1da
Marked the RequestProcessorTrait as internal
saranshdhingra Jan 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
225 changes: 225 additions & 0 deletions Core/src/ApiHelperTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
<?php

/**
* Copyright 2023 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Google\Cloud\Core;

use Google\Protobuf\NullValue;
use Google\Cloud\Core\Duration;

/**
* @internal
* Supplies helper methods to interact with the APIs.
*/
trait ApiHelperTrait
{
use ArrayTrait;
use TimeTrait;

/**
* Format a struct for the API.
*
* @param array $fields
* @return array
*/
private function formatStructForApi(array $fields)
{
$fFields = [];

foreach ($fields as $key => $value) {
$fFields[$key] = $this->formatValueForApi($value);
}

return ['fields' => $fFields];
}

private function unpackStructFromApi(array $struct)
{
$vals = [];
foreach ($struct['fields'] as $key => $val) {
$vals[$key] = $this->unpackValue($val);
}
return $vals;
}

private function unpackValue($value)
{
if (count($value) > 1) {
throw new \RuntimeException("Unexpected fields in struct: $value");
}

foreach ($value as $setField => $setValue) {
switch ($setField) {
case 'listValue':
$valueList = [];
foreach ($setValue['values'] as $innerValue) {
$valueList[] = $this->unpackValue($innerValue);
}
return $valueList;
case 'structValue':
return $this->unpackStructFromApi($value['structValue']);
default:
return $setValue;
}
}
}

private function flattenStruct(array $struct)
{
return $struct['fields'];
}

private function flattenValue(array $value)
{
if (count($value) > 1) {
throw new \RuntimeException("Unexpected fields in struct: $value");
}

if (isset($value['nullValue'])) {
return null;
}

return array_pop($value);
}

private function flattenListValue(array $value)
{
return $value['values'];
}

/**
* Format a list for the API.
*
* @param array $list
* @return array
*/
private function formatListForApi(array $list)
{
$values = [];

foreach ($list as $value) {
$values[] = $this->formatValueForApi($value);
}

return ['values' => $values];
}

/**
* Format a value for the API.
*
* @param mixed $value
* @return array
*/
private function formatValueForApi($value)
{
$type = gettype($value);

switch ($type) {
case 'string':
return ['string_value' => $value];
case 'double':
case 'integer':
return ['number_value' => $value];
case 'boolean':
return ['bool_value' => $value];
case 'NULL':
return ['null_value' => NullValue::NULL_VALUE];
case 'array':
if (!empty($value) && $this->isAssoc($value)) {
return ['struct_value' => $this->formatStructForApi($value)];
}

return ['list_value' => $this->formatListForApi($value)];
}

return [];
}

/**
* Format a gRPC timestamp to match the format returned by the REST API.
*
* @param array $timestamp
* @return string
*/
private function formatTimestampFromApi(array $timestamp)
{
$timestamp += [
'seconds' => 0,
'nanos' => 0
];

$dt = $this->createDateTimeFromSeconds($timestamp['seconds']);

return $this->formatTimeAsString($dt, $timestamp['nanos']);
}

/**
* Format a timestamp for the API with nanosecond precision.
*
* @param string $value
* @return array
*/
private function formatTimestampForApi($value)
{
list ($dt, $nanos) = $this->parseTimeString($value);

return [
'seconds' => (int) $dt->format('U'),
'nanos' => (int) $nanos
];
}

/**
* Format a duration for the API.
*
* @param string|mixed $value
* @return array
*/
private function formatDurationForApi($value) : array

Check failure on line 191 in Core/src/ApiHelperTrait.php

View workflow job for this annotation

GitHub Actions / backwards-compatibility-check

The return type of Google\Cloud\Core\GrpcTrait#formatDurationForApi() changed from no type to array
saranshdhingra marked this conversation as resolved.
Show resolved Hide resolved
{
if (is_string($value)) {
$d = explode('.', trim($value, 's'));
if (count($d) < 2) {
$seconds = $d[0];
$nanos = 0;
} else {
$seconds = (int) $d[0];
$nanos = $this->convertFractionToNanoSeconds($d[1]);
}
} elseif ($value instanceof Duration) {
$d = $value->get();
$seconds = $d['seconds'];
$nanos = $d['nanos'];
}

return [
'seconds' => $seconds,
'nanos' => $nanos
];
}

/**
* Construct a gapic client. Allows for tests to intercept.
*
* @param string $gapicName
* @param array $config
* @return mixed
*/
protected function constructGapic(string $gapicName, array $config)

Check failure on line 221 in Core/src/ApiHelperTrait.php

View workflow job for this annotation

GitHub Actions / backwards-compatibility-check

The parameter $gapicName of Google\Cloud\Core\GrpcTrait#constructGapic() changed from no type to a non-contravariant string

Check failure on line 221 in Core/src/ApiHelperTrait.php

View workflow job for this annotation

GitHub Actions / backwards-compatibility-check

The parameter $gapicName of Google\Cloud\Core\GrpcTrait#constructGapic() changed from no type to string
{
return new $gapicName($config);
}
}
Loading
Loading