import logic.accounting.dsl.{DSLResource, DSLAgreement}
import collection.mutable
import logic.events.WalletEntry
+import util.json.JsonSupport
/**
case class GroupMembershipsSnapshot(data: List[String], snapshotTime: Long) extends UserDataSnapshot[List[String]]
/**
- * Maintains the current state of resources owned by the user. In order to have a
- * uniform representation of the resource state for all resource types
- * (complex or simple) the following convention applies:
+ * Maintains the current state of resources owned by the user.
+ * The encoding of the stored Map is as follows:
+ *
+ * key: ResourceInstanceId(DSLResource.name, instance-id)
+ * value: ResourceStateSnapshot(current-resource-value, last-update-timestamp)
+ *
+ * In order to have a uniform representation of the resource state for all
+ * resource types (complex or simple) the following convention applies:
+ *
+ * - If the resource is complex, the key is stored as ResourceInstanceId(DSLResource.name, instance-id)
+ * - If the resource is simple, the key is stored as ResourceInstanceId(DSLResource.name, 1)
*
- * * If the resource is complex, then `data.get(AResource)` returns a Map of
- * `("instance-id" -> current_resource_value)`, as expected.
- * * If the resource is simple, then `data.get(AResource)` returns
- * `("1" -> current_resource_value)`. This means that simple resources are
- * always stored with key 1 as `instance-id`.
*/
-case class OwnedResourcesSnapshot(data: Map[DSLResource, Map[String, Float]], snapshotTime: Long)
- extends UserDataSnapshot[Map[DSLResource, Map[String, Float]]]
+case class ResourceInstanceId(name: String, instanceId: String)
+case class ResourceStateSnapshot(value: Float, lastUpdate: Long)
+case class OwnedResourcesSnapshot(data: Map[ResourceInstanceId, ResourceStateSnapshot], snapshotTime: Long)
+ extends UserDataSnapshot[Map[ResourceInstanceId, ResourceStateSnapshot]]
+
/**
* A generic exception thrown when errors occur in dealing with user data snapshots
val oldOwnedResources = _userState.ownedResources
// Find or create the new resource instance map
val oldOwnedResourcesData = oldOwnedResources.data
- val oldRCInstanceMap = oldOwnedResourcesData.get(resource) match {
- case Some(resourceMap) ⇒ resourceMap
- case None ⇒ Map[String, Float]()
+ val key = ResourceInstanceId(resource.name, instanceId)
+ val oldRCInstance = oldOwnedResourcesData.get(key) match {
+ case Some(resourceState) ⇒ resourceState
+ case None ⇒ ResourceStateSnapshot(0, 0)
}
- // Update the new value in the resource instance map
- val newRCInstanceMap: Map[String, Float] = oldRCInstanceMap.updated(instanceId, ev.value)
+ // Update the new value in the resource state
+ val newRCInstanceMap = oldRCInstance.copy(value = ev.value, lastUpdate = ev.occurredMillis)
- val newOwnedResourcesData = oldOwnedResourcesData.updated(resource, newRCInstanceMap)
+ val newOwnedResourcesData = oldOwnedResourcesData.updated(key, newRCInstanceMap)
// A. First state diff: the modified resource value
val StateChangeMillis = TimeHelpers.nowMillis
// TODO: the snapshot time should be per instanceId?
// TODO: Related events
val walletEntriesM = chargeEvent(ev, agreement, ev.value,
- new Date(oldOwnedResources.snapshotTime),
+ new Date(oldRCInstance.lastUpdate),
findRelatedEntries(resource, ev.getInstanceId(policy)))
walletEntriesM match {
case Just(walletEntries) ⇒
import gr.grnet.aquarium.logic.test.DSLTest
import gr.grnet.aquarium.logic.accounting.Policy
import org.junit.Test
+import gr.grnet.aquarium.util.json.JsonSupport
+import gr.grnet.aquarium.logic.accounting.dsl.DSLResource
/**
*
PaymentOrdersSnapshot(Nil, now),
OwnedGroupsSnapshot(Nil, now),
GroupMembershipsSnapshot(Nil, now),
- OwnedResourcesSnapshot(Map(("foo", "1") -> (0F, 0L)), now)
+ OwnedResourcesSnapshot(Map(ResourceInstanceId("foo", "1") ->
+ ResourceStateSnapshot(0F, 0L)), now)
)
println(state.toJson)