@volatile private[this] var _chargingBehaviorMap = Map[String, ChargingBehavior]()
- private[this] val policyHistory = new PolicyHistory
-
private[this] val _isStopping = new AtomicBoolean(false)
override def toString = "%s/v%s".format(getClass.getName, version)
def userStateStore = apply(EnvKeys.storeProvider).userStateStore
- def policyStore = apply(EnvKeys.storeProvider).policyStore
+ def policyStore = new PolicyHistory(apply(EnvKeys.storeProvider).policyStore)
def eventsStoreFolder = apply(EnvKeys.eventsStoreFolder)
package gr.grnet.aquarium.policy
-import scala.collection.immutable.TreeSet
+import collection.immutable.{SortedMap, TreeSet}
import gr.grnet.aquarium.Timespan
import gr.grnet.aquarium.util.Lock
+import gr.grnet.aquarium.store.PolicyStore
+import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
+import collection.immutable
/**
* A mutable container of policy models.
*
* @author Christos KK Loverdos <loverdos@gmail.com>
+ * @author Prodromos Gerakios <pgerakios@grnet.gr>
*/
-class PolicyHistory {
+class PolicyHistory(policyStore: PolicyStore) extends PolicyStore {
+ override type Policy = PolicyModel
private[this] val lock = new Lock()
- @volatile private[this] var _policies = TreeSet[PolicyModel]()
+ @volatile private[this] var _policies = TreeSet[Policy]()
+ private def emptyMap = immutable.SortedMap[Timeslot,Policy]()
+
+ private[this] def synchronized[A](f: => A) : A =
+ lock.withLock {
+ if(_policies.isEmpty)
+ _policies ++= policyStore.loadAndSortPoliciesWithin(0,Long.MaxValue).values
+ f
+ }
+
+ private[this] def policyAt(s:Long) : PolicyModel =
+ new StdPolicy("", None, Timespan(s), Set(), Set(), Map())
+
+ def loadAndSortPoliciesWithin(fromMillis: Long, toMillis: Long): SortedMap[Timeslot, Policy] =
+ synchronized {
+ val range = Timeslot(fromMillis,toMillis)
+ /* ``to'' method: return the subset of all policies.from <= range.to */
+ _policies.to(policyAt(range.to.getTime)).foldLeft (emptyMap) { (map,p) =>
+ if(p.validityTimespan.toTimeslot.to.getTime >= range.from.getTime)
+ map + ((p.validityTimespan.toTimeslot,p))
+ else
+ map
+ }
+ }
- def insertNewPolicy(newPolicy: PolicyModel): Unit = {
- lock.withLock(_policies += newPolicy)
- }
/**
* Return the last (ordered) policy that starts before timeMillis
*
- * @param timeMillis
+ * @param atMillis
* @return
*/
- def findPolicyAt(timeMillis: Long): Option[PolicyModel] = {
- lock.withLock {
+ def loadValidPolicyAt(atMillis: Long): Option[Policy] =
+ synchronized {
// Take the subset of all ordered policies up to the one with less than or equal start time
// and then return the last item. This should be the policy right before the given time.
// TODO: optimize the creation of the fake StdPolicy
- _policies.to(new StdPolicy("", None, Timespan(timeMillis), Set(), Set(), Map())).lastOption
+ _policies.to(policyAt(atMillis)).lastOption
}
- }
+
+
+ /**
+ * Store an accounting policy.
+ */
+ def insertPolicy(policy: PolicyModel): Policy =
+ synchronized {
+ var p = policyStore.insertPolicy(policy)
+ _policies += p
+ p
+ }
}
trait PolicyStore {
type Policy <: PolicyModel
- /**
- * Load all accounting policies valid after the specified time instance.
- * The results are returned sorted by PolicyEntry.validFrom
- */
- def loadPoliciesAfter(afterMillis: Long): List[Policy]
+ def loadAndSortPoliciesWithin(fromMillis: Long, toMillis: Long): SortedMap[Timeslot, Policy]
- def loadAndSortPoliciesWithin(fromMillis: Long, toMillis: Long): SortedMap[Timeslot, Policy] = {
- // FIXME implement
- throw new UnsupportedOperationException
- }
-
- def loadValidPolicyAt(atMillis: Long): Option[Policy] = {
- // FIXME implement
- throw new UnsupportedOperationException
- }
+ def loadValidPolicyAt(atMillis: Long): Option[Policy]
/**
* Store an accounting policy.
*/
def insertPolicy(policy: PolicyModel): Policy
- /**
- * Find a policy by its unique id.
- */
- def findPolicyByID(id: String): Option[Policy]
}
\ No newline at end of file
import gr.grnet.aquarium.util.Tags
import gr.grnet.aquarium.computation.BillingMonthInfo
import gr.grnet.aquarium.policy.{PolicyModel, StdPolicy}
+import collection.immutable.SortedMap
+import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
/**
* An implementation of various stores that persists parts in memory.
*
* @author Christos KK Loverdos <loverdos@gmail.com>
* @author Georgios Gousios <gousiosg@gmail.com>
+ * @author Prodromos Gerakios <grnet.gr>
*/
class MemStoreProvider
}
//- IMEventStore
- def loadPoliciesAfter(afterMillis: Long) =
- _policies.filter(p => p.validFrom > afterMillis)
- .sortWith((a,b) => a.validFrom < b.validFrom)
-
- def findPolicyByID(id: String) = {
- _policies.find(p => p.id == id)
- }
-
/**
* Store an accounting policy.
*/
localPolicy
}
+
+ def loadValidPolicyAt(atMillis: Long): Option[Policy] = {
+ throw new UnsupportedOperationException
+ }
+
+ def loadAndSortPoliciesWithin(fromMillis: Long, toMillis: Long): SortedMap[Timeslot, Policy] = {
+ throw new UnsupportedOperationException
+ }
}
object MemStoreProvider {
import gr.grnet.aquarium.computation.BillingMonthInfo
import gr.grnet.aquarium.policy.PolicyModel
import gr.grnet.aquarium.{Aquarium, AquariumException}
+import collection.immutable.SortedMap
+import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
/**
* Mongodb implementation of the various aquarium stores.
*
* @author Christos KK Loverdos <loverdos@gmail.com>
* @author Georgios Gousios <gousiosg@gmail.com>
+ * @author Prodromos Gerakios <pgerakio@grnet.gr>
*/
class MongoDBStore(
val aquarium: Aquarium,
val dbPolicy = MongoDBPolicy.fromOther(policy, new ObjectId().toStringMongod)
MongoDBStore.insertObject(dbPolicy, policies, MongoDBStore.jsonSupportToDBObject)
}
+
+ def loadValidPolicyAt(atMillis: Long): Option[Policy] = {
+ throw new UnsupportedOperationException
+ }
+
+ def loadAndSortPoliciesWithin(fromMillis: Long, toMillis: Long): SortedMap[Timeslot, Policy] = {
+ throw new UnsupportedOperationException
+ }
//-PolicyStore
}