How to send a masstransit command using SQS? - amazon-sqs

I am able to send messages with rabbitmq by using this
private void SendRabbitMqCommand(string queueName, object message)
{
var hostname = ConfigurationManager.AppSettings["ExportQueueHostname"];
var uri = new Uri(string.Concat(hostname, "/", queueName));
var sendEndpoint = this._bus.GetSendEndpoint(uri).Result;
sendEndpoint.Send(message);
}
But now I need to switch to SQS. I have been trying to figure out how to build the "uri" for the GetSendEndpoint method and cannot seem to find an example in the documentation.
BTW, I am using the latest MassTransit production build 5.5.6 and my company does not like using development builds. I read that in version 6 it will be possible to do following below:
var uri = new Uri("queue:" + queueName)
But I cannot use version 6 as it is not yet released as a production build.

Related

What is the alternative to TwilioClient.Init() in Twilio.Api Version 3.4.1.0

I want to send notification to Twilio and according to its official documentation TwilioClient.Init is used to initialize base class in latest versions.
Due to dependency on other dlls , I have to use Twilio.Api version 3.4.1.0 and there is no TwilioClient.Init method present in that old version.
So, what is the alternate method to TwilioClient.Init to Initialize?
You can instantiate the TwilioRestClient directly like this:
using Twilio;
string accountSid = Environment.GetEnvironmentVariable("...");
string authToken = Environment.GetEnvironmentVariable("...");
var client = new TwilioRestClient(accountSid, authToken);
Then for example to send a message pass the client into the resource method:
var message = MessageResource.Create(
to: new PhoneNumber("+1..."),
from: new PhoneNumber("+1..."),
body: "Hello from C#",
client: client);
Some documentation can be found in Manual Client Initialization.
The old versions are also on GitHub, I couldn't find 3.4.1, the closest tag I found was 3.2.3.
But be careful, the version you're trying to use is deprecated and Twilio will no longer provides bug fixes for it!

How to use a Google Secret in a deployed Cloud Run Service (managed)?

