Masstransit with Amazon SQS not working in EKS - amazon-sqs

I have configured the bus like this
services.AddMassTransit(x =>
{
x.UsingAmazonSqs((context, cfg) =>
{
cfg.Durable = true;
cfg.AutoDelete = false;
cfg.Host("us-east-2", h =>
{
});
});
});
I've not specified credential to allow AWS SDK to resolve the credential automatically.
https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/creds-assign.html
The setup works fine on my local machine with a AWS session profile. However when I deploy the code in EKS, I got the following message:
Health check masstransit-bus with status Degraded completed after 1.9351ms with message 'Degraded Endpoints: {{THE BUS ENDPOINT}}'
There's no other error or warning, but the bus is not working. I have verified IRSA (https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) has been configured correctly for the pod.
Am I missing something? What can I do to track down the underlying issue?

Related

Created a user pool client using Cognito Identity Provider Client SDK for JavaScript v3, but can't fetch token using (client_credentials) grant type

Created a user pool client using Cognito Identity Provider Client SDK for JavaScript v3
npm install #aws-sdk/client-cognito-identity-provider.
The following code shows how I created the resources server and the user pool client, using the mentioned👆 SDK...
let poolName = 'UserPool';
const client =new CognitoIdentityProviderClient({
region: process.env.COGNITO_AWS_REGION
});
// create resource server
const createResourceServerCommand = new CreateResourceServerCommand({
Name: poolName,
UserPoolId: UserPool.Id,
Identifier: 'https://localhost:8080/api/v2',
Scopes: [
{
ScopeName: 'access',
ScopeDescription: 'General access to API'
}
]
});
const { ResourceServer } = await client.send(createResourceServerCommand);
// create the user pool client
const createUserPoolClientCommand = new CreateUserPoolClientCommand({
ClientName: 'Default',
UserPoolId: UserPool.Id,
ExplicitAuthFlows: ['USER_PASSWORD_AUTH'],
GenerateSecret: true,
AllowedOAuthFlows: ['client_credentials'],
SupportedIdentityProviders: ['COGNITO'],
AllowedOAuthScopes: [ 'https://localhost:8080/api/v2/access' ]
});
const { UserPoolClient } = await client.send(createUserPoolClientCommand);
...but, I can't fetch tokens using the grant type client_credentials. Therefore getting the following error.
{
"error": "invalid_grant"
}
However, if I use AWS console to navigate to the user pool > Client > Edit the hosted UI and click on the save button without making any changes...
... I am able to fetch a token using the client_credentials grant type.
Is there any setting that I might be missing in the above code that AWS console is setting? I need the following code to automate the creation of user pools.
When I switched to the old I noticed this notification
Apparently, Oauth flows are not enabled by default. Hence adding the following attribute to the CreateUserPoolClientCommandInput object AllowedOAuthFlowsUserPoolClient: true enables it. Hope this helps some newbie like me out there.

How do I get my physical device running React Native on Expo Go to communicate with my app's rails backend api?

I am currently trying to run my react-native/rails app on my phone for testing purposes. I can run my sign in and log in screens fine because they do not communicate with my server until the user info is entered. When running my server i use:
$ rails s --binding=0.0.0.0
I do not receive any errors other than knowing my server is not being communicated with. This all works fine on my Android Studio Emulator as well.
// one of my fetch GET requests
export function requestCurrentUser(username, auth_token) {
return function action(dispatch) {
const request = fetch(`'http://10.0.2.2:3000'/users/${username}`, {
method: 'GET',
headers: {
"Authorization": auth_token
}
});
return request.then(
response => response.json(),
err => console.log("user error"),
)
.then(
json => dispatch(receiveCurrentUser({id: json.id, email: json.email, username: json.username})),
err => console.log("user json error"),
);
}
}
I've tried changing my Phone IP settings to a 10.0.2.2 Gateway, and using my phone's IP in my fetch request. I feel like I am missing something conceptually. Thanks in advance.
In fetch request you need to use the IP from the machine that are running the rails server,
probably your notebook and use the same network to connect your app and your rails backend api. In order to test, you can try directly access your api in your phone browser accessing http://IP_FROM_RAILS_MACHINE:3000

