Skip to content

Commit

Permalink
feat: add universe domain environment variable to core, bigquery, and…
Browse files Browse the repository at this point in the history
… storage
  • Loading branch information
bshaffer committed Feb 15, 2024
1 parent 1e35432 commit 95288ca
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 40 deletions.
2 changes: 1 addition & 1 deletion BigQuery/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"minimum-stability": "stable",
"require": {
"php": ">=7.4",
"google/cloud-core": "^1.53",
"google/cloud-core": "^1.55",
"ramsey/uuid": "^3.0|^4.0"
},
"require-dev": {
Expand Down
5 changes: 4 additions & 1 deletion BigQuery/src/Connection/Rest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ public function __construct(array $config = [])
'serviceDefinitionPath' => __DIR__ . '/ServiceDefinition/bigquery-v2.json',
'componentVersion' => BigQueryClient::VERSION,
'apiEndpoint' => null,
'universeDomain' => GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN,
// If the user has not supplied a universe domain, use the environment variable if set.
// Otherwise, use the default ("googleapis.com").
'universeDomain' => getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN')
?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN,
];

$apiEndpoint = $this->getApiEndpoint(null, $config, self::DEFAULT_API_ENDPOINT_TEMPLATE);
Expand Down
47 changes: 31 additions & 16 deletions BigQuery/tests/Unit/Connection/RestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,49 @@ public function setUp(): void
}