I have a running cloud run service user-service. For test purposes I passed client secrets via environment variables as plain text. Now since everything is working fine I'd like to use a secret instead.
In the "Variables" tab of the "Edit Revision" option I can declare environment variables but I have no idea how to pass in a secret? Do I just need to pass the secret name like ${my-secret-id} in the value field of the variable? There is not documentation on how to use secrets in this tab only a hint at the top:
Store and consume secrets using Secret Manager
Which is not very helpful in this case.
You can now read secrets from Secret Manager as environment variables in Cloud Run. This means you can audit your secrets, set permissions per secret, version secrets, etc, and your code doesn't have to change.
You can point to the secrets through the Cloud Console GUI (console.cloud.google.com) or make the configuration when you deploy your Cloud Run service from the command-line:
gcloud beta run deploy SERVICE --image IMAGE_URL --update-secrets=ENV_VAR_NAME=SECRET_NAME:VERSION
Six-minute video overview: https://youtu.be/JIE89dneaGo
Detailed docs: https://cloud.google.com/run/docs/configuring/secrets
UPDATE 2021: There is now a Cloud Run preview for loading secrets to an environment variable or a volume. https://cloud.google.com/run/docs/configuring/secrets
The question is now answered however I have been experiencing a similar problem using Cloud Run with Java & Quarkus and a native image created using GraalVM.
While Cloud Run is a really interesting technology at the time of writing it lacks the ability to load secrets through the Cloud Run configuration. This has certainly added complexity in my app when doing local development.
Additionally Google's documentation is really quite poor. The quick-start lacks a clear Java example for getting a secret[1] without it being set in the same method - I'd expect this to have been the most common use case!
The javadoc itself seems to be largely autogenerated with protobuf language everywhere. There are various similarly named methods like getSecret, getSecretVersion and accessSecretVersion
I'd really like to see some improvment from Google around this. I don't think it is asking too much for dedicated teams to make libraries for common languages with proper documentation.
Here is a snippet that I'm using to load this information. It requires the GCP Secret library and also the GCP Cloud Core library for loading the project ID.
public String getSecret(final String secretName) {
LOGGER.info("Going to load secret {}", secretName);
// SecretManagerServiceClient should be closed after request
try (SecretManagerServiceClient client = buildClient()) {
// Latest is an alias to the latest version of a secret
final SecretVersionName name = SecretVersionName.of(getProjectId(), secretName, "latest");
return client.accessSecretVersion(name).getPayload().getData().toStringUtf8();
}
}
private String getProjectId() {
if (projectId == null) {
projectId = ServiceOptions.getDefaultProjectId();
}
return projectId;
}
private SecretManagerServiceClient buildClient() {
try {
return SecretManagerServiceClient.create();
} catch(final IOException e) {
throw new RuntimeException(e);
}
}
[1] - https://cloud.google.com/secret-manager/docs/reference/libraries
Google have documentation for the Secret manager client libraries that you can use in your api.
This should help you do what you want
https://cloud.google.com/secret-manager/docs/reference/libraries
Since you haven't specified a language I have a nodejs example of how to access the latest version of your secret using your project id and secret name. The reason I add this is because the documentation is not clear on the string you need to provide as the name.
const [version] = await this.secretClient.accessSecretVersion({
name: `projects/${process.env.project_id}/secrets/${secretName}/versions/latest`,
});
return version.payload.data.toString()
Be sure to allow secret manager access in your IAM settings for the service account that your api uses within GCP.
I kinda found a way to use secrets as environment variables.
The following doc (https://cloud.google.com/sdk/gcloud/reference/run/deploy) states:
Specify secrets to mount or provide as environment variables. Keys
starting with a forward slash '/' are mount paths. All other keys
correspond to environment variables. The values associated with each
of these should be in the form SECRET_NAME:KEY_IN_SECRET; you may omit
the key within the secret to specify a mount of all keys within the
secret. For example:
'--update-secrets=/my/path=mysecret,ENV=othersecret:key.json' will
create a volume with secret 'mysecret' and mount that volume at
'/my/path'. Because no secret key was specified, all keys in
'mysecret' will be included. An environment variable named ENV will
also be created whose value is the value of 'key.json' in
'othersecret'. At most one of these may be specified
Here is a snippet of Java code to get all secrets of your Cloud Run project. It requires the com.google.cloud/google-cloud-secretmanager artifact.
Map<String, String> secrets = new HashMap<>();
String projectId;
String url = "http://metadata.google.internal/computeMetadata/v1/project/project-id";
HttpURLConnection conn = (HttpURLConnection)(new URL(url).openConnection());
conn.setRequestProperty("Metadata-Flavor", "Google");
try {
InputStream in = conn.getInputStream();
projectId = new String(in.readAllBytes(), StandardCharsets.UTF_8);
} finally {
conn.disconnect();
}
Set<String> names = new HashSet<>();
try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {
ProjectName projectName = ProjectName.of(projectId);
ListSecretsPagedResponse pagedResponse = client.listSecrets(projectName);
pagedResponse
.iterateAll()
.forEach(secret -> { names.add(secret.getName()); });
for (String secretName : names) {
String name = secretName.substring(secretName.lastIndexOf("/") + 1);
SecretVersionName nameParam = SecretVersionName.of(projectId, name, "latest");
String secretValue = client.accessSecretVersion(nameParam).getPayload().getData().toStringUtf8();
secrets.put(secretName, secretValue);
}
}
Cloud Run support for referencing Secret Manager Secrets is now at general availability (GA).
https://cloud.google.com/run/docs/release-notes#November_09_2021

Vault .NET - Invalid path for a versioned K/V secrets engine

I've added all my configuration details in the Vault. The detail you can see in the attached image below. This follows a specific path i.e kv/unistad/dev/workflow/camunda/1.0
However, when I try to read this information using Vault.NET with the following nuget package
Install-Package Vault
My code looks something like this:
var endpoint = "http://openblue-bridge.com:32270";
var token = "s.inklpUdNxet1ZJtaCLMpEIPA";
var vaultClient = new VaultClient(new Uri(endpoint), token);
string project = "unistad";
string environment = "dev";
string appVersion = "1.0";
var secretPath = $"kv/{project}/{environment}/workflow/camunda/{appVersion}";
// Use client to read a key-value secret.
var secrets = await vaultClient.Secret.Read< Dictionary<string, string>> (secretPath);
When I run the above code I get the following error:
Invalid path for a versioned K/V secrets engine. See the API docs for
the appropriate API endpoints to use. If using the Vault CLI, use
'vault kv get' for this operation.
I'm not sure how can I fix this error. Any help would be really appreciated.
You are using v2 of the kv engine. For that engine, you need to have /data/ in the path, as shown in the API docs. The requirement for this prefix is also described in the engine docs.
So the solution to your problem is specifically to change your path from
var secretPath = $"kv/{project}/{environment}/workflow/camunda/{appVersion}";
to
var secretPath = $"kv/data/{project}/{environment}/workflow/camunda/{appVersion}";

TFS2018 path to api

I have a TFS2018 setup on a server and I am trying to figure out what is the path to the api. Should the path look look like this? Do I have to enable the API on the server?
https://myserver/tfs/DefaultCollection/MyProject/_apis
If I run this in code like this
var cred = new VssCredentials(
new WindowsCredential(new NetworkCredential("username", "Pass")));
var buildClient = new BuildHttpClient(new Uri("https://myserver/tfs/DefaultCollection/MyProject/_apis", UriKind.Absolute), cred);
await buildClient.CreateDefinitionAsync(buildDef);
I get the following error
Web method running:
[https://myserver/tfs/DefaultCollection/MyProject/_apis]
(OPTIONS)_apis[]
It depends on how the server was setup. If it's a fresh install, the /tfs/ is no longer used. If it's an upgrade the /tfs/ is retained to not break existing clients. And I suspect you can leave off the /_api/ part as well, as that should be automatically added.
The best way to get to the BuildCLient is to use the TFS Server or Collection object and request the server:
var collection = new TfsTeamProjectCollection(tfsCollectionUri, credential);
var buildClient = collection.GetClient<BuildHttpClient>();

Google API Client Library freezing up in IIS when making request

I have been using the Google API Client Library for .NET for loading Google Analytics data into my application:
Recently though I have found it to have started freezing up completely. The Execute() command makes a connection to the Google server.
It makes a successful request to :
https://accounts.google.com/o/oauth2/token
which returns something like :
{
"access_token" : "ya30.HAKlQSGZo2GnK5wxlxx9TLTQUyD9Xkt7AZxuQnDY-KhJuCyrCtN_xHIP",
"token_type" : "Bearer",
"expires_in" : 3600
}
But then never returns from the Execute call.
The same code in a console app returns immediately, but in IIS it is currently never returning.
In a previous version it worked just fine (I'm not exactly sure which version it changed).
I have Load User Profile set to true.
What could be causing this?
var SERVICE_ACCOUNT_PKCS12_FILE_PATH = #"C:\TEMP\GoogleAnalytics-privatekey.p12";
X509Certificate2 certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
// Create credentials (not my real login here)
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer("86987278011-ctegcus4og7kn6oigkrv8po5pf67bbgj#developer.gserviceaccount.com")
{
Scopes = new[] { AnalyticsService.Scope.AnalyticsReadonly }
}.FromCertificate(certificate));
// Create the service
var service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Google Analytics Application",
});
// get accounts
accounts = service.Management.Accounts.List();
var items = accounts.Execute();
As explained in Google Calendar API - Not Returning From Execute() C#, we currently have a bug in the latest version of Google.Apis.Auth v 1.9.3.
We already have a fix for it, in our repository (https://github.com/google/google-api-dotnet-client), so you can test it yourself with the Analytics API (https://developers.google.com/resources/api-libraries/download/analytics/v3/csharp).
A new release of the library is planned to be in the next few weeks so stay tuned - http://google-api-dotnet-client.blogspot.com/
Update (Dec 15th): New NuGet packages for 1.10.0 are available, read more about it at: http://google-api-dotnet-client.blogspot.com/2015/12/announcing-release-of-1100.html

Resources