ed80f656a2573fde154587f4ec711dd722b3ccdc
[aquarium] / src / main / scala / gr / grnet / aquarium / store / PolicyStore.scala
1 /*
2  * Copyright 2011-2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above
13  *      copyright notice, this list of conditions and the following
14  *      disclaimer in the documentation and/or other materials
15  *      provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * The views and conclusions contained in the software and
31  * documentation are those of the authors and should not be
32  * interpreted as representing official policies, either expressed
33  * or implied, of GRNET S.A.
34  */
35
36 package gr.grnet.aquarium.store
37
38 import scala.collection.immutable
39 import collection.immutable.SortedMap
40 import gr.grnet.aquarium.logic.accounting.dsl.{DSL, DSLPolicy, Timeslot}
41 import com.ckkloverdos.maybe.{NoVal, Just, Maybe}
42 import gr.grnet.aquarium.event.PolicyEntry
43
44 /**
45  * A store for serialized policy entries.
46  *
47  * @author Georgios Gousios <gousiosg@gmail.com>
48  */
49 trait PolicyStore {
50
51   /**
52    * Load all accounting policies valid after the specified time instance.
53    * The results are returned sorted by PolicyEntry.validFrom
54    */
55   def loadPolicyEntriesAfter(after: Long): List[PolicyEntry]
56
57   def loadAndSortPolicyEntriesWithin(fromMillis: Long, toMillis: Long): SortedMap[Timeslot, PolicyEntry] = {
58     val all = loadPolicyEntriesAfter(0L)
59     val filtered = all.filter { policyEntry ⇒
60       policyEntry.validFrom <= fromMillis &&
61       policyEntry.validTo   >= toMillis
62     }
63
64     (immutable.SortedMap[Timeslot, PolicyEntry]() /: filtered) { (map, policyEntry) ⇒
65       map.updated(policyEntry.fromToTimeslot, policyEntry)
66     }
67   }
68   
69   def loadAndSortPoliciesWithin(fromMillis: Long, toMillis: Long, dsl: DSL): SortedMap[Timeslot, DSLPolicy] = {
70     for((timeslot, policyEntry) <- loadAndSortPolicyEntriesWithin(fromMillis, toMillis))
71       yield (timeslot, dsl.parse(policyEntry.policyYAML))
72   }
73   
74   def loadValidPolicyEntryAt(atMillis: Long): Maybe[PolicyEntry] = Maybe {
75     loadPolicyEntriesAfter(0L).find { policyEntry ⇒
76       policyEntry.fromToTimeslot.containsTimeInMillis(atMillis)
77     } match {
78       case Some(policyEntry) ⇒
79         policyEntry
80       case None ⇒
81         null // Do not worry, this will be transformed to a NoVal by the Maybe polymorphic constructor
82     }
83   }
84   
85   def loadValidPolicyAt(atMillis: Long, dsl: DSL): Maybe[DSLPolicy] = {
86     loadValidPolicyEntryAt(atMillis).map(policyEntry ⇒ dsl.parse(policyEntry.policyYAML))
87   }
88
89   /**
90    * Store an accounting policy.
91    */
92   def storePolicyEntry(policy: PolicyEntry): Maybe[RecordID]
93
94   /**
95    * Updates the policy record whose id is equal to the id
96    * of the provided policy entry.
97    */
98   def updatePolicyEntry(policy: PolicyEntry): Unit
99
100   /**
101    * Find a policy by its unique id
102    */
103   def findPolicyEntry(id: String): Maybe[PolicyEntry]
104 }