Google Cloud IoT - sendCommandToDevice - Service Unavailable - google-cloud-platform

The sendCommandToDevice endpoint seems to be unavailable. I tried sending the command directly from the cloud console on the device page. The notification at the bottom left said, Command sent to device, but the inspector on chrome showed a 503 error. Time of error: 17:46:02 UTC Saturday, 27 October 2018
Request:
Request URL: https://cloudiot.clients6.google.com/v1/projects/<project-id>/locations/<location-name>/registries/<registry-name>/devices/<device-name>/:sendCommandToDevice?key=<removed>
Request Method: POST
Status Code: 503
Remote Address: 216.58.196.74:443
Referrer Policy: no-referrer-when-downgrade
Payload: {binaryData: "eyJ0ZXN0IjoxfQ==", subfolder: ""}
Response:
{
"error": {
"code": 503,
"message": "The service is currently unavailable.",
"status": "UNAVAILABLE"
}
}
Also, an additional note, sendCommandToDevice is not available in the nodejs client library (34.0.0). I had to do API discovery to have the method available.

Are you still receiving the 503? I tested this just now and was able to receive messages successfully.
Also, regarding the the lack of availability of Commands features in the client library, Commands is still in Beta and those methods will be available in the client library once it is fully released.

This is probably due to
bug in the node library
bug in Google's RPC endpoint
Lack of testing on Google's part
The problem is that subfolder MUST be specified, and MUST not be an empty string.
As I was using this in a Firebase function, I just use the firebase subfolder for any commands being sent that do not have a specific subfolder
const request = {
name: `${registryName}/devices/${deviceId}`,
binaryData: Buffer.from(JSON.stringify(commandMessage)).toString("base64"),
subfolder: 'firebase'
}
Here's functions deps:
"dependencies": {
"firebase-admin": "^6.4.0",
"firebase-functions": "^2.1.0",
"fs-extra": "^7.0.0",
"googleapis": "^36.0.0",
},

Related

NextJS API Lambda Execution Error AWS Amplify

