google-cloud-php icon indicating copy to clipboard operation
google-cloud-php copied to clipboard

Fatal Error in RequestHandler class with emulator without GRPC extension

Open mrVrAlex opened this issue 10 months ago • 6 comments

Hi

Any Client API (for example PubSub) can not work with emulator without grpc extension. When we put in clientConfig 'emulatorHost' & 'hasEmulator' keys (PubSub client set it when exist PUBSUB_EMULATOR_HOST env) then it config passing to RequestHandler constructor and using here https://github.com/googleapis/google-cloud-php/blob/85748387bed4dd1dece6dee255f9efe801f2dbd2/Core/src/RequestHandler.php#L71 And there call $this->emulatorGapicConfig function which part of EmulatorTrait https://github.com/googleapis/google-cloud-php/blob/main/Core/src/EmulatorTrait.php#L44

And without any conditions code try build array config with call \Grpc\ChannelCredentials::createInsecure() which part of GRPC extension.

In result:

Fatal error: Uncaught Error: Class "Grpc\ChannelCredentials" not found in /app/vendor/google/cloud-core/src/EmulatorTrait.php:44
Stack trace:
#0 /app/vendor/google/cloud-core/src/RequestHandler.php(72): Google\Cloud\Core\RequestHandler->emulatorGapicConfig('pubsub:8681')
#1 /app/vendor/google/cloud-pubsub/src/PubSubClient.php(215): Google\Cloud\Core\RequestHandler->__construct(Object(Google\ApiCore\Serializer), Array, Array)

Another (maybe related) issue when try avoid Fatal error with stub class & method for ChannelCredentials and put in config ['transport' => 'resr'] then I got different error:

