Data retrieval from Orion Context Broker subscription fails - fiware

With a successful subscription in Orion Context Broker, a listening accumulator server fails to recieve any data, under any circumstances I can find to test.
We are using an Ubuntu virtual machine that has a nested virtual machine with FIWARE Orion in it. Having subscribed to Orion Context Broker and confirmed that it was successful by checking the database and also having confirmed that data is successfully updated, the accumulator server fails to respond. unable to tell if this is a failure to send from Orion, or to receive by accumulator, and unsure how to check and continue, we humbly beg the wisdom of the stack overflow community.
We have run the accumulator server on both virtual machine on the same PC and on another PC with non-vm Ubuntu. The script we are using to subscribe is presented below:
Orion VM
{
"duration": "P1M",
"entities": [
{
"type": "Thing",
"id": "Sensor_GV_01",
"isPattern": "false"
}
],
"throttling": "PT1S",
"reference": "http://10.224.24.236:1028/accumulate",
"attributes": [
"temperature",
"pressure"
]
}
EDIT 1
upon using GET/v2/subscriptions/ we receive that the subscription is present but it gives only basic info, no Timesent values. It is pretty much the same thing we receive when we ask MongoDB directly.
Also, forgot to mention, Orion version we are using is 1.9.0 Subscription check

Related

Fiware IoT Agent - data loss issue

We are observing significant data loss in IoT Agent. The data loss happens when IoT agent receives data from our VerneMQ MQTT broker.
Our data is flowing at a rate of 1000/min. When the IoT Agent is started, it works fine for approximately 12 hours, but after 12 hours we see average data loss of 20%.
We have one other subscriber apart from IoT Agent which receives the same data from VerneMQ topic, and that subscriber receives all the data from VerneMQ. The data loss is only in IoT Agent.
We are running IoT Agent and Orion Context Broker on AWS environment using ECS/Fargate services. Each IoT Agent and Orion instance runs in a separate dedicated container.
When IoT Agent is running on one ECS container it works fine without data loss, but when ECS container increased to more than one, there seems to be a data loss. Can you please guide and help us to resolve this issue.
Details about our environment:
IoT Agent version:
{
"libVersion": "2.12.0-next",
"port": "4041",
"baseRoot": "/",
"version": "1.14.0-next" }
Orion Context Broker version:
{ "orion": {
"version": "2.3.0",
"uptime": "0 d, 3 h, 51 m, 36 s",
"git_hash": "764f44bff1e73f819d4e0ac52e878272c375d322",
"compile_time": "Tue Nov 5 09:38:37 UTC 2019",
"compiled_by": "root",
"compiled_in": "38ab37448d3a",
"release_date": "Tue Nov 5 09:38:37 UTC 2019",
"doc": "https://fiware-orion.rtfd.io/en/2.3.0/" } }
Environment variables set in IoT Agent:
Taking into account:
When IoT Agent is running on one ECS container it works fine without data loss, but when ECS container increased to more than one, there seems to be a data loss
it seems the problem in somehow related with the underlying infrastructure but not with the FIWARE software itself. Thus, I'd suggest to review your AWS ECS settings (unfortunatelly, I'm not an expert in AWS ECS, so I cannot provide more specific feedback).
When you say "data loss", do you mean that VerneMQ logs it's dropping messages? This can happen if the consumer is overloaded. In that case, VerneMQ will protect it by load shedding messages.
Your current messages rates should not be a problem though.
André (with the VerneMQ project)

Is there a way to have multiple external IP addresses with Elastic Beanstalk?

