SNS, how to guard against silently losing notifications on 404 - http

This is a follow up question to Why is AWS SNS treating 404 response from subscriber as successful?
I understand SNS will treat 200-4xx responses of subscribing HTTP endpoints as successfully handled and will not attempt redelivery.
This however seems to introduce the issue where a missing subscribing endpoint (for example, one that was mistakenly removed from a production environment) will go unnoticed and will cause notifications to go silently unhandled: Most web frameworks will default to returning 404 in such cases, SNS will in turn interpret that as successfully handled and will never retry or move the notification to the DLQ.
Is there some obvious workaround, best practice or approach to monitoring that will remedy this?

Related

Avoid spamming to my API that build with Firebase Function

I am building some internal API for my apps/website with Firebase Functions. Internal API as in to let my apps/website to process something on server side, its doesn't mean to open to public use.
My Apps is built with ionic and website is built with angular.
I noticed the one of Firebase Functions Pricing calculation include "Invocations". Is that Invocations means every time when I call the API equal to 1 Invocation? If yes, then the API might be abused by end user, since they able to view the website source and found the API.
I been searching solution in google, some of them suggest to enable authentication and cors, to avoid abuse of the usage. But authentication and cors still counting the Invocations right?
My code structure:
client call API by get/post method, pass user TOKEN that get from Firebase Authentication
request reach the Firebase Functions
server will check the preflight info by using CORS, as well as validate the TOKEN.
Return error if didn't pass on the (3), else proceed to execute the function.
So I assume if end user inspect my web source code and get the API URL, they can simply spam my API right? Then my bill will burst because of the load of Invocations.
If you suspect that your project is being abused, which is always possible, contact Firebase support to work towards a resolution.

SNS getEndpointAttributes Returns Old Data After EventEndpointUpdated Event

When attaching a topic to a SNS application's "Endpoint updated" configurable topic I'm experiencing some unexpected behavior. Per AWS's documentation on SNS Application Events, I should receive an event on my configured topic when a platform endpoint has been updated to disabled or it's token changed.
In my case I have a lambda function subscribed to this topic that then retrieves the platform endpoint's attributes via a call to AWS's javascript sdk SNS.getEndpointAttributes so that I can check what attribute have changed to either delete the endpoint or update the associated token in my persistent storage. This call however is returning the endpoints as Enabled = true which then prevents me from taking the corrective actions. However if I look in the AWS SNS console I can see the endpoint has been disabled as Enabled = false.
Have others experienced similar inconsistencies and if so what's the best practice to get around them? Thanks for any input!
I was also facing the similar problem when amazon notified me sns application events via http. To work around this problem i actually delayed the execution of code that sync these endpoint updates with my database. To achieve this i scheduled a job for my background queue worker and delayed its execution after 30 seconds from the time amazon notified via http. I don't know whether it is a best practice or not but it is working in my scenario.

How do I communicate / trigger a Webtask from Firebas?

In an interesting blogpost about 'Firebase Authentication with the Firebase 3.0 SDK and Auth0 Integration', it is stated that:
You can even have Firebase communicate with Webtask!
Now I can imagine the (web)client triggering a Firebase operation and subsequently a Webtask, but not the other way around. Or am I missing something?
Firebase can run as a serverless app, but it can also run on the server. You can even have Firebase communicate with Webtask! (sic!)
I think that paragraph is misleadingly phrased, perhaps it was just added at the last minute to spark interest. You can have a webtask communicate with Firebase, not the other way around. You don't "run Firebase" on your server either.
TL;DR: A client application may call a webtask with an HTTP request, and that task can read/write the database, but not in any other order.
Here's a quick and dirty reality check as of Nov. 2016:
The Realtime Database by itself does not provide you with a way of executing code. This includes responding to database changes and user requests, handling fan-in and fan-out operations, etc. There is no support for webhooks either.
Which means you have to provide your own execution environment for such logic on a custom server, or you can try to cram as much as possible into the client code. This is a pretty exhaustive topic by itself.
Webtasks are short-lived functions that respond to HTTP requests. Their lifecycle always starts with a request, so they are not fit for continuously watching the database for changes. But they are perfectly valid for handling requests coming in from your client application.
As you can store "secrets" for the webtasks, you can authenticate the task on an admin access level. This gives you the possibility to verify client tokens – which should be sent along with the request –; perform complex authorization and validation, and perform RTDB write operations you wouldn't trust the clients with.
Or trigger external services securely. The possibilities are close to endless.

How to handle disabled endpoint in SNS

I'm using AWS SNS for send a push notification to mobile app by subscribe all the device under a single SNS Topic. Then to send notification I just send to that topic.However if some endpoint could not receive a message for whatever reason, SNS will mark that endpoint as disabled.
This could be good if SNS only mark a permanent invalid endpoint, but it's not. Since if I re-enable it, then after next push notification sent its might not back to disable again which mean in the next push it can receive a message properly.
The process to re-enable was quite pain, I have to schedule a batch process to loop all the endpoint under each SNS application and re-enable each device endpoint 1 by 1. This take hours and increasing as device number grow.
How can I know which endpoint was really no longer valid due to user already uninstall an app so I don't have to bother re-enable it?
Or, is there any better way to handle this?
I believe the right solution of the problem is to stop the endpoints from getting disabled in the first place. The strategy should be such that SNS only disable the permanently invalid endpoints such as app uninstalled cases and avoid/recover from other cases.
I was in contact with the AWS support. I came to know about a case where the device token for a device can become invalid and in my case, I had a logic where I was re-enabling the endpoint of the device but using the same invalid token as before. Because of this the endpoint will become enabled but as soon as there is a push done to it, SNS will mark it disabled again since the underlying token is invalid. The right thing to do is to check if the token has changed or not from the device side and when it has pass the token for SNS registration again.
Below is the pseudo code for this strategy:
///////////////////////
retrieve the latest token from the mobile OS
if (endpoint arn not stored)
# first time registration
call CreatePlatformEndpoint
store returned endpoint arn
endif
call GetEndpointAttributes on the endpoint arn
if (getting attributes encountered NotFound exception)
#endpoint was deleted
call CreatePlatformEndpoint
store returned endpoint arn
else
if (token in endpoint does not match latest) or
(GetEndpointAttributes shows endpoint as disabled)
call SetEndpointAttributes to set the
latest token and enable the endpoint
endif
endif
//////////////////////

How to subscribe/unsubscribe each server in an auto-scaling group to SNS

We are using Elastic Beanstalk to serve a REST API. Now, I want to develop an endpoint that serves notifications from an SNS-topic in an asynchronous way.
In order to receive those notifications, I need to subscribe the API-servers to the SNS-topic. How could I do this, with the scenario in mind that the EBS application can scale up to multiple servers and scale down again? I don't want a lot of dead links subscribed to the SNS-topic...
In spring world we have a #PostConstruct which gets called on server startup, where you can subscribe "this.server" url to a given topic (you may need to build a proper working subscription url --using InetAddress et el).
Hence there is the working subscribe url using #RestController which confirms such an subscription instantaneously causes sns endpoint to be registered. Any new servers will do the same aka getting registered themselves (when new stack is created). We also need additional code for the consumption of notification messages subsequently and do something when confirmed subscription endpoints receive one.
The way AWS wants you to use SNS is not by directly subscribing to it. Any notification which need to trigger something in a component should buffer notifications with an SQS queue. For this reason we chose to do Pub-Sub with a variable/scalable group of Subs using the Amazon managed Redis distribution.

Resources