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

Implement logic to handle ReportingCtrl and expirydeadline attribute in UserDistanceSubscription

parent edd74ca6
Loading
Loading
Loading
Loading
+308 −131
Original line number Diff line number Diff line
@@ -141,6 +141,9 @@ type DistanceCheck_ struct {
	NextTts                int32 //next time to send, derived from frequency
	NbNotificationsSent    int32
	NotificationCheckReady bool
	Reporting_amount       int32
	Reporting_interval     int32
	TimeStamp              int64
	Subscription           *UserDistanceSubscription
}

@@ -870,22 +873,22 @@ func checkNotificationDistancePeriodicTrigger1() {
	//only check if there is at least one subscription
	mutex.Lock()
	defer mutex.Unlock()
	currentTime := time.Now().Unix()
	//check all that applies
	for subsId, distanceCheck := range distanceSubscriptionMap1 {
		// if distanceCheck != nil && distanceCheck.Subscription != nil {
		// if distanceCheck.Subscription.Count == 0 || (distanceCheck.Subscription.Count != 0 && distanceCheck.NbNotificationsSent < distanceCheck.Subscription.Count) {
		// 	if distanceCheck.NextTts != 0 {
		// 		distanceCheck.NextTts--
		// 	}
		// 	if distanceCheck.NextTts == 0 {
		// 		distanceCheck.NotificationCheckReady = true
		// 	} else {
		// 		distanceCheck.NotificationCheckReady = false
		// 	}
		if distanceCheck != nil && distanceCheck.Subscription != nil {

		// 	if !distanceCheck.NotificationCheckReady {
		// 		continue
		// 	}
			// Check if the current time exceeds the expiry time
			if distanceCheck.Subscription.ExpiryDeadline != nil && time.Now().Unix() > int64(distanceSubscriptionMap1[subsId].TimeStamp) {
				subsIdStr := strconv.Itoa(subsId)
				log.Info("Expiry deadline passed for subscription: ")
				// Optionally, you can remove the subscription from the map or perform other cleanup actions
				err := rc.JSONDelEntry(baseKey+typeDistanceSubscription+":"+subsIdStr, ".")
				if err != nil {
					log.Error(err.Error())
				}
				continue
			}

			//loop through every reference address
			returnAddr := make(map[string]*gisClient.Distance)
@@ -976,15 +979,37 @@ func checkNotificationDistancePeriodicTrigger1() {
			if skipThisSubscription {
				continue
			}
			if distanceCheck.Subscription.ReportingCtrl != nil {
				// If NextTts has passed, send notification

				if currentTime >= int64(distanceCheck.NextTts) {
					// Update NextTts for the next notification
					distanceCheck.NextTts = int32(currentTime + int64(distanceCheck.Reporting_interval))
					// Check if reporting amount is reached
					if distanceCheck.Reporting_amount <= 0 {
						// If reporting amount is zero, no more notifications should be sent
						continue
					}
					// Decrement reporting amount
					distanceCheck.Reporting_amount--
					sendDistanceNotification(subsId, returnAddr, distanceCheck)
				}
			} else {
				// If no reporting control parameters, send notification without conditions
				sendDistanceNotification(subsId, returnAddr, distanceCheck)
			}
		}
	}
}

func sendDistanceNotification(subsId int, returnAddr map[string]*gisClient.Distance, distanceCheck *DistanceCheck_) {
	if len(returnAddr) > 0 {
		//update nb of notification sent anch check if valid
		subsIdStr := strconv.Itoa(subsId)

		var distanceNotif UserDistanceNotification
		distanceNotif.DistanceEvent = distanceCheck.Subscription.Criteria
			// distanceNotif.IsFinalNotification = false
			// distanceNotif.Link = distanceCheck.Subscription.Link

		distanceNotif.Links = distanceCheck.Subscription.Links
		var userList UserList
		var userInfoList []UserInfo
		for terminalAddr, distanceInfo := range returnAddr {
@@ -1001,8 +1026,6 @@ func checkNotificationDistancePeriodicTrigger1() {
			timestamp.Seconds = int32(seconds)
			locationInfo.Timestamp = &timestamp
			userInfo.LocationInfo = &locationInfo
				// retrievalStatus := RETRIEVED_RetrievalStatus
				// terminalLocation.LocationRetrievalStatus = &retrievalStatus
			userInfoList = append(userInfoList, userInfo)
		}
		userList.User = userInfoList
@@ -1013,11 +1036,164 @@ func checkNotificationDistancePeriodicTrigger1() {
		distanceCheck.NbNotificationsSent++
		sendSubscriptionNotification3(distanceCheck.Subscription.CallbackReference, inlineDistanceSubscriptionNotification)
		log.Info("Distance Notification"+"("+subsIdStr+") For ", returnAddr)
			// distanceSubscriptionMap[subsId].NextTts = distanceCheck.Subscription.Frequency
			// distanceSubscriptionMap[subsId].NotificationCheckReady = false
		}
	}
}

// func checkNotificationDistancePeriodicTrigger1() {

// 	//only check if there is at least one subscription
// 	mutex.Lock()
// 	defer mutex.Unlock()
// 	//check all that applies
// 	for subsId, distanceCheck := range distanceSubscriptionMap1 {
// 		if distanceCheck != nil && distanceCheck.Subscription != nil {
// 			// if distanceCheck.Subscription.Count == 0 || (distanceCheck.Subscription.Count != 0 && distanceCheck.NbNotificationsSent < distanceCheck.Subscription.Count) {
// 			// 	if distanceCheck.NextTts != 0 {
// 			// 		distanceCheck.NextTts--
// 			// 	}
// 			// 	if distanceCheck.NextTts == 0 {
// 			// 		distanceCheck.NotificationCheckReady = true
// 			// 	} else {
// 			// 		distanceCheck.NotificationCheckReady = false
// 			// 	}

// 			// 	if !distanceCheck.NotificationCheckReady {
// 			// 		continue
// 			// 	}

// 			//loop through every reference address
// 			returnAddr := make(map[string]*gisClient.Distance)
// 			skipThisSubscription := false

// 			//if reference address is specified, reference addresses are checked agains each monitored address
// 			//if reference address is nil, each pair of the monitored address should be checked
// 			//creating address pairs to check
// 			//e.g. refAddr = A, B ; monitoredAddr = C, D, E ; resultingPairs {A,C - A,D - A,E - B,C - B,D - B-E}
// 			//e.g. monitoredAddr = A, B, C ; resultingPairs {A,B - B,A - A,C - C,A - B,C - C,B}

// 			var addressPairs []Pair
// 			if distanceCheck.Subscription.ReferenceAddress != nil {
// 				for _, refAddr := range distanceCheck.Subscription.ReferenceAddress {
// 					//loop through every monitored address
// 					for _, monitoredAddr := range distanceCheck.Subscription.MonitoredAddress {
// 						pair := Pair{addr1: refAddr, addr2: monitoredAddr}
// 						addressPairs = append(addressPairs, pair)
// 					}
// 				}
// 			} else {
// 				nbIndex := len(distanceCheck.Subscription.MonitoredAddress)
// 				for i := 0; i < nbIndex-1; i++ {
// 					for j := i + 1; j < nbIndex; j++ {
// 						pair := Pair{addr1: distanceCheck.Subscription.MonitoredAddress[i], addr2: distanceCheck.Subscription.MonitoredAddress[j]}
// 						addressPairs = append(addressPairs, pair)
// 						//need pair to be symmetrical so that each is used as reference point and monitored address
// 						pair = Pair{addr1: distanceCheck.Subscription.MonitoredAddress[j], addr2: distanceCheck.Subscription.MonitoredAddress[i]}
// 						addressPairs = append(addressPairs, pair)
// 					}
// 				}
// 			}

// 			for _, pair := range addressPairs {
// 				refAddr := pair.addr1
// 				monitoredAddr := pair.addr2

// 				//check if one of the address if both addresses are connected, if not, disregard this pair
// 				if !addressConnectedMap[refAddr] || !addressConnectedMap[monitoredAddr] {
// 					//ignore that pair and continue processing
// 					continue
// 				}

// 				var distParam gisClient.TargetPoint
// 				distParam.AssetName = monitoredAddr

// 				distResp, httpResp, err := gisAppClient.GeospatialDataApi.GetDistanceGeoDataByName(context.TODO(), refAddr, distParam)
// 				if err != nil {
// 					//getting distance of an element that is not in the DB (not in scenario, not connected) returns error code 400 (bad parameters) in the API. Using that error code to track that request made it to GIS but no good result, so ignore that address (monitored or ref)
// 					if httpResp.StatusCode == http.StatusBadRequest {
// 						//ignore that pair and continue processing
// 						continue
// 					} else {
// 						log.Error("Failed to communicate with gis engine: ", err)
// 						return
// 					}
// 				}

// 				distance := int32(distResp.Distance)

// 				switch *distanceCheck.Subscription.Criteria {
// 				case ALL_WITHIN_DISTANCE_DistanceCriteria:
// 					if float32(distance) < distanceCheck.Subscription.Distance {
// 						returnAddr[monitoredAddr] = &distResp
// 					} else {
// 						skipThisSubscription = true
// 					}
// 				case ALL_BEYOND_DISTANCE_DistanceCriteria:
// 					if float32(distance) > distanceCheck.Subscription.Distance {
// 						returnAddr[monitoredAddr] = &distResp
// 					} else {
// 						skipThisSubscription = true
// 					}
// 				case ANY_WITHIN_DISTANCE_DistanceCriteria:
// 					if float32(distance) < distanceCheck.Subscription.Distance {
// 						returnAddr[monitoredAddr] = &distResp
// 					}
// 				case ANY_BEYOND_DISTANCE_DistanceCriteria:
// 					if float32(distance) > distanceCheck.Subscription.Distance {
// 						returnAddr[monitoredAddr] = &distResp
// 					}
// 				default:
// 				}
// 				if skipThisSubscription {
// 					break
// 				}
// 			}
// 			if skipThisSubscription {
// 				continue
// 			}
// 			if len(returnAddr) > 0 {
// 				//update nb of notification sent anch check if valid
// 				subsIdStr := strconv.Itoa(subsId)

// 				var distanceNotif UserDistanceNotification
// 				distanceNotif.DistanceEvent = distanceCheck.Subscription.Criteria
// 				// distanceNotif.IsFinalNotification = false
// 				// distanceNotif.Link = distanceCheck.Subscription.Link

// 				var userList UserList
// 				var userInfoList []UserInfo
// 				for terminalAddr, distanceInfo := range returnAddr {
// 					var userInfo UserInfo
// 					userInfo.Address = terminalAddr
// 					var locationInfo LocationInfo
// 					locationInfo.Latitude = nil
// 					locationInfo.Latitude = append(locationInfo.Latitude, distanceInfo.DstLatitude)
// 					locationInfo.Longitude = nil
// 					locationInfo.Longitude = append(locationInfo.Longitude, distanceInfo.DstLongitude)
// 					locationInfo.Shape = 2
// 					seconds := time.Now().Unix()
// 					var timestamp TimeStamp
// 					timestamp.Seconds = int32(seconds)
// 					locationInfo.Timestamp = &timestamp
// 					userInfo.LocationInfo = &locationInfo
// 					// retrievalStatus := RETRIEVED_RetrievalStatus
// 					// terminalLocation.LocationRetrievalStatus = &retrievalStatus
// 					userInfoList = append(userInfoList, userInfo)
// 				}
// 				userList.User = userInfoList
// 				distanceNotif.MonitoredUsers = &userList
// 				distanceNotif.NotificationType = "UserDistanceNotification"
// 				var inlineDistanceSubscriptionNotification InlineUserDistanceNotification
// 				inlineDistanceSubscriptionNotification.UserDistanceNotification = &distanceNotif
// 				distanceCheck.NbNotificationsSent++
// 				sendSubscriptionNotification3(distanceCheck.Subscription.CallbackReference, inlineDistanceSubscriptionNotification)
// 				log.Info("Distance Notification"+"("+subsIdStr+") For ", returnAddr)
// 				// distanceSubscriptionMap[subsId].NextTts = distanceCheck.Subscription.Frequency
// 				// distanceSubscriptionMap[subsId].NotificationCheckReady = false
// 			}
// 		}
// 	}
// }

func checkNotificationDistancePeriodicTrigger() {

	//only check if there is at least one subscription
@@ -1507,18 +1683,19 @@ func registerDistance1(distanceSub *UserDistanceSubscription, subsIdStr string)
	if err != nil {
		log.Error(err)
	}

	var expiryTime int64
	if distanceSub != nil && distanceSub.ExpiryDeadline != nil {
		expiryTime = time.Now().Unix() + int64(distanceSub.ExpiryDeadline.Seconds)
	}
	mutex.Lock()
	defer mutex.Unlock()
	var distanceCheck DistanceCheck_
	if distanceSub != nil && distanceSub.ReportingCtrl != nil {
		distanceCheck.Reporting_amount = distanceSub.ReportingCtrl.MaximumCount
		distanceCheck.Reporting_interval = distanceSub.ReportingCtrl.MinimumInterval
	}
	distanceCheck.TimeStamp = expiryTime
	distanceCheck.Subscription = distanceSub
	// distanceCheck.NbNotificationsSent = 0
	//checkImmediate ignored, will be hit on next check anyway
	//if distanceSub.CheckImmediate {
	//distanceCheck.NextTts = 0 //next time periodic trigger hits, will be forced to trigger
	//} else {
	//		distanceCheck.NextTts = distanceSub.Frequency
	//	}
	distanceSubscriptionMap1[subsId] = &distanceCheck
}

+2 −16
Original line number Diff line number Diff line
/*
 * Copyright (c) 2022  The AdvantEDGE Authors
 *
 * 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.
 *
 * AdvantEDGE Location API
 *
 * Location Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC013 Location API](https://www.etsi.org/deliver/etsi_gs/MEC/001_099/013/02.02.01_60/gs_mec013v020201p.pdf) <p>The API is based on the Open Mobile Alliance's specification RESTful Network API for Zonal Presence <p>[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt) <p>**Micro-service**<br>[meep-loc-serv](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-loc-serv) <p>**Type & Usage**<br>Edge Service used by edge applications that want to get information about Users (UE) and Zone locations <p>**Note**<br>AdvantEDGE supports all of Location API endpoints (see below).
 * Location Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC013 Location API](https://www.etsi.org/deliver/etsi_gs/MEC/001_099/013/03.01.01_60/gs_mec013v030101p.pdf) <p>The API is based on the Open Mobile Alliance's specification RESTful Network API for Zonal Presence <p>[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt) <p>**Micro-service**<br>[meep-loc-serv](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-loc-serv) <p>**Type & Usage**<br>Edge Service used by edge applications that want to get information about Users (UE) and Zone locations <p>**Note**<br>AdvantEDGE supports all of Location API endpoints (see below).
 *
 * API version: 2.2.1
 * API version: 3.1.1
 * Contact: AdvantEDGE@InterDigital.com
 * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
 */
+2 −2
Original line number Diff line number Diff line
/*
 * AdvantEDGE Location API
 *
 * Location Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC013 Location API](https://www.etsi.org/deliver/etsi_gs/MEC/001_099/013/02.02.01_60/gs_mec013v020201p.pdf) <p>The API is based on the Open Mobile Alliance's specification RESTful Network API for Zonal Presence <p>[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt) <p>**Micro-service**<br>[meep-loc-serv](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-loc-serv) <p>**Type & Usage**<br>Edge Service used by edge applications that want to get information about Users (UE) and Zone locations <p>**Note**<br>AdvantEDGE supports all of Location API endpoints (see below).
 * Location Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC013 Location API](https://www.etsi.org/deliver/etsi_gs/MEC/001_099/013/03.01.01_60/gs_mec013v030101p.pdf) <p>The API is based on the Open Mobile Alliance's specification RESTful Network API for Zonal Presence <p>[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt) <p>**Micro-service**<br>[meep-loc-serv](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-loc-serv) <p>**Type & Usage**<br>Edge Service used by edge applications that want to get information about Users (UE) and Zone locations <p>**Note**<br>AdvantEDGE supports all of Location API endpoints (see below).
 *
 * API version: 2.2.1
 * API version: 3.1.1
 * Contact: AdvantEDGE@InterDigital.com
 * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
 */