/**
* @dataProvider clientUniverseDomainConfigProvider
* @dataProvider provideApiEndpointForUniverseDomain
*/
public function testApiEndpointForUniverseDomain($config, $expectedEndpoint, $expectException = false)
{
if ($expectException) {
$this->expectException(UnexpectedValueException::class);
public function testApiEndpointForUniverseDomain(
array $config,
string $expectedEndpoint,
string $envUniverse = null,
) {
if ($envUniverse) {
putenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN=' . $envUniverse);
}
$rest = TestHelpers::stub(Rest::class, [$config], ['requestBuilder']);
$rest = new Rest($config);

$rb = $rest->___getProperty('requestBuilder');
$r = new \ReflectionObject($rb);
$p = $r->getProperty('baseUri');
$r = new \ReflectionClass($rest);
$p = $r->getProperty('apiEndpoint');
$p->setAccessible(true);

$this->assertEquals($expectedEndpoint, $p->getValue($rb));
if ($envUniverse) {
putenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN');
}

$this->assertEquals($expectedEndpoint, $p->getValue($rest));
}

public function clientUniverseDomainConfigProvider()
public function provideApiEndpointForUniverseDomain()
{
return [
[[], 'https://bigquery.googleapis.com/bigquery/v2/'], // default
[['apiEndpoint' => 'https://foobar.com'], 'https://foobar.com/bigquery/v2/'],
[['universeDomain' => 'googleapis.com'], 'https://bigquery.googleapis.com/bigquery/v2/'],
[['universeDomain' => 'abc.def.ghi'], 'https://bigquery.abc.def.ghi/bigquery/v2/'],
[['universeDomain' => null], '', true],
[[], 'https://bigquery.googleapis.com/'], // default
[['apiEndpoint' => 'https://foobar.com'], 'https://foobar.com/'],
[['universeDomain' => 'googleapis.com'], 'https://bigquery.googleapis.com/'],
[['universeDomain' => 'abc.def.ghi'], 'https://bigquery.abc.def.ghi/'],
[[], 'https://bigquery.abc.def.ghi/', 'abc.def.ghi'],
[['universeDomain' => 'googleapis.com'], 'https://bigquery.googleapis.com/', 'abc.def.ghi'],
];
}

public function testApiEndpointForUniverseDomainThrowsException()
{
$this->expectException(UnexpectedValueException::class);
$this->expectExceptionMessage('The "universeDomain" config value must be set to use the default API endpoint template.');

new Rest(['universeDomain' => null]);
}

/**
* @dataProvider methodProvider
*/
Expand Down
6 changes: 5 additions & 1 deletion Core/src/GrpcTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ private function getGaxConfig(
$config['credentials'] = new CredentialsWrapper(
$this->requestWrapper->getCredentialsFetcher(),
$authHttpHandler,
$universeDomain ?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN
// If the universe domain hasn't been explicitly set, check the the environment variable,
// otherwise assume GDU ("googleapis.com").
$universeDomain
?: getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN')
?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN
);
} else {
$config += [
Expand Down
3 changes: 0 additions & 3 deletions Core/src/RequestWrapperTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ trait RequestWrapperTrait
*/
private $quotaProject;

private string $universeDomain;
private bool $hasCheckedUniverse = false;

/**
* Sets common defaults between request wrappers.
*
Expand Down
53 changes: 53 additions & 0 deletions Core/tests/Unit/GrpcTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use UnexpectedValueException;

/**
* @group core
Expand Down Expand Up @@ -196,10 +197,62 @@ function () {
);
}

/**
* @dataProvider provideGetGaxConfig
*/
public function testUniverseDomainFromGaxConfig(
?string $universeDomain,
string $expectedUniverseDomain,
string $envUniverse = null
) {
if ($envUniverse) {
putenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN=' . $envUniverse);
}

$fetcher = $this->prophesize(FetchAuthTokenInterface::class)->reveal();
$this->requestWrapper->getCredentialsFetcher()->willReturn($fetcher);

$impl = new GrpcTraitImpl();
$impl->setRequestWrapper($this->requestWrapper->reveal());

$config = $impl->getGaxConfig('1.2.3', null, $universeDomain);
$refl = new \ReflectionClass($config['credentials']);
$prop = $refl->getProperty('universeDomain');
$prop->setAccessible(true);
$universeDomain = $prop->getValue($config['credentials']);

if ($envUniverse) {
// We have to do this instead of using "@runInSeparateProcess" because in the case of
// an error, PHPUnit throws a "Serialization of 'ReflectionClass' is not allowed" error.
// @TODO: Remove this once we've updated to PHPUnit 10.
putenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN');
}

$this->assertEquals($expectedUniverseDomain, $universeDomain);
}

public function provideGetGaxConfig()
{
return [
[null, 'googleapis.com'], // default
['ab.cd', 'ab.cd'], // explicitly set
[null, 'ab.cd', 'ab.cd'], // from env var
['googleapis.com', 'googleapis.com', 'ab.cd'], // explicitly set takes priority over env var
];
}

private function noop()
{
return function () {
return;
};
}
}

class GrpcTraitImpl
{
use GrpcTrait {
getGaxConfig as public;
}
}

2 changes: 1 addition & 1 deletion Storage/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"minimum-stability": "stable",
"require": {
"php": ">=7.4",
"google/cloud-core": "^1.53",
"google/cloud-core": "^1.55",
"ramsey/uuid": "^4.2.3"
},
"require-dev": {
Expand Down
5 changes: 4 additions & 1 deletion Storage/src/Connection/Rest.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ public function __construct(array $config = [])
'serviceDefinitionPath' => __DIR__ . '/ServiceDefinition/storage-v1.json',
'componentVersion' => StorageClient::VERSION,
'apiEndpoint' => null,
'universeDomain' => GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN,
// If the user has not supplied a universe domain, use the environment variable if set.
// Otherwise, use the default ("googleapis.com").
'universeDomain' => getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN')
?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN,
// Cloud Storage needs to provide a default scope because the Storage
// API does not accept JWTs with "audience"
'scopes' => StorageClient::FULL_CONTROL_SCOPE,
Expand Down
47 changes: 31 additions & 16 deletions Storage/tests/Unit/Connection/RestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,34 +62,49 @@ public function setUp(): void
}

/**
* @dataProvider clientUniverseDomainConfigProvider
* @dataProvider provideApiEndpointForUniverseDomain
*/
public function testApiEndpointForUniverseDomain($config, $expectedEndpoint, $expectException = false)
{
if ($expectException) {
$this->expectException(UnexpectedValueException::class);
public function testApiEndpointForUniverseDomain(
array $config,
string $expectedEndpoint,
string $envUniverse = null,
) {
if ($envUniverse) {
putenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN=' . $envUniverse);
}
$rest = TestHelpers::stub(Rest::class, [$config], ['requestBuilder']);
$rest = new Rest($config);

$rb = $rest->___getProperty('requestBuilder');
$r = new \ReflectionObject($rb);
$p = $r->getProperty('baseUri');
$r = new \ReflectionClass($rest);
$p = $r->getProperty('apiEndpoint');
$p->setAccessible(true);

$this->assertEquals($expectedEndpoint, $p->getValue($rb));
if ($envUniverse) {
putenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN');
}

$this->assertEquals($expectedEndpoint, $p->getValue($rest));
}

public function clientUniverseDomainConfigProvider()
public function provideApiEndpointForUniverseDomain()
{
return [
[[], 'https://storage.googleapis.com/storage/v1/'], // default
[['apiEndpoint' => 'https://foobar.com'], 'https://foobar.com/storage/v1/'],
[['universeDomain' => 'googleapis.com'], 'https://storage.googleapis.com/storage/v1/'],
[['universeDomain' => 'abc.def.ghi'], 'https://storage.abc.def.ghi/storage/v1/'],
[['universeDomain' => null], '', true],
[[], 'https://storage.googleapis.com/'], // default
[['apiEndpoint' => 'https://foobar.com'], 'https://foobar.com/'],
[['universeDomain' => 'googleapis.com'], 'https://storage.googleapis.com/'],
[['universeDomain' => 'abc.def.ghi'], 'https://storage.abc.def.ghi/'],
[[], 'https://storage.abc.def.ghi/', 'abc.def.ghi'],
[['universeDomain' => 'googleapis.com'], 'https://storage.googleapis.com/', 'abc.def.ghi'],
];
}

public function testApiEndpointForUniverseDomainThrowsException()
{
$this->expectException(UnexpectedValueException::class);
$this->expectExceptionMessage('The "universeDomain" config value must be set to use the default API endpoint template.');

new Rest(['universeDomain' => null]);
}

/**
* @dataProvider methodProvider
* @todo revisit this approach
Expand Down

0 comments on commit 95288ca

Please sign in to comment.