func main() { addr := flag.String("http", ":8080", "Server address & port") mongoURL := flag.String("mongodb", "mongodb://localhost/watch", "MongoDB connection URL") natsURL := flag.String("nats", nats.DefaultURL, "NATS connection URL") docker := flag.Bool("docker", false, "for docker") flag.Parse() // Если запускается внутри контейнера if *docker { tmp1 := os.Getenv("NATSADDR") tmp2 := os.Getenv("MONGODB") natsURL = &tmp1 mongoURL = &tmp2 } e = echo.New() // инициализируем HTTP-обработку e.Debug() // режим отладки e.SetLogPrefix("") // убираем префикс в логе e.SetLogLevel(0) // устанавливаем уровень вывода всех сообщений (TRACE) llog = e.Logger() // интерфейс вывода в лог llog.Info("Connecting to MongoDB %q...", *mongoURL) mdb, err := mongo.Connect(*mongoURL) if err != nil { llog.Error("Error connecting to MongoDB: %v", err) return } defer mdb.Close() if usersDB, err = users.InitDB(mdb); err != nil { llog.Error("Error initializing UsersDB: %v", err) return } if placesDB, err = places.InitDB(mdb); err != nil { llog.Error("Error initializing PlacesDB: %v", err) return } if tracksDB, err = tracks.InitDB(mdb); err != nil { llog.Error("Error initializing TracksDB: %v", err) return } if sensorsDB, err = sensors.InitDB(mdb); err != nil { llog.Error("Error initializing SensorsDB: %v", err) return } groupID = usersDB.GetSampleGroupID() // временная инициализация пользователей log.Println("Connecting to NATS...") nc, err := nats.Connect(*natsURL) if err != nil { log.Printf("Error connecting to NATS: %v", err) return } defer nc.Close() nce, err = nats.NewEncodedConn(nc, nats.JSON_ENCODER) if err != nil { log.Printf("Error initializing NATS encoder: %v", err) return } // инициализируем работу с токенами tokenEngine, err = token.Init("com.xyzrd.geotracker", time.Minute*30, nil) if err != nil { llog.Error("Error initializing Token Engine: %v", err) return } llog.Debug("CryptoKey: %v", tokenEngine.CryptoKey()) e.Use(Logger()) e.Use(middleware.Recover()) e.Use(middleware.Gzip()) apiV1 := e.Group("/api/v1") // группа URL для обработки API версии 1.0. apiV1.Get("/login", login) // авторизация пользователя apiV1Sec := apiV1.Group("") // группа запросов с авторизацией apiV1Sec.Use(auth) // добавляем проверку токена в заголовке apiV1Sec.Get("/users", getUsers) // возвращает список пользователей apiV1Sec.Get("/places", getPlaces) // возвращает список интересующих мест apiV1Sec.Post("/places", postPlace) // добавляет определение нового места apiV1Sec.Get("/places/:place-id", getPlace) // возвращает информацию об указаном месте apiV1Sec.Put("/places/:place-id", putPlace) // изменяет определение места apiV1Sec.Delete("/places/:place-id", deletePlace) // удаляет определение места apiV1Sec.Get("/devices", getDevices) // возвращает список устройств apiV1Sec.Post("/devices", postDevicePairing) // привязка устройства к группе apiV1Sec.Post("/devices/:device-id", postDevicePairing) // привязка устройства к группе apiV1Sec.Get("/devices/:device-id/tracks", getTracks) // возвращает список трекингов устройства apiV1Sec.Post("/devices/:device-id/tracks", postTracks) // добавляет данные о треках устройства apiV1Sec.Get("/devices/:device-id/sensors", getSensors) // возвращает список трекингов устройства apiV1Sec.Post("/devices/:device-id/sensors", postSensors) // добавляет данные о треках устройства apiV1Sec.Post("/push/:push-type", postRegister) // регистрирует устройство для отправки push-сообщений apiV1Sec.Delete("/push/:push-type/:token", deleteRegister) // удаляет токен из хранилища llog.Info("Starting HTTP server at %q...", *addr) e.Run(*addr) }
func subscribe(mdb *mongo.DB, nc *nats.Conn) error { nce, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER) if err != nil { return err } // nce.Subscribe("*", func(subj, reply string, data []byte) { // log.Printf("DEBUG: %q [%q]\n%s", subj, reply, string(data)) // }) lbs, err := lbs.InitDB(mdb) if err != nil { return err } if lbs.Records() == 0 { log.Warn("LBS DB is empty!") } lbsGoogle, err := geolocate.New(geolocate.Google, googleToken) if err != nil { return err } nce.Subscribe(serviceNameLBS, func(_, reply string, req geolocate.Request) { resp, err := lbsGoogle.Get(req) logger := log.WithFields(log.Fields{"request": req, "response": resp}) if err != nil { logger.WithError(err).Error("LBS Google error") } if err := nce.Publish(reply, resp); err != nil { logger.WithError(err).Error("LBS Google response error") } else { logger.Debug("LBS") } _, err = lbs.Get(req) // оставил для сохранения в базу запроса. if err != nil { logger.WithError(err).Error("LBS Internal response error") } }) ubloxCache, err := ublox.InitCache(mdb, ubloxToken) if err != nil { return err } profile := ublox.DefaultProfile nce.Subscribe(serviceNameUblox, func(_, reply string, point geo.Point) { data, err := ubloxCache.Get(point, profile) logger := log.WithFields(log.Fields{"request": point, "response length": len(data)}) if err != nil { logger.WithError(err).Error("UBLOX error") } if err := nce.Publish(reply, data); err != nil { logger.WithError(err).Error("UBLOX response error") } else { logger.Debug("UBLOX") } }) usersDB, err := users.InitDB(mdb) if err != nil { return err } // уникальный идентификатор группы пока для примера задан явно // groupID := users.SampleGroupID groupID := usersDB.GetSampleGroupID() nce.Subscribe(serviceNameIMEI, func(_, reply, data string) { group, err := usersDB.GetGroup(groupID) logger := log.WithFields(log.Fields{"request": data, "response": group}) if err != nil { logger.WithError(err).Error("IMEI error") } if err := nce.Publish(reply, group); err != nil { logger.WithError(err).Error("IMEI response error") } else { logger.Debug("IMEI") } }) tracksDB, err := tracks.InitDB(mdb) if err != nil { return err } nce.Subscribe(serviceNameTracks, func(tracks []tracks.TrackData) { logger := log.WithField("request", tracks) if err := tracksDB.Add(tracks...); err != nil { logger.WithError(err).Error("TRACKS error") } else { logger.Debug("TRACKS") } }) sensorsDB, err := sensors.InitDB(mdb) if err != nil { return err } nce.Subscribe(serviceNameSensors, func(sensors []sensors.SensorData) { logger := log.WithField("request", sensors) if err := sensorsDB.Add(sensors...); err != nil { logger.WithError(err).Error("SENSORS error") } else { logger.Debug("SENSORS") } }) var pairs pairing.Pairs nce.Subscribe(serviceNamePairing, func(_, reply, deviceID string) { key := pairs.Generate(deviceID) logger := log.WithFields(log.Fields{"request": deviceID, "response": key}) if err := nce.Publish(reply, key); err != nil { logger.WithError(err).Error("PAIR error") } else { logger.Debug("PAIR") } }) nce.Subscribe(serviceNamePairingKey, func(_, reply, key string) { newDeviceID := pairs.GetDeviceID(key) logger := log.WithFields(log.Fields{"request": key, "response": newDeviceID}) if err := nce.Publish(reply, newDeviceID); err != nil { logger.WithError(err).Error("PAIR KEY error") } else { logger.Debug("PAIR KEY") } }) return nil }