Skip to content
loc-serv.go 92.4 KiB
Newer Older
 * Copyright (c) 2019  InterDigital Communications, Inc
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
Simon Pastor's avatar
Simon Pastor committed
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"sync"
	"time"

	sbi "github.com/InterDigitalInc/AdvantEDGE/go-apps/meep-loc-serv/sbi"
	dkm "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr"
Simon Pastor's avatar
Simon Pastor committed
	gisClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-engine-client"
	httpLog "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger"
	log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
	met "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-metrics"
	redis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis"
	"github.com/gorilla/mux"
)

Simon Pastor's avatar
Simon Pastor committed
const LocServBasePath = "/location/v2/"
const locServKey = "loc-serv:"
const logModuleLocServ = "meep-loc-serv"
const serviceName = "Location Service"

const typeZone = "zone"
const typeAccessPoint = "accessPoint"
const typeUser = "user"
const typeZonalSubscription = "zonalsubs"
const typeUserSubscription = "usersubs"
const typeZoneStatusSubscription = "zonestatus"
Simon Pastor's avatar
Simon Pastor committed
const typeDistanceSubscription = "distance"
const typeAreaCircleSubscription = "areacircle"
const (
	notifZonalPresence = "ZonalPresenceNotification"
	notifZoneStatus    = "ZoneStatusNotification"
Simon Pastor's avatar
Simon Pastor committed
	notifSubscription  = "SubscriptionNotification"
Simon Pastor's avatar
Simon Pastor committed
	queryZoneId  []string
	queryApId    []string
	queryAddress []string
Simon Pastor's avatar
Simon Pastor committed
	userList     *UserList
}

type ApUserData struct {
	queryInterestRealm string
	apList             *AccessPointList
}

Simon Pastor's avatar
Simon Pastor committed
type Pair struct {
	addr1 string
	addr2 string
}

var nextZonalSubscriptionIdAvailable int
var nextUserSubscriptionIdAvailable int
var nextZoneStatusSubscriptionIdAvailable int
Simon Pastor's avatar
Simon Pastor committed
var nextDistanceSubscriptionIdAvailable int
var nextAreaCircleSubscriptionIdAvailable int
var zonalSubscriptionEnteringMap = map[int]string{}
var zonalSubscriptionLeavingMap = map[int]string{}
var zonalSubscriptionTransferringMap = map[int]string{}
var zonalSubscriptionMap = map[int]string{}
var userSubscriptionEnteringMap = map[int]string{}
var userSubscriptionLeavingMap = map[int]string{}
var userSubscriptionTransferringMap = map[int]string{}
var userSubscriptionMap = map[int]string{}
var zoneStatusSubscriptionMap = map[int]*ZoneStatusCheck{}

Simon Pastor's avatar
Simon Pastor committed
var distanceSubscriptionMap = map[int]*DistanceCheck{}

var distancePeriodicTicker *time.Ticker

var areaCircleSubscriptionMap = map[int]*AreaCircleCheck{}

type ZoneStatusCheck struct {
	ZoneId                 string
	Serviceable            bool
	Unserviceable          bool
	Unknown                bool
Simon Pastor's avatar
Simon Pastor committed
	NbUsersInZoneThreshold int32
	NbUsersInAPThreshold   int32
Simon Pastor's avatar
Simon Pastor committed
type DistanceCheck struct {
	NextTts      int32 //next time to send, derived from frequency
	Subscription *DistanceNotificationSubscription
}

type AreaCircleCheck struct {
	NextTts      int32 //next time to send, derived from frequency
	AddrInArea   map[string]bool
	Subscription *CircleNotificationSubscription
}

Simon Pastor's avatar
Simon Pastor committed
var currentStoreName = ""
Simon Pastor's avatar
Simon Pastor committed
var redisAddr string = "meep-redis-master.default.svc.cluster.local:6379"
var influxAddr string = "http://meep-influxdb.default.svc.cluster.local:8086"
Simon Pastor's avatar
Simon Pastor committed
var rc *redis.Connector
var mutex sync.Mutex
Simon Pastor's avatar
Simon Pastor committed
var gisAppClient *gisClient.APIClient

Simon Pastor's avatar
Simon Pastor committed
func notImplemented(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusNotImplemented)
}

Simon Pastor's avatar
Simon Pastor committed
// Init - Location Service initialization
func Init() (err error) {
Simon Pastor's avatar
Simon Pastor committed
	sandboxNameEnv := strings.TrimSpace(os.Getenv("MEEP_SANDBOX_NAME"))
	if sandboxNameEnv != "" {
		sandboxName = sandboxNameEnv
	}
	if sandboxName == "" {
		err = errors.New("MEEP_SANDBOX_NAME env variable not set")
		log.Error(err.Error())
		return err
	}
	log.Info("MEEP_SANDBOX_NAME: ", sandboxName)
Simon Pastor's avatar
Simon Pastor committed
	// hostUrl is the url of the node serving the resourceURL
	// Retrieve public url address where service is reachable, if not present, use Host URL environment variable
	hostUrl, err = url.Parse(strings.TrimSpace(os.Getenv("MEEP_PUBLIC_URL")))
	if err != nil || hostUrl == nil || hostUrl.String() == "" {
		hostUrl, err = url.Parse(strings.TrimSpace(os.Getenv("MEEP_HOST_URL")))
		if err != nil {
			hostUrl = new(url.URL)
		}
Simon Pastor's avatar
Simon Pastor committed
	log.Info("resource URL: ", hostUrl)

	// Set base path
	basePath = "/" + sandboxName + LocServBasePath
	// Get base storage key
	baseKey = dkm.GetKeyRoot(sandboxName) + locServKey

Simon Pastor's avatar
Simon Pastor committed
	rc, err = redis.NewConnector(redisAddr, LOC_SERV_DB)
Simon Pastor's avatar
Simon Pastor committed
		log.Error("Failed connection to Redis DB. Error: ", err)
	_ = rc.DBFlush(baseKey)
Simon Pastor's avatar
Simon Pastor committed
	log.Info("Connected to Redis DB, location service table")
Simon Pastor's avatar
Simon Pastor committed
	gisAppClientCfg := gisClient.NewConfiguration()
	gisAppClientCfg.BasePath = hostUrl.String() + "/" + sandboxName + "/gis/v1"

	gisAppClient = gisClient.NewAPIClient(gisAppClientCfg)
	if gisAppClient == nil {
		log.Error("Failed to create GIS App REST API client: ", gisAppClientCfg.BasePath)
		err := errors.New("Failed to create GIS App REST API client")
		return err
	}

	userTrackingReInit()
	zonalTrafficReInit()
Simon Pastor's avatar
Simon Pastor committed
	distanceReInit()
	areaCircleReInit()
Loading
Loading full blame…