I'm using Amazon Elastic Beanstalk with a VPC and I want to have multiple environments (workers) with different IP addresses. I don't need them to be static, I would actually prefer them to change regularly if possible.
Is there a way to have multiple environments with dynamic external IP addresses?
It's hard to understand the use case of wanting to change the instance IP address of an Elastic Beanstalk environment. The fundamental advantage that a managed service like Elastic Beanstalk provides is abstraction over the underlying architecture for a deployment. You are given a CNAME to access the environment's (your application's) API and you shouldn't be relying on the internal IP addresses or Load Balancer URLs for anything as they can be added, removed by the beanstalk service at will.
That being said, there is a way that you can achieve having changing IPs for the underlying instances.
Elastic Beanstalk Rebuild Environment destroys the existing resources including EC2s and creates new resources resulting in your instances having new IP addresses. This would work given that a scheduled downtime (of a few minutes depending on your resources) is not a problem for this use case.
You can use one the following two ways to schedule an environment rebuild
Solution 1:
You can schedule your Rebuild Environment using a simple lambda function.
import boto3
envid=['e-awsenvidid']
client = boto3.client('elasticbeanstalk')
def handler(event, context):
try:
for appid in range(len(envid)):
response = client.rebuild_environment(EnvironmentId=str(envid[appid].strip()))
if response:
print('Restore environment %s' %str(envid[appid]))
else:
print('Failed to Restore environment %s' %str(envid[appid]))
except Exception as e:
print('EnvironmentID is not valid')
In order to do this you will have to create an IAM role with the required permissions.
You can find a comprehensive guide in this AWS Guide.
Solution 2:
You can use a cron job to rebuild the environment using aws-cli. You can follow the steps below to achieve this.
Create EC2 instance
Create IAM Role with permission to rebuild environment
The following example policy would work
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"elasticbeanstalk:RebuildEnvironment"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
Attach the IAM role to the EC2 instance
Add a cron job using command crontab -e
The following example cron job rebuilds the environment at 12.00 am on the 1st of every month
0 0 1 * * aws elasticbeanstalk rebuild-environment --environment-name my-environment-name
Save the cronjob and exit.
It is not recommended to rebuild the environment unnecessarily, but as of now there is no explicit way to achieve your particular requirement. So hope this helps!
Further Reading:
https://docs.aws.amazon.com/cli/latest/reference/elasticbeanstalk/rebuild-environment.html
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environment-management-rebuild.html
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html
https://awspolicygen.s3.amazonaws.com/policygen.html

Cannot connect to Google MySQL from deployed Kubernetes NodeJS app

I have been trying for the past couple of days to get my deployed NodeJS Kubernetes LoadBalancer app to connect to a Google Cloud MySQL instance. the SQL database and the Kubernetes deployment exist in the same Google project. Both The ORM of choice for this project is Sequelize. Here is a snippet of my connection configuration:
"deployConfigs": {
"username": DB_USERNAME,
"password": DB_PASSWORD,
"database": DB_DATABASE,
"host": DB_HOST,
"port": 3306,
"dialect": "mysql",
"socketPath": "/cloudsql/INSTANCE_NAME"
}
When I run the application locally with the same configurations, I am able to query from the database. I can also hit the NodeJS LoadBalancer URL to get a valid API response as long as the API does not hit the database.
I have whitelisted my IP as well as the IP for the NodeJS LoadBalancer API but I still get the following response:
{
"name": "SequelizeConnectionError",
"parent": {
"errorno": "ETIMEDOUT",
"code": "ETIMEDOUT",
"syscall": "connect",
"fatal": true
},
"original": {
"errorno": "ETIMEDOUT",
"code": "ETIMEDOUT",
"syscall": "connect",
"fatal": true
}
}
I followed the instructions for creating a Proxy through a Kubernetes deployment but I don't think that will necessarily solve my issue because I simply want to connect from my Kubernetes app to a persistent database.
Again, I have been able to successfully hit the remote DB when running the container locally and when running the node app locally. I am really unsure as to why this will not connect when deployed.
Thanks!
So Kubernetes does a lot Source NATing so I had to add a rule like this on my network to allow outgoing traffic everywhere from my cluster in GCE:
This is very permissive so you might just want to add it for testing purposes initially. You can also check connectivity to MySQL by shelling into a running pod:
$ kubectl exec -it <running-pod> sh
/home/user # telnet $DB_HOST 3306
It sounds like you might be attempting to connect to your Cloud SQL instance via its public IP? If that's the case, then be careful as that is not supported. Take a look at this documentation page to figure out what's the best way to go about it.
You mentioned you're already using a proxy, but didn't mention which one. If it's the Cloud SQL Proxy, then it should allow you to perform any kind of operation you want against your database, all it does is establish a connection between a client (i.e. a pod) and the Cloud SQL instance. This Proxy should work without any issues.
Don't forget to setup the appropriate grants and all of that stuff on the Cloud SQL side of things.
I have figured it out.
When creating a MYSQL instance you need to do two things (Go to the section titled "Authorized Networks"):
Add a network and give it the name "Application" and the value "127.0.0.1". The environment variable DB_INSTANCE_HOST in your Kubernetes secret should also be set to "127.0.0.1" to prevent ETIMEOUT or ECONNREFUSED from occurring when connecting to MySQL with Node.js.
Create another network and give it the name "Local computer." Search for "my IP address" in a new tab in your browser, then enter that IP in the local computer value input field. (The goal of step two is to connect your instance to MySQL Workbench running on your computer so that you can start building and managing databases.)
That's it!
If you have any questions, write back and we can speak on Facebook or Instagram. I can then help you through the deployment process and address any issues you may have.

Cant connect to AWS Aurora cluster endpoint but can access Writier instance

I have a MySql Aurora cluster setup on AWS. For the last few weeks I have had all of my apps pointing to an instance endpoint, and it has been working fine. Yesterday, however, I started getting errors on inserts/updates saying that the instance was in ReadOnly mode and couldnt be updated.
Apparently the Reader/Writer endpoints can change and what I am really supposed to do is point to the cluster endpoint, which will route the request appropriately. I have tried pointing directly to that cluster endpoint, but it always fails. The error message is fairly generic, telling me to check my username/password, make sure I am not blocked by a firewall, and all of the normal default solutions.
My Cluster is in a VPC, but the Subnets assigned to the cluster are public (they are routed through Internet Gateway).
The ready/writer instances have the same Security Group and VPC configuration. I can connect to the Reader instance (Read Only) but not the Writer instance.
Any idea what else I could look for? Most forums say that I need to check my Routing Tables or security groups, but from what I can tell that are all open to all traffic (I realize that is a bad configuration, I am just trying to get this working). Is there anything else that I should be checking?
Thanks
Update
I can Telnet in to the Reader instance, but not the Writer instance. They are in the same VPC, and both use the public subnet as far as I can tell.
Update 2
My Lambda functions that are in the same VPC as my RDS can access the Cluster endpoint, so I guess its just a problem getting outside. I thought that would be resolved by having a public subnet in the VPC but it doesnt seem to work for that endpoint.
Merely having public subnets would not be enough, you need to explicitly enable public accessibility for your db instances. Public Accessibility is an instance level setting, and you need to turn that ON on all your instances in the cluster. Given your symptoms, I suspect if you have enabled public access on one of your instances and not on some of the others. You can check the same via CLI using the describe-db-clusters API and filtering or searching for PubliclyAccessible. Here is an example:
aws rds describe-db-instances --region us-west-2 --output json --query 'DBInstances[?Engine==`aurora`].{instance:DBInstanceIdentifier, cluster:DBClusterIdentifier, isPublic:PubliclyAccessible }'
[
{
"instance": "karthik1",
"isPublic": true,
"cluster": "karthik-cluster"
},
{
"instance": "karthik2",
"isPublic": false,
"cluster": "karthik-cluster"
}
]
You modify an instance and enable public access on it using the modify-db-instance API.
Hope this helps.

Store in Cosmos data coming from Orion to Cygnus

I have one doubt about how to persist data in an architecture where Cygnus is subscribed to Orion Context Broker and then Cygnus must persist data in Cosmos. Is it necessary to implement a custom WebHDFS client for persisting the data from Cygnus to Cosmos or can it be automatically stored if we configure Cosmos via CLI? After reading some documentation I don't know if this "last step" can be done through configuration using CLI or if a custom client is needed. When could be not necessary a custom WebHDFS client?
As said, Cygnus subscribes to Orion in order to receive notifications about certain desired entities, when any of their attributes changes.
What happens then? Cygnus uses WebHDFS REST API for writting data into Cosmos HDFS, typically a file per notified entity. Initially, if the file does not exits, the "create" operation from the REST API is used; if it already exists, the "append" operation is used.
Where are the above files created? Cygnus HDFS files path is as:
/user/<your_cosmos_username>/<notified_fiware_service>/<notified_fiware_servicePath>/<built_destination>/<built_destination>.txt
The notified_fiware_service and notified_fiware_servicePath are Http headers sent by Orion in the notification; they are about how to organize the data. The built_destination is usually the result of concatenating the notified entityId and the entityType.
Finally, your_cosmos_username is your Linux and HDFS username in the FIWARE LAB Cosmos deployment. This is obtained by login with your FIWARE LAB credentials at http://cosmos.lab.fi-ware.org/cosmos-gui/. You only have to this once in your life; it is, let's say, a provisioning step that creates the Unix username and your HDFS userspace.