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 Handwritten Bigtable Client #1392

Merged
merged 15 commits into from
Nov 5, 2018
Merged
Show file tree
Hide file tree
Changes from 14 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
31 changes: 21 additions & 10 deletions Bigtable/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,39 @@ $ composer require google/cloud
This component supports both REST over HTTP/1.1 and gRPC. In order to take advantage of the benefits offered by gRPC (such as streaming methods)
please see our [gRPC installation guide](https://cloud.google.com/php/grpc).

### Notable Client Differences

The handwritten client offered by this package differs from the others in `google-cloud-php` in that it more directly wraps our generated clients.
This means some of the idioms and configuration options you are used to may differ slightly. The most notable differences are outlined below:

- A key file is now provided through the `credentials` configuration option as opposed to either `keyFile` or `keyFilePath`.
- There is now more granular control over retry logic. Please see [the `bigtable_client_config.json` file](https://github.com/googleapis/google-cloud-php/blob/master/Bigtable/src/V2/resources/bigtable_client_config.json)
for an example of the configuration which can be passed into the client at construction time.
- Exceptions triggered at the network level utilize the base class `Google\ApiCore\ApiException` as opposed to `Google\Cloud\Core\ServiceException`.
- The `authHttpHandler` and `httpHandler` client configuration options are now provided through `$credentialsConfig['authHttpHandler']`
and `$transportConfig['httpHandler']`, respectively. Additionally, please note the `httpHandler` should now return an implementation of [Guzzle's `PromiseInterface`](https://github.com/guzzle/promises/blob/master/src/PromiseInterface.php).

### Authentication

Please see our [Authentication guide](https://github.com/GoogleCloudPlatform/google-cloud-php/blob/master/AUTHENTICATION.md) for more information
on authenticating your client. Once authenticated, you'll be ready to start making requests.

When going through the authentication guide, please take note that the handwritten client for this package will more closely follow the conventions
outlined for the generated clients.

### Sample

```php
require 'vendor/autoload.php';

use Google\Cloud\Bigtable\V2\BigtableClient;
use Google\Cloud\Bigtable\BigtableClient;

$bigtableClient = new BigtableClient();
$formattedTableName = $bigtableClient->tableName('[PROJECT]', '[INSTANCE]', '[TABLE]');
$bigtable = new BigtableClient();
$table = $bigtable->table('my-instance', 'my-table');
$rows = $table->readRows();

try {
$stream = $bigtableClient->readRows($formattedTableName);
foreach ($stream->readAll() as $element) {
// doSomethingWith($element);
}
} finally {
$bigtableClient->close();
foreach ($rows as $row) {
print_r($row) . PHP_EOL;
}
```

Expand Down
16 changes: 16 additions & 0 deletions Bigtable/phpunit-conformance.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true">
<testsuites>
<testsuite>
<directory>tests/Conformance</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
<exclude>
<directory suffix=".php">src/V[!a-zA-Z]*</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
175 changes: 175 additions & 0 deletions Bigtable/src/BigtableClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php
/**
* Copyright 2018, Google LLC 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\Bigtable;

use Google\ApiCore\CredentialsWrapper;
use Google\ApiCore\Transport\TransportInterface;
use Google\ApiCore\ValidationException;
use Google\Auth\FetchAuthTokenInterface;
use Google\Cloud\Bigtable\V2\BigtableClient as GapicClient;
use Google\Cloud\Core\ArrayTrait;

/**
* Google Cloud Bigtable is Google's NoSQL Big Data database service.
* Find more information at the
* [Google Cloud Bigtable Docs](https://cloud.google.com/bigtable/docs/).
*
* Example:
* ```
* use Google\Cloud\Bigtable\BigtableClient;
*
* $bigtable = new BigtableClient();
* ```
*/
class BigtableClient
{
use ArrayTrait;

const VERSION = '0.5.3';

/**
* @var GapicClient
*/
private $gapicClient;

/**
* @var string
*/
private $projectId;

/**
* Create a Bigtable client.
*
* @param array $config [optional] {
* Configuration options.
*
* @type string $projectId The project ID from the Google Developer's
* Console.
* @type string $serviceAddress The address of the API remote host. May
* optionally include the port, formatted as "<uri>:<port>".
* **Defaults to** 'bigtable.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
* $config['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}.
* @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.
* @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
* $config['transportConfig'] and the $config['serviceAddress']
* 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 `build` method on {@see Google\ApiCore\Transport\GrpcTransport}
* and {@see Google\ApiCore\Transport\RestTransport} for the
* supported options.
* }
* @throws ValidationException
*/
public function __construct(array $config = [])
{
if (!isset($config['transportConfig']['grpc']['stubOpts'])) {
$config['transportConfig']['grpc']['stubOpts'] = [];
}

// Workaround for large messages.
$config['transportConfig']['grpc']['stubOpts'] += [
'grpc.max_send_message_length' => -1,
'grpc.max_receive_message_length' => -1
];

$this->projectId = $this->pluck('projectId', $config, false)
?: $this->detectProjectId();
$this->gapicClient = new GapicClient($config);
}

/**
* Returns a table instance which can be used to read rows and to perform
* insert, update, and delete operations.
*
* Example:
* ```
* $table = $bigtable->table('my-instance', 'my-table');
* ```
*
* @param string $instanceId The instance ID.
* @param string $tableId The table ID.
* @param array $options [optional] {
* Configuration options.
*
* @type string $appProfileId This value specifies routing for
* replication. **Defaults to** the "default" application profile.
* @type array $headers Headers to be passed with each request.
* }
* @return Table
*/
public function table($instanceId, $tableId, array $options = [])
{
return new Table(
$this->gapicClient,
GapicClient::tableName($this->projectId, $instanceId, $tableId),
$options
);
}

/**
* Attempts to detect the project ID.
*
* @todo Add better support for detecting the project ID (check keyFile/GCE metadata server).
* @return string
* @throws ValidationException If a project ID cannot be detected.
*/
private function detectProjectId()
{
if (getenv('GOOGLE_CLOUD_PROJECT')) {
return getenv('GOOGLE_CLOUD_PROJECT');
}

if (getenv('GCLOUD_PROJECT')) {
return getenv('GCLOUD_PROJECT');
}

throw new ValidationException(
'No project ID was provided, ' .
'and we were unable to detect a default project ID.'
);
}
}
Loading