Skip to content
loc-serv.go 29.6 KiB
Newer Older
/*
 * Copyright (c) 2019
 * InterDigital Communications, Inc.
 * All rights reserved.
 *
 * The information provided herein is the proprietary and confidential
 * information of InterDigital Communications, Inc.
 */
package server

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"

	log "github.com/InterDigitalInc/AdvantEDGE/go-apps/meep-loc-serv/log"
	db "github.com/InterDigitalInc/AdvantEDGE/go-apps/meep-loc-serv/redis"
	sbi "github.com/InterDigitalInc/AdvantEDGE/go-apps/meep-loc-serv/sbi"
	subs "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-loc-serv-notification-client"
	"github.com/KromDaniel/rejonson"
	"github.com/go-redis/redis"
	"github.com/gorilla/mux"
)

const basepathURL = "http://meep-loc-serv/etsi-013/location/v1/"
const moduleLocServ string = "loc-serv"

const typeZone = "zone"
const typeAccessPoint = "accessPoint"
const typeUser = "user"
const typeZonalSubscription = "zonalsubs"
const typeUserSubscription = "usersubs"
const typeZoneStatusSubscription = "zonestatus"

const locServChannel string = moduleLocServ

var nextZonalSubscriptionIdAvailable int
var nextUserSubscriptionIdAvailable int

//var nextZoneStatusSubscriptionIdAvailable = 1

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 pubsub *redis.PubSub
var LOC_SERV_DB = 5
var dbClient *rejonson.Client

// Init - Location Service initialization
func Init() (err error) {

	// Connect to Redis DB
	dbClient, err = db.RedisDBConnect(LOC_SERV_DB)
	if err != nil {
		log.Error("Failed connection to Active DB for server. Error: ", err)
		return err
	}
	log.Info("Connected to Active location service DB")

	// Subscribe to Pub-Sub events for MEEP Controller
	// NOTE: Current implementation is RedisDB Pub-Sub
	pubsub, err = db.Subscribe(dbClient, locServChannel)
	if err != nil {
		log.Error("Failed to subscribe to Pub/Sub events. Error: ", err)
		return err
	}

	userTrackingReInit()
	zonalTrafficReInit()

	_ = sbi.Init(updateUserInfo, updateZoneInfo, updateAccessPointInfo)
	return nil
}

// Run - MEEP Location Service execution
func Run() {

	// Listen for subscribed events. Provide event handler method.
	_ = db.Listen(pubsub, eventHandler)
}

func eventHandler(channel string, payload string) {
	// Handle Message according to Rx Channel
	switch channel {

	// MEEP Ctrl Engine active scenario update Channel
	case locServChannel:
		log.Debug("Event received on location service channel in server : ", payload)
		go checkNotificationRegistrations(payload)

	default:
		log.Warn("Unsupported channel")
	}
}

func createClient(notifyPath string) (*subs.APIClient, error) {
	// Create & store client for App REST API
	subsAppClientCfg := subs.NewConfiguration()
	subsAppClientCfg.BasePath = notifyPath
	subsAppClient := subs.NewAPIClient(subsAppClientCfg)
	if subsAppClient == nil {
		log.Error("Failed to create Subscription App REST API client: ", subsAppClientCfg.BasePath)
		err := errors.New("Failed to create Subscription App REST API client")
		return nil, err
	}
	return subsAppClient, nil
}

func deregisterZonal(subsIdStr string) {
	subsId, _ := strconv.Atoi(subsIdStr)
	zonalSubscriptionMap[subsId] = ""
	zonalSubscriptionEnteringMap[subsId] = ""
	zonalSubscriptionLeavingMap[subsId] = ""
	zonalSubscriptionTransferringMap[subsId] = ""
func registerZonal(zoneId string, event []UserEventType, subsIdStr string) {

	subsId, _ := strconv.Atoi(subsIdStr)

	if event != nil {
		for i := 0; i < len(event); i++ {
			switch event[i] {
			case ENTERING:
				zonalSubscriptionEnteringMap[subsId] = zoneId
				zonalSubscriptionLeavingMap[subsId] = zoneId
			case TRANSFERRING:
				zonalSubscriptionTransferringMap[subsId] = zoneId
		zonalSubscriptionEnteringMap[subsId] = zoneId
		zonalSubscriptionLeavingMap[subsId] = zoneId
		zonalSubscriptionTransferringMap[subsId] = zoneId
	}
	zonalSubscriptionMap[subsId] = zoneId
}

func deregisterUser(subsIdStr string) {
	subsId, _ := strconv.Atoi(subsIdStr)
	userSubscriptionMap[subsId] = ""
	userSubscriptionEnteringMap[subsId] = ""
	userSubscriptionLeavingMap[subsId] = ""
	userSubscriptionTransferringMap[subsId] = ""
func registerUser(userAddress string, event []UserEventType, subsIdStr string) {

	subsId, _ := strconv.Atoi(subsIdStr)

	if event != nil {
		for i := 0; i < len(event); i++ {
			switch event[i] {
			case ENTERING:
				userSubscriptionEnteringMap[subsId] = userAddress
				userSubscriptionLeavingMap[subsId] = userAddress
			case TRANSFERRING:
				userSubscriptionTransferringMap[subsId] = userAddress
		userSubscriptionEnteringMap[subsId] = userAddress
		userSubscriptionLeavingMap[subsId] = userAddress
		userSubscriptionTransferringMap[subsId] = userAddress
	}
	userSubscriptionMap[subsId] = userAddress
}

func checkNotificationRegistrations(payload string) {
	values := strings.Split(payload, ":")
	if len(values) == 5 {
		//value is split in 5 newZoneId:oldZoneId:newAccessPointId:oldAccessPointId:userAddress
		checkNotificationRegisteredUsers(values[0], values[1], values[2], values[3], values[4])
		checkNotificationRegisteredZones(values[0], values[1], values[2], values[3], values[4])
	}
}

func checkNotificationRegisteredUsers(oldZoneId string, newZoneId string, oldApId string, newApId string, userId string) {

	//check all that applies
	for subsId, value := range userSubscriptionMap {
		if value == userId {
Loading
Loading full blame…