Commit deb98a1f authored by Ikram Haq's avatar Ikram Haq
Browse files

Implement logic to handle userAreaSubscription

parent 50d5eb14
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -254,9 +254,9 @@ func convertJsonToPeriodicSubscription(jsonInfo string) *PeriodicNotificationSub
}
*/

func convertAreaCircleSubscriptionToJson(circleSubs *CircleNotificationSubscription) string {
func convertAreaCircleSubscriptionToJson(AreaSubs *UserAreaSubscription) string {

	jsonInfo, err := json.Marshal(*circleSubs)
	jsonInfo, err := json.Marshal(*AreaSubs)
	if err != nil {
		log.Error(err.Error())
		return ""
+95 −83
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ type AreaCircleCheck struct {
	AddrInArea             map[string]bool
	NbNotificationsSent    int32
	NotificationCheckReady bool
	Subscription           *CircleNotificationSubscription
	Subscription           *UserAreaSubscription
}

type PeriodicCheck struct {
@@ -1383,7 +1383,7 @@ func deregisterAreaCircle(subsIdStr string) {
	areaCircleSubscriptionMap[subsId] = nil
}

func registerAreaCircle(areaCircleSub *CircleNotificationSubscription, subsIdStr string) {
func registerAreaCircle(areaSub *UserAreaSubscription, subsIdStr string) {

	subsId, err := strconv.Atoi(subsIdStr)
	if err != nil {
@@ -1393,7 +1393,7 @@ func registerAreaCircle(areaCircleSub *CircleNotificationSubscription, subsIdStr
	mutex.Lock()
	defer mutex.Unlock()
	var areaCircleCheck AreaCircleCheck
	areaCircleCheck.Subscription = areaCircleSub
	areaCircleCheck.Subscription = areaSub
	areaCircleCheck.NbNotificationsSent = 0
	areaCircleCheck.AddrInArea = map[string]bool{}
	//checkImmediate ignored, will be hit on next check anyway
@@ -2660,20 +2660,23 @@ func areaSubDELETE(w http.ResponseWriter, r *http.Request) {
func areaSubListGET(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")

	var response InlineNotificationSubscriptionList
	var areaCircleSubList NotificationSubscriptionList
	areaCircleSubList.ResourceURL = &LinkType{}
	areaCircleSubList.ResourceURL.Href = hostUrl.String() + basePath + "subscriptions/area/circle"
	response.NotificationSubscriptionList = &areaCircleSubList

	var response []InlineNotificationSubscriptionList
	var subscriptions []Subscription
	keyName := baseKey + typeAreaCircleSubscription + "*"
	err := rc.ForEachJSONEntry(keyName, populateAreaCircleList, &areaCircleSubList)
	err := rc.ForEachJSONEntry(keyName, populateUserAreaList, &subscriptions)
	if err != nil {
		log.Error(err.Error())
		errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError)
		return
	}

	response = append(response, InlineNotificationSubscriptionList{
		NotificationSubscriptionList: &NotificationSubscriptionList{
			Subscription: subscriptions,
			ResourceURL: &LinkType{
				Href: hostUrl.String() + basePath + "subscriptions/area",
			},
		},
	})
	jsonResponse, err := json.Marshal(response)
	if err != nil {
		log.Error(err.Error())
@@ -2688,9 +2691,9 @@ func areaSubGET(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	vars := mux.Vars(r)

	var response InlineCircleNotificationSubscription
	var areaCircleSub CircleNotificationSubscription
	response.CircleNotificationSubscription = &areaCircleSub
	var response InlineUserAreaSubscription
	var areaCircleSub UserAreaSubscription
	response.UserAreaSubscription = &areaCircleSub
	jsonAreaCircleSub, _ := rc.JSONGetEntry(baseKey+typeAreaCircleSubscription+":"+vars["subscriptionId"], ".")
	if jsonAreaCircleSub == "" {
		w.WriteHeader(http.StatusNotFound)
@@ -2716,9 +2719,9 @@ func areaSubGET(w http.ResponseWriter, r *http.Request) {

func areaSubPOST(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	var response InlineCircleNotificationSubscription
	var response InlineUserAreaSubscription

	var body InlineCircleNotificationSubscription
	var body InlineUserAreaSubscription
	decoder := json.NewDecoder(r.Body)
	err := decoder.Decode(&body)
	if err != nil {
@@ -2726,7 +2729,7 @@ func areaSubPOST(w http.ResponseWriter, r *http.Request) {
		errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError)
		return
	}
	areaCircleSub := body.CircleNotificationSubscription
	areaCircleSub := body.UserAreaSubscription

	if areaCircleSub == nil {
		log.Error("Body not present")
@@ -2740,44 +2743,40 @@ func areaSubPOST(w http.ResponseWriter, r *http.Request) {
		errHandlerProblemDetails(w, "Mandatory CallbackReference parameter not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Address == nil {
	if areaCircleSub.AddressList == nil {
		log.Error("Mandatory Address parameter not present")
		errHandlerProblemDetails(w, "Mandatory Address parameter not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Latitude == 0 {
		log.Error("Mandatory Latitude parameter not present")
		errHandlerProblemDetails(w, "Mandatory Latitude parameter not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Longitude == 0 {
		log.Error("Mandatory Longitude parameter not present")
		errHandlerProblemDetails(w, "Mandatory Longitude parameter not present", http.StatusBadRequest)
	if len(areaCircleSub.AreaDefine.Points) == 0 {
		log.Error("Latitude and longitude not present")
		errHandlerProblemDetails(w, "Latitude and longitude not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Radius == 0 {
	if areaCircleSub.AreaDefine.Radius == 0 {
		log.Error("Mandatory Radius parameter not present")
		errHandlerProblemDetails(w, "Mandatory Radius parameter not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.EnteringLeavingCriteria == nil {
		log.Error("Mandatory EnteringLeavingCriteria parameter not present")
		errHandlerProblemDetails(w, "Mandatory EnteringLeavingCriteria parameter not present", http.StatusBadRequest)
	if len(areaCircleSub.LocationEventCriteria) == 0 {
		log.Error("LocationEventCriteria not present")
		errHandlerProblemDetails(w, "LocationEventCriteria not present", http.StatusBadRequest)
		return
	} else {
		switch *areaCircleSub.EnteringLeavingCriteria {
		case ENTERING_EnteringLeavingCriteria, LEAVING_EnteringLeavingCriteria:
		default:
			log.Error("Invalid Mandatory EnteringLeavingCriteria parameter value")
			errHandlerProblemDetails(w, "Invalid Mandatory EnteringLeavingCriteria parameter value", http.StatusBadRequest)
			return
		}
	}
	if areaCircleSub.Frequency == 0 {
		log.Error("Mandatory Frequency parameter not present")
		errHandlerProblemDetails(w, "Mandatory Frequency parameter not present", http.StatusBadRequest)

	// Check if EnteringLeavingCriteria values are valid
	for _, criteria := range areaCircleSub.LocationEventCriteria {
		if criteria != ENTERING_AREA_EVENT && criteria != LEAVING_AREA_EVENT {
			log.Error("Invalid EnteringLeavingCriteria parameter value")
			errHandlerProblemDetails(w, "Invalid EnteringLeavingCriteria parameter value", http.StatusBadRequest)
			return
		}
	}
	// if areaCircleSub.Frequency == 0 {
	// 	log.Error("Mandatory Frequency parameter not present")
	// 	errHandlerProblemDetails(w, "Mandatory Frequency parameter not present", http.StatusBadRequest)
	// 	return
	// }
	/*
		  if areaCircleSub.CheckImmediate == nil {
				  log.Error("Mandatory CheckImmediate parameter not present")
@@ -2802,19 +2801,22 @@ func areaSubPOST(w http.ResponseWriter, r *http.Request) {
		   }
		   //else, lasts forever or until subscription is deleted
	*/
	if areaCircleSub.Duration != 0 { //used to be string -> zonalTrafficSub.Duration != "" && zonalTrafficSub.Duration != "0" {
		//TODO start a timer mecanism and expire subscription
		log.Info("Non zero duration")
	}
	// if areaCircleSub.Duration != 0 { //used to be string -> zonalTrafficSub.Duration != "" && zonalTrafficSub.Duration != "0" {
	// 	//TODO start a timer mecanism and expire subscription
	// 	log.Info("Non zero duration")
	// }
	//else, lasts forever or until subscription is deleted

	areaCircleSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/area/circle/" + subsIdStr
	areaCircleSub.Links = &Links{
		Self: &LinkType{
			Href: hostUrl.String() + basePath + "subscriptions/area/" + subsIdStr,
		},
	}

	_ = rc.JSONSetEntry(baseKey+typeAreaCircleSubscription+":"+subsIdStr, ".", convertAreaCircleSubscriptionToJson(areaCircleSub))

	registerAreaCircle(areaCircleSub, subsIdStr)

	response.CircleNotificationSubscription = areaCircleSub
	response.UserAreaSubscription = areaCircleSub

	jsonResponse, err := json.Marshal(response)
	if err != nil {
@@ -2828,11 +2830,9 @@ func areaSubPOST(w http.ResponseWriter, r *http.Request) {

func areaSubPUT(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	var response InlineUserAreaSubscription
	vars := mux.Vars(r)

	var response InlineCircleNotificationSubscription

	var body InlineCircleNotificationSubscription
	var body InlineUserAreaSubscription
	decoder := json.NewDecoder(r.Body)
	err := decoder.Decode(&body)
	if err != nil {
@@ -2840,7 +2840,7 @@ func areaSubPUT(w http.ResponseWriter, r *http.Request) {
		errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError)
		return
	}
	areaCircleSub := body.CircleNotificationSubscription
	areaCircleSub := body.UserAreaSubscription

	if areaCircleSub == nil {
		log.Error("Body not present")
@@ -2854,36 +2854,35 @@ func areaSubPUT(w http.ResponseWriter, r *http.Request) {
		errHandlerProblemDetails(w, "Mandatory CallbackReference parameter not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Address == nil {
	if areaCircleSub.AddressList == nil {
		log.Error("Mandatory Address parameter not present")
		errHandlerProblemDetails(w, "Mandatory Address parameter not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Latitude == 0 {
		log.Error("Mandatory Latitude parameter not present")
		errHandlerProblemDetails(w, "Mandatory Latitude parameter not present", http.StatusBadRequest)
	if len(areaCircleSub.AreaDefine.Points) == 0 {
		log.Error("Latitude and longitude not present")
		errHandlerProblemDetails(w, "Latitude and longitude not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Longitude == 0 {
		log.Error("Mandatory Longitude parameter not present")
		errHandlerProblemDetails(w, "Mandatory Longitude parameter not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Radius == 0 {
	if areaCircleSub.AreaDefine.Radius == 0 {
		log.Error("Mandatory Radius parameter not present")
		errHandlerProblemDetails(w, "Mandatory Radius parameter not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.EnteringLeavingCriteria == nil {
		log.Error("Mandatory EnteringLeavingCriteria parameter not present")
		errHandlerProblemDetails(w, "Mandatory EnteringLeavingCriteria parameter not present", http.StatusBadRequest)
	if len(areaCircleSub.LocationEventCriteria) == 0 {
		log.Error("LocationEventCriteria not present")
		errHandlerProblemDetails(w, "LocationEventCriteria not present", http.StatusBadRequest)
		return
	}
	if areaCircleSub.Frequency == 0 {
		log.Error("Mandatory Frequency parameter not present")
		errHandlerProblemDetails(w, "Mandatory Frequency parameter not present", http.StatusBadRequest)

	// Check if EnteringLeavingCriteria values are valid
	for _, criteria := range areaCircleSub.LocationEventCriteria {
		if criteria != ENTERING_AREA_EVENT && criteria != LEAVING_AREA_EVENT {
			log.Error("Invalid EnteringLeavingCriteria parameter value")
			errHandlerProblemDetails(w, "Invalid EnteringLeavingCriteria parameter value", http.StatusBadRequest)
			return
		}
	}
	/*
		  if areaCircleSub.CheckImmediate == nil {
				  log.Error("Mandatory CheckImmediate parameter not present")
@@ -2898,7 +2897,7 @@ func areaSubPUT(w http.ResponseWriter, r *http.Request) {
				  return
		  }
	*/
	if areaCircleSub.ResourceURL == "" {
	if areaCircleSub.Links.Self.Href == "" {
		log.Error("Mandatory ResourceURL parameter not present")
		errHandlerProblemDetails(w, "Mandatory ResourceURL parameter not present", http.StatusBadRequest)
		return
@@ -2906,7 +2905,7 @@ func areaSubPUT(w http.ResponseWriter, r *http.Request) {

	subsIdParamStr := vars["subscriptionId"]

	selfUrl := strings.Split(areaCircleSub.ResourceURL, "/")
	selfUrl := strings.Split(areaCircleSub.Links.Self.Href, "/")
	subsIdStr := selfUrl[len(selfUrl)-1]

	//body content not matching parameters
@@ -2916,7 +2915,11 @@ func areaSubPUT(w http.ResponseWriter, r *http.Request) {
		return
	}

	areaCircleSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/area/circle/" + subsIdStr
	areaCircleSub.Links = &Links{
		Self: &LinkType{
			Href: hostUrl.String() + basePath + "subscriptions/area/" + subsIdStr,
		},
	}

	subsId, err := strconv.Atoi(subsIdStr)
	if err != nil {
@@ -2940,7 +2943,7 @@ func areaSubPUT(w http.ResponseWriter, r *http.Request) {
	areaCircleSubscriptionMap[subsId].NbNotificationsSent = notifSent
	areaCircleSubscriptionMap[subsId].AddrInArea = addrInArea

	response.CircleNotificationSubscription = areaCircleSub
	response.UserAreaSubscription = areaCircleSub

	jsonResponse, err := json.Marshal(response)
	if err != nil {
@@ -2952,17 +2955,26 @@ func areaSubPUT(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, string(jsonResponse))
}

func populateAreaCircleList(key string, jsonInfo string, userData interface{}) error {
func populateUserAreaList(key string, jsonInfo string, userData interface{}) error {

	areaCircleList := userData.(*NotificationSubscriptionList)
	var areaCircleInfo CircleNotificationSubscription
	subscriptions := userData.(*[]Subscription)
	var areaInfo UserAreaSubscription

	// Format response
	err := json.Unmarshal([]byte(jsonInfo), &areaCircleInfo)
	err := json.Unmarshal([]byte(jsonInfo), &areaInfo)
	if err != nil {
		return err
	}
	areaCircleList.CircleNotificationSubscription = append(areaCircleList.CircleNotificationSubscription, areaCircleInfo)
	href := ""
	if areaInfo.Links != nil && areaInfo.Links.Self != nil {
		href = areaInfo.Links.Self.Href
	}
	// Create a Subscription instance
	sub := Subscription{
		Href:             href,
		SubscriptionType: areaInfo.SubscriptionType,
	}
	*subscriptions = append(*subscriptions, sub)
	return nil
}

@@ -5601,8 +5613,8 @@ func areaCircleReInit() {
	maxAreaCircleSubscriptionId := 0
	mutex.Lock()
	defer mutex.Unlock()
	for _, areaCircleSub := range areaCircleList.CircleNotificationSubscription {
		resourceUrl := strings.Split(areaCircleSub.ResourceURL, "/")
	for _, areaCircleSub := range areaCircleList.UserAreaSubscription {
		resourceUrl := strings.Split(areaCircleSub.Links.Self.Href, "/")
		subscriptionId, err := strconv.Atoi(resourceUrl[len(resourceUrl)-1])
		if err != nil {
			log.Error(err)
@@ -5614,10 +5626,10 @@ func areaCircleReInit() {
			areaCircleCheck.Subscription = &areaCircleSub
			areaCircleCheck.NbNotificationsSent = 0
			areaCircleCheck.AddrInArea = map[string]bool{}
			if areaCircleSub.CheckImmediate {
			if areaCircleSub.RequestTestNotification {
				areaCircleCheck.NextTts = 0 //next time periodic trigger hits, will be forced to trigger
			} else {
				areaCircleCheck.NextTts = areaCircleSub.Frequency
				areaCircleCheck.NextTts = areaCircleSub.ReportingCtrl.MaximumFrequency
			}
			areaCircleSubscriptionMap[subscriptionId] = &areaCircleCheck
		}
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ type NotificationSubscriptionList struct {

	UserLocationPeriodicSubscription []UserLocationPeriodicSubscription `json:"UserLocationPeriodicSubscription,omitempty"`
	// Collection of CircleNotificationSubscription elements, see note 2.
	CircleNotificationSubscription []CircleNotificationSubscription `json:"circleNotificationSubscription,omitempty"`
	UserAreaSubscription []UserAreaSubscription `json:"userAreaSubscription,omitempty"`
	// Collection of DistanceNotificationSubscription elements, see note 2.
	DistanceNotificationSubscription []DistanceNotificationSubscription `json:"distanceNotificationSubscription,omitempty"`
	// Collection of PeriodicNotificationSubscription elements, see note 2.
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ type UserAreaSubscription struct {

	AreaDefine *AreaInfo `json:"areaDefine"`
	// URI exposed by the client on which to receive notifications via HTTP. See note 1.
	CallbackReference string `json:"callbackReference,omitempty"`
	CallbackReference *CallbackReference `json:"callbackReference"`
	// A correlator that the client can use to tag this particular resource representation during a request to create a resource on the server. See note 2.
	ClientCorrelator string `json:"clientCorrelator,omitempty"`