I have a NextJS app that runs on AWS amplify. I built a basic REST API by adding a pages/api directory to my project. The endpoint returns a 200 and some test JSON data. This works fine when I run the project locally. I deployed to AWS Amplify and the build detects that a Next API is present so it provisions a Lambda and configures the CloudFront behavior for /api/* routes to point to the Lambda function. When hitting the API CloudFront returns a 503 error:
503 ERROR
The request could not be satisfied.
The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront)
Request ID: YnQI9alkoBXwkmkkpXwa29zqXaOT06VCXiBZWJI6xQVkhQ8MElB2bQ==
It doesn't appear that CloudFront is even calling the Lambda, as I am unable to see any logs in Cloudwatch. I've tried to debug and built a test that passes a mock CloudFront event request to the Lambda but I am unable to get my API to execute successfully.
It seems that Amplify/Next provides a lot of boilerplate code for supporting Next API routes so I'm not sure where to focus my debugging efforts.
Has anyone run into this issue before? Any guidance or suggestions would be super helpful!
I did have a similary problem, but i'm using serverless with #sls-next/serverless-component component. Because in moment hasn't support for NextJs 12 version.
In my package.json i'm force NextJs version for more recently in 11, this case is 11.1.4.
// package.json
{
"name": "next-aws",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "^11.1.4",
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"#types/node": "^14.14.37",
"#types/react": "^17.0.3",
"typescript": "^4.2.3"
}
}

How to set the api version being called in API Gateway when integrating with AWS Service CloudWatch?

I get the following error message when calling actions for CloudWatch in API Gateway.
"Error": {
"Code": "InvalidAction",
"Message": "Could not find operation DescribeAlarms for version 2009-05-15",
"Type": "Sender"
}
I've been using DescribeAlarms for testing. My setup is as follows.
Integration Type = AWS Service
AWS Service = CloudWatch
HTTP method = POST
Action = DescribeAlarms
The error references the API Version 2009-05-15, which only has ListMetrics and GetMetricStatistics according to it's documentation on page 54. ListMetrics does indeed work as expected with my setup.
The current version is 2010-08-01 but I don't see anyway to reference that in API Gateway. In an example of a POST request in the documentation it shows a header labeled x-amz-target with a value of GraniteServiceVersion20100801.API_Name.
My interpretation is I can put Name = x-amz-target and value 'GraniteServiceVersion20100801.DescribeAlarms' in my http header for the Integration Request in API Gateway.
This doesn't change the response and gives the same error message.
I also used the --debug in CLI when calling describe-alarms, and in the body it shows...
"body": {
"Action":"DescribeAlarms",
"Version":"2010-08-01"
}
So I also set http headers to include Content-Type with a value of 'application/x-amz-json-1.1' and then put in
{
"Action":"DescribeAlarms",
"Version":"2010-08-01"
}
but nothing changed with that either.
Any help or guidance would be greatly appreciated.
Under Method Integration -> URL Query String Parameters
I added Version as the Name and '2010-08-01' under Mapped From.
All actions are now working as expected.
I'm trying to PutMetrics directly from Api Gateway -> Cloudwatch using PutMetricData, Version in the query string params didn't work for me.
These 3 HTTP headers in the Integration Request solved it for me:
Content-Type 'application/json'
X-Amz-Target 'GraniteServiceVersion20100801.PutMetricData'
Content-Encoding 'amz-1.0'

.NET Core 3.1 CORS not working on Ember (3.12) web UI

I am migrating a .NET Core Web API from 2.2 to 3.1. I have followed the Microsoft migration instructions and placed the call to the CORS middleware between UseRouting and UseEnpoints. However, I am still getting CORS errors.
In the ConfigureServices method, I have:
services.AddCors();
In the Configure method, I have:
app.UseRouting();
app.UseCors(options => options
.AllowAnyOrigin()
.AllowAnyHeader().AllowAnyMethod()
);
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
The console error in the web browser is:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://localhost:5000/users/login. (Reason:
CORS header ‘Access-Control-Allow-Origin’ missing).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://localhost:5000/users/login. (Reason:
CORS request did not succeed).
Diagnostics:
I tried following Microsoft's documentation Enable Cross-Origin Requests (CORS) in ASP.NET Core, but it uses outdated references, such as; UseMvc and IHostingEnvironment.
I tried creating a brand new Web API and Ember Web-UI, but that did not work either. You can find a simple example getting-started-with-ember-js-and-net-core-3
Any idea what is causing the problem?
The ideal bounty reward will go to the answer that works. Preferably, a working bare-bones project will be posted on Git.
Note: I am allowing any origin right now just so I can get it to work. Ultimately, this will need to work with a Web-UI that is on http://localhost:4200
Update
The status code received is HTTP 405 - method not allowed. The method in question is an OPTIONS method.
The .NET Core 2.2 to 3.0 migration document is incorrect. The call to UseCors(); needs to be placed before the UseRouting() function. I went ahead and added it before the UseHttpsRedirection() as I saw that in an implementation on another site.
https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#migrate-startupconfigure
In ConfigureServices
services.AddCors(options =>
{
options.AddPolicy("CorsApiPolicy",
builder =>
{
builder.WithOrigins("http://localhost:4200")
.WithHeaders(new[] { "authorization", "content-type", "accept" })
.WithMethods(new[] { "GET", "POST", "PUT", "DELETE", "OPTIONS" })
;
});
});
In Configure
app.UseCors("CorsApiPolicy");
//app.UseHttpsRedirection();
app.UseJsonApi();
app.UseRouting();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});

Ionic app not issuing POST request

I have an interesting problem with my Ionic application with a Django API server backend.
In previous versions of my app (0.0.1-.0.0.5) this hasn't come up, but starting now I'm not able to issue a POST request to get my authentication token.
Using Ionic locally ionic serve against my deployed server, when I attempt a login, my server registers an OPTIONS /token-auth/ and then POST /token-auth/. When I run the application on my device ionic run android and attempt to login the server only registers the OPTIONS request but does not register the POST, according to the server logs.
I've found out this is due to CORS, it issues an OPTIONS first to see what it is allowed to issue. For some reason the OPTIONS request comes back with absolutely nothing. In my other Django Rest Framework projects, the OPTIONS comes back with a proper response. I think this is related, but it's strange that it works from localhost to the deployed server with the OPTIONS request responding the same.
My login function is pretty basic:
$http({
method: 'POST',
url: config.apiUrl + 'token-auth/',
data: {
"username": usernameElement[0].value,
"password": passwordElement[0].value
}
}).then(function(data) {
console.log('success', data);
...
}, function(err) {
console.log('error', err);
...
});
Another thing I find interesting is that it runs the error function but instead of giving me back a normal error object in the err variable, I get back what appears to be the request object. I have never seen this before.
{
"data":null,
"status":0,
"config":{
"method":"POST","transformRequest":[null],
"transformResponse":[null],
"url":"http://example.com/api/token-auth/",
"data":{
"username":"myuser",
"password":"mypassword"
},
"headers":{
"Accept":"application/json, text/plain, */*",
"Content-Type":"application/json;charset=utf-8"}
},
"statusText":""
}
Runs fine local app to deployed server
Device app to deployed server doesn't register POST request, only OPTIONS
AJAX error return is the request object, not the error response object
I've been stuck on this for a couple days now and am looking for any ideas.
This was in fact a CORS problem. After debugging through django-cors-headers I found that it was not passing the CORS. I later found out that instead of serving on http://192.168.1.36:8100 for some reason ionic switched to serve on http://192.168.1.10:8100

