From fe367bf30631a470be738370bc3cbcab9fff7c02 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 16 Jun 2026 11:53:15 -0700 Subject: [PATCH 1/2] chore(gax): upgrade to google/longrunning:v1, remove deprecated classes and methods --- Gax/composer.json | 2 +- Gax/src/AgentHeader.php | 4 +- Gax/src/ApiException.php | 2 + Gax/src/ApiKeyHeaderCredentials.php | 2 + Gax/src/ApiStatus.php | 2 + Gax/src/ArrayTrait.php | 2 + Gax/src/BidiStream.php | 2 + Gax/src/Call.php | 2 + Gax/src/ClientOptionsTrait.php | 2 + Gax/src/ClientStream.php | 2 + Gax/src/CredentialsWrapper.php | 20 +----- Gax/src/FixedSizeCollection.php | 2 + Gax/src/GPBLabel.php | 2 + Gax/src/GPBType.php | 2 + Gax/src/GapicClientTrait.php | 4 +- Gax/src/GrpcSupportTrait.php | 2 + Gax/src/HeaderCredentialsInterface.php | 2 + Gax/src/InsecureCredentialsWrapper.php | 2 + Gax/src/InsecureRequestBuilder.php | 1 + Gax/src/KnownTypes.php | 7 +- .../CredentialsWrapperMiddleware.php | 2 + Gax/src/Middleware/FixedHeaderMiddleware.php | 2 + Gax/src/Middleware/MiddlewareInterface.php | 2 + Gax/src/Middleware/OperationsMiddleware.php | 2 + .../Middleware/OptionsFilterMiddleware.php | 2 + Gax/src/Middleware/PagedMiddleware.php | 2 + .../RequestAutoPopulationMiddleware.php | 2 + .../Middleware/ResponseMetadataMiddleware.php | 2 + Gax/src/Middleware/RetryMiddleware.php | 6 +- .../Middleware/TransportCallMiddleware.php | 2 + Gax/src/OperationResponse.php | 2 + Gax/src/Options/CallOptions.php | 12 +--- Gax/src/Options/ClientOptions.php | 2 + Gax/src/Options/OptionsInterface.php | 2 + Gax/src/Options/OptionsTrait.php | 2 + Gax/src/Options/TransportOptions.php | 2 + .../GrpcFallbackTransportOptions.php | 2 + .../TransportOptions/GrpcTransportOptions.php | 15 ++-- .../TransportOptions/RestTransportOptions.php | 2 + Gax/src/Page.php | 2 + Gax/src/PageStreamingDescriptor.php | 2 + Gax/src/PagedListResponse.php | 2 + Gax/src/PathTemplate.php | 2 + Gax/src/PollingTrait.php | 4 +- Gax/src/RequestBuilder.php | 2 + Gax/src/RequestParamsHeaderDescriptor.php | 2 + Gax/src/ResourceHelperTrait.php | 2 + .../AbsoluteResourceTemplate.php | 2 + Gax/src/ResourceTemplate/Parser.php | 2 + .../RelativeResourceTemplate.php | 6 +- .../ResourceTemplateInterface.php | 2 + Gax/src/ResourceTemplate/Segment.php | 2 + Gax/src/RetrySettings.php | 2 + Gax/src/Serializer.php | 4 +- Gax/src/ServerStream.php | 2 + Gax/src/ServerStreamingCallInterface.php | 2 + Gax/src/ServiceAddressTrait.php | 64 ----------------- Gax/src/Testing/GeneratedTest.php | 2 + .../Testing/MessageAwareArrayComparator.php | 2 + Gax/src/Testing/MessageAwareExporter.php | 2 + Gax/src/Testing/MockBidiStreamingCall.php | 2 + Gax/src/Testing/MockClientStreamingCall.php | 2 + Gax/src/Testing/MockGrpcTransport.php | 2 + Gax/src/Testing/MockServerStreamingCall.php | 2 + Gax/src/Testing/MockStatus.php | 2 + Gax/src/Testing/MockStubTrait.php | 2 + Gax/src/Testing/MockTransport.php | 2 + Gax/src/Testing/MockUnaryCall.php | 2 + .../Testing/ProtobufGPBEmptyComparator.php | 2 + Gax/src/Testing/ProtobufMessageComparator.php | 2 + Gax/src/Testing/ReceivedRequest.php | 2 + Gax/src/Testing/SerializationTrait.php | 2 + Gax/src/Transport/Grpc/ForwardingCall.php | 2 + .../Grpc/ForwardingServerStreamingCall.php | 2 + .../Transport/Grpc/ForwardingUnaryCall.php | 2 + .../Grpc/ServerStreamingCallWrapper.php | 2 + .../Grpc/UnaryInterceptorInterface.php | 61 ---------------- Gax/src/Transport/GrpcFallbackTransport.php | 8 ++- Gax/src/Transport/GrpcTransport.php | 25 ++----- Gax/src/Transport/HttpUnaryTransportTrait.php | 2 + Gax/src/Transport/Rest/JsonStreamDecoder.php | 2 + .../Rest/RestServerStreamingCall.php | 2 + Gax/src/Transport/RestTransport.php | 8 ++- Gax/src/Transport/TransportInterface.php | 2 + Gax/src/UriTrait.php | 2 + Gax/src/ValidationException.php | 2 + Gax/src/ValidationTrait.php | 2 + Gax/src/Version.php | 2 + .../src/V1beta1/Client/ComplianceClient.php | 2 + .../src/V1beta1/Client/EchoClient.php | 2 + .../src/V1beta1/Client/IdentityClient.php | 2 + .../src/V1beta1/Client/MessagingClient.php | 2 + .../V1beta1/Client/SequenceServiceClient.php | 2 + .../src/V1beta1/Client/TestingClient.php | 2 + .../compliance_descriptor_config.php | 2 + .../compliance_rest_client_config.php | 2 + .../resources/echo_descriptor_config.php | 2 + .../resources/echo_rest_client_config.php | 2 + .../resources/identity_descriptor_config.php | 2 + .../resources/identity_rest_client_config.php | 2 + .../resources/messaging_descriptor_config.php | 2 + .../messaging_rest_client_config.php | 2 + .../sequence_service_descriptor_config.php | 2 + .../sequence_service_rest_client_config.php | 2 + .../resources/testing_descriptor_config.php | 2 + .../resources/testing_rest_client_config.php | 2 + Gax/tests/Unit/CredentialsWrapperTest.php | 61 ---------------- Gax/tests/Unit/GapicClientTraitTest.php | 18 ++--- .../Middleware/OperationsMiddlewareTest.php | 10 +-- Gax/tests/Unit/ServiceAddressTraitTest.php | 69 ------------------- .../testdata/mocks/src/GapicClientStub.php | 2 + 111 files changed, 244 insertions(+), 345 deletions(-) delete mode 100644 Gax/src/ServiceAddressTrait.php delete mode 100644 Gax/src/Transport/Grpc/UnaryInterceptorInterface.php delete mode 100644 Gax/tests/Unit/ServiceAddressTraitTest.php diff --git a/Gax/composer.json b/Gax/composer.json index f6869faa4e29..70d5eb81d15a 100644 --- a/Gax/composer.json +++ b/Gax/composer.json @@ -14,7 +14,7 @@ "guzzlehttp/promises": "^2.0", "guzzlehttp/psr7": "^2.0", "google/common-protos": "^4.4", - "google/longrunning": "~0.4", + "google/longrunning": "~0.4||^1.0", "ramsey/uuid": "^4.0" }, "require-dev": { diff --git a/Gax/src/AgentHeader.php b/Gax/src/AgentHeader.php index 4fda2b0e9a98..4754a9752fff 100644 --- a/Gax/src/AgentHeader.php +++ b/Gax/src/AgentHeader.php @@ -1,4 +1,6 @@ credentialsFetcher->getLastReceivedToken(); - if (self::isExpired($token)) { - $this->checkUniverseDomain(); - - $token = $this->credentialsFetcher->fetchAuthToken($this->authHttpHandler); - if (!self::isValid($token)) { - return ''; - } - } - return empty($token['access_token']) ? '' : 'Bearer ' . $token['access_token']; - } - /** * @param string $audience optional audience for self-signed JWTs. * @return callable Callable function that returns an authorization header. diff --git a/Gax/src/FixedSizeCollection.php b/Gax/src/FixedSizeCollection.php index 03ec835c1368..13d4f3219cc2 100644 --- a/Gax/src/FixedSizeCollection.php +++ b/Gax/src/FixedSizeCollection.php @@ -1,4 +1,6 @@ \Google\Rpc\RetryInfo::class, 'google.rpc.debuginfo-bin' => \Google\Rpc\DebugInfo::class, diff --git a/Gax/src/Middleware/CredentialsWrapperMiddleware.php b/Gax/src/Middleware/CredentialsWrapperMiddleware.php index 086df0ef0252..e406e77662a9 100644 --- a/Gax/src/Middleware/CredentialsWrapperMiddleware.php +++ b/Gax/src/Middleware/CredentialsWrapperMiddleware.php @@ -1,4 +1,6 @@ retrySettings->getMaxRpcTimeoutMillis(); $totalTimeoutMs = $this->retrySettings->getTotalTimeoutMillis(); - $delayMs = $this->retrySettings->getInitialRetryDelayMillis(); + $delayMs = (int) $this->retrySettings->getInitialRetryDelayMillis(); $timeoutMs = $options['timeoutMillis']; $currentTimeMs = $this->getCurrentTimeMs(); $deadlineMs = $this->deadlineMs ?: $currentTimeMs + $totalTimeoutMs; @@ -180,7 +182,7 @@ private function retry(Call $call, array $options, string $status) ); } - protected function getCurrentTimeMs() + protected function getCurrentTimeMs(): float { return microtime(true) * 1000.0; } diff --git a/Gax/src/Middleware/TransportCallMiddleware.php b/Gax/src/Middleware/TransportCallMiddleware.php index 1306f78e11d0..dfd68cc121db 100644 --- a/Gax/src/Middleware/TransportCallMiddleware.php +++ b/Gax/src/Middleware/TransportCallMiddleware.php @@ -1,4 +1,6 @@ setTransportOptions($transportSpecificOptions); - - return $this; - } - /** * @param RetrySettings|array|null $retrySettings * diff --git a/Gax/src/Options/ClientOptions.php b/Gax/src/Options/ClientOptions.php index b9677fe20399..994bbc81b884 100644 --- a/Gax/src/Options/ClientOptions.php +++ b/Gax/src/Options/ClientOptions.php @@ -1,4 +1,6 @@ getCurrentTimeMillis() > $endTime) { return false; } - $this->sleepMillis($currentPollDelayMillis); + $this->sleepMillis((int) $currentPollDelayMillis); if ($pollCallable()) { return true; } diff --git a/Gax/src/RequestBuilder.php b/Gax/src/RequestBuilder.php index 330d13dd4239..179c48d9e3b9 100644 --- a/Gax/src/RequestBuilder.php +++ b/Gax/src/RequestBuilder.php @@ -1,4 +1,6 @@ renderingException($bindings, "missing required binding '$key' for segment '$segment'"); } $value = $bindings[$key]; - if (!is_null($value) && $segment->matches($value)) { + if (!is_null($value) && $segment->matches((string) $value)) { $literalSegments[] = new Segment( Segment::LITERAL_SEGMENT, - $value, + (string) $value, $segment->getValue(), $segment->getTemplate(), $segment->getSeparator() diff --git a/Gax/src/ResourceTemplate/ResourceTemplateInterface.php b/Gax/src/ResourceTemplate/ResourceTemplateInterface.php index ffa3c8138da5..d5cb1357f519 100644 --- a/Gax/src/ResourceTemplate/ResourceTemplateInterface.php +++ b/Gax/src/ResourceTemplate/ResourceTemplateInterface.php @@ -1,4 +1,6 @@ $values) { foreach ($values as $value) { $decodedValue = ['@type' => $key]; - if (self::hasBinaryHeaderSuffix($key)) { + if (is_string($key) && self::hasBinaryHeaderSuffix($key)) { if (isset(KnownTypes::BIN_TYPES[$key])) { $class = KnownTypes::BIN_TYPES[$key]; /** diff --git a/Gax/src/ServerStream.php b/Gax/src/ServerStream.php index 3257e65504fa..c659041c5584 100644 --- a/Gax/src/ServerStream.php +++ b/Gax/src/ServerStream.php @@ -1,4 +1,6 @@ null, 'logger' => null, ]; - list($baseUri, $port) = self::normalizeServiceAddress($apiEndpoint); + list($baseUri, $port) = self::normalizeApiEndpoint($apiEndpoint); $httpHandler = $config['httpHandler'] ?: self::buildHttpHandlerAsync(logger: $config['logger']); $transport = new GrpcFallbackTransport("$baseUri:$port", $httpHandler); if ($config['clientCertSource']) { diff --git a/Gax/src/Transport/GrpcTransport.php b/Gax/src/Transport/GrpcTransport.php index 5fd03a6fe52d..1881335467f7 100644 --- a/Gax/src/Transport/GrpcTransport.php +++ b/Gax/src/Transport/GrpcTransport.php @@ -1,4 +1,6 @@ null, 'logger' => null, ]; - list($addr, $port) = self::normalizeServiceAddress($apiEndpoint); + list($addr, $port) = self::normalizeApiEndpoint($apiEndpoint); $host = "$addr:$port"; $stubOpts = $config['stubOpts']; // Set the required 'credentials' key in stubOpts if it is not already set. Use diff --git a/Gax/src/Transport/HttpUnaryTransportTrait.php b/Gax/src/Transport/HttpUnaryTransportTrait.php index 38c4ca1f5522..8a9b3bea16b7 100644 --- a/Gax/src/Transport/HttpUnaryTransportTrait.php +++ b/Gax/src/Transport/HttpUnaryTransportTrait.php @@ -1,4 +1,6 @@ false, 'logger' => null, ]; - list($baseUri, $port) = self::normalizeServiceAddress($apiEndpoint); + list($baseUri, $port) = self::normalizeApiEndpoint($apiEndpoint); $requestBuilder = $config['hasEmulator'] ? new InsecureRequestBuilder("$baseUri:$port", $restConfigPath) : new RequestBuilder("$baseUri:$port", $restConfigPath); diff --git a/Gax/src/Transport/TransportInterface.php b/Gax/src/Transport/TransportInterface.php index 682a4301989c..8ae6d918c590 100644 --- a/Gax/src/Transport/TransportInterface.php +++ b/Gax/src/Transport/TransportInterface.php @@ -1,4 +1,6 @@ getAuthorizationHeaderCallback()(); } - /** - * Same test as above, but calls the deprecated CredentialsWrapper::getBearerString method - * instead of CredentialsWrapper::getAuthorizationHeaderCallback - * @dataProvider provideCheckUniverseDomainFails - */ - public function testCheckUniverseDomainOnGetBearerStringFails( - ?string $universeDomain, - ?string $credentialsUniverse, - ?string $message = null - ) { - $this->expectException(ValidationException::class); - $this->expectExceptionMessage($message ?: sprintf( - 'The configured universe domain (%s) does not match the credential universe domain (%s)', - is_null($universeDomain) ? GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN : $universeDomain, - is_null($credentialsUniverse) ? GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN : $credentialsUniverse, - )); - $fetcher = $this->prophesize(FetchAuthTokenInterface::class); - // When the $credentialsUniverse is null, the fetcher doesn't implement GetUniverseDomainInterface - if (!is_null($credentialsUniverse)) { - $fetcher->willImplement(GetUniverseDomainInterface::class); - $fetcher->getUniverseDomain()->willReturn($credentialsUniverse); - } - $fetcher->getLastReceivedToken()->willReturn(null); - // When $universeDomain is null, it means no $universeDomain argument was provided - if (is_null($universeDomain)) { - $credentialsWrapper = new CredentialsWrapper($fetcher->reveal()); - } else { - $credentialsWrapper = new CredentialsWrapper($fetcher->reveal(), null, $universeDomain); - } - // Check getBearerString (deprecated) - $credentialsWrapper->getBearerString(); - } - public function provideCheckUniverseDomainFails() { return [ @@ -314,11 +281,6 @@ public function testCheckUniverseDomainPasses(?string $universeDomain, ?string $ ['authorization' => ['Bearer abc']], $credentialsWrapper->getAuthorizationHeaderCallback()() ); - // Check getBearerString (deprecated) - $this->assertEquals( - 'Bearer abc', - $credentialsWrapper->getBearerString() - ); } public function provideCheckUniverseDomainPasses() @@ -344,29 +306,6 @@ public function testCheckUniverseDomainOnGceCredentialsDoesNotCheck() $credentialsWrapper->checkUniverseDomain(); } - /** - * @dataProvider getBearerStringData - * @runInSeparateProcess - */ - public function testGetBearerString(string $fetcherFunc, $expectedBearerString) - { - $fetcher = $this->$fetcherFunc(); - $credentialsWrapper = new CredentialsWrapper($fetcher); - $bearerString = $credentialsWrapper->getBearerString(); - $this->assertSame($expectedBearerString, $bearerString); - } - - public function getBearerStringData() - { - return [ - ['getExpiredFetcher', 'Bearer 456'], - ['getEagerExpiredFetcher', 'Bearer 456'], - ['getUnexpiredFetcher', 'Bearer 123'], - ['getInsecureFetcher', ''], - ['getNullFetcher', ''], - ]; - } - /** * @dataProvider getAuthorizationHeaderCallbackData * @runInSeparateProcess diff --git a/Gax/tests/Unit/GapicClientTraitTest.php b/Gax/tests/Unit/GapicClientTraitTest.php index fef2951d4197..06c7b3fb58a1 100644 --- a/Gax/tests/Unit/GapicClientTraitTest.php +++ b/Gax/tests/Unit/GapicClientTraitTest.php @@ -1581,17 +1581,17 @@ public function __invoke(Call $call, array $options) $transport->startUnaryCall( Argument::type(Call::class), [ - 'transportOptions' => [ - 'custom' => ['addModifyUnaryCallableOption' => true] - ], - 'headers' => AgentHeader::buildAgentHeader([]), - 'credentialsWrapper' => CredentialsWrapper::build([ - 'keyFile' => __DIR__ . '/testdata/creds/json-key-file.json' - ]) + 'transportOptions' => [ + 'custom' => ['addModifyUnaryCallableOption' => true] + ], + 'headers' => AgentHeader::buildAgentHeader([]), + 'credentialsWrapper' => CredentialsWrapper::build([ + 'keyFile' => __DIR__ . '/testdata/creds/json-key-file.json' + ]) ] ) - ->shouldBeCalledOnce() - ->willReturn(new FulfilledPromise(new Operation())); + ->shouldBeCalledOnce() + ->willReturn(new FulfilledPromise(new Operation())); $client->startCall( 'simpleMethod', diff --git a/Gax/tests/Unit/Middleware/OperationsMiddlewareTest.php b/Gax/tests/Unit/Middleware/OperationsMiddlewareTest.php index 7d7dac94189e..1c264ae76ee9 100644 --- a/Gax/tests/Unit/Middleware/OperationsMiddlewareTest.php +++ b/Gax/tests/Unit/Middleware/OperationsMiddlewareTest.php @@ -33,9 +33,9 @@ namespace Google\ApiCore\Tests\Unit\Middleware; use Google\ApiCore\Call; -use Google\ApiCore\LongRunning\OperationsClient; +use Google\LongRunning\Client\OperationsClient; use Google\ApiCore\Middleware\OperationsMiddleware; -use Google\ApiCore\Testing\MockResponse; +use Google\ApiCore\Testing\MockRequest; use GuzzleHttp\Promise\Promise; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; @@ -50,11 +50,11 @@ public function testOperationNameMethodDescriptor() $operationsClient = $this->prophesize(OperationsClient::class); $descriptor = [ - 'operationNameMethod' => 'getNumber' + 'operationNameMethod' => 'getPageToken' ]; $handler = function (Call $call, $options) use (&$callCount) { return $promise = new Promise(function () use (&$promise) { - $response = new MockResponse(['number' => 123]); + $response = new MockRequest(['page_token' => 'abc']); $promise->resolve($response); }); }; @@ -64,6 +64,6 @@ public function testOperationNameMethodDescriptor() [] )->wait(); - $this->assertEquals(123, $response->getName()); + $this->assertEquals('abc', $response->getName()); } } diff --git a/Gax/tests/Unit/ServiceAddressTraitTest.php b/Gax/tests/Unit/ServiceAddressTraitTest.php deleted file mode 100644 index ba5cf81c7a64..000000000000 --- a/Gax/tests/Unit/ServiceAddressTraitTest.php +++ /dev/null @@ -1,69 +0,0 @@ -assertSame($expectedAddress, $actualAddress); - $this->assertSame($expectedPort, $actualPort); - } - - public function normalizeServiceAddressData() - { - return [ - ['simple.com:123', 'simple.com', '123'], - ['really.long.and.dotted:456', 'really.long.and.dotted', '456'], - ['noport.com', 'noport.com', self::$defaultPort], - ]; - } - - /** - * @dataProvider normalizeServiceAddressInvalidData - */ - public function testNormalizeServiceAddressInvalid($serviceAddressString) - { - $this->expectException(ValidationException::class); - $this->expectExceptionMessage('Invalid apiEndpoint'); - - self::normalizeServiceAddress($serviceAddressString); - } - - public function normalizeServiceAddressInvalidData() - { - return [ - ['too.many:colons:123'], - ['too:many:colons'], - ]; - } -} diff --git a/Gax/tests/Unit/testdata/mocks/src/GapicClientStub.php b/Gax/tests/Unit/testdata/mocks/src/GapicClientStub.php index d5a022de7c78..4520de072c76 100644 --- a/Gax/tests/Unit/testdata/mocks/src/GapicClientStub.php +++ b/Gax/tests/Unit/testdata/mocks/src/GapicClientStub.php @@ -1,4 +1,6 @@ Date: Tue, 16 Jun 2026 12:49:40 -0700 Subject: [PATCH 2/2] add new ApiEndpoint trait --- Gax/src/ApiEndpointTrait.php | 62 +++++++++++++++++++++++ Gax/tests/Unit/ApiEndpointTraitTest.php | 65 +++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 Gax/src/ApiEndpointTrait.php create mode 100644 Gax/tests/Unit/ApiEndpointTraitTest.php diff --git a/Gax/src/ApiEndpointTrait.php b/Gax/src/ApiEndpointTrait.php new file mode 100644 index 000000000000..df74fed5ccba --- /dev/null +++ b/Gax/src/ApiEndpointTrait.php @@ -0,0 +1,62 @@ +assertSame($expectedAddress, $actualAddress); + $this->assertSame($expectedPort, $actualPort); + } + + public function normalizeApiEndpointData() + { + return [ + ['simple.com:123', 'simple.com', '123'], + ['really.long.and.dotted:456', 'really.long.and.dotted', '456'], + ['noport.com', 'noport.com', self::$defaultPort], + ]; + } + + /** + * @dataProvider normalizeApiEndpointInvalidData + */ + public function testNormalizeApiEndpointInvalid($ApiEndpointString) + { + $this->expectException(ValidationException::class); + $this->expectExceptionMessage('Invalid apiEndpoint'); + + self::normalizeApiEndpoint($ApiEndpointString); + } + + public function normalizeApiEndpointInvalidData() + { + return [ + ['too.many:colons:123'], + ['too:many:colons'], + ]; + } +}