C# AWS lambda calling an HTTP end point randomly gives BadGateway - aws-lambda

I have a C# AWS Lambda that is calling back to a server with the result of it's work using HttpClient SendAsync.
Sometimes it works fine, other times, having processed exactly the same payload so the call back will be the same it results in a BadGateway. As far as I know I have no further logs available to me as to why.
Anyone got any ideas?

For Bad Gateway (HTTP 502) check the server logs first that you are connecting. It is a server side error so the logs would be a good place to look first. Also with Lambda check that the Lambda scaling is not creating too many connections that makes the web server give issues.

Related

Websocket connection using AWS Lambda + API Gateway

I have a react application and I would like to setup a websocket connection to my backend for some realtime updates. I was going to deploy an EC2 or ECS-cluster to host websocket connections. Then I stumbled into some articles showing how websocket connection can be setup in a serverless manner.
One example: https://medium.com/#likhita507/real-time-chat-application-using-webscockets-in-apigateway-e3ed759c4740
However, I can't seem to figure out how this works for a few reasons.
Lambda has a max runtime of 15 min
How does the backend establish a connection when no lambda is running and the backend wants to invoke a message to the frontend
Does this entail that I have to keep a lambda alive all the time, if so, it no longer feels like a good idea. In the above example, what I can't grasp is that when creating that chat application, can each chat room only exist for 15 min? And if a user disconnects from the room, how will that user be updated on new messages.
Does anyone have any experience with this kind of solution?
It's the API Gateway that keeps the websocket connection alive. The browser (or whatever your client is) is connecting to the Gateway, not the lambda function.
The gateway triggers the Lambda function. You hook this up by selecting LAMBDA_PROXY from Integration Request. You can connect each route to a separate function, or have them all dealt with by one, whichever you prefer. Unless you're doing something very complicated in the function, it should only be executing for a few ms.
Communicating from the function to the original client is done through the gateway too - with APIGatewayManagementAPI.postToConnection (or you could roll your own http version using the connection URL I guess).

What happens if UI makes a rest call and the server stops?

Suppose, UI is making calls to rest service and the server stops.
Does UI come to know about the server's state?
Does UI get any response back from the server?
What difference does it make if the rest call was POST or PUT?
When REST Api is stopped,the UI/Browser/Client will show "Could not get any response
There was an error connecting to " error, irrespective of request type: PUT /POST.
To answer your questions :
Does UI come to know about the server's state?
If Server stops, you will get an error like : error connecting server. Which can be traced to multiple rootcauses. One of them can be : Server has stopped.
In case of error, Server's state can be sent to client using various error codes like:
500 Internal Server Error The 500 status code, or Internal Server Error, means that server cannot process the request for an unknown reason. Here is list of status codes for REST APis: https://www.w3.org/Protocols/HTTP/HTRESP.html
Does UI get any response back from the server?
If server is stopped, UI/Client will receive no response.
What difference does it make if the rest call was POST or PUT?
If the server has stopped, it doesn't make any difference.
You can run this scenario using a browser and running any app/REST service in your local machine.
(For this test you need not have any REST application running in your local, as you only want to test when it is stopped)
For instance, if your REST application server is up and available at port 8080, you can send request to this server by sending request form your browser : http://localhost:8080
For testing with POST/PUT collections, you can use any API Development tools like : Postman.
Let's assue your REST Api , exposes following urls :
/myPostRequest POST
/myPutRequest PUT
When you hit these urls from POSTMAN you get the same response :
POST http://localhost:8080/myPostRequest :
Could not get any response
There was an error connecting to http://localhost:8080/transition-order.
PUT http://localhost:8080/myPutRequest :
Could not get any response
There was an error connecting to http://localhost:8080/transition-order.
Client(could be UI) and Server are two dumb applications. They do and say what they are told to.
So whenever a client tries to call a server on a socket and there is no server listening to it, there is no response returned to the client. The client can interpret it in whatever way it wants. Most of the browsers show <host> refused to connect.
But if a server is listening to a socket, it responds to the client whichever way it was programmed to do. The server sends an appropriate status code and expects that the client knows how to interpret it. A server can send any random number it wants... the catch is, the client must know how to interpret it. otherwise, it's just one-way communication.
In order to provide smooth client-server communication, section 10 of RFC 2616 defines various codes with specific meaning as shown here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
These status codes are the same for all the types of Http methods.

