refactoring
This commit is contained in:
parent
3983a91475
commit
5aed4560e9
10 changed files with 167 additions and 143 deletions
|
@ -31,9 +31,10 @@ func NewRestAPI(connection string, weatherStorage storage.WeatherStorage, sensor
|
||||||
//Start a new Rest-API instance
|
//Start a new Rest-API instance
|
||||||
func (api *weatherRestApi) Start() error {
|
func (api *weatherRestApi) Start() error {
|
||||||
handler := api.handleRequests()
|
handler := api.handleRequests()
|
||||||
return http.ListenAndServe(api.connection, handler) // http.ListenAndServe(api.connection, handler)
|
return http.ListenAndServe(api.connection, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Close the rest api
|
||||||
func (api *weatherRestApi) Close() {
|
func (api *weatherRestApi) Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,24 +78,24 @@ func (api *weatherRestApi) getData(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
data, err := api.weaterStorage.GetData(query)
|
data, err := api.weaterStorage.GetData(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
http.Error(w, "error executing query", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res := storage.ToMap(storage.GetOnlyQueriedFields(data, query))
|
res := storage.ToMap(storage.GetOnlyQueriedFields(data, query))
|
||||||
json.NewEncoder(w).Encode(res)
|
json.NewEncoder(w).Encode(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *weatherRestApi) randomWeatherHandler(w http.ResponseWriter, r *http.Request) {
|
func (api *weatherRestApi) randomWeatherHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
datapoint := storage.NewRandomWeatherData(uuid.Nil)
|
|
||||||
|
|
||||||
w.Header().Add("content-type", "application/json")
|
w.Header().Add("content-type", "application/json")
|
||||||
json.NewEncoder(w).Encode(datapoint)
|
json.NewEncoder(w).Encode(storage.NewRandomWeatherData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *weatherRestApi) randomWeatherListHandler(w http.ResponseWriter, r *http.Request) {
|
func (api *weatherRestApi) randomWeatherListHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var datapoints = make([]storage.WeatherData, 0)
|
var datapoints = make([]*storage.WeatherData, 0)
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
datapoints = append(datapoints, storage.NewRandomWeatherData(uuid.Nil))
|
datapoints = append(datapoints, storage.NewRandomWeatherData())
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Add("content-type", "application/json")
|
w.Header().Add("content-type", "application/json")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
@ -21,7 +21,7 @@ func (registry *inmemorySensorRegistry) RegisterSensorByName(name string) (*Weat
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if exist {
|
if exist {
|
||||||
return nil, fmt.Errorf("Sensorname already exists")
|
return nil, errors.New("sensorname already exists")
|
||||||
}
|
}
|
||||||
sensor := new(WeatherSensor)
|
sensor := new(WeatherSensor)
|
||||||
sensor.Name = name
|
sensor.Name = name
|
||||||
|
@ -45,7 +45,7 @@ func (registry *inmemorySensorRegistry) ResolveSensorById(sensorId uuid.UUID) (*
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("sensor does not exist")
|
return nil, errors.New("sensor does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (registry *inmemorySensorRegistry) ExistSensor(sensor *WeatherSensor) (bool, error) {
|
func (registry *inmemorySensorRegistry) ExistSensor(sensor *WeatherSensor) (bool, error) {
|
|
@ -2,7 +2,7 @@ package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
"weather-data/config"
|
"weather-data/config"
|
||||||
|
@ -59,7 +59,7 @@ func (registry *mongodbSensorRegistry) RegisterSensorByName(name string) (*Weath
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if exist {
|
if exist {
|
||||||
return nil, fmt.Errorf("Sensorname already exists")
|
return nil, errors.New("sensorname already exists")
|
||||||
}
|
}
|
||||||
sensor := new(WeatherSensor)
|
sensor := new(WeatherSensor)
|
||||||
sensor.Name = name
|
sensor.Name = name
|
||||||
|
@ -96,7 +96,7 @@ func (registry *mongodbSensorRegistry) ResolveSensorById(sensorId uuid.UUID) (*W
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("sensor does not exist")
|
return nil, errors.New("sensor does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (registry *mongodbSensorRegistry) ExistSensor(sensor *WeatherSensor) (bool, error) {
|
func (registry *mongodbSensorRegistry) ExistSensor(sensor *WeatherSensor) (bool, error) {
|
||||||
|
|
20
storage/sensor-registry.go
Normal file
20
storage/sensor-registry.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import "github.com/google/uuid"
|
||||||
|
|
||||||
|
type SensorRegistry interface {
|
||||||
|
RegisterSensorByName(string) (*WeatherSensor, error)
|
||||||
|
ExistSensor(*WeatherSensor) (bool, error)
|
||||||
|
ResolveSensorById(uuid.UUID) (*WeatherSensor, error)
|
||||||
|
GetSensors() ([]*WeatherSensor, error)
|
||||||
|
Close() error
|
||||||
|
}
|
||||||
|
|
||||||
|
//WeatherSensor is the data for a new Sensorregistration
|
||||||
|
type WeatherSensor struct {
|
||||||
|
Name string
|
||||||
|
Id uuid.UUID
|
||||||
|
Location string
|
||||||
|
Longitude float64
|
||||||
|
Latitude float64
|
||||||
|
}
|
|
@ -3,8 +3,6 @@ package storage
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -28,28 +26,35 @@ func GetSensorValueTypes() []SensorValueType {
|
||||||
return []SensorValueType{Temperature, Pressure, Humidity, Co2Level}
|
return []SensorValueType{Temperature, Pressure, Humidity, Co2Level}
|
||||||
}
|
}
|
||||||
|
|
||||||
//WeatherStorage interface for different storage-implementations of weather data
|
|
||||||
type WeatherStorage interface {
|
|
||||||
Save(WeatherData) error
|
|
||||||
GetData(*WeatherQuery) ([]*WeatherData, error)
|
|
||||||
Close() error
|
|
||||||
}
|
|
||||||
|
|
||||||
type SensorRegistry interface {
|
|
||||||
RegisterSensorByName(string) (*WeatherSensor, error)
|
|
||||||
ExistSensor(*WeatherSensor) (bool, error)
|
|
||||||
ResolveSensorById(uuid.UUID) (*WeatherSensor, error)
|
|
||||||
GetSensors() ([]*WeatherSensor, error)
|
|
||||||
Close() error
|
|
||||||
}
|
|
||||||
|
|
||||||
//WeatherData type
|
//WeatherData type
|
||||||
type WeatherData struct {
|
type WeatherData struct {
|
||||||
Values map[SensorValueType]float64
|
Values map[SensorValueType]float64
|
||||||
SensorId uuid.UUID `json:"sensorId"`
|
SensorId uuid.UUID
|
||||||
TimeStamp time.Time `json:"timestamp"`
|
TimeStamp time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewRandomWeatherData creates random WeatherData
|
||||||
|
func NewRandomWeatherData() *WeatherData {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
var data = new(WeatherData)
|
||||||
|
data.Values = make(map[SensorValueType]float64)
|
||||||
|
data.Values[Humidity] = rand.Float64() * 100
|
||||||
|
data.Values[Pressure] = rand.Float64()*80 + 960
|
||||||
|
data.Values[Temperature] = rand.Float64()*40 - 5
|
||||||
|
data.Values[Co2Level] = rand.Float64()*50 + 375
|
||||||
|
data.SensorId = uuid.New()
|
||||||
|
data.TimeStamp = time.Now()
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewRandomWeatherData creates random WeatherData
|
||||||
|
func NewWeatherData() *WeatherData {
|
||||||
|
var data = new(WeatherData)
|
||||||
|
data.Values = make(map[SensorValueType]float64)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
//OnlyQueriedValues remove all values not contained by the WeatherQuery
|
||||||
func (data *WeatherData) OnlyQueriedValues(query *WeatherQuery) *WeatherData {
|
func (data *WeatherData) OnlyQueriedValues(query *WeatherQuery) *WeatherData {
|
||||||
for _, sensorValueType := range GetSensorValueTypes() {
|
for _, sensorValueType := range GetSensorValueTypes() {
|
||||||
if !query.Values[sensorValueType] {
|
if !query.Values[sensorValueType] {
|
||||||
|
@ -59,19 +64,21 @@ func (data *WeatherData) OnlyQueriedValues(query *WeatherQuery) *WeatherData {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ToMap converts WeatherData to a map[string]interface{}
|
||||||
func (data *WeatherData) ToMap() map[string]interface{} {
|
func (data *WeatherData) ToMap() map[string]interface{} {
|
||||||
mappedData := map[string]interface{}{
|
mappedData := map[string]interface{}{
|
||||||
"sensorId": data.SensorId.String(),
|
SensorId: data.SensorId.String(),
|
||||||
"timeStamp": data.TimeStamp.String(),
|
TimeStamp: data.TimeStamp.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for sensorValueType, value := range data.Values {
|
for sensorValueType, value := range data.Values {
|
||||||
mappedData[string(sensorValueType)] = value //strconv.FormatFloat(value, 'f', -1, 64)
|
mappedData[string(sensorValueType)] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
return mappedData
|
return mappedData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FromMap converts a map[string]interface{} to WeatherData
|
||||||
func FromMap(value map[string]interface{}) (*WeatherData, error) {
|
func FromMap(value map[string]interface{}) (*WeatherData, error) {
|
||||||
var data = new(WeatherData)
|
var data = new(WeatherData)
|
||||||
data.Values = make(map[SensorValueType]float64)
|
data.Values = make(map[SensorValueType]float64)
|
||||||
|
@ -113,6 +120,7 @@ func FromMap(value map[string]interface{}) (*WeatherData, error) {
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//GetOnlyQueriedFields execute onlyQueriedValues on WeatherData slice an return this
|
||||||
func GetOnlyQueriedFields(dataPoints []*WeatherData, query *WeatherQuery) []*WeatherData {
|
func GetOnlyQueriedFields(dataPoints []*WeatherData, query *WeatherQuery) []*WeatherData {
|
||||||
for _, data := range dataPoints {
|
for _, data := range dataPoints {
|
||||||
data.OnlyQueriedValues(query)
|
data.OnlyQueriedValues(query)
|
||||||
|
@ -120,6 +128,7 @@ func GetOnlyQueriedFields(dataPoints []*WeatherData, query *WeatherQuery) []*Wea
|
||||||
return dataPoints
|
return dataPoints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ToMap mapps all WeatherData of a slice ToMap
|
||||||
func ToMap(dataPoints []*WeatherData) []map[string]interface{} {
|
func ToMap(dataPoints []*WeatherData) []map[string]interface{} {
|
||||||
var result = make([]map[string]interface{}, 0)
|
var result = make([]map[string]interface{}, 0)
|
||||||
for _, data := range dataPoints {
|
for _, data := range dataPoints {
|
||||||
|
@ -127,77 +136,3 @@ func ToMap(dataPoints []*WeatherData) []map[string]interface{} {
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
//WeatherSensor is the data for a new Sensorregistration
|
|
||||||
type WeatherSensor struct {
|
|
||||||
Name string
|
|
||||||
Id uuid.UUID
|
|
||||||
Location string
|
|
||||||
Longitude float64
|
|
||||||
Latitude float64
|
|
||||||
}
|
|
||||||
|
|
||||||
type WeatherQuery struct {
|
|
||||||
Start time.Time
|
|
||||||
End time.Time
|
|
||||||
SensorId uuid.UUID
|
|
||||||
Values map[SensorValueType]bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (query *WeatherQuery) Init() {
|
|
||||||
query.Start = time.Now().Add(-1 * time.Hour * 24 * 14)
|
|
||||||
query.End = time.Now()
|
|
||||||
query.SensorId = uuid.Nil
|
|
||||||
query.Values = make(map[SensorValueType]bool)
|
|
||||||
for _, sensorValueType := range GetSensorValueTypes() {
|
|
||||||
query.Values[sensorValueType] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseFromUrlQuery(query url.Values) (*WeatherQuery, error) {
|
|
||||||
result := new(WeatherQuery)
|
|
||||||
result.Init()
|
|
||||||
|
|
||||||
start := query.Get("start")
|
|
||||||
end := query.Get("end")
|
|
||||||
|
|
||||||
if len(start) != 0 {
|
|
||||||
if tval, err := time.Parse(time.RFC3339, start); err == nil {
|
|
||||||
result.Start = tval
|
|
||||||
} else if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(end) != 0 {
|
|
||||||
if tval, err := time.Parse(time.RFC3339, end); err == nil {
|
|
||||||
result.End = tval
|
|
||||||
} else if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, sensorValueType := range GetSensorValueTypes() {
|
|
||||||
queryParam := query.Get(string(sensorValueType))
|
|
||||||
if bval, err := strconv.ParseBool(queryParam); err == nil {
|
|
||||||
result.Values[sensorValueType] = bval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//NewRandomWeatherData creates random WeatherData with given Location
|
|
||||||
func NewRandomWeatherData(sensorId uuid.UUID) WeatherData {
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
var data WeatherData
|
|
||||||
data.Values[Humidity] = rand.Float64() * 100
|
|
||||||
data.Values[Pressure] = rand.Float64()*80 + 960
|
|
||||||
data.Values[Temperature] = rand.Float64()*40 - 5
|
|
||||||
data.Values[Co2Level] = rand.Float64()*50 + 375
|
|
||||||
data.SensorId = sensorId
|
|
||||||
data.TimeStamp = time.Now()
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
68
storage/weather-query.go
Normal file
68
storage/weather-query.go
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WeatherQuery struct {
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
SensorId uuid.UUID
|
||||||
|
Values map[SensorValueType]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewWeatherQuery creates a new empty WeatherQuery
|
||||||
|
func NewWeatherQuery() *WeatherQuery {
|
||||||
|
query := new(WeatherQuery)
|
||||||
|
query.Values = make(map[SensorValueType]bool)
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
func (query *WeatherQuery) Init() {
|
||||||
|
query.Start = time.Now().Add(-1 * time.Hour * 24 * 14)
|
||||||
|
query.End = time.Now()
|
||||||
|
query.SensorId = uuid.Nil
|
||||||
|
for _, sensorValueType := range GetSensorValueTypes() {
|
||||||
|
query.Values[sensorValueType] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseFromUrlQuery(query url.Values) (*WeatherQuery, error) {
|
||||||
|
result := NewWeatherQuery()
|
||||||
|
result.Init()
|
||||||
|
|
||||||
|
start := query.Get("start")
|
||||||
|
end := query.Get("end")
|
||||||
|
|
||||||
|
if len(start) != 0 {
|
||||||
|
if tval, err := time.Parse(time.RFC3339, start); err == nil {
|
||||||
|
result.Start = tval
|
||||||
|
} else if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(end) != 0 {
|
||||||
|
if tval, err := time.Parse(time.RFC3339, end); err == nil {
|
||||||
|
result.End = tval
|
||||||
|
} else if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sensorValueType := range GetSensorValueTypes() {
|
||||||
|
queryParam := query.Get(string(sensorValueType))
|
||||||
|
if bval, err := strconv.ParseBool(queryParam); err == nil {
|
||||||
|
result.Values[sensorValueType] = bval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
8
storage/weather-storage.go
Normal file
8
storage/weather-storage.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
//WeatherStorage interface for different storage-implementations of weather data
|
||||||
|
type WeatherStorage interface {
|
||||||
|
Save(WeatherData) error
|
||||||
|
GetData(*WeatherQuery) ([]*WeatherData, error)
|
||||||
|
Close() error
|
||||||
|
}
|
|
@ -77,8 +77,7 @@ func (source *mqttWeatherSource) mqttMessageHandler() mqtt.MessageHandler {
|
||||||
lastWeatherData, found := source.getUnwrittenDatapoints(sensorId)
|
lastWeatherData, found := source.getUnwrittenDatapoints(sensorId)
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
lastWeatherData = new(storage.WeatherData)
|
lastWeatherData = storage.NewWeatherData()
|
||||||
lastWeatherData.Values = make(map[storage.SensorValueType]float64)
|
|
||||||
lastWeatherData.SensorId = sensorId
|
lastWeatherData.SensorId = sensorId
|
||||||
source.lastWeatherDataPoints = append(source.lastWeatherDataPoints, lastWeatherData)
|
source.lastWeatherDataPoints = append(source.lastWeatherDataPoints, lastWeatherData)
|
||||||
}
|
}
|
||||||
|
@ -91,15 +90,6 @@ func (source *mqttWeatherSource) mqttMessageHandler() mqtt.MessageHandler {
|
||||||
sensorValueType := storage.SensorValueType(regexTopic.FindStringSubmatch(msg.Topic())[3])
|
sensorValueType := storage.SensorValueType(regexTopic.FindStringSubmatch(msg.Topic())[3])
|
||||||
lastWeatherData.Values[sensorValueType] = value
|
lastWeatherData.Values[sensorValueType] = value
|
||||||
lastWeatherData.TimeStamp = time.Now()
|
lastWeatherData.TimeStamp = time.Now()
|
||||||
|
|
||||||
/* only use predefined sensorValueTypes
|
|
||||||
for _, sensorValueType := range storage.GetSensorValueTypes() {
|
|
||||||
if strings.HasSuffix(msg.Topic(), string(sensorValueType)) {
|
|
||||||
lastWeatherData.Values[sensorValueType], _ = strconv.ParseFloat(string(msg.Payload()), 64)
|
|
||||||
lastWeatherData.TimeStamp = time.Now()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +97,7 @@ func (source *mqttWeatherSource) publishDataValues() {
|
||||||
for {
|
for {
|
||||||
for len(source.lastWeatherDataPoints) != 0 {
|
for len(source.lastWeatherDataPoints) != 0 {
|
||||||
current := *source.lastWeatherDataPoints[0]
|
current := *source.lastWeatherDataPoints[0]
|
||||||
diff := time.Now().Sub(current.TimeStamp)
|
diff := time.Since(current.TimeStamp)
|
||||||
if diff >= source.config.MinDistToLastValue {
|
if diff >= source.config.MinDistToLastValue {
|
||||||
if err := source.newWeatherData(current); err != nil {
|
if err := source.newWeatherData(current); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -120,7 +110,6 @@ func (source *mqttWeatherSource) publishDataValues() {
|
||||||
}
|
}
|
||||||
time.Sleep(source.config.PublishInterval)
|
time.Sleep(source.config.PublishInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (source *mqttWeatherSource) getUnwrittenDatapoints(sensorId uuid.UUID) (*storage.WeatherData, bool) {
|
func (source *mqttWeatherSource) getUnwrittenDatapoints(sensorId uuid.UUID) (*storage.WeatherData, bool) {
|
||||||
|
|
24
weathersource/weather-source-base.go
Normal file
24
weathersource/weather-source-base.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package weathersource
|
||||||
|
|
||||||
|
import "weather-data/storage"
|
||||||
|
|
||||||
|
//WeatherSourceBase is the lowlevel-implementation of the WeatherSource interface, intended to used by highlevel-implementations
|
||||||
|
type WeatherSourceBase struct {
|
||||||
|
newWeatherDataCallbackFuncs []NewWeatherDataCallbackFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
//AddNewWeatherDataCallback adds a new callbackMethod for incoming weather data
|
||||||
|
func (source *WeatherSourceBase) AddNewWeatherDataCallback(callback NewWeatherDataCallbackFunc) {
|
||||||
|
source.newWeatherDataCallbackFuncs = append(source.newWeatherDataCallbackFuncs, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewWeatherData executes all newWeatherDataCallbackFuncs for this datapoint
|
||||||
|
func (source *WeatherSourceBase) NewWeatherData(datapoint storage.WeatherData) error {
|
||||||
|
for _, callback := range source.newWeatherDataCallbackFuncs {
|
||||||
|
err := callback(datapoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -10,24 +10,3 @@ type WeatherSource interface {
|
||||||
AddNewWeatherDataCallback(NewWeatherDataCallbackFunc)
|
AddNewWeatherDataCallback(NewWeatherDataCallbackFunc)
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
//WeatherSourceBase is the lowlevel-implementation of the WeatherSource interface, intended to used by highlevel-implementations
|
|
||||||
type WeatherSourceBase struct {
|
|
||||||
newWeatherDataCallbackFuncs []NewWeatherDataCallbackFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
//AddNewWeatherDataCallback adds a new callbackMethod for incoming weather data
|
|
||||||
func (source *WeatherSourceBase) AddNewWeatherDataCallback(callback NewWeatherDataCallbackFunc) {
|
|
||||||
source.newWeatherDataCallbackFuncs = append(source.newWeatherDataCallbackFuncs, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
//NewWeatherData executes all newWeatherDataCallbackFuncs for this datapoint
|
|
||||||
func (source *WeatherSourceBase) NewWeatherData(datapoint storage.WeatherData) error {
|
|
||||||
for _, callback := range source.newWeatherDataCallbackFuncs {
|
|
||||||
err := callback(datapoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue