How to query all services (groups) from an iotagent - fiware

We have a hard time understanding the meaning of the different hierarchy levels provided by the iotagent. There is the fiware-service, the fiware-servicepath and underneath it is a bunch of services that in turn have a bunch of devices associated.
Now we understood how to query for all devices and all services underneath a given fiware-service and fiware-servicepath. We also understood how to query for all fiware-servicepaths given a certain fiware-service. But how to query for all those "top level" fiware-services?
Our goal is to create a device management user interface which enables an end user to provision and unprovision the devices he is managing. Maybe we have a misconception of the fiware-service here but since one can add such services with a certain POST request our expectation would be that we can somehow query for all those services. What are we missing?
If there really is no way to query the top level services, I'd like to ask for the reasoning of this as I cannot find that in the docs.

Under NGSI-v2, all context brokers are implicitly multitenant. Using a different fiware-service for your provisioned devices should imply that the devices and their data are owned by separate business concern, so there should be no need to retrieve and combine provisioned devices from separated concerns.
When using the mongo-DB option with an IoT Agent, the fiware-service helps to provide a unique database name for each tenanted service.
There should be no need to combine the IoT Agent data (services and devices), however there may be a valid use case for combining Context Data coming from separate Tenants (after securing legal agreement from each party of course) - in this case you could create a simple proxy handler which is capable of handling the /v2/op/query and/or /v2/op/update endpoints and forwarding the request with amended headers.
const express = require('express');
const router = express.Router();
const request = require('request-promise');
const BASE_PATH =
process.env.CONTEXT_BROKER || 'http://localhost:1026/v2';
function forwardRequest(req, res) {
// Add necessary validation
const headers = req.headers;
headers['fiware-service' : 'XXXX'];
headers['fiware-servicepath': 'YYYY'];
headers['Accept': 'application/json'];
const options = {
url: BASE_PATH + req.path,
method: req.method,
headers,
json: true
};
request(options)
.then(async function(cbResponse) {
return res.send(compacted);
})
.catch(function(err) {
return res.send(err);
});
}
router.post(
'/op/query', forwardRequest
);

Related

Where to specify whether it's a GET or POST?

When I create a new Google Cloud function, the default code given is:
const functions = require('#google-cloud/functions-framework');
functions.http('helloHttp', (req, res) => {
res.send(`Hello ${req.query.name || req.body.name || 'World'}!`);
});
However, in this tutorial, the function is specified as:
exports.validateTemperature = async (req, res) => {
try {
if (req.body.temp < 100) {
res.status(200).send("Temperature OK");
} else {
res.status(200).send("Too hot");
}
} catch (error) {
//return an error
console.log("got error: ", error);
res.status(500).send(error);
}
};
What is the difference between the two? How do they work in the bigger scheme of things?
In the second example, the code is listening for a Http POST request. Where is this specified?
Through the two methods you exposed the result is the same, a HTTP Path is used to receive the Request and Response objects.
Inside the Request object, you may find the Body (usually filled in POST & PUT requests but not limited to) and the Method (GET, POST, PUT, etc).
Therefore, your Cloud Function code will be used with both a GET and a POST call in either solution.
Functions Framework
Functions Framework turns a Cloud Functions snippet into a workable server. It's kind of like register a handler function to an express router, and run the express app behind the scenes.
The main use case is local development and migrant to App Engine or other services. They both need to start a HTTP server, and functions framework does that.
Express
Node.js runtime explains your code snippet using Express framework.
The validateTemperature accepts all HTTP methods.
We often filter HTTP methods by a router. Although you can do it in with req.method. And router, web server level is what you don't want to reapeat again and again.
If you want to split requests by method when buiding an API service, you could consider let Cloud Endpoints or some API Gateway stands before your functions.

What is the right way to use a database with flutter?

I have an app which interacts with the database directly with mysql1 library like the example below:
Future FetchData() async {
final connection = await MySqlConnection.connect(ConnectionSettings(
host: 'mysql-hostname.example.com',
port: 3306,
user: 'root',
password: 'root',
db: 'testDB',
));
var results = await connection.query('SELECT * FROM `testTable` WHERE 1');
for (var row in results) {
print('${row[0]}');
}
// Finally, close the connection
await connection.close();
}
I wonder if this is a safe and secure method. Because when I build the app I pack all the information (username, password) about connecting my database in the app. Is this risky so should I use a separate back-end for this kind of tasks?
It is generally safer to put a trusted backend environment between your database and app. But even in this case you will have to ensure that only your app has access to this backend resource.
For example if you use Firebase as backend, there is an AppCheck service available. Although this is relatively new, it can attest your app's authenticity.
If you prefer to do it on your own, you can create a bearer token that your app will add the the requests, preferably in the request's Authorization header, and check it in the backend before accessing protected resources. But then the question remains, where do you store this bearer token safely.
If you want to keep it in your code, you should properly obfuscate the code before uploading it to the app stores. Even in this case it is a good idea to check for rooted or jailbroken devices to prevent misuse, for example check out flutter_jailbreak_detection.
There are also secure storage packages, which can store sensitive data in a safer way. Unlike SharedPreferences, these can mitigate the risks of unauthorited access to your secrets. See flutter_secure_storage for example.
It really depends on the level of security that you are looking for. Are you storing user-generated sensitive information in your database? Then the answer is that you should ideally not store that information in your code nor should you ship your application with that information bundled inside it.
I highly suggest that you start using Firebase for your usage. Firebase is an absolutely fantastic and free product provided by the Google, the same company behind Flutter, and within a few minutes you can build a whole experience that relies on authentication with Firebase and you can safely store user-generated content in Firebase.