ApolloServer: "Could not connect to websocket endpoint ws://localhost:4000/subscriptions. Please check if the endpoint url is correct."

I can't implement any subscriptions because it suddenly disconnects from it when I try to listen to some endpoint with GraphQL Playground:
{"error": "Could not connect to websocket endpoint wss://localhost:4000/graphql. Please check if the endpoint url is correct."}
I'm using ApolloServer alone, no express or anything else. It is containerized with Docker using node14 image, the port is properly fowarded, queries and mutations works properly.
This is the configuration snippet:
const server = new ApolloServer({
typeDefs: mergedTypeDefs,
resolvers: mergedResolvers,
playground: {
subscriptionEndpoint: 'ws://localhost:4000/graphql'
},
subscriptions: {
keepAlive: 9000,
onConnect: (connParams, webSocket, context) => {
console.log('CLIENT CONNECTED');
},
onDisconnect: (webSocket, context) => {
console.log('CLIENT DISCONNECTED')
}
},
context: {
models
}
});
I tried everything, from using 'wss' instead of 'ws' to change the path. I checked for typos and didn't find one. What bothers me is that the paths are the same so It should at least try to notify me by the onConnect or onDisconnect but it doesn't.
This is the message through Chrome's dev tools:
WebSocket connection to 'wss://localhost:4000/graphql' failed: WebSocket is closed before the connection is established.
I tested subscriptions with a 'tutorial' project outside the container and it works fine.
Sometimes, the only function of subscriptions that works is onDisconnect but after 2-5 seconds after receiving the error message on PlayGround, and Still it doesn't gives me any insight on the problem.
Any help or suggestion is appreciated.
wss will definitely not work locally without certificate, so use ws as a protocol.
If it works without Docker, then everything should be fine code-wise.
You should also make sure that you've mapped ports correctly, i.e. exposed port 4000 https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose

MassTransit with SQS/SNS. Publish into SNS?

