1
votes

I working with Google cloud Stackdriver Trace API with C# (dotnet core) and working according to this article.

I already added all the needed code and want to try it locally (on my development machine). Since I'm not running from the GCP cloud, I created a new Service Account with the needed permissions. Google said in the article:

GCP client libraries use Application default credentials (ADC) to find your application's credentials. You provide these credentials by setting the GOOGLE_APPLICATION_CREDENTIALS environment variable:

export GOOGLE_APPLICATION_CREDENTIALS=path-to-your-service-accounts-private-key

Now my code fails when reaching this point:

services.AddGoogleExceptionLogging(options =>
{
    options.ProjectId = Configuration["Stackdriver:ProjectId"];
    options.ServiceName = Configuration["Stackdriver:ServiceName"];
    options.Version = Configuration["Stackdriver:Version"];
});

With the message:

System.InvalidOperationException: 'Error reading credential file from location C:******.json: Could not find file. Please check the value of the Environment Variable GOOGLE_APPLICATION_CREDENTIALS'

For many reasons, I don't want to use the environment variable called GOOGLE_APPLICATION_CREDENTIALS. Instead, I'm looking for a way to provide it the actual file path, without using an environment variable.

How I can do it?

2

2 Answers

0
votes

The command you are using

export GOOGLE_APPLICATION_CREDENTIALS=path-to-your-service-accounts-private-key

is used in Linux, but the error your post specified this

.... Error reading credential file from location C:******.json: Could not find file …..

in this case seems you are using windows and you need to use the command “SET” to assign the value, is located in “Setting the environment variable” paragraph.

You can also pass the service account key in code, in this case you need to install the Cloud Storage client library you can view an example in the paragraph “Passing the path to the service account key in code” where you can see this code for C# and you have a link to GitHub with an example code.

// Some APIs, like Storage, accept a credential in their Create()
// method.
public object AuthExplicit(string projectId, string jsonPath)
{
    // Explicitly use service account credentials by specifying
    // the private key file.
    var credential = GoogleCredential.FromFile(jsonPath);
    var storage = StorageClient.Create(credential);
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}
// Other APIs, like Language, accept a channel in their Create()
// method.
public object AuthExplicit(string projectId, string jsonPath)
{
    var credential = GoogleCredential.FromFile(jsonPath)
        .CreateScoped(LanguageServiceClient.DefaultScopes);
    var channel = new Grpc.Core.Channel(
        LanguageServiceClient.DefaultEndpoint.ToString(),
        credential.ToChannelCredentials());
    var client = LanguageServiceClient.Create(channel);
    AnalyzeSentiment(client);
    return 0;
}
0
votes

Since you don't want to use the environment variable, have you tried to authenticate using the gcloud SDK ?

As explained here :

If running locally for development/testing, you can authenticate using the Google Cloud SDK. Download the SDK if you haven't already, then login by running the following in the command line:

gcloud auth application-default login

Otherwise, the only other way to do it would be specifying the path on your source code.

You should be able to do that with the example provided here. Tweak it to suit your specific needs.

This sample shows how to create a client using credentials loaded from a JSON file:

using Google.Cloud.ErrorReporting.V1Beta1;
using Google.Apis.Auth.OAuth2;
using Grpc.Auth;
using Grpc.Core;
...
GoogleCredential cred = GoogleCredential.FromFile("/path/to/credentials.json");
Channel channel = new Channel(
    ReportErrorsServiceClient.DefaultEndpoint.Host, ReportErrorsServiceClient.DefaultEndpoint.Port, cred.ToChannelCredentials());
ReportErrorsServiceClient client = ReportErrorsServiceClient.Create(channel);
...
// Shutdown the channel when it is no longer required.
channel.ShutdownAsync().Wait();