forked from micro/services
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add location service * Update README.md
- Loading branch information
Showing
15 changed files
with
869 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
location |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
FROM alpine | ||
ADD location /location | ||
ENTRYPOINT [ "/location" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
GOPATH:=$(shell go env GOPATH) | ||
.PHONY: init | ||
init: | ||
go get -u github.com/golang/protobuf/proto | ||
go get -u github.com/golang/protobuf/protoc-gen-go | ||
go get github.com/micro/micro/v3/cmd/protoc-gen-micro | ||
.PHONY: proto | ||
proto: | ||
protoc --proto_path=. --micro_out=. --go_out=:. proto/location.proto | ||
|
||
.PHONY: build | ||
build: | ||
go build -o location *.go | ||
|
||
.PHONY: test | ||
test: | ||
go test -v ./... -cover | ||
|
||
.PHONY: docker | ||
docker: | ||
docker build . -t location:latest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Location Service | ||
|
||
A realtime GPS location tracking and search service | ||
|
||
Generated with | ||
|
||
``` | ||
micro new location | ||
``` | ||
|
||
## Usage | ||
|
||
Generate the proto code | ||
|
||
``` | ||
make proto | ||
``` | ||
|
||
Run the service | ||
|
||
``` | ||
micro run . | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package domain | ||
|
||
import ( | ||
"sync" | ||
|
||
geo "github.com/hailocab/go-geoindex" | ||
"github.com/micro/micro/v3/service/errors" | ||
common "github.com/micro/services/location/proto" | ||
) | ||
|
||
var ( | ||
mtx sync.RWMutex | ||
defaultIndex = geo.NewPointsIndex(geo.Km(0.5)) | ||
) | ||
|
||
type Entity struct { | ||
ID string | ||
Type string | ||
Latitude float64 | ||
Longitude float64 | ||
Timestamp int64 | ||
} | ||
|
||
func (e *Entity) Id() string { | ||
return e.ID | ||
} | ||
|
||
func (e *Entity) Lat() float64 { | ||
return e.Latitude | ||
} | ||
|
||
func (e *Entity) Lon() float64 { | ||
return e.Longitude | ||
} | ||
|
||
func (e *Entity) ToProto() *common.Entity { | ||
return &common.Entity{ | ||
Id: e.ID, | ||
Type: e.Type, | ||
Location: &common.Point{ | ||
Latitude: e.Latitude, | ||
Longitude: e.Longitude, | ||
Timestamp: e.Timestamp, | ||
}, | ||
} | ||
} | ||
|
||
func ProtoToEntity(e *common.Entity) *Entity { | ||
return &Entity{ | ||
ID: e.Id, | ||
Type: e.Type, | ||
Latitude: e.Location.Latitude, | ||
Longitude: e.Location.Longitude, | ||
Timestamp: e.Location.Timestamp, | ||
} | ||
} | ||
|
||
func Read(id string) (*Entity, error) { | ||
mtx.RLock() | ||
defer mtx.RUnlock() | ||
|
||
p := defaultIndex.Get(id) | ||
if p == nil { | ||
return nil, errors.NotFound("location.read", "Not found") | ||
} | ||
|
||
entity, ok := p.(*Entity) | ||
if !ok { | ||
return nil, errors.InternalServerError("location.read", "Error reading entity") | ||
} | ||
|
||
return entity, nil | ||
} | ||
|
||
func Save(e *Entity) { | ||
mtx.Lock() | ||
defaultIndex.Add(e) | ||
mtx.Unlock() | ||
} | ||
|
||
func Search(typ string, entity *Entity, radius float64, numEntities int) []*Entity { | ||
mtx.RLock() | ||
defer mtx.RUnlock() | ||
|
||
points := defaultIndex.KNearest(entity, numEntities, geo.Meters(radius), func(p geo.Point) bool { | ||
e, ok := p.(*Entity) | ||
if !ok || e.Type != typ { | ||
return false | ||
} | ||
return true | ||
}) | ||
|
||
var entities []*Entity | ||
|
||
for _, point := range points { | ||
e, ok := point.(*Entity) | ||
if !ok { | ||
continue | ||
} | ||
entities = append(entities, e) | ||
} | ||
|
||
return entities | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package main | ||
|
||
//go:generate make proto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package handler | ||
|
||
import ( | ||
"context" | ||
"log" | ||
|
||
"github.com/micro/micro/v3/service" | ||
"github.com/micro/micro/v3/service/errors" | ||
"github.com/micro/services/location/domain" | ||
loc "github.com/micro/services/location/proto" | ||
"github.com/micro/services/location/subscriber" | ||
) | ||
|
||
type Location struct{} | ||
|
||
func (l *Location) Read(ctx context.Context, req *loc.ReadRequest, rsp *loc.ReadResponse) error { | ||
log.Print("Received Location.Read request") | ||
|
||
id := req.Id | ||
|
||
if len(id) == 0 { | ||
return errors.BadRequest("location.read", "Require Id") | ||
} | ||
|
||
entity, err := domain.Read(id) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
rsp.Entity = entity.ToProto() | ||
|
||
return nil | ||
} | ||
|
||
func (l *Location) Save(ctx context.Context, req *loc.SaveRequest, rsp *loc.SaveResponse) error { | ||
log.Print("Received Location.Save request") | ||
|
||
entity := req.GetEntity() | ||
|
||
if entity.GetLocation() == nil { | ||
return errors.BadRequest("location.save", "Require location") | ||
} | ||
|
||
p := service.NewEvent(subscriber.Topic) | ||
if err := p.Publish(ctx, entity); err != nil { | ||
return errors.InternalServerError("location.save", err.Error()) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (l *Location) Search(ctx context.Context, req *loc.SearchRequest, rsp *loc.SearchResponse) error { | ||
log.Print("Received Location.Search request") | ||
|
||
entity := &domain.Entity{ | ||
Latitude: req.Center.Latitude, | ||
Longitude: req.Center.Longitude, | ||
} | ||
|
||
entities := domain.Search(req.Type, entity, req.Radius, int(req.NumEntities)) | ||
|
||
for _, e := range entities { | ||
rsp.Entities = append(rsp.Entities, e.ToProto()) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"github.com/micro/micro/v3/service" | ||
"github.com/micro/services/location/handler" | ||
pb "github.com/micro/services/location/proto" | ||
"github.com/micro/services/location/subscriber" | ||
) | ||
|
||
func main() { | ||
location := service.New( | ||
service.Name("location"), | ||
) | ||
|
||
pb.RegisterLocationHandler(location.Server(), new(handler.Location)) | ||
|
||
service.Subscribe(subscriber.Topic, new(subscriber.Location)) | ||
|
||
if err := location.Run(); err != nil { | ||
log.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
service location |
Oops, something went wrong.