Kibana won't connect to Elasticsearch on Amazon's Elasticsearch Service

After switching from hosting my own Elastiscsearch cluster to Amazon's Elasticsearch Service,
my Kibana dashboards (versions 4.0.2 and 4.1.2) won't load and I'm receiving the following error in kibana.log:
{
"name": "Kibana",
"hostname": "logs.example.co",
"pid": 8037,
"level": 60,
"err": {
"message": "Not Found",
"name": "Error",
"stack": "Error: Not Found\n at respond (\/srv\/kibana\/kibana-4.1.2-linux-x64\/src\/node_modules\/elasticsearch\/src\/lib\/transport.js:235:15)\n at checkRespForFailure (\/srv\/kibana\/kibana-4.1.2-linux-x64\/src\/node_modules\/elasticsearch\/src\/lib\/transport.js:203:7)\n at HttpConnector.<anonymous> (\/srv\/kibana\/kibana-4.1.2-linux-x64\/src\/node_modules\/elasticsearch\/src\/lib\/connectors\/http.js:156:7)\n at IncomingMessage.bound (\/srv\/kibana\/kibana-4.1.2-linux-x64\/src\/node_modules\/elasticsearch\/node_modules\/lodash-node\/modern\/internals\/baseBind.js:56:17)\n at IncomingMessage.emit (events.js:117:20)\n at _stream_readable.js:944:16\n at process._tickCallback (node.js:442:13)"
},
"msg": "",
"time": "2015-10-14T20:48:40.169Z",
"v": 0
}
unfortunately, this error is not very helpful. I assume it's a wrapped HTTP 404, but for what?
How can I connect a Kibana install to Amazon's Elasticsearch Service?
Here are a some things to keep in mind when using Amazon's Elasticsearch Service:
Modifications to the access policies take a non-deterministic amount of time. I've found that it's good to wait at least 15 minutes after the status is no longer "processing" after making policy changes.
It listens on port 80 for HTTP requests and not the standard port 9200. Be sure that your elasticsearch_url configuration directive reflects this, e.g.:
elasticsearch_url: "http://es.example.co:80"
It's very likely that your Kibana instance will not have the necessary permissions to create the index that it needs to show you a dashboard -- this is towards the root of the issue. Check out the indexes on the Elasticsearch domain and look for a line that matches the kibana_index config directive (e.g. via http://es.example.co/_cat/indices).
for instance, if your kibana_index directive is the value is .kibana-4, if you don't see a line like the following:
green open .kibana-4 1 1 3 2 30.3kb 17.2kb
then your Kibana index was not able to create the index it needs. If you go to the dashboard for the Elasticsearch service in amazon and click on the Kibana link, it will likely create a .kibana-4 index for you.
You can specify this index in your existing Kibana's configuration and you should see the next point.
Your existing Kibana install will likely require authentication via the header:
Kibana: Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header.
You can configure this in Kibana and can see the general signing API request documentation for more help.
It's worth noting that the error messaging is reportably better in Kibana 4.2, but as that's in beta and Amazon's Elasticsearch Service was very recently released, the above should be helpful in debugging.