-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
166 lines (152 loc) · 6 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
"github.com/gorilla/mux"
"github.com/umahmood/haversine"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var client *mongo.Client
// Cardinal is the database structure
type Cardinal struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
Latitude float64 `json:"latitude,omitempty" bson:"latitude,omitempty"`
Longitude float64 `json:"longitude,omitempty" bson:"longitude,omitempty"`
}
// Distance is the heversine distance betwhen 2 coordinates
type Distance struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
Km float64 `json:"km,omitempty" bson:"km,omitempty"`
}
// CreateCoordinateEndpoint is the method that creates new points in map
func CreateCoordinateEndpoint(response http.ResponseWriter, request *http.Request) {
response.Header().Set("content-type", "application/json")
var coordinate Cardinal
_ = json.NewDecoder(request.Body).Decode(&coordinate)
collection := client.Database("db").Collection("coordinates")
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(5)*time.Second)
defer cancel()
result, _ := collection.InsertOne(ctx, coordinate)
json.NewEncoder(response).Encode(result)
}
// DeleteCoordinateEndpoint find coordinate by id and delete it
func DeleteCoordinateEndpoint(response http.ResponseWriter, request *http.Request) {
response.Header().Set("content-type", "application/json")
params := mux.Vars(request)
id, _ := primitive.ObjectIDFromHex(params["id"])
var coordinate Cardinal
collection := client.Database("db").Collection("coordinates")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err := collection.FindOneAndDelete(ctx, Cardinal{ID: id}).Decode(&coordinate)
if err != nil {
response.WriteHeader(http.StatusInternalServerError)
response.Write([]byte(`{ "message": "` + err.Error() + `" }`))
return
}
json.NewEncoder(response).Encode(coordinate)
}
// GetCoordinatesEndpoint retuns all the points in existence
func GetCoordinatesEndpoint(response http.ResponseWriter, request *http.Request) {
response.Header().Set("content-type", "application/json")
var coordinates []Cardinal
collection := client.Database("db").Collection("coordinates")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{})
if err != nil {
response.WriteHeader(http.StatusInternalServerError)
response.Write([]byte(`{ "message": "` + err.Error() + `" }`))
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var person Cardinal
cursor.Decode(&person)
coordinates = append(coordinates, person)
}
if err := cursor.Err(); err != nil {
response.WriteHeader(http.StatusInternalServerError)
response.Write([]byte(`{ "message": "` + err.Error() + `" }`))
return
}
json.NewEncoder(response).Encode(coordinates)
}
// GetCoordinateEndpoint recieve the id of coordinate and return the structure
func GetCoordinateEndpoint(response http.ResponseWriter, request *http.Request) {
response.Header().Set("content-type", "application/json")
params := mux.Vars(request)
id, _ := primitive.ObjectIDFromHex(params["id"])
var coordinate Cardinal
collection := client.Database("db").Collection("coordinates")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err := collection.FindOne(ctx, Cardinal{ID: id}).Decode(&coordinate)
if err != nil {
response.WriteHeader(http.StatusInternalServerError)
response.Write([]byte(`{ "message": "` + err.Error() + `" }`))
return
}
json.NewEncoder(response).Encode(coordinate)
}
// GetDistancesEndpoint calculate the distance betwhen user corrdinate vs all of the other coordinates
func GetDistancesEndpoint(response http.ResponseWriter, request *http.Request) {
response.Header().Set("content-type", "application/json")
params := mux.Vars(request)
llat, _ := strconv.ParseFloat(params["lat"], 64)
llon, _ := strconv.ParseFloat(params["lon"], 64)
local := haversine.Coord{Lat: llat, Lon: llon}
var distances []Distance
collection := client.Database("db").Collection("coordinates")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{})
if err != nil {
response.WriteHeader(http.StatusInternalServerError)
response.Write([]byte(`{ "message": "` + err.Error() + `" }`))
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var coordinate Cardinal
var distance Distance
cursor.Decode(&coordinate)
parking := haversine.Coord{Lat: coordinate.Latitude, Lon: coordinate.Longitude}
_, km := haversine.Distance(local, parking)
distance.ID = coordinate.ID
distance.Km = km
distances = append(distances, distance)
}
if err := cursor.Err(); err != nil {
response.WriteHeader(http.StatusInternalServerError)
response.Write([]byte(`{ "message": "` + err.Error() + `" }`))
return
}
json.NewEncoder(response).Encode(distances)
}
func home(response http.ResponseWriter, request *http.Request) {
flag := "works fine"
json.NewEncoder(response).Encode(flag)
}
func main() {
fmt.Println("Starting the application...")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
clientOptions := options.Client().ApplyURI("mongodb://routes-map-ms_routes-map-db_1:27017")
client, _ = mongo.Connect(ctx, clientOptions)
router := mux.NewRouter()
router.HandleFunc("/coordinate", CreateCoordinateEndpoint).Methods("POST")
router.HandleFunc("/coordinate/{id}", DeleteCoordinateEndpoint).Methods("DELETE")
router.HandleFunc("/coordinate", GetCoordinatesEndpoint).Methods("GET")
router.HandleFunc("/coordinate/{id}", GetCoordinateEndpoint).Methods("GET")
router.HandleFunc("/", home).Methods("GET")
router.HandleFunc("/distances/{lat}/{lon}", GetDistancesEndpoint).Methods("GET")
http.ListenAndServe(":4003", router)
}