mirror of
https://github.com/mainflux/mainflux.git
synced 2025-05-02 22:17:10 +08:00

* 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>
186 lines
3.8 KiB
Go
186 lines
3.8 KiB
Go
//
|
|
// Copyright (c) 2018
|
|
// Mainflux
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package mocks
|
|
|
|
import (
|
|
"sort"
|
|
"strconv"
|
|
"sync"
|
|
|
|
"github.com/mainflux/mainflux/bootstrap"
|
|
)
|
|
|
|
var _ bootstrap.ConfigRepository = (*configRepositoryMock)(nil)
|
|
|
|
type configRepositoryMock struct {
|
|
mu sync.Mutex
|
|
counter uint64
|
|
configs map[string]bootstrap.Config
|
|
unknown map[string]string
|
|
}
|
|
|
|
// NewConfigsRepository creates in-memory thing repository.
|
|
func NewConfigsRepository(unknown map[string]string) bootstrap.ConfigRepository {
|
|
return &configRepositoryMock{
|
|
configs: make(map[string]bootstrap.Config),
|
|
unknown: unknown,
|
|
}
|
|
}
|
|
|
|
func (crm *configRepositoryMock) Save(config bootstrap.Config) (string, error) {
|
|
crm.mu.Lock()
|
|
defer crm.mu.Unlock()
|
|
|
|
for _, v := range crm.configs {
|
|
if v.MFThing == config.MFThing || v.ExternalID == config.ExternalID {
|
|
return "", bootstrap.ErrConflict
|
|
}
|
|
}
|
|
|
|
crm.counter++
|
|
config.MFThing = strconv.FormatUint(crm.counter, 10)
|
|
crm.configs[config.MFThing] = config
|
|
delete(crm.unknown, config.ExternalID)
|
|
|
|
return config.MFThing, nil
|
|
}
|
|
|
|
func (crm *configRepositoryMock) RetrieveByID(key, id string) (bootstrap.Config, error) {
|
|
c, ok := crm.configs[id]
|
|
if !ok {
|
|
return bootstrap.Config{}, bootstrap.ErrNotFound
|
|
}
|
|
if c.Owner != key {
|
|
return bootstrap.Config{}, bootstrap.ErrUnauthorizedAccess
|
|
}
|
|
|
|
return c, nil
|
|
|
|
}
|
|
|
|
func (crm *configRepositoryMock) RetrieveAll(key string, filter bootstrap.Filter, offset, limit uint64) []bootstrap.Config {
|
|
configs := make([]bootstrap.Config, 0)
|
|
|
|
if offset < 0 || limit <= 0 {
|
|
return configs
|
|
}
|
|
|
|
first := uint64(offset) + 1
|
|
last := first + uint64(limit)
|
|
var state bootstrap.State = -1
|
|
if s, ok := filter["state"]; ok {
|
|
val, _ := strconv.Atoi(s)
|
|
state = bootstrap.State(val)
|
|
}
|
|
|
|
for _, v := range crm.configs {
|
|
id, _ := strconv.ParseUint(v.MFThing, 10, 64)
|
|
if id >= first && id < last {
|
|
if (state == -1 || v.State == state) && v.Owner == key {
|
|
configs = append(configs, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
sort.SliceStable(configs, func(i, j int) bool {
|
|
return configs[i].MFThing < configs[j].MFThing
|
|
})
|
|
|
|
return configs
|
|
}
|
|
|
|
func (crm *configRepositoryMock) RetrieveByExternalID(externalKey, externalID string) (bootstrap.Config, error) {
|
|
for _, thing := range crm.configs {
|
|
if thing.ExternalID == externalID && thing.ExternalKey == externalKey {
|
|
return thing, nil
|
|
}
|
|
}
|
|
|
|
return bootstrap.Config{}, bootstrap.ErrNotFound
|
|
}
|
|
|
|
func (crm *configRepositoryMock) Update(config bootstrap.Config) error {
|
|
crm.mu.Lock()
|
|
defer crm.mu.Unlock()
|
|
|
|
if _, ok := crm.configs[config.MFThing]; !ok {
|
|
return bootstrap.ErrNotFound
|
|
}
|
|
|
|
crm.configs[config.MFThing] = config
|
|
|
|
return nil
|
|
}
|
|
|
|
func (crm *configRepositoryMock) Remove(key, id string) error {
|
|
for k, v := range crm.configs {
|
|
if v.Owner == key && k == id {
|
|
delete(crm.configs, k)
|
|
break
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (crm *configRepositoryMock) ChangeState(key, id string, state bootstrap.State) error {
|
|
crm.mu.Lock()
|
|
defer crm.mu.Unlock()
|
|
|
|
config, ok := crm.configs[id]
|
|
if !ok {
|
|
return bootstrap.ErrNotFound
|
|
}
|
|
if config.Owner != key {
|
|
return bootstrap.ErrUnauthorizedAccess
|
|
}
|
|
|
|
config.State = state
|
|
crm.configs[id] = config
|
|
return nil
|
|
}
|
|
|
|
func (crm *configRepositoryMock) RetrieveUnknown(offset, limit uint64) []bootstrap.Config {
|
|
res := []bootstrap.Config{}
|
|
i := uint64(0)
|
|
l := int(limit)
|
|
var keys []string
|
|
for k := range crm.unknown {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
if i >= offset && len(res) < l {
|
|
res = append(res, bootstrap.Config{
|
|
ExternalID: k,
|
|
ExternalKey: crm.unknown[k],
|
|
})
|
|
}
|
|
i++
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func (crm *configRepositoryMock) RemoveUnknown(key, id string) error {
|
|
for k, v := range crm.unknown {
|
|
if k == id && v == key {
|
|
delete(crm.unknown, k)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (crm *configRepositoryMock) SaveUnknown(key, id string) error {
|
|
crm.unknown[id] = key
|
|
return nil
|
|
}
|