1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-29 13:49:28 +08:00
Dušan Borovčanin 22fc26b375 MF-513 - Add Bootstrapping service (#524)
* Introduce Config response for bootstrap procedure

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add inital service implementation

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Enable status change

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Fix logger import

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update BSS to send config in valid format

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use ConfigReader to create valid format response

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update config retrieval error handle

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Enable Thing deletion API

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add API support for fetching Thing by ID

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add list Things endpoint

Update database schema

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use MF API to update status

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use Channels list

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Fix reading Thing from the database

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Create Mainflux Thing when adding new Thing to BS

Create MF Thing as soon as Bootstrap service thing is added. There are 2
main reasons to create Thing when adding a new BS Thing over creating
Thing on bootstrapping:
1) On bootstrapping time, user JWT will not be sent as a part of
request, so there is no mechanism to send a valid API call to Mainflux.
2) This way, Bootstrap service will be in sync with Mainlux: each Thing
existing in BS will also be in Mainflux.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add Thing update

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Remove API key from BS service

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Improve channels update algorithm

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Refactor code

Remove unused fields, comment code and simplfy some method signatures.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Remove Identity Provider and use gRPC

Update dependencies

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add external auth key

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update BS config reader

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update docker-compose

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update env variable read

Add MQTT password to bootstrap response.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update response fields and tags

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Remove status check

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Enable BS of active Things

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add NewThing state

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Rename Status to State

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update README.md

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add filterng

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update List endpoint

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Fix Database query

Remove copyright headers.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add filter type

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Gateway provisioning (1.d)

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update self-bootstrapping feature

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add mocks

Update dependencies to the newest Mainflux version.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add thing service tests

Mocks fix.
Some of the service code intentionally left untested due to possible
changes in future.
Fix copyright headers and update Mainflux and other dependencies.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use name "Config" instead of "Thing"

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Refactor code

Remove commented code.
Fix typo.
Remove unused exported error.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Simplify service tests

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Remove Assign method

Raise test coverage.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update database schema

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Store unknown bootstrap attempts

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update unknown bootstrap handling

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update naming

Fix uses of `Thing` in DB and `api` package.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add endpoint tests

Currently, only test for adding a new Config are implemented.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add initialization of DB tests

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add DB tests

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update readme file

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add API docs

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Remove Mainflux from vendor

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add licence headers

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Fix service and endpoint tests

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Raise test coverage

Remove unused repsonse type.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update build and deployment

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update API docs

Fix typo.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update imports formatting

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Make state response empty

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Raise test coverage

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update API docs

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update readme file

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use uuid as a primary key

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use Mainflux ID

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Remove `Created` state.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Move State to separate file

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add Things prefix

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update API and API docs

Be consistent in API naming and add some useful comments.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Refactor repository implementation

Cleanup code, make it more readable. Fix missing drop in migrations.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use "cfg" insted of "thing"

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Fix tests

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update tables names

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>
2019-01-09 15:42:23 +01:00

181 lines
3.7 KiB
Go

//
// Copyright (c) 2018
// Mainflux
//
// SPDX-License-Identifier: Apache-2.0
//
package api
import (
"context"
"github.com/go-kit/kit/endpoint"
"github.com/mainflux/mainflux/bootstrap"
)
func addEndpoint(svc bootstrap.Service) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(addReq)
if err := req.validate(); err != nil {
return nil, err
}
config := bootstrap.Config{
ExternalID: req.ExternalID,
ExternalKey: req.ExternalKey,
MFChannels: req.Channels,
Content: req.Content,
}
saved, err := svc.Add(req.key, config)
if err != nil {
return nil, err
}
res := configRes{
id: saved.MFThing,
created: true,
}
return res, nil
}
}
func viewEndpoint(svc bootstrap.Service) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(entityReq)
if err := req.validate(); err != nil {
return nil, err
}
config, err := svc.View(req.key, req.id)
if err != nil {
return nil, err
}
res := viewRes{
MFThing: config.MFThing,
MFKey: config.MFKey,
Channels: config.MFChannels,
ExternalID: config.ExternalID,
ExternalKey: config.ExternalKey,
Content: config.Content,
State: config.State,
}
return res, nil
}
}
func updateEndpoint(svc bootstrap.Service) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(updateReq)
if err := req.validate(); err != nil {
return nil, err
}
config := bootstrap.Config{
MFThing: req.id,
MFChannels: req.Channels,
Content: req.Content,
State: req.State,
}
if err := svc.Update(req.key, config); err != nil {
return nil, err
}
res := configRes{
id: config.MFThing,
created: false,
}
return res, nil
}
}
func listEndpoint(svc bootstrap.Service) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(listReq)
if err := req.validate(); err != nil {
return nil, err
}
configs, err := svc.List(req.key, req.filter, req.offset, req.limit)
if err != nil {
return nil, err
}
res := listRes{
Configs: []viewRes{},
}
for _, cfg := range configs {
view := viewRes{
MFThing: cfg.MFThing,
MFKey: cfg.MFKey,
Channels: cfg.MFChannels,
ExternalID: cfg.ExternalID,
ExternalKey: cfg.ExternalKey,
Content: cfg.Content,
State: cfg.State,
}
res.Configs = append(res.Configs, view)
}
return res, nil
}
}
func removeEndpoint(svc bootstrap.Service) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(entityReq)
if err := req.validate(); err != nil {
return removeRes{}, err
}
if err := svc.Remove(req.key, req.id); err != nil {
return nil, err
}
return removeRes{}, nil
}
}
func bootstrapEndpoint(svc bootstrap.Service, reader bootstrap.ConfigReader) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(bootstrapReq)
if err := req.validate(); err != nil {
return nil, err
}
cfg, err := svc.Bootstrap(req.key, req.id)
if err != nil {
return nil, err
}
return reader.ReadConfig(cfg)
}
}
func stateEndpoint(svc bootstrap.Service) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(changeStateReq)
if err := req.validate(); err != nil {
return nil, err
}
if err := svc.ChangeState(req.key, req.id, req.State); err != nil {
return nil, err
}
return stateRes{}, nil
}
}