Mainflux.mainflux/sdk/go/sdk.go

262 lines
7.7 KiB
Go
Raw Normal View History

// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0
package sdk
import (
"crypto/tls"
"errors"
"fmt"
"net/http"
"github.com/mainflux/mainflux"
)
const (
// CTJSON represents JSON content type.
CTJSON ContentType = "application/json"
// CTJSONSenML represents JSON SenML content type.
CTJSONSenML ContentType = "application/senml+json"
// CTBinary represents binary content type.
CTBinary ContentType = "application/octet-stream"
)
var (
// ErrConflict indicates that create or update of entity failed because
// entity with same name already exists.
ErrConflict = errors.New("entity already exists")
// ErrFailedCreation indicates that entity creation failed.
ErrFailedCreation = errors.New("failed to create entity")
// ErrFailedUpdate indicates that entity update failed.
ErrFailedUpdate = errors.New("failed to update entity")
MF-417 - Implement SDK tests (#438) * Add SKD tests for creating channel Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK tests for Channel function Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add list channels over SDK tests Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK tests for updating channel Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK tests for deleting channel Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add users service SDK tests Signed-off-by: Ivan Milošević <iva@blokovi.com> * SDK things tests Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK test for connecting and disconnecting things from channel Signed-off-by: Ivan Milošević <iva@blokovi.com> * testing SDK sending messages Signed-off-by: Ivan Milošević <iva@blokovi.com> * add tests for SDK func SetContentType Signed-off-by: Ivan Milošević <iva@blokovi.com> * add all test cases for sending messages Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add handling StatusBadRequest when deleting thing over SDK Signed-off-by: Ivan Milošević <iva@blokovi.com> * Update error responses when deleting channel and thing Signed-off-by: Ivan Milošević <iva@blokovi.com> * Removed unused Unauthorized response when creating user Signed-off-by: Ivan Milošević <iva@blokovi.com> * update testing CreateChannel, tests if response is some string Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add bad request case in testing CreateToken Signed-off-by: Ivan Milošević <iva@blokovi.com> * Remove response error conflict from things service Signed-off-by: Ivan Milošević <iva@blokovi.com> * Fix definition of sdk.ErrFailedDisconnect and return error in test cases for disconnecting things Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add handling errors and formatting code Signed-off-by: Ivan Milošević <iva@blokovi.com> * Defined new ErrFailedPublish error in SDK Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK test for version Signed-off-by: Ivan Milošević <iva@blokovi.com> * Delete unused http response status in sdk.DeleteChannel Signed-off-by: Ivan Milošević <iva@blokovi.com>
2018-11-20 04:27:01 +08:00
// ErrFailedPublish indicates that publishing message failed.
ErrFailedPublish = errors.New("failed to publish message")
// ErrFailedRead indicates that read messages failed.
ErrFailedRead = errors.New("failed to read messages")
// ErrFailedRemoval indicates that entity removal failed.
ErrFailedRemoval = errors.New("failed to remove entity")
// ErrFailedConnection indicates that connecting thing to channel failed.
ErrFailedConnection = errors.New("failed to connect thing to channel")
// ErrFailedDisconnect indicates that disconnecting thing from a channel failed.
MF-417 - Implement SDK tests (#438) * Add SKD tests for creating channel Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK tests for Channel function Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add list channels over SDK tests Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK tests for updating channel Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK tests for deleting channel Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add users service SDK tests Signed-off-by: Ivan Milošević <iva@blokovi.com> * SDK things tests Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK test for connecting and disconnecting things from channel Signed-off-by: Ivan Milošević <iva@blokovi.com> * testing SDK sending messages Signed-off-by: Ivan Milošević <iva@blokovi.com> * add tests for SDK func SetContentType Signed-off-by: Ivan Milošević <iva@blokovi.com> * add all test cases for sending messages Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add handling StatusBadRequest when deleting thing over SDK Signed-off-by: Ivan Milošević <iva@blokovi.com> * Update error responses when deleting channel and thing Signed-off-by: Ivan Milošević <iva@blokovi.com> * Removed unused Unauthorized response when creating user Signed-off-by: Ivan Milošević <iva@blokovi.com> * update testing CreateChannel, tests if response is some string Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add bad request case in testing CreateToken Signed-off-by: Ivan Milošević <iva@blokovi.com> * Remove response error conflict from things service Signed-off-by: Ivan Milošević <iva@blokovi.com> * Fix definition of sdk.ErrFailedDisconnect and return error in test cases for disconnecting things Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add handling errors and formatting code Signed-off-by: Ivan Milošević <iva@blokovi.com> * Defined new ErrFailedPublish error in SDK Signed-off-by: Ivan Milošević <iva@blokovi.com> * Add SDK test for version Signed-off-by: Ivan Milošević <iva@blokovi.com> * Delete unused http response status in sdk.DeleteChannel Signed-off-by: Ivan Milošević <iva@blokovi.com>
2018-11-20 04:27:01 +08:00
ErrFailedDisconnect = errors.New("failed to disconnect thing from channel")
// ErrInvalidArgs indicates that invalid argument was passed.
ErrInvalidArgs = errors.New("invalid argument passed")
// ErrFetchFailed indicates that fetching of entity data failed.
ErrFetchFailed = errors.New("failed to fetch entity")
// ErrUnauthorized indicates unauthorized access.
ErrUnauthorized = errors.New("unauthorized access")
// ErrNotFound indicates that entity doesn't exist.
ErrNotFound = errors.New("entity not found")
// ErrInvalidContentType indicates that nonexistent message content type
// was passed.
ErrInvalidContentType = errors.New("Unknown Content Type")
)
// ContentType represents all possible content types.
type ContentType string
var _ SDK = (*mfSDK)(nil)
// User represents mainflux user its credentials.
type User struct {
Email string `json:"email"`
Password string `json:"password"`
}
// Thing represents mainflux thing.
type Thing struct {
MF-549 - Change metadata format from JSON string to JSON object (#706) * Update metadata type in things service Update things service so that metadata has map type. Update repo implementation by adding sqlx lib. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add sqlx lib to bootstrap service Add sqlx lib to bootstrap service and update metadata field type. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update metadata in redis streams consumer Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update tests for bootstrap service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix mongo reader logging and driver version Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix mongo reader and writer Fix mongo reader and writer by updating driver version. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update SDK with new metadata format Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update LoRa adapter with new metadata format Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update users service in order to use sqlx Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Replace anonymous struct with map Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update docs for LoRa adapter Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix LoRa application metadata format Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix metadata format in LoRa docs Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add metadata2 var to SDK things test Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com>
2019-04-16 20:58:56 +08:00
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Key string `json:"key,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
MF-483 - Enable channels and devices corresponding lists in backend (#520) * Add list channels by thing id endpoint Add list channels by thing id endpoint to things service. Add pagination format and logic. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add fetch channels by thing endpoint Add fetch channels by thing endpoint with pagination. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update list endpoints to contain pagination Update list endpoints to contain pagination metadata. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add tests for two new endpoints Add tests for two new endpoints and update existing ones. Also, remove connected field from channel response. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix tests for SDK Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add SDK methods for new endpoints Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update swagger docs for things service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add error handling to http tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix response body in http tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Remove unused responses from things service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add test cases to things postgres tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add test cases for event sourcing Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com>
2019-01-08 18:53:24 +08:00
// ThingsPage contains list of things in a page with proper metadata.
type ThingsPage struct {
Things []Thing `json:"things"`
Total uint64 `json:"total"`
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
}
// Channel represents mainflux channel.
type Channel struct {
MF-549 - Change metadata format from JSON string to JSON object (#706) * Update metadata type in things service Update things service so that metadata has map type. Update repo implementation by adding sqlx lib. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add sqlx lib to bootstrap service Add sqlx lib to bootstrap service and update metadata field type. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update metadata in redis streams consumer Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update tests for bootstrap service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix mongo reader logging and driver version Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix mongo reader and writer Fix mongo reader and writer by updating driver version. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update SDK with new metadata format Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update LoRa adapter with new metadata format Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update users service in order to use sqlx Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Replace anonymous struct with map Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update docs for LoRa adapter Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix LoRa application metadata format Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix metadata format in LoRa docs Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add metadata2 var to SDK things test Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com>
2019-04-16 20:58:56 +08:00
ID string `json:"id,omitempty"`
Name string `json:"name"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
MF-483 - Enable channels and devices corresponding lists in backend (#520) * Add list channels by thing id endpoint Add list channels by thing id endpoint to things service. Add pagination format and logic. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add fetch channels by thing endpoint Add fetch channels by thing endpoint with pagination. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update list endpoints to contain pagination Update list endpoints to contain pagination metadata. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add tests for two new endpoints Add tests for two new endpoints and update existing ones. Also, remove connected field from channel response. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix tests for SDK Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add SDK methods for new endpoints Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update swagger docs for things service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add error handling to http tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix response body in http tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Remove unused responses from things service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add test cases to things postgres tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add test cases for event sourcing Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com>
2019-01-08 18:53:24 +08:00
}
// ChannelsPage contains list of channels in a page with proper metadata.
type ChannelsPage struct {
Channels []Channel `json:"channels"`
Total uint64 `json:"total"`
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
}
// MessagesPage contains list of messages in a page with proper metadata.
type MessagesPage struct {
Total uint64 `json:"total"`
Offset uint64 `json:"offset"`
Limit uint64 `json:"limit"`
Messages []mainflux.Message `json:"messages,omitempty"`
}
// ConnectionIDs contains ID lists of things and channels to be connected
type ConnectionIDs struct {
ChannelIDs []string `json:"channel_ids"`
ThingIDs []string `json:"thing_ids"`
}
// SDK contains Mainflux API.
type SDK interface {
// CreateUser registers mainflux user.
CreateUser(user User) error
// CreateToken receives credentials and returns user token.
CreateToken(user User) (string, error)
// CreateThing registers new thing and returns its id.
CreateThing(thing Thing, token string) (string, error)
// CreateThings registers new things and returns their ids.
CreateThings(things []Thing, token string) ([]Thing, error)
// Things returns page of things.
Things(token string, offset, limit uint64, name string) (ThingsPage, error)
MF-483 - Enable channels and devices corresponding lists in backend (#520) * Add list channels by thing id endpoint Add list channels by thing id endpoint to things service. Add pagination format and logic. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add fetch channels by thing endpoint Add fetch channels by thing endpoint with pagination. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update list endpoints to contain pagination Update list endpoints to contain pagination metadata. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add tests for two new endpoints Add tests for two new endpoints and update existing ones. Also, remove connected field from channel response. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix tests for SDK Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add SDK methods for new endpoints Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update swagger docs for things service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add error handling to http tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix response body in http tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Remove unused responses from things service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add test cases to things postgres tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add test cases for event sourcing Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com>
2019-01-08 18:53:24 +08:00
// ThingsByChannel returns page of things that are connected to specified
// channel.
ThingsByChannel(token, chanID string, offset, limit uint64) (ThingsPage, error)
// Thing returns thing object by id.
Thing(id, token string) (Thing, error)
// UpdateThing updates existing thing.
UpdateThing(thing Thing, token string) error
// DeleteThing removes existing thing.
DeleteThing(id, token string) error
// ConnectThing connects thing to specified channel by id.
ConnectThing(thingID, chanID, token string) error
// Connect bulk connects things to channels specified by id.
Connect(conns ConnectionIDs, token string) error
// DisconnectThing disconnect thing from specified channel by id.
DisconnectThing(thingID, chanID, token string) error
// CreateChannel creates new channel and returns its id.
CreateChannel(channel Channel, token string) (string, error)
// CreateChannels registers new channels and returns their ids.
CreateChannels(channels []Channel, token string) ([]Channel, error)
// Channels returns page of channels.
Channels(token string, offset, limit uint64, name string) (ChannelsPage, error)
MF-483 - Enable channels and devices corresponding lists in backend (#520) * Add list channels by thing id endpoint Add list channels by thing id endpoint to things service. Add pagination format and logic. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add fetch channels by thing endpoint Add fetch channels by thing endpoint with pagination. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update list endpoints to contain pagination Update list endpoints to contain pagination metadata. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add tests for two new endpoints Add tests for two new endpoints and update existing ones. Also, remove connected field from channel response. Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix tests for SDK Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add SDK methods for new endpoints Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Update swagger docs for things service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add error handling to http tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Fix response body in http tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Remove unused responses from things service Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add test cases to things postgres tests Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add test cases for event sourcing Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com>
2019-01-08 18:53:24 +08:00
// ChannelsByThing returns page of channels that are connected to specified
// thing.
ChannelsByThing(token, thingID string, offset, limit uint64) (ChannelsPage, error)
// Channel returns channel data by id.
Channel(id, token string) (Channel, error)
// UpdateChannel updates existing channel.
UpdateChannel(channel Channel, token string) error
// DeleteChannel removes existing channel.
DeleteChannel(id, token string) error
// SendMessage send message to specified channel.
SendMessage(chanID, msg, token string) error
// ReadMessages read messages of specified channel.
ReadMessages(chanID, token string) (MessagesPage, error)
// SetContentType sets message content type.
SetContentType(ct ContentType) error
// Version returns used mainflux version.
Version() (string, error)
}
type mfSDK struct {
baseURL string
readerURL string
readerPrefix string
usersPrefix string
thingsPrefix string
channelsPrefix string
httpAdapterPrefix string
msgContentType ContentType
client *http.Client
}
// Config contains sdk configuration parameters.
type Config struct {
BaseURL string
ReaderURL string
ReaderPrefix string
UsersPrefix string
ThingsPrefix string
HTTPAdapterPrefix string
MsgContentType ContentType
TLSVerification bool
}
// NewSDK returns new mainflux SDK instance.
func NewSDK(conf Config) SDK {
return &mfSDK{
baseURL: conf.BaseURL,
readerURL: conf.ReaderURL,
readerPrefix: conf.ReaderPrefix,
usersPrefix: conf.UsersPrefix,
thingsPrefix: conf.ThingsPrefix,
httpAdapterPrefix: conf.HTTPAdapterPrefix,
msgContentType: conf.MsgContentType,
client: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: !conf.TLSVerification,
},
},
},
}
}
func (sdk mfSDK) sendRequest(req *http.Request, token, contentType string) (*http.Response, error) {
if token != "" {
req.Header.Set("Authorization", token)
}
if contentType != "" {
req.Header.Add("Content-Type", contentType)
}
return sdk.client.Do(req)
}
func createURL(baseURL, prefix, endpoint string) string {
if prefix == "" {
return fmt.Sprintf("%s/%s", baseURL, endpoint)
}
return fmt.Sprintf("%s/%s/%s", baseURL, prefix, endpoint)
}