X-Git-Url: https://code.grnet.gr/git/aquarium/blobdiff_plain/b71ac54f72a1a54c9c50bf7d410f6369dba8c5c2..e5369e9d799fdd317fec4e4896081b10f4047f89:/src/main/scala/gr/grnet/aquarium/charging/state/UserStateModel.scala diff --git a/src/main/scala/gr/grnet/aquarium/charging/state/UserStateModel.scala b/src/main/scala/gr/grnet/aquarium/charging/state/UserStateModel.scala index ff8c25d..99f8e8d 100644 --- a/src/main/scala/gr/grnet/aquarium/charging/state/UserStateModel.scala +++ b/src/main/scala/gr/grnet/aquarium/charging/state/UserStateModel.scala @@ -35,116 +35,126 @@ package gr.grnet.aquarium.charging.state -import gr.grnet.aquarium.message.avro.gen.UserStateMsg +import gr.grnet.aquarium.message.avro.gen.{UserAgreementMsg, IMEventMsg, UserAgreementHistoryMsg, UserStateMsg} import gr.grnet.aquarium.Real +import scala.collection.immutable +import gr.grnet.aquarium.policy.UserAgreementModel +import gr.grnet.aquarium.message.avro.{MessageFactory, MessageHelpers, ModelFactory} +import gr.grnet.aquarium.logic.accounting.dsl.Timeslot /** * - * A wrapper around [[gr.grnet.aquarium.message.avro.gen.UserStateMsg]] with convenient (sorted) + * A wrapper around [[gr.grnet.aquarium.message.avro.gen.UserStateMsg]] and + * [[]] with convenient (sorted) * user agreement history. * * @author Christos KK Loverdos */ -final class UserStateModel(msg: UserStateMsg) { +final class UserStateModel( + private[this] var _userStateMsg: UserStateMsg, + private[this] var _userAgreementHistoryMsg: UserAgreementHistoryMsg +) { + require(this._userStateMsg ne null, "this._userStateMsg ne null") + require(this._userAgreementHistoryMsg ne null, "this._userAgreementHistoryMsg ne null") - def userID = msg.getUserID + private[this] var _latestIMEventOccurredMillis = 0L + private[this] var _userCreationIMEventMsgOpt: Option[IMEventMsg] = None - def latestResourceEventOccurredMillis = this.msg.getLatestResourceEventOccurredMillis + private[this] var _userAgreementModels: immutable.SortedSet[UserAgreementModel] = { + var userAgreementModels = immutable.SortedSet[UserAgreementModel]() + val userAgreements = _userAgreementHistoryMsg.getAgreements.iterator() + while(userAgreements.hasNext) { + val userAgreement = userAgreements.next() + val userAgreementModel = ModelFactory.newUserAgreementModel(userAgreement) + userAgreementModels += userAgreementModel - @inline final def totalCredits: Real = { - Real(msg.getTotalCredits) + checkUserCreationIMEvent(userAgreement.getRelatedIMEventMsg) + checkLatestIMEventOccurredMillis(userAgreement.getRelatedIMEventMsg) + } + + userAgreementModels + } + + private[this] def checkUserCreationIMEvent(imEvent: IMEventMsg) { + if(MessageHelpers.isIMEventCreate(imEvent)) { + this._userCreationIMEventMsgOpt = Some(imEvent) + } + } + private[this] def checkLatestIMEventOccurredMillis(imEvent: IMEventMsg) { + if(imEvent ne null) { + if(this._latestIMEventOccurredMillis < imEvent.getOccurredMillis) { + this._latestIMEventOccurredMillis = imEvent.getOccurredMillis + } + } + } + + private[this] def updateOtherVars(imEvent: IMEventMsg) { + checkUserCreationIMEvent(imEvent) + checkLatestIMEventOccurredMillis(imEvent) + } + + def userID = this._userAgreementHistoryMsg.getUserID + + def latestIMEventOccurredMillis = this._latestIMEventOccurredMillis + + def hasUserCreationEvent = this._userCreationIMEventMsgOpt.isDefined + + def userCreationIMEventOpt = this._userCreationIMEventMsgOpt + + def unsafeUserCreationIMEvent = this._userCreationIMEventMsgOpt.get + + def unsafeUserCreationMillis = unsafeUserCreationIMEvent.getOccurredMillis + + def size: Int = _userAgreementHistoryMsg.getAgreements.size() + + def userStateMsg = this._userStateMsg + + def updateUserStateMsg(msg: UserStateMsg) { + this._userStateMsg = msg + } + + def userAgreementHistoryMsg = this._userAgreementHistoryMsg + + def updateUserAgreementHistoryMsg(msg: UserAgreementHistoryMsg) { + this._userAgreementHistoryMsg = msg } - override def toString = msg.toString - -// def newForImplicitEndsAsPreviousEvents( -// previousResourceEvents: mutable.Map[(String, String), ResourceEventModel] -// ) = { -// -// new WorkingUserState( -// this.userID, -// this.parentUserStateIDInStore, -// this.chargingReason, -// this.resourceTypesMap, -// previousResourceEvents, -// this.implicitlyIssuedStartEventOfResourceInstance, -// this.accumulatingAmountOfResourceInstance, -// this.chargingDataOfResourceInstance, -// this.totalCredits, -// this.workingAgreementHistory, -// this.latestUpdateMillis, -// this.latestResourceEventOccurredMillis, -// this.billingPeriodOutOfSyncResourceEventsCounter, -// this.walletEntries -// ) -// } - -// def getChargingDataForResourceEvent(resourceAndInstanceInfo: (String, String)): mutable.Map[String, Any] = { -// chargingDataOfResourceInstance.get(resourceAndInstanceInfo) match { -// case Some(map) ⇒ -// map -// -// case None ⇒ -// val map = mutable.Map[String, Any]() -// chargingDataOfResourceInstance(resourceAndInstanceInfo) = map -// map -// -// } -// } - -// def setChargingDataForResourceEvent( -// resourceAndInstanceInfo: (String, String), -// data: mutable.Map[String, Any] -// ): Unit = { -// chargingDataOfResourceInstance(resourceAndInstanceInfo) = data -// } - - /** - * Find those events from `implicitlyIssuedStartEvents` and `previousResourceEvents` that will generate implicit - * end events along with those implicitly issued events. Before returning, remove the events that generated the - * implicit ends from the internal state of this instance. - * - * @see [[gr.grnet.aquarium.charging.ChargingBehavior]] - */ -// def findAndRemoveGeneratorsOfImplicitEndEvents( -// chargingBehaviorOfResourceType: ResourceType ⇒ ChargingBehavior, -// /** -// * The `occurredMillis` that will be recorded in the synthetic implicit OFFs. -// * Normally, this will be the end of a billing month. -// */ -// newOccuredMillis: Long -// ): (List[ResourceEventModel], List[ResourceEventModel]) = { -// -// val buffer = mutable.ListBuffer[(ResourceEventModel, ResourceEventModel)]() -// val checkSet = mutable.Set[ResourceEventModel]() -// -// def doItFor(map: mutable.Map[(String, String), ResourceEventModel]): Unit = { -// val resourceEvents = map.valuesIterator -// for { -// resourceEvent ← resourceEvents -// resourceType ← resourceTypesMap.get(resourceEvent.safeResource) -// chargingBehavior = chargingBehaviorOfResourceType.apply(resourceType) -// } { -// if(chargingBehavior.supportsImplicitEvents) { -// if(chargingBehavior.mustConstructImplicitEndEventFor(resourceEvent)) { -// val implicitEnd = chargingBehavior.constructImplicitEndEventFor(resourceEvent, newOccuredMillis) -// -// if(!checkSet.contains(resourceEvent)) { -// checkSet.add(resourceEvent) -// buffer append ((resourceEvent, implicitEnd)) -// } -// -// // remove it anyway -// map.remove((resourceEvent.safeResource, resourceEvent.safeInstanceID)) -// } -// } -// } -// } -// -// doItFor(previousEventOfResourceInstance) // we give priority for previous events -// doItFor(implicitlyIssuedStartEventOfResourceInstance) // ... over implicitly issued ones ... -// -// (buffer.view.map(_._1).toList, buffer.view.map(_._2).toList) -// } + def agreementByTimeslot: immutable.SortedMap[Timeslot, UserAgreementModel] = { + immutable.TreeMap(_userAgreementModels.map(ag ⇒ (ag.timeslot, ag)).toSeq: _*) + } + + def insertUserAgreementModel(userAgreement: UserAgreementModel) { + MessageHelpers.insertUserAgreement(this._userAgreementHistoryMsg, userAgreement.msg) + + this._userAgreementModels += userAgreement + + updateOtherVars(userAgreement.msg.getRelatedIMEventMsg) + } + + def insertUserAgreementMsg(userAgreementMsg: UserAgreementMsg) { + insertUserAgreementModel(ModelFactory.newUserAgreementModel(userAgreementMsg)) + } + + def insertUserAgreementMsgFromIMEvent(imEvent: IMEventMsg) { + val userAgreementMsg = MessageFactory.newUserAgreementFromIMEventMsg(imEvent) + insertUserAgreementMsg(userAgreementMsg) + } + + def oldestAgreementModel: Option[UserAgreementModel] = { + _userAgreementModels.headOption + } + + def newestAgreementModel: Option[UserAgreementModel] = { + _userAgreementModels.lastOption + } + + def latestResourceEventOccurredMillis = this._userStateMsg.getLatestResourceEventOccurredMillis + + @inline final def totalCreditsAsReal: Real = Real(this._userStateMsg.getTotalCredits) + + @inline final def totalCredits: String = this._userStateMsg.getTotalCredits + + override def toString = _userStateMsg.toString + }