From 0b985ff4360cf9c4fbf20d86209c29429e6dbaca Mon Sep 17 00:00:00 2001 From: 3to5thpower Date: Sat, 7 Nov 2020 12:20:49 +0900 Subject: [PATCH] =?UTF-8?q?=E9=A0=91=E5=BC=B5=E3=81=A3=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/go.mod | 2 + backend/go.sum | 13 ++++ backend/touch/logic.go | 106 +++++++++++++++++++++++++++ backend/touch/logic_test.go | 139 ++++++++++++++++++++++++++++++++++++ backend/touch/touch.go | 50 +++++++++++++ 5 files changed, 310 insertions(+) create mode 100644 backend/touch/logic.go create mode 100644 backend/touch/logic_test.go create mode 100644 backend/touch/touch.go diff --git a/backend/go.mod b/backend/go.mod index cc7673b..7f836a0 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -4,6 +4,8 @@ go 1.12 require ( github.com/aws/aws-lambda-go v1.20.0 + github.com/eclipse/paho.mqtt.golang v1.2.0 github.com/go-sql-driver/mysql v1.5.0 github.com/stretchr/testify v1.6.1 + golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 // indirect ) diff --git a/backend/go.sum b/backend/go.sum index b854e0b..91eb505 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -6,6 +6,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/jphacks/D_2017 v0.0.0-20201022014100-6791d717d111 h1:I9PEAYIbRpzDTA/ClEFHsRSmYJPG6bT6HpWY0QcXKiY= @@ -18,6 +20,17 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/backend/touch/logic.go b/backend/touch/logic.go new file mode 100644 index 0000000..3a69940 --- /dev/null +++ b/backend/touch/logic.go @@ -0,0 +1,106 @@ +package main + +import ( + "strconv" + "time" + + "github.com/jphacks/D_2017/model" + "github.com/jphacks/D_2017/repository" + + _ "github.com/go-sql-driver/mysql" // グローバル設定を宣言(DBドライバの設定) +) + +type touchLogic struct { + logRepository repository.LogRepositoryInterface + readerRepository repository.ReaderRepositoryInterface + cardRepository repository.CardRepositoryInterface + roomRepository repository.RoomRepositoryInterface + bodyTemperatureRepository repository.BodyTemperatureRepositoryInterface +} + +func newTouchLogic(logRepository repository.LogRepositoryInterface, + readerRepository repository.ReaderRepositoryInterface, + cardRepository repository.CardRepositoryInterface, + roomRepository repository.RoomRepositoryInterface, + bodyTemperatureRepository repository.BodyTemperatureRepositoryInterface) *touchLogic { + return &touchLogic{ + logRepository, + readerRepository, + cardRepository, + roomRepository, + bodyTemperatureRepository, + } +} + +func exit(logic *touchLogic, log model.Log, time time.Time) (string, error) { + s := `{"result":"exit"}` + _, err := logic.logRepository.UpdateLeftAtByID(log.ID, time) + return s, err +} + +func enter(logic *touchLogic, userID string, roomID int) (string, error) { + s := `{"result":"accept"}` + log, _ := model.NewLog(userID, roomID) + _, err := logic.logRepository.Insert(log) + return s, err +} + +func (logic *touchLogic) handle(unixtime string, idm string, macAddress string) (string, error) { + // 時刻生成 + timeInt, _ := strconv.ParseInt(unixtime, 10, 64) + time := time.Unix(timeInt, 0) + + // userIDの特定 + card, err := logic.cardRepository.SelectByIDm(idm) + if err != nil || card == nil { + return `{"result":"reject"}`, err + } + userID := card.UserID + + //roomIDの特定 + reader, err := logic.readerRepository.SelectByMACAddress(macAddress) + if err != nil { + return `{"result":"reject"}`, err + } + roomID := reader.RoomID + + // 今部屋に入っていれば退室処理 + enteringLogs, err := logic.logRepository.SelectEnteringByRoomID(roomID) + for _, log := range *enteringLogs { + if log.UserID == userID { + return exit(logic, log, time) + } + } + + // 入室可能かどうかの判定 + + // 現在の人数の確認 + memberCount := len(*enteringLogs) + room, err := logic.roomRepository.SelectByID(roomID) + if memberCount >= room.LimitNumber { + return `{"result":"reject"}`, nil + } + + // [TODO] allow_missingならログが2週間分あることを確認 + + // 体温チェック + twoWeekAgo := time.AddDate(0, 0, -14) + temperatures, _ := logic.bodyTemperatureRepository.SelectByUserIDBetween(userID, twoWeekAgo, time) + + canEnter := true + for _, temp := range *temperatures { + if !temp.IsTrusted { + continue + } + canEnter = canEnter && (temp.Temperature < room.LimitBodyTemperature) + } + + //入れた場合 + if canEnter { + return enter(logic, userID, roomID) + } + + // 拒否 + return `{"result":"reject"}`, nil + +} diff --git a/backend/touch/logic_test.go b/backend/touch/logic_test.go new file mode 100644 index 0000000..239caff --- /dev/null +++ b/backend/touch/logic_test.go @@ -0,0 +1,139 @@ +package main + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/jphacks/D_2017/repository" + "github.com/jphacks/D_2017/response" + + "github.com/jphacks/D_2017/model" +) + +type mockCardRepository struct {} +func (cardRepository *mockCardRepository) Insert(record *model.Card) (*model.Card, error) { + return nil, nil +} +func (cardRepository *mockCardRepository) DeleteByIDm(IDm string) error { + return nil +} +func (cardRepository *mockCardRepository) SelectByIDm(IDm string) (*model.Card, error) { + return &model.Card{ + IDm: "0000000000000000", + UserID: "test-user", + }, nil +} +func newMockCardRepository() repository.CardRepositoryInterface { + return &mockCardRepository{} +} +type mockRoomRepository struct {} +func newMockRoomRepository() repository.RoomRepositoryInterface { + return &mockRoomRepository{} +} +func (r *mockRoomRepository) Insert(*model.Room) (*model.Room, error){ + return nil, nil +} + +func (r *mockRoomRepository) Update(*model.Room) (*model.Room, error){ + return nil, nil +} + +func (r *mockRoomRepository) SelectByID(int) (*model.Room, error) { + return &model.Room{ + RoomID: 42, + Name: "room1", + LimitNumber: 2, + LimitBodyTemperature: 37.0, + AllowMissing: true, + }, nil +} +type mockReaderRepository struct{} +func newMcokReaderRepository() repository.ReaderRepositoryInterface { + return &mockReaderRepository{} +} +func (r *mockReaderRepository) Insert(*model.Reader) (*model.Reader, error){ + return nil, nil +} +func (r *mockReaderRepository) SelectByUserID(string) (*[]model.Reader, error){ + return nil, nil +} +func (r *mockReaderRepository) SelectByRoomID(int) (*[]model.Reader, error){ + return nil, nil +} +func (r *mockReaderRepository) SelectByMACAddress(macAddress string) (*model.Reader, error) { + return &model.Reader{ + MACAddress: "0000000000000000", + UserID: "test-user", + RoomID: 42, + },nil +} + +type mockBodyTemperatureRepository struct {} +func newMockBodyTemperatureRepository() repository.BodyTemperatureRepositoryInterface { + return &mockBodyTemperatureRepository{} +} +func (m *mockBodyTemperatureRepository) Insert(*model.BodyTemperature) (*model.BodyTemperature, error) { + return nil, nil +} +func (m *mockBodyTemperatureRepository) UpdateIsTrustedByID(bool, int) (*model.BodyTemperature, error) { + return nil, nil +} +func (m *mockBodyTemperatureRepository) SelectByID(int) (*model.BodyTemperature, error) { + return nil, nil +} +func (m *mockBodyTemperatureRepository) SelectByUserID(string, int,int) (*[]model.BodyTemperature, error) { + return nil, nil +} +func (m *mockBodyTemperatureRepository) SelectByUserIDBetween(userID string, since time.Time, until time.Time) (*[]model.BodyTemperature, error) { + var array [3]model.BodyTemperature + times := [3]time.Time{ + time.Date(2014, time.December, 31, 12, 15, 24, 0, time.UTC), + time.Date(2014, time.December, 31, 12, 14, 24, 0, time.UTC), + time.Date(2014, time.December, 31, 12, 13, 24, 0, time.UTC), + } + array[0] = model.BodyTemperature{ + ID: 42, + UserID: "test-user", + Temperature: 36.5, + MACAddress: "00:00:00:00:00", + IsTrusted: true, + CreatedAt: ×[0], + } + array[1] = model.BodyTemperature{ + ID: 43, + UserID: "test-user", + Temperature: 36.3, + MACAddress: "00:00:00:00:00", + IsTrusted: true, + CreatedAt: ×[1], + } + array[2] = model.BodyTemperature{ + ID: 44, + UserID: "test-user", + Temperature: 36.6, + MACAddress: "00:00:00:00:00", + IsTrusted: true, + CreatedAt: ×[2], + } + res := array[:] + return &res, nil +} + +type mockLogRepository struct {} +func newMockLogRepository() repository.LogRepositoryInterface { + return &mockLogRepository{} +} +func (r *mockLogRepository) Insert(*model.Log) (*model.Log, error) { + return nil, nil +} +func (r *mockLogRepository) Select +func (r *mockLogRepository) UpdateLeftByID + + + + +func TestHandle(t *testing.T) { + +} \ No newline at end of file diff --git a/backend/touch/touch.go b/backend/touch/touch.go new file mode 100644 index 0000000..b3c8830 --- /dev/null +++ b/backend/touch/touch.go @@ -0,0 +1,50 @@ +package main + +import ( + "context" + "log" + + "github.com/aws/aws-lambda-go/lambda" + "github.com/jphacks/D_2017/repository" + + mqtt "github.com/eclipse/paho.mqtt.golang" + _ "github.com/go-sql-driver/mysql" // グローバル設定を宣言(DBドライバの設定) +) + +// Event - 送られてくるjson +type Event struct { + Timestamp string `json:"timestamp"` + Idm string `json:"idm"` + MacAddress string `json:"mac_address"` +} + +func eventHandler(ctx context.Context, event Event) (string, error) { + // イベントからデータ取得 + unixtime := event.Timestamp + idm := event.Idm + macAddress := event.MacAddress + + // mqtt初期化処理 + client := mqtt.NewClient(mqtt.NewClientOptions()) + if token := client.Connect(); token.Wait() && token.Error() != nil { + log.Fatalf("Mqtt error: %s", token.Error()) + } + + logic := newTouchLogic(repository.NewLogRepository(), + repository.NewReaderRepository(), + repository.NewCardRepository(), + repository.NewRoomRepository(), + repository.NewBodyTemperatureRepository()) + + payload, err := logic.handle(unixtime, idm, macAddress) + if err != nil { + client.Publish("iot-data", 0, false, `{"result":"reject"}`) + return "failed", err + } + client.Publish("iot-data", 0, false, payload) + return "success", nil +} + +func main() { + lambda.Start(eventHandler) +}