Good day,
I was using "Google.Cloud.PubSub.V1 Api Version="1.0.0-beta20" which allowed me to switch between pubsub emulator and the “real” cloud pubsub as per code below:
var emulatorHostAndPort = Environment.GetEnvironmentVariable("PUBSUB_EMULATOR_HOST");
var subscriberApiClient = string.IsNullOrEmpty(emulatorHostAndPort)
? SubscriberServiceApiClient.Create(CreateChannelWithCredentials(credentialPath))
: SubscriberServiceApiClient.Create(new Channel(emulatorHostAndPort, ChannelCredentials.Insecure));
var subscriber = SubscriberClient.Create(subscription.SubscriptionName, new[] { subscriberApiClient });
In the code above I’m able to pass subscriberApiClient with the preconfigured Channel pointing to pubsub emulator host/port to SubscriberClient.Create method, and then use SubscriberClient which allows for simpler api specifically StartAsync method which I use quite a lot throughout the codebase.
After upgrading to "Google.Cloud.PubSub.V1" Version="1.0.0" (not beta) I cannot find any corresponding way of being able to pass a preconfigured Channel which would allow me to make a switch similar to how I was doing it using older api; the SubscriberClient.Create method has been replaced with SubscriberClient.CreateAsync which takes SubscriberClient.ClientCreationSettings and SubscriberClient.Settings but I wasn’t able to identify which of those can be used to use pubsub emulator (using a Channel or otherwise).
Is there anything I may have missed? I’d greatly appreciate your response.
You are correct that the SubscriberClient.Create(...) method has been removed.
The way to achieve this in v1.0.0 is to configure the ChannelCredentials and ServiceEndpoint in the ClientCreationSettings; then pass this to SubscriberClient.CreateAsync(...).
You will need to refactor your code slightly, but this will allow you to achieve the same outcome.
Thanks for your prompt response.
Are there any plans to use an "PUBSUB_EMULATOR_HOST" environment variable to take care of it automatically, i.e. how it's done in Python api, where you only need to set the environment variable?
we may support an environment variable in a later version, but this isn't certain and won't be soon.
Closing. Please leave a further comment if you think it needs re-opening.
Hi @chrisdunelm ,
I am refactoring our code for the non-beta version, and am stuck on the same problem.
Basic setup: We alternate between dockerized pubsub emulator in development and the real pubsub in production.
Basic problem: Unsure how to setup "ServiceEndpoint" for this case.
Same code:
`
public abstract class Publisher : IDisposable
{
private readonly PubSubOption _options;
private readonly Emulator _emulator;
private readonly Task<PublisherClient> _client;
protected Publisher(PubSubOption options, IApplicationLifetime applicationLifetime )
{
_options = options;
if (_options.UseEmulator)
{
_emulator = Emulator.Create(new UriBuilder
{
Host = _options.EmulatorHost,
Port = _options.EmulatorPort
}.Uri);
_client = Task.FromResult(_emulator.CreatePublisherClient(TopicName));
}
else
{
_client = PublisherClient.CreateAsync(TopicName, _options.PublisherClientCreationSettings,
_options.PublisherClientSettings);
}
applicationLifetime.ApplicationStopping.Register(() =>
{
//do cleanup
});
}
}`
And the Emulator class
`
public class Emulator
{
public Uri Uri { get; }
private readonly PublisherServiceApiClient _pubApiClient;
public Emulator(Uri uri)
{
_startInfo = new ProcessStartInfo
{
FileName = "gcloud",
Arguments = $"beta emulators pubsub start --host-port={uri.Host}:{uri.Port}",
UseShellExecute = true
};
Uri = uri;
_pubApiClient = CreatePublisherServiceApiClient();
}
public static Emulator Create(Uri uri)
{
return new Emulator(uri);
}
public PublisherServiceApiClient CreatePublisherServiceApiClient()
{
var channel = new Channel(Uri.Host, Uri.Port, ChannelCredentials.Insecure);
return PublisherServiceApiClient.Create(channel);
}
public PublisherClient CreatePublisherClient(TopicName topic, PublisherClient.Settings settings = null)
{
return PublisherClient.Create(topic, new []{_pubApiClient}, settings);
}
`
The ServiceEndpoint is the hostname and port of the service. So for the emulator I would expect the code to be something like: new Google.Api.Gax.Grpc.ServiceEndpoint(uri.Host, uri.Port);
Most helpful comment
we may support an environment variable in a later version, but this isn't certain and won't be soon.