Difficulty using Wiremock, microservices, and external https service - no traffic captured

I have a system with microservice architecture. So I have a setup such that when I hit an URL, for example "http://localhost:8081/data/myId/" I get back a JSON response describing a resource. This is the system which I have created.
It turns out that there is some more complexity as to get this response, I am making a connection to an external service provider - this is what I want to use WireMock to mock, as this service provider has an API call limit. Let us say that I am interacting with this service provider at the following URL "https://api.dummyservice.com/". (So all "http://localhost:8081/data/myId/" calls consist of a "https://api.dummyservice.com/" call.)
So I am using WireMock as follows
java -jar '/home/user/Desktop/wiremock-standalone-2.19.0.jar'
--recd-mappings
--proxy-all https://api.dummyservice.com/
--verbose
--print-all-network-traffic
My intention is to listen to all calls at https://api.dummyservice.com/ through my microservice-based system so that I can stub and mock the responses. The problem is that I am not capturing any traffic at all when I access "http://localhost:8081/data/myId/" and get a successful response back!
Have I misunderstood WireMock's application? How can I debug this issue? It seems that I am performing quite a straightforward task.
I am on an Ubuntu 18.04 system if it makes any difference.
It seems you use standalone WireMock in a proper way, but please check correct params here
--record-mappings
--proxy-all="https://api.dummyservice.com/"

AWS SNS not sending subscription confirmation for HTTP

I am trying to set up a basic SNS subscription but it looks like AWS never sends the confirmation, either through the console or using the SDK.
Steps I have taken so far:
I have set up a Topic using the AWS console
I have added HTTP subscriptions to both an ngrok tunnel URL and also a public web server URL using both the AWS console and the ruby SDK
I have allowed everyone to subscribe to the Topic by editing the Topic policy in the AWS console
By tailing the logs on both my localhost and public web servers I can see that no request is ever sent to the endpoint.
I'm pretty stumped here because it seems like it should definitely be working, or at least sending something (anything) to my endpoints?
The code I'm using for the ruby sdk is as follows:
sns = AWS::SNS.new(access_key_id: ENV['AWS_ACCESS_KEY_ID'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'])
# I only have one topic
topic = sns.topics.first
topic.subscribe(URI.parse('http://<NGROK_URL>.ngrok.com/notifications/notify'))
topic.subscriptions.first
# returns: => <AWS::SNS::Subscription arn:PendingConfirmation>
This turned out to be an issue related to the region I was working in. I changed to Oregon and all confirmations are sending immediately.
There must be some permissions setting somewhere that prevents you from sending any messages at all from certain regions, but it was failing silently.
For me, it appears that it may not be the region (though I was trying us-east-1 too), but how ngrok's network is set up. I used a different site-forwarding service (finch) and was completely successful. This AWS forum topic makes be think that the problem may be intermittent, too.

Making request using WebSockets in sails but not receiving response from the server

I'm starting with Websockets and I have a problem.
I have a sails.js application that uses sockets to update the client side.
On the client side it makes an API call using socket.get("/api/v1/actor...") to bring all the items of the database. When I see what the WebSocket's traffic on the Chrome console:
As you can see, the connection has been established and the API call has been correctly done through the socket.
The problem is, there is no answer from the server, not even an error.
If I make the same API call using ajax, I get response, but it doesn't work using WebSockets.
Any idea what might be producing this behavior?
EDIT: I add here the code here that processes the request and this one here that sends the request, but the problem is that it never execute this code. I think we we are closer to the find the cause, since we think it has to do with a network problem. We figured there is an F5 reverse-proxy which is not properly set up to handle websockets
The answer didn't make any sense now that I've seen the code that's why I've edited it. I only answered because I could't comment on your question and ask you for the code.
Your calling code seems correct and the server side of things the process of response should be handled automatically by the framework, you only need to return some JSON in the controller method.
I instantiated a copy of the server (just changed the adapters to run it locally) and the server replied to the web socket requests (although I only tested the route '/index').
Normally when the problems are caused by a reverse proxy the socket simply refuses to connect and you can't even send data to server. Does the property "socket.socket.connected" returns true?
The best way to test is to write a small node application with socket.io client and test it in the same machine that the application server is running, then you can exclude network problems.

Resources