Example #1
0
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)
}
Example #2
0
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
}