WebBluetooth GATT Characteric Notification Setup too slow - How to improve Setup time?

I try to connect to a BLE device (a LEGO Powered UP device) using WebBluetooth. I did this already using .NET/WinRT on the same notebook (works nicely) and now I try to write an adapter for using it in Blazor. The LEGO PoweredUp device implements a communication protocol using BLE GATT characteristic w/ Notifications and WriteValue.
As soon as the device is connecting, it is instantly sending a series of notifications (as kind of a response to the connect before) exposing information I need. I am able to setup the notification receiver fast enough in .NET using WinRT. However, with Chrome's WebBluetooth I only receive - depending on the timing/iteration - between the last 3 and 9 message (9 messages is expected). I guess this is just a regular race condition.
My Question: Is this expected? Can I do something against it?
Below a minimal viable test (which should return 9 messages when connected to a LEGO Technic Control+ Hub).
function writeToLog(x) {
console.log(x.target.value.buffer);
}
async function connectToLwpDevice() {
const serviceUuid = "00001623-1212-EFDE-1623-785FEABCD123".toLowerCase();
const characteristicUuid = "00001624-1212-EFDE-1623-785FEABCD123".toLowerCase();
const device = await navigator.bluetooth.requestDevice({ filters: [{ services: [serviceUuid] }] });
const connectedDevice = await device.gatt.connect();
const service = await connectedDevice.getPrimaryService(serviceUuid);
const characteristic = await service.getCharacteristic(characteristicUuid);
characteristic.addEventListener('characteristicvaluechanged', writeToLog);
await characteristic.startNotifications();
}
I don't believe there is anything that can be done about this at the moment. I've filed an issue against the Web Bluetooth specification to track the changes I believe are necessary in order to enable the reception of these notifications.

Feathers.js and background jobs, how to trigger service event (or realtime update clients)

Looking a bit through the feathers docs I understood that is based on services and hooks and that services have the events that also help to offer realtime sync between server and client.
As long as things are simple, as in docs I understand, basically having a service generated and then adding/saving/updating using the service methods will triggeer the event.
My scenario is a bit different:
The API endpoint does not return info from a table but complex queries based on multiple tables
I need to have background workers that do operations on the database,probably using Kue (if there's no better way inside feathers), when a worker finishes the job, I need to have a way to trigger the API service so it updates the clients with the new data.
How can I do this in feathers?
Both scenarios can be handled with Feathers like this:
Feathers services do not have to be tied to a table. You can implement a custom service just like you would in any other framework (controller). It is not uncommon to create Dashboard services that aggregates different service calls or uses service.Model to access the ORM you are using directly:
class MyService {
find(params) {
const userModel = this.app.service('users').Model;
const invoiceModel = this.app.service('invoices').Model;
return userModel.doSomething()
.then(data => invoiceModel.doSomethingElse());
}
setup(app, path) {
this.app = app;
}
}
Background workers should also be using the Feathers API (in Node this can be done by either using the application directly via const app = require('./src/app') or connecting transparently through Feathers as the client) so that all connected clients will get updates automatically. Then there should be no need to trigger events manually (which comes with caveats like having to also run your raw data through any hooks that change the data).

Keeping a user logged in with nodeJS

I have a login system with my NodeJS using mysql-node.
The problem i have how ever is how to keep the user logged in, if they refresh the page they have to login again, because i do not know how to store the session.
My login system is like this:
socket.on('login', function(data,callBack){
var username = sanitize(data['login']).escape(),
pass = sanitize(data['password']).escape();
var query = connection.query('SELECT uid FROM users WHERE name = ? AND pass = ?', [username,pass],
function(err,results){
if(err){
console.log('Oh No! '+err);
} else if(results.length == 1){
//some how set a session here
} else if(!results.length) {
console.log('No rows found!');
}
});
});
I'm having difficulty understanding how i set up a session for each client that connects. Is this possible with NodeJS ?
Reading that they assign express to var app but if i already have this : var app = http.createServer( ... how can i also assign express to it :S bit confusing
You need to understand the difference between a express' server and a native NodeJS' server, here my link comparaison nodejs server vs express server
So you can do:
var app = express();
var server = http.createServer(app);
This enable you to have still the low level functionnaly with NodeJS.
So, if you don't want to use existing modules or framework, you can build your own session manager:
using cookie
using IP/UA
using socket
The best way would be first to implement it with socket, for example:
server.on('connection', function (socket) {
socket.id = id;
});
or
server.on('request', function (req, res) {
req.connection.id = id; // The socket can also be accessed at request.connection.
});
So, you just need to implement a middleware who check the id.
If you want to prevent from session prediction, session sidejacking, etc. you need to combine cookies, ip, socket, and your ideas to make it more secure for your app.
Once you've done your session manager, you can choose where to store the sessions, in a simple object, in redis, in mongodb, in mysql ... (express use MemoryStore by default, but maybe not now)
I don't have an idea if nodejs has core feature of saving sessions. you need to use a database along with it. using Express will help you to utilized a database to persist user sessions. You better study and use it
http://expressjs.com/
http://blog.modulus.io/nodejs-and-express-sessions
I don't think there is any session mechanism within Nodejs' core. However, they are plenty of libraries that would allow you to do it. The first that comes to mind is Connect's session, which is a middleware for Nodejs. Have a look at this question for more details on how to use it.
Have a look at this tutorial from dailyjs which tries to include Express's session into a notepad webapp. The source code is available here. (Note that Express' session is based on Connect's, and is practically the same).
EDIT: Here is a more complete example for Node authentication, using mongoose. They do however show their schemas, so I assume you can easily do the transition to MySQL.