There is an official examples of MassTransit with SQS. The "bus" is configured to use SQS (x.UsingAmazonSqs). The receive endpoint is an SQS which in turn subscribed to an SNS topic. However there is no example how to Publish into SNS.
How to publish into SNS topic?
How to configure SQS/SNS to use http, since I develop against localstack?
AWS sdk version:
var cfg = new AmazonSimpleNotificationServiceConfig { ServiceURL = "http://localhost:4566", UseHttp = true };
Update:
After Chris's reference and experiments with configuration I came up with the following for the 'localstack' SQS/SNS. This configuration executes without errors and Worker gets called, and publishes a message to a bus. However consumer class is not triggered and doesn't seem messages end up in the queue (or rather topic).
public static readonly AmazonSQSConfig AmazonSQSConfig = new AmazonSQSConfig { ServiceURL = "http://localhost:4566" };
public static AmazonSimpleNotificationServiceConfig AmazonSnsConfig = new AmazonSimpleNotificationServiceConfig {ServiceURL = "http://localhost:4566"};
...
services.AddMassTransit(x =>
{
x.AddConsumer<MessageConsumer>();
x.UsingAmazonSqs((context, cfg) =>
{
cfg.Host(new Uri("amazonsqs://localhost:4566"), h =>
{
h.Config(AmazonSQSConfig);
h.Config(AmazonSnsConfig);
h.EnableScopedTopics();
});
cfg.ReceiveEndpoint(queueName: "deal_queue", e =>
{
e.Subscribe("deal-topic", s =>
{
});
});
});
});
services.AddMassTransitHostedService(waitUntilStarted: true);
services.AddHostedService<Worker>();
Update 2:
When I look at sns subscriptions I see that the first which was created and subscribed manually through aws cli has a correct Endpoint, while the second that was created by MassTransit library has incorrect one. How to configure Endpoint for the SQS queue?
$ aws --endpoint-url=http://localhost:4566 sns list-subscriptions-by-topic --topic-arn "arn:aws:sns:us-east-1:000000000000:deal-topic"
{
"Subscriptions": [
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:deal-topic:c804da4a-b12c-4203-83ec-78492a77b262",
"Owner": "",
"Protocol": "sqs",
"Endpoint": "http://localhost:4566/000000000000/deal_queue",
"TopicArn": "arn:aws:sns:us-east-1:000000000000:deal-topic"
},
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:deal-topic:b47d8361-0717-413a-92ee-738d14043a87",
"Owner": "",
"Protocol": "sqs",
"Endpoint": "arn:aws:sqs:us-east-1:000000000000:deal_queue",
"TopicArn": "arn:aws:sns:us-east-1:000000000000:deal-topic"
}
Update 3:
I've cloned the project and ran some unit tests of the project for AmazonSQS bus configuration, consumers don't seem to work.
When I list subscriptions after the test run I can tell that Endpoints are incorrect.
...
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:MassTransit_TestFramework_Messages-PongMessage:e16799c2-9dd3-458d-bc28-52a16d646de3",
"Owner": "",
"Protocol": "sqs",
"Endpoint": "arn:aws:sqs:us-east-1:000000000000:input_queue",
"TopicArn": "arn:aws:sns:us-east-1:000000000000:MassTransit_TestFramework_Messages-PongMessage"
},
...
Could it be that AmazonSQS for localstack has a major bug?
It's not clear how to use library with 'localstack' sqs, how to point out to actual endpoint (QueueUrl) of an SQS queue.
Whenever Publish is called in MassTransit, messages are published to SNS. Those messages are then routed to receive endpoints as configured. There is no need to understand SQS or SNS when using MassTransit with Amazon SQS/SNS.
In MassTransit, you create consumers, those consumers consume message types, and MassTransit configures topics/queues as needed. Any of the samples using RabbitMQ, Azure Service Bus, etc. are easily converted to SQS by changing UsingRabbitMq to UsingAmazonSqs (and adding the appropriate NuGet package).
Looks like your configuration is setup properly to publish, but there are probably at least a few reasons I can think of why you are not receiving messages:
Issue with the current version of localstack. I had to use 0.11.2 - see Localstack with MassTransit not getting messages
You are publishing to a different topic. Masstransit will create the topic using the name of the message type. This may not match the topic you configured on the receive endpoint. You can change the topic name by configuring the topology - see How can I configure the topic name when using MassTransit SQS?
Your consumer is not configured on the receive endpoint - see the example below
public static readonly AmazonSQSConfig AmazonSQSConfig = new AmazonSQSConfig { ServiceURL = "http://localhost:4566" };
public static AmazonSimpleNotificationServiceConfig AmazonSnsConfig = new AmazonSimpleNotificationServiceConfig {ServiceURL = "http://localhost:4566"};
...
services.AddMassTransit(x =>
{
x.UsingAmazonSqs((context, cfg) =>
{
cfg.Host(new Uri("amazonsqs://localhost:4566"), h =>
{
h.Config(AmazonSQSConfig);
h.Config(AmazonSnsConfig);
});
cfg.ReceiveEndpoint(queueName: "deal_queue", e =>
{
e.Subscribe("deal-topic", s => {});
e.Consumer<MessageConsumer>();
});
});
});
services.AddMassTransitHostedService(waitUntilStarted: true);
services.AddHostedService<Worker>();
From what I see in the docs about Consumers you should be able to add your consumer to the AddMastTransit configuration like your original sample, but it didn't work for me.

Unable to replicate database in pouchDB

I'm trying a react native application using couchDB 2.1.1. PouchDB entry in package json looks like this:
"pouchdb": "^6.3.4",
"pouchdb-react-native": "^6.3.4",
Replication is as shown below:
const localDB = new PouchDB('employee');
const remoteDB = new PouchDB('http://username:password#localhost:5984/employee');
localDB.replicate.from(
remoteDB,
(err, response) => {
if (err) {
return console.log(err);
}
},
);
I get following error:
{"code":"ETIMEDOUT","status":0,"result":{"ok":false,"start_time":"...","docs_read":0,"docs_written":0,"doc_write_failures":0,"errors":[],"status":"aborting","end_time":"...","last_seq":0}}
Almost all the times this works fine when I run the app in debug mode. Tried ajax timeout as shown here PouchDB ETIMEDOUT error. This didn't work. Is there something that I'm supposed to look in my code? Please help.
Had the same issue, the following fixed it for me:
Use your PC ip address instead of localhost
Configure your firewall
to allow connections on port 5984 OR just disable it (Not
recommended)

Resources