In CurlFactory.php line 210:
                                                                               
  [GuzzleHttp\Exception\ConnectException]                                      
  cURL error 35: OpenSSL/3.1.4: error:0A00010B:SSL routines::wrong version nu  
  mber (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://p  
  ubsub:8681/v1/projects/emulator-project/topics/local.esbNew:publish?%24alt=  
  json%3Benum-encoding%3Dint  

Because client by some reason choose HTTPS schema instead of HTTP and emulator don't work with SSL...

So this is bug?

Environment details

  • OS: ANY
  • PHP version: ANY
  • Package name and version: PubSub 2.0

Steps to reproduce

  1. take official docker php image
  2. run emulator
  3. run code in example

Code example

putenv('PUBSUB_EMULATOR_HOST=localhost:8900');
$pubsub = new PubSubClient(['projectId' => 'my-project']);

mrVrAlex avatar Mar 27 '24 17:03 mrVrAlex

Hello! Thank you for commenting on this. Does it work when you install the grpc extension for PHP? If so, I suggest doing this.

In the meantime, if the emulator requires gRPC, we should wrap the EmulatorTrait to check if grpc is installed, and throw an exception if it isn't.

bshaffer avatar Apr 03 '24 20:04 bshaffer

Yes with gRPC extension it is worked properly. But if google/cloud-pubsub v2.x and others (which depends on new EmulatorTrait) not works with emulators via http protocol - then it is major breaking changes? Maybe this should reflect in changelog & documentation? (BTW: in our case we can not use grpc extension in PHP because it conflict with swoole / openswoole extension)

mrVrAlex avatar Apr 09 '24 14:04 mrVrAlex

(BTW: in our case we can not use grpc extension in PHP because it conflict with swoole / openswoole extension)

Can you elaborate more on this? This is news to me, and it's something we should file as a bug in the grpc repo to get fixed.

bshaffer avatar May 06 '24 15:05 bshaffer

@mrVrAlex

it is major breaking changes?

No, because the emulators have never worked with REST, only with gRPC. To confirm this, I checked out v0.233.0 (which is the same as google/cloud-pubsub:v1.51.1, the last release before 2.0), and used composer install --prefer-lowest, and received the same error you have here. So AFAICT, REST has never worked in the emulator... there does not seem to be any regression here.

We could open this as a feature request against gcloud, but otherwise this is out of our (the client library team's) hands.

bshaffer avatar May 06 '24 15:05 bshaffer

@bshaffer afaik the grpc extension was always optional. We were using the pubsub emulator on local machines without grpc and without any credentials file with PubSub v1, but after upgrading to PubSub v2 we can't because we get error:

In CredentialsWrapper.php line 319:
 
  Could not construct ApplicationDefaultCredentials
 
 
In ApplicationDefaultCredentials.php line 201:
 
  Your default credentials were not found. To set up Application Default Credentials, see https://c
  loud.google.com/docs/authentication/external/set-up-adc

pulzarraider avatar Jun 10 '24 10:06 pulzarraider

I have tried some half-empty configuration to avoid the first exceptions, but I got the same error, as it is described in this ticket:

[Symfony\Component\ErrorHandler\Error\ClassNotFoundError]
  Attempted to load class "ChannelCredentials" from namespace "Grpc".
  Did you forget a "use" statement for another namespace?

It would be great if we could use version 2 in the same way with pubsub emulator without the mandatory grpc extension.

pulzarraider avatar Jun 10 '24 10:06 pulzarraider

I ended up creating a stub file and requiring that to get this working - grpc.php.stub:

<?php

/**
 * PubSubClient assumes that if the PUBSUB_EMULATOR_HOST env var is set that the grpc extension is installed :(
 */

declare(strict_types=1);

namespace Grpc;

if (! class_exists('Grpc\ChannelCredentials')) {
    class ChannelCredentials {
        public static function createInsecure(): null
        {
            return null;
        }
    }
}

Then ensure the PUBSUB_EMULATOR_HOST environment variable is set and instantiate PubSubClient with something like:

        require_once 'grpc.php.stub';

        return new PubSubClient([
            'projectId'         => 'emulator-project',
            'credentialsConfig' => [
                'keyFile'     => [
                    "client_id"     => "fake-fake-fake.apps.googleusercontent.com",
                    "client_secret" => "fake-fake-fake",
                    "refresh_token" => "fake-fake-fake",
                    "type"          => "authorized_user"
                ],
            ],
        ]);

(Note that the docblock on the constructor is wrong - the keyFile stuff needs to be under credentialsConfig).

It'd be great to get grpc working without segfaults on swoole / openswoole. No idea where to start on that one though.

kynx avatar Aug 06 '24 15:08 kynx

@pulzarraider I'm stuck with the same issue from your comment https://github.com/googleapis/google-cloud-php/issues/7187#issuecomment-2157990748. If I understood the discussion it boils down to the missing grpc extension even if it wasn't necessary in pubsub.

I presume that once/if your PR https://github.com/googleapis/gax-php/pull/582 gets merged, this should work as in the v1 without any credentials?

ollosh avatar Sep 09 '24 14:09 ollosh

@ollosh It should be working if you update to the latest version of google/cloud-core now that https://github.com/googleapis/google-cloud-php/pull/7588 is merged and released. See the comment on that PR to work around it using https instead of http URLs to access the emulator.

kynx avatar Sep 09 '24 17:09 kynx

@ollosh even with my MR https://github.com/googleapis/gax-php/pull/582 you will still need credentials. I managed to get it working using these fake credentials for emulator:

{"project_id":"emulator-project","client_id":"emulator","client_secret":"emulator","refresh_token":"emulator","type":"authorized_user"}

pulzarraider avatar Sep 10 '24 06:09 pulzarraider

@pulzarraider thank you! I've managed to get it working with that and with the changes from https://github.com/googleapis/google-cloud-php/pull/7588. If I understand it correctly, those changes from that PR will become obsolete if https://github.com/googleapis/gax-php/pull/582 gets merged?

ollosh avatar Sep 10 '24 07:09 ollosh

@ollosh yes. Code from https://github.com/googleapis/gax-php/pull/582 allows Pub/Sub client to work with emulator without requiring significant modifications to the client to get the http urls mentioned in #7588.

pulzarraider avatar Sep 10 '24 08:09 pulzarraider

Amazing, thx for all the info! :crossed_fingers: that it gets merged soon!

ollosh avatar Sep 10 '24 08:09 ollosh