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

introduce gRPC logging support #217

Merged
merged 5 commits into from
Oct 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"james-heinrich/getid3": "^1.9",
"erusev/parsedown": "^1.6",
"vierbergenlars/php-semver": "^3.0",
"google/proto-client-php": "^0.4",
"google/proto-client-php": "^0.5",
"google/gax": "^0.3"
},
"suggest": {
Expand Down
74 changes: 74 additions & 0 deletions src/ArrayTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
/**
* Copyright 2016 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;

/**
* Provides basic array helper methods.
*/
trait ArrayTrait
{
/**
* Pluck a value out of an array.
*
* @param string $key
* @param array $arr
* @return string
* @throws \InvalidArgumentException
*/
private function pluck($key, array &$arr)
{
if (!isset($arr[$key])) {
throw new \InvalidArgumentException(
"Key $key does not exist in the provided array."
);
}

$value = $arr[$key];
unset($arr[$key]);
return $value;
}

/**
* Pluck a subset of an array.
*
* @param string $keys
* @param array $arr
* @return string
*/
private function pluckArray(array $keys, &$arr)
{
$values = [];

foreach ($keys as $key) {
$values[$key] = $this->pluck($key, $arr);
}

return $values;
}

/**
* Determine whether given array is associative.
*
* @param array $arr
* @return bool
*/
private function isAssoc(array $arr)
{
return array_keys($arr) !== range(0, count($arr) - 1);
}
}
14 changes: 0 additions & 14 deletions src/Datastore/DatastoreTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@

namespace Google\Cloud\Datastore;

use InvalidArgumentException;
use Psr\Http\Message\StreamInterface;

/**
* Utility methods for data formatting.
*/
Expand All @@ -39,15 +36,4 @@ private function partitionId($projectId, $namespaceId)
'namespaceId' => $namespaceId
]);
}

/**
* Determine whether given array is associative
*
* @param array $value
* @return bool
*/
private function isAssoc(array $value)
{
return array_keys($value) !== range(0, count($value) - 1);
}
}
2 changes: 2 additions & 0 deletions src/Datastore/EntityMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace Google\Cloud\Datastore;

use Google\Cloud\ArrayTrait;
use Google\Cloud\Datastore\Entity;
use Google\Cloud\Datastore\GeoPoint;
use Google\Cloud\Datastore\Key;
Expand All @@ -28,6 +29,7 @@
*/
class EntityMapper
{
use ArrayTrait;
use DatastoreTrait;

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Datastore/Key.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace Google\Cloud\Datastore;

use Google\Cloud\ArrayTrait;
use InvalidArgumentException;
use JsonSerializable;

Expand Down Expand Up @@ -75,6 +76,7 @@
*/
class Key implements JsonSerializable
{
use ArrayTrait;
use DatastoreTrait;

const TYPE_NAME = 'name';
Expand Down
2 changes: 2 additions & 0 deletions src/Datastore/Query/GqlQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace Google\Cloud\Datastore\Query;

use Google\Cloud\ArrayTrait;
use Google\Cloud\Datastore\DatastoreTrait;
use Google\Cloud\Datastore\EntityMapper;
use InvalidArgumentException;
Expand Down Expand Up @@ -72,6 +73,7 @@
*/
class GqlQuery implements QueryInterface
{
use ArrayTrait;
use DatastoreTrait;

const BINDING_NAMED = 'namedBindings';
Expand Down
15 changes: 11 additions & 4 deletions src/GrpcRequestWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace Google\Cloud;

use DrSlump\Protobuf\Codec\CodecInterface;
use DrSlump\Protobuf\Message;
use Google\Auth\FetchAuthTokenInterface;
use Google\Auth\HttpHandler\HttpHandlerFactory;
Expand All @@ -41,6 +42,11 @@ class GrpcRequestWrapper
*/
private $authHttpHandler;

/**
* @var CodecInterface A codec used to encode responses.
*/
private $codec;

/**
* @var array gRPC specific configuration options passed off to the GAX
* library.
Expand All @@ -65,6 +71,7 @@ class GrpcRequestWrapper
*
* @type callable $authHttpHandler A handler used to deliver Psr7
* requests specifically for authentication.
* @type CodecInterface $codec A codec used to encode responses.
* @type array $grpcOptions gRPC specific configuration options passed
* off to the GAX library.
* }
Expand All @@ -74,10 +81,12 @@ public function __construct(array $config = [])
$this->setCommonDefaults($config);
$config += [
'authHttpHandler' => null,
'codec' => new PhpArray(),
'grpcOptions' => []
];

$this->authHttpHandler = $config['authHttpHandler'] ?: HttpHandlerFactory::build();
$this->codec = $config['codec'];
$this->grpcOptions = $config['grpcOptions'];
}

Expand Down Expand Up @@ -132,13 +141,11 @@ public function send(callable $request, array $args, array $options = [])
private function handleResponse($response)
{
if ($response instanceof PagedListResponse) {
return $response->getPage()
->getResponseObject()
->serialize(new PhpArray());
$response = $response->getPage()->getResponseObject();
}

if ($response instanceof Message) {
return $response->serialize(new PhpArray());
return $response->serialize($this->codec);
}

return null;
Expand Down
128 changes: 117 additions & 11 deletions src/GrpcTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,21 @@

namespace Google\Cloud;

use DateTime;
use DateTimeZone;
use Google\Auth\FetchAuthTokenCache;
use Google\Auth\Cache\MemoryCacheItemPool;
use Google\Cloud\ArrayTrait;
use Google\Cloud\GrpcRequestWrapper;
use Google\Cloud\ServiceBuilder;

/**
* Provides shared functionality for gRPC service implementations.
*/
trait GrpcTrait
{
use ArrayTrait;

/**
* @var GrpcRequestWrapper Wrapper used to handle sending requests to the
* gRPC API.
Expand Down Expand Up @@ -58,22 +66,120 @@ public function send(callable $request, array $args)
}

/**
* Pluck a value out of an array.
* Gets the default configuration for generated GAX clients.
*
* @param string $key
* @param array $args
* @return array
*/
private function getGaxConfig()
{
return [
'credentialsLoader' => new FetchAuthTokenCache(
$this->requestWrapper->getCredentialsFetcher(),
null,
new MemoryCacheItemPool()
),
'enableCaching' => false,
'appName' => 'gcloud-php',
'version' => ServiceBuilder::VERSION
];
}

/**
* Format a gRPC timestamp to match the format returned by the REST API.
*
* @param array $timestamp
* @return string
*/
public function pluck($key, array &$args)
private function formatTimestampFromApi(array $timestamp)
{
$formattedTime = (new DateTime())
->setTimeZone(new DateTimeZone('UTC'))
->setTimestamp($timestamp['seconds'])
->format('Y-m-d\TH:i:s');
return $formattedTime .= sprintf('.%sZ', rtrim($timestamp['nanos'], '0'));
}

/**
* Format a set of labels for the API.
*
* @param array $labels
* @return array
*/
private function formatLabelsForApi(array $labels)
{
if (!isset($args[$key])) {
throw new \InvalidArgumentException(
"Key $key does not exist in the provided array."
);
$fLabels = [];

foreach ($labels as $key => $value) {
$fLabels[] = [
'key' => $key,
'value' => $value
];
}

$value = $args[$key];
unset($args[$key]);
return $value;
return $fLabels;
}

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

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

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

/**
* 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 array $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 'array':
if ($this->isAssoc($value)) {
return ['struct_value' => $this->formatStructForApi($value)];
}

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