root / src / main / scala / gr / grnet / aquarium / Aquarium.scala @ 7dbaeb04
History | View | Annotate | Download (15.3 kB)
1 | 12a4f3c9 | Christos KK Loverdos | /* |
---|---|---|---|
2 | 04b151ba | Christos KK Loverdos | * Copyright 2011-2012 GRNET S.A. All rights reserved. |
3 | 12a4f3c9 | Christos KK Loverdos | * |
4 | 12a4f3c9 | Christos KK Loverdos | * Redistribution and use in source and binary forms, with or |
5 | 12a4f3c9 | Christos KK Loverdos | * without modification, are permitted provided that the following |
6 | 12a4f3c9 | Christos KK Loverdos | * conditions are met: |
7 | 12a4f3c9 | Christos KK Loverdos | * |
8 | 12a4f3c9 | Christos KK Loverdos | * 1. Redistributions of source code must retain the above |
9 | 12a4f3c9 | Christos KK Loverdos | * copyright notice, this list of conditions and the following |
10 | 12a4f3c9 | Christos KK Loverdos | * disclaimer. |
11 | 12a4f3c9 | Christos KK Loverdos | * |
12 | 12a4f3c9 | Christos KK Loverdos | * 2. Redistributions in binary form must reproduce the above |
13 | 12a4f3c9 | Christos KK Loverdos | * copyright notice, this list of conditions and the following |
14 | 12a4f3c9 | Christos KK Loverdos | * disclaimer in the documentation and/or other materials |
15 | 12a4f3c9 | Christos KK Loverdos | * provided with the distribution. |
16 | 12a4f3c9 | Christos KK Loverdos | * |
17 | 12a4f3c9 | Christos KK Loverdos | * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
18 | 12a4f3c9 | Christos KK Loverdos | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
19 | 12a4f3c9 | Christos KK Loverdos | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
20 | 12a4f3c9 | Christos KK Loverdos | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
21 | 12a4f3c9 | Christos KK Loverdos | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
22 | 12a4f3c9 | Christos KK Loverdos | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
23 | 12a4f3c9 | Christos KK Loverdos | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
24 | 12a4f3c9 | Christos KK Loverdos | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
25 | 12a4f3c9 | Christos KK Loverdos | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
26 | 12a4f3c9 | Christos KK Loverdos | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
27 | 12a4f3c9 | Christos KK Loverdos | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
28 | 12a4f3c9 | Christos KK Loverdos | * POSSIBILITY OF SUCH DAMAGE. |
29 | 12a4f3c9 | Christos KK Loverdos | * |
30 | 12a4f3c9 | Christos KK Loverdos | * The views and conclusions contained in the software and |
31 | 12a4f3c9 | Christos KK Loverdos | * documentation are those of the authors and should not be |
32 | 12a4f3c9 | Christos KK Loverdos | * interpreted as representing official policies, either expressed |
33 | 12a4f3c9 | Christos KK Loverdos | * or implied, of GRNET S.A. |
34 | 12a4f3c9 | Christos KK Loverdos | */ |
35 | 12a4f3c9 | Christos KK Loverdos | |
36 | 12a4f3c9 | Christos KK Loverdos | package gr.grnet.aquarium |
37 | 12a4f3c9 | Christos KK Loverdos | |
38 | 695c71e2 | Christos KK Loverdos | import com.ckkloverdos.env.Env |
39 | 695c71e2 | Christos KK Loverdos | import com.ckkloverdos.key.{IntKey, StringKey, LongKey, TypedKeySkeleton, TypedKey, BooleanKey} |
40 | ba69480b | Christos KK Loverdos | import com.ckkloverdos.props.Props |
41 | 7dbaeb04 | Christos KK Loverdos | import gr.grnet.aquarium.store.{PolicyStore, StoreProvider} |
42 | 695c71e2 | Christos KK Loverdos | import java.io.File |
43 | 695c71e2 | Christos KK Loverdos | import gr.grnet.aquarium.util.{Loggable, Lifecycle} |
44 | 6ad32d72 | Christos KK Loverdos | import gr.grnet.aquarium.service.{StoreWatcherService, RabbitMQService, TimerService, EventBusService, AkkaService} |
45 | 695c71e2 | Christos KK Loverdos | import com.ckkloverdos.convert.Converters |
46 | b30e5a44 | Christos KK Loverdos | import java.util.concurrent.atomic.AtomicBoolean |
47 | 695c71e2 | Christos KK Loverdos | import org.slf4j.{LoggerFactory, Logger} |
48 | 695c71e2 | Christos KK Loverdos | import com.ckkloverdos.maybe._ |
49 | 695c71e2 | Christos KK Loverdos | import com.ckkloverdos.sys.SysProp |
50 | 7de7765f | Christos KK Loverdos | import gr.grnet.aquarium.service.event.AquariumCreatedEvent |
51 | 7dbaeb04 | Christos KK Loverdos | import gr.grnet.aquarium.policy.{FullPriceTable, PolicyModel, CachingPolicyStore, PolicyDefinedFullPriceTableRef, StdUserAgreement, UserAgreementModel, ResourceType} |
52 | 2a29acf9 | Christos KK Loverdos | import gr.grnet.aquarium.charging.{ChargingService, ChargingBehavior} |
53 | 2a29acf9 | Christos KK Loverdos | import gr.grnet.aquarium.util.date.TimeHelpers |
54 | 12a4f3c9 | Christos KK Loverdos | |
55 | 12a4f3c9 | Christos KK Loverdos | /** |
56 | 12a4f3c9 | Christos KK Loverdos | * |
57 | 695c71e2 | Christos KK Loverdos | * @author Christos KK Loverdos <loverdos@gmail.com> |
58 | 12a4f3c9 | Christos KK Loverdos | */ |
59 | 695c71e2 | Christos KK Loverdos | |
60 | 695c71e2 | Christos KK Loverdos | final class Aquarium(env: Env) extends Lifecycle with Loggable { |
61 | 695c71e2 | Christos KK Loverdos | import Aquarium.EnvKeys |
62 | 9ce8385e | Christos KK Loverdos | |
63 | b7b59f6f | Christos KK Loverdos | @volatile private[this] var _chargingBehaviorMap = Map[String, ChargingBehavior]() |
64 | b7b59f6f | Christos KK Loverdos | |
65 | 7dbaeb04 | Christos KK Loverdos | private[this] lazy val cachingPolicyStore = new CachingPolicyStore( |
66 | 7dbaeb04 | Christos KK Loverdos | apply(EnvKeys.defaultPolicyModel), |
67 | 7dbaeb04 | Christos KK Loverdos | apply(EnvKeys.storeProvider).policyStore |
68 | 7dbaeb04 | Christos KK Loverdos | ) |
69 | 7dbaeb04 | Christos KK Loverdos | |
70 | b30e5a44 | Christos KK Loverdos | private[this] val _isStopping = new AtomicBoolean(false) |
71 | b30e5a44 | Christos KK Loverdos | |
72 | 5e4d8d64 | Christos KK Loverdos | override def toString = "%s/v%s".format(getClass.getName, version) |
73 | 5e4d8d64 | Christos KK Loverdos | |
74 | b30e5a44 | Christos KK Loverdos | def isStopping() = _isStopping.get() |
75 | b30e5a44 | Christos KK Loverdos | |
76 | 6453d1cf | Christos KK Loverdos | @inline |
77 | 6453d1cf | Christos KK Loverdos | def getClientLogger(client: AnyRef): Logger = { |
78 | 6453d1cf | Christos KK Loverdos | client match { |
79 | 6453d1cf | Christos KK Loverdos | case null ⇒ |
80 | 6453d1cf | Christos KK Loverdos | this.logger |
81 | 6453d1cf | Christos KK Loverdos | |
82 | 6453d1cf | Christos KK Loverdos | case _ ⇒ |
83 | 6453d1cf | Christos KK Loverdos | LoggerFactory.getLogger(client.getClass) |
84 | 6453d1cf | Christos KK Loverdos | } |
85 | 6453d1cf | Christos KK Loverdos | } |
86 | 6453d1cf | Christos KK Loverdos | |
87 | 3004b61c | Christos KK Loverdos | def debug(client: AnyRef, fmt: String, args: Any*) = { |
88 | 6453d1cf | Christos KK Loverdos | getClientLogger(client).debug(fmt.format(args: _*)) |
89 | 3004b61c | Christos KK Loverdos | } |
90 | 3004b61c | Christos KK Loverdos | |
91 | 3004b61c | Christos KK Loverdos | def info(client: AnyRef, fmt: String, args: Any*) = { |
92 | 6453d1cf | Christos KK Loverdos | getClientLogger(client).info(fmt.format(args: _*)) |
93 | 3004b61c | Christos KK Loverdos | } |
94 | 3004b61c | Christos KK Loverdos | |
95 | 3004b61c | Christos KK Loverdos | def warn(client: AnyRef, fmt: String, args: Any*) = { |
96 | 6453d1cf | Christos KK Loverdos | getClientLogger(client).warn(fmt.format(args: _*)) |
97 | 3004b61c | Christos KK Loverdos | } |
98 | 3004b61c | Christos KK Loverdos | |
99 | 695c71e2 | Christos KK Loverdos | @throws(classOf[AquariumInternalError]) |
100 | 695c71e2 | Christos KK Loverdos | def apply[T: Manifest](key: TypedKey[T]): T = { |
101 | 695c71e2 | Christos KK Loverdos | try { |
102 | 695c71e2 | Christos KK Loverdos | env.getEx(key) |
103 | 695c71e2 | Christos KK Loverdos | } catch { |
104 | 695c71e2 | Christos KK Loverdos | case e: Exception ⇒ |
105 | 695c71e2 | Christos KK Loverdos | throw new AquariumInternalError("Could not locate %s in Aquarium environment".format(key)) |
106 | 03046173 | Christos KK Loverdos | } |
107 | 03046173 | Christos KK Loverdos | } |
108 | 03046173 | Christos KK Loverdos | |
109 | b7b59f6f | Christos KK Loverdos | private[this] lazy val _allServices = Aquarium.ServiceKeys.map(this.apply(_)) |
110 | af872cfe | Georgios Gousios | |
111 | b30e5a44 | Christos KK Loverdos | private[this] def startServices(): Unit = { |
112 | 6107e07c | Christos KK Loverdos | for(service ← _allServices) { |
113 | 6a8f1284 | Christos KK Loverdos | logStartingF(service.toString) { |
114 | 6a8f1284 | Christos KK Loverdos | service.start() |
115 | 6a8f1284 | Christos KK Loverdos | } {} |
116 | 6107e07c | Christos KK Loverdos | } |
117 | 6adaafb6 | Christos KK Loverdos | } |
118 | 6adaafb6 | Christos KK Loverdos | |
119 | b30e5a44 | Christos KK Loverdos | private[this] def stopServices(): Unit = { |
120 | 6a8f1284 | Christos KK Loverdos | val services = _allServices.reverse |
121 | 6a8f1284 | Christos KK Loverdos | |
122 | 6a8f1284 | Christos KK Loverdos | for(service ← services) { |
123 | 6a8f1284 | Christos KK Loverdos | logStoppingF(service.toString) { |
124 | 6a8f1284 | Christos KK Loverdos | safeUnit(service.stop()) |
125 | 6a8f1284 | Christos KK Loverdos | } {} |
126 | 6a8f1284 | Christos KK Loverdos | } |
127 | 6adaafb6 | Christos KK Loverdos | } |
128 | 6adaafb6 | Christos KK Loverdos | |
129 | 695c71e2 | Christos KK Loverdos | private[this] def showBasicConfiguration(): Unit = { |
130 | b30e5a44 | Christos KK Loverdos | for(folder ← this.eventsStoreFolder) { |
131 | 695c71e2 | Christos KK Loverdos | logger.info("{} = {}", EnvKeys.eventsStoreFolder.name, folder) |
132 | b30e5a44 | Christos KK Loverdos | } |
133 | b30e5a44 | Christos KK Loverdos | this.eventsStoreFolder.throwMe // on error |
134 | 758f18b8 | Christos KK Loverdos | } |
135 | b30e5a44 | Christos KK Loverdos | |
136 | 758f18b8 | Christos KK Loverdos | private[this] def addShutdownHooks(): Unit = { |
137 | b30e5a44 | Christos KK Loverdos | Runtime.getRuntime.addShutdownHook(new Thread(new Runnable { |
138 | b30e5a44 | Christos KK Loverdos | def run = { |
139 | cbd58d68 | Christos KK Loverdos | if(!_isStopping.get()) { |
140 | cbd58d68 | Christos KK Loverdos | logStoppingF("Aquarium") { |
141 | cbd58d68 | Christos KK Loverdos | stop() |
142 | cbd58d68 | Christos KK Loverdos | } {} |
143 | b30e5a44 | Christos KK Loverdos | } |
144 | b30e5a44 | Christos KK Loverdos | } |
145 | b30e5a44 | Christos KK Loverdos | })) |
146 | b30e5a44 | Christos KK Loverdos | } |
147 | b30e5a44 | Christos KK Loverdos | |
148 | 695c71e2 | Christos KK Loverdos | def start(): Unit = { |
149 | cbd58d68 | Christos KK Loverdos | this._isStopping.set(false) |
150 | 695c71e2 | Christos KK Loverdos | showBasicConfiguration() |
151 | 758f18b8 | Christos KK Loverdos | addShutdownHooks() |
152 | cbd58d68 | Christos KK Loverdos | startServices() |
153 | 758f18b8 | Christos KK Loverdos | } |
154 | 758f18b8 | Christos KK Loverdos | |
155 | 695c71e2 | Christos KK Loverdos | def stop(): Unit = { |
156 | b30e5a44 | Christos KK Loverdos | this._isStopping.set(true) |
157 | 6adaafb6 | Christos KK Loverdos | stopServices() |
158 | 6adaafb6 | Christos KK Loverdos | } |
159 | 199695ce | Christos KK Loverdos | |
160 | 695c71e2 | Christos KK Loverdos | /** |
161 | 695c71e2 | Christos KK Loverdos | * Stops Aquarium after the given millis. Used during testing. |
162 | 695c71e2 | Christos KK Loverdos | */ |
163 | 695c71e2 | Christos KK Loverdos | def stopAfterMillis(millis: Long) { |
164 | 695c71e2 | Christos KK Loverdos | Thread sleep millis |
165 | 695c71e2 | Christos KK Loverdos | stop() |
166 | 119e4381 | Christos KK Loverdos | } |
167 | 119e4381 | Christos KK Loverdos | |
168 | 695c71e2 | Christos KK Loverdos | /** |
169 | 695c71e2 | Christos KK Loverdos | * Reflectively provide a new instance of a class and configure it appropriately. |
170 | 695c71e2 | Christos KK Loverdos | */ |
171 | b7b59f6f | Christos KK Loverdos | def newInstance[C <: AnyRef](_class: Class[C]): C = { |
172 | b7b59f6f | Christos KK Loverdos | newInstance(_class.getName) |
173 | b7b59f6f | Christos KK Loverdos | } |
174 | b7b59f6f | Christos KK Loverdos | |
175 | b7b59f6f | Christos KK Loverdos | /** |
176 | b7b59f6f | Christos KK Loverdos | * Reflectively provide a new instance of a class and configure it appropriately. |
177 | b7b59f6f | Christos KK Loverdos | */ |
178 | b7b59f6f | Christos KK Loverdos | def newInstance[C <: AnyRef](className: String): C = { |
179 | 695c71e2 | Christos KK Loverdos | val originalProps = apply(EnvKeys.originalProps) |
180 | 2ffb577f | Christos KK Loverdos | |
181 | 695c71e2 | Christos KK Loverdos | val instanceM = MaybeEither(defaultClassLoader.loadClass(className).newInstance().asInstanceOf[C]) |
182 | 695c71e2 | Christos KK Loverdos | instanceM match { |
183 | 695c71e2 | Christos KK Loverdos | case Just(instance) ⇒ |
184 | 7de7765f | Christos KK Loverdos | // eventBus.addSubscriber[C](instance) |
185 | 7de7765f | Christos KK Loverdos | instance match { |
186 | 7de7765f | Christos KK Loverdos | case aquariumAware: AquariumAware ⇒ |
187 | 7de7765f | Christos KK Loverdos | aquariumAware.awareOfAquarium(AquariumCreatedEvent(this)) |
188 | 7de7765f | Christos KK Loverdos | |
189 | 7de7765f | Christos KK Loverdos | case _ ⇒ |
190 | 7de7765f | Christos KK Loverdos | } |
191 | 695c71e2 | Christos KK Loverdos | |
192 | 695c71e2 | Christos KK Loverdos | instance match { |
193 | 695c71e2 | Christos KK Loverdos | case configurable: Configurable if (originalProps ne null) ⇒ |
194 | 695c71e2 | Christos KK Loverdos | val localProps = configurable.propertyPrefix match { |
195 | 695c71e2 | Christos KK Loverdos | case somePrefix @ Some(prefix) ⇒ |
196 | 695c71e2 | Christos KK Loverdos | if(prefix.length == 0) { |
197 | 695c71e2 | Christos KK Loverdos | logger.warn( |
198 | 695c71e2 | Christos KK Loverdos | "Property prefix for %s is %s. Consider using None".format(instance, somePrefix)) |
199 | 695c71e2 | Christos KK Loverdos | } |
200 | 695c71e2 | Christos KK Loverdos | |
201 | 695c71e2 | Christos KK Loverdos | originalProps.subsetForKeyPrefix(prefix) |
202 | 695c71e2 | Christos KK Loverdos | |
203 | 695c71e2 | Christos KK Loverdos | case None ⇒ |
204 | 695c71e2 | Christos KK Loverdos | originalProps |
205 | 695c71e2 | Christos KK Loverdos | } |
206 | 695c71e2 | Christos KK Loverdos | |
207 | 7de7765f | Christos KK Loverdos | logger.debug("Configuring {} with props (prefix={})", configurable.getClass.getName, configurable.propertyPrefix) |
208 | 695c71e2 | Christos KK Loverdos | MaybeEither(configurable configure localProps) match { |
209 | 695c71e2 | Christos KK Loverdos | case Just(_) ⇒ |
210 | 7de7765f | Christos KK Loverdos | logger.info("Configured {} with props (prefix={})", configurable.getClass.getName, configurable.propertyPrefix) |
211 | 695c71e2 | Christos KK Loverdos | |
212 | 695c71e2 | Christos KK Loverdos | case Failed(e) ⇒ |
213 | 695c71e2 | Christos KK Loverdos | throw new AquariumInternalError("Could not configure instance of %s".format(className), e) |
214 | 695c71e2 | Christos KK Loverdos | } |
215 | 695c71e2 | Christos KK Loverdos | |
216 | 695c71e2 | Christos KK Loverdos | case _ ⇒ |
217 | 695c71e2 | Christos KK Loverdos | } |
218 | ee343d66 | Georgios Gousios | |
219 | 7de7765f | Christos KK Loverdos | instance |
220 | 7de7765f | Christos KK Loverdos | |
221 | 695c71e2 | Christos KK Loverdos | case Failed(e) ⇒ |
222 | 695c71e2 | Christos KK Loverdos | throw new AquariumInternalError("Could not instantiate %s".format(className), e) |
223 | 489d6802 | Georgios Gousios | } |
224 | 489d6802 | Georgios Gousios | |
225 | 695c71e2 | Christos KK Loverdos | } |
226 | 0e00e810 | Christos KK Loverdos | |
227 | 6ad32d72 | Christos KK Loverdos | def currentResourceTypesMap: Map[String, ResourceType] = { |
228 | 2a29acf9 | Christos KK Loverdos | val policyOpt = policyStore.loadValidPolicyAt(TimeHelpers.nowMillis()) |
229 | 2a29acf9 | Christos KK Loverdos | if(policyOpt.isEmpty) { |
230 | 2a29acf9 | Christos KK Loverdos | throw new AquariumInternalError("Not even the default policy found") |
231 | 2a29acf9 | Christos KK Loverdos | } |
232 | 2a29acf9 | Christos KK Loverdos | |
233 | 2a29acf9 | Christos KK Loverdos | policyOpt.get.resourceTypesMap |
234 | 0e00e810 | Christos KK Loverdos | } |
235 | 0e00e810 | Christos KK Loverdos | |
236 | 2a29acf9 | Christos KK Loverdos | def unsafeValidPolicyAt(referenceTimeMillis: Long): PolicyModel = { |
237 | 2a29acf9 | Christos KK Loverdos | policyStore.loadValidPolicyAt(referenceTimeMillis) match { |
238 | 2a29acf9 | Christos KK Loverdos | case None ⇒ |
239 | 2a29acf9 | Christos KK Loverdos | throw new AquariumInternalError( |
240 | 2a29acf9 | Christos KK Loverdos | "No policy found at %s".format(TimeHelpers.toYYYYMMDDHHMMSSSSS(referenceTimeMillis)) |
241 | 2a29acf9 | Christos KK Loverdos | ) |
242 | 2a29acf9 | Christos KK Loverdos | |
243 | 2a29acf9 | Christos KK Loverdos | case Some(policy) ⇒ |
244 | 2a29acf9 | Christos KK Loverdos | policy |
245 | 2a29acf9 | Christos KK Loverdos | } |
246 | 0e00e810 | Christos KK Loverdos | } |
247 | 0e00e810 | Christos KK Loverdos | |
248 | 2a29acf9 | Christos KK Loverdos | def unsafePriceTableForRoleAt(role: String, referenceTimeMillis: Long): FullPriceTable = { |
249 | 2a29acf9 | Christos KK Loverdos | val policyAtReferenceTime = unsafeValidPolicyAt(referenceTimeMillis) |
250 | 2a29acf9 | Christos KK Loverdos | policyAtReferenceTime.roleMapping.get(role) match { |
251 | 2a29acf9 | Christos KK Loverdos | case None ⇒ |
252 | 2a29acf9 | Christos KK Loverdos | throw new AquariumInternalError("Unknown price table for role %s at %s".format( |
253 | 2a29acf9 | Christos KK Loverdos | role, |
254 | 2a29acf9 | Christos KK Loverdos | TimeHelpers.toYYYYMMDDHHMMSSSSS(referenceTimeMillis) |
255 | 2a29acf9 | Christos KK Loverdos | )) |
256 | 2a29acf9 | Christos KK Loverdos | |
257 | 2a29acf9 | Christos KK Loverdos | case Some(fullPriceTable) ⇒ |
258 | 2a29acf9 | Christos KK Loverdos | fullPriceTable |
259 | 2a29acf9 | Christos KK Loverdos | } |
260 | 0e00e810 | Christos KK Loverdos | } |
261 | b33dcda7 | Christos KK Loverdos | |
262 | 2a29acf9 | Christos KK Loverdos | /** |
263 | 2a29acf9 | Christos KK Loverdos | * Computes the initial user agreement for the given role and reference time. Also, |
264 | 2a29acf9 | Christos KK Loverdos | * records the ID from a potential related IMEvent. |
265 | 2a29acf9 | Christos KK Loverdos | * |
266 | 2a29acf9 | Christos KK Loverdos | * @param role The role in the agreement |
267 | 2a29acf9 | Christos KK Loverdos | * @param referenceTimeMillis The reference time to consider for the agreement |
268 | 2a29acf9 | Christos KK Loverdos | */ |
269 | 2a29acf9 | Christos KK Loverdos | def initialUserAgreement( |
270 | 2a29acf9 | Christos KK Loverdos | role: String, |
271 | 2a29acf9 | Christos KK Loverdos | referenceTimeMillis: Long, |
272 | 2a29acf9 | Christos KK Loverdos | relatedIMEventID: Option[String] |
273 | 2a29acf9 | Christos KK Loverdos | ): UserAgreementModel = { |
274 | 2a29acf9 | Christos KK Loverdos | |
275 | 2a29acf9 | Christos KK Loverdos | // Just checking |
276 | 2a29acf9 | Christos KK Loverdos | assert(null ne unsafePriceTableForRoleAt(role, referenceTimeMillis)) |
277 | 2a29acf9 | Christos KK Loverdos | |
278 | 2a29acf9 | Christos KK Loverdos | StdUserAgreement( |
279 | 2a29acf9 | Christos KK Loverdos | "<StandardUserAgreement>", |
280 | 2a29acf9 | Christos KK Loverdos | relatedIMEventID, |
281 | 2a29acf9 | Christos KK Loverdos | 0, |
282 | 2a29acf9 | Christos KK Loverdos | Long.MaxValue, |
283 | 2a29acf9 | Christos KK Loverdos | role, |
284 | 2a29acf9 | Christos KK Loverdos | PolicyDefinedFullPriceTableRef |
285 | 2a29acf9 | Christos KK Loverdos | ) |
286 | 2a29acf9 | Christos KK Loverdos | } |
287 | 2a29acf9 | Christos KK Loverdos | |
288 | 2a29acf9 | Christos KK Loverdos | def initialUserBalance(role: String, referenceTimeMillis: Long): Double = { |
289 | 2a29acf9 | Christos KK Loverdos | // FIXME: Where is the mapping? |
290 | 2a29acf9 | Christos KK Loverdos | 1000.0 |
291 | b33dcda7 | Christos KK Loverdos | } |
292 | 1a5a2e04 | Christos KK Loverdos | |
293 | b7b59f6f | Christos KK Loverdos | def chargingBehaviorOf(resourceType: ResourceType): ChargingBehavior = { |
294 | b7b59f6f | Christos KK Loverdos | val className = resourceType.chargingBehavior |
295 | b7b59f6f | Christos KK Loverdos | _chargingBehaviorMap.get(className) match { |
296 | b7b59f6f | Christos KK Loverdos | case Some(chargingBehavior) ⇒ |
297 | b7b59f6f | Christos KK Loverdos | chargingBehavior |
298 | b7b59f6f | Christos KK Loverdos | |
299 | b7b59f6f | Christos KK Loverdos | case _ ⇒ |
300 | b7b59f6f | Christos KK Loverdos | // It does not matter if this is entered by multiple threads and more than one instance of the same class |
301 | b7b59f6f | Christos KK Loverdos | // is created. The returned instance is not meant to be cached. |
302 | 2a29acf9 | Christos KK Loverdos | try { |
303 | 2a29acf9 | Christos KK Loverdos | val chargingBehavior = newInstance[ChargingBehavior](className) |
304 | 2a29acf9 | Christos KK Loverdos | _chargingBehaviorMap synchronized { |
305 | 2a29acf9 | Christos KK Loverdos | _chargingBehaviorMap = _chargingBehaviorMap.updated(className, chargingBehavior) |
306 | 2a29acf9 | Christos KK Loverdos | } |
307 | b7b59f6f | Christos KK Loverdos | |
308 | 2a29acf9 | Christos KK Loverdos | chargingBehavior |
309 | 2a29acf9 | Christos KK Loverdos | } |
310 | 2a29acf9 | Christos KK Loverdos | catch { |
311 | 2a29acf9 | Christos KK Loverdos | case e: Exception ⇒ |
312 | 2a29acf9 | Christos KK Loverdos | throw new AquariumInternalError("Could not load charging behavior %s".format(className), e) |
313 | 2a29acf9 | Christos KK Loverdos | } |
314 | b7b59f6f | Christos KK Loverdos | } |
315 | b7b59f6f | Christos KK Loverdos | } |
316 | b7b59f6f | Christos KK Loverdos | |
317 | 7dbaeb04 | Christos KK Loverdos | def defaultPolicyModel = apply(EnvKeys.defaultPolicyModel) |
318 | 7dbaeb04 | Christos KK Loverdos | |
319 | 695c71e2 | Christos KK Loverdos | def defaultClassLoader = apply(EnvKeys.defaultClassLoader) |
320 | 3a9638eb | Christos KK Loverdos | |
321 | b7b59f6f | Christos KK Loverdos | def resourceEventStore = apply(EnvKeys.storeProvider).resourceEventStore |
322 | 07322062 | Christos KK Loverdos | |
323 | b7b59f6f | Christos KK Loverdos | def imEventStore = apply(EnvKeys.storeProvider).imEventStore |
324 | 07322062 | Christos KK Loverdos | |
325 | b7b59f6f | Christos KK Loverdos | def userStateStore = apply(EnvKeys.storeProvider).userStateStore |
326 | 695c71e2 | Christos KK Loverdos | |
327 | 7dbaeb04 | Christos KK Loverdos | def policyStore = this.cachingPolicyStore |
328 | 695c71e2 | Christos KK Loverdos | |
329 | 695c71e2 | Christos KK Loverdos | def eventsStoreFolder = apply(EnvKeys.eventsStoreFolder) |
330 | 695c71e2 | Christos KK Loverdos | |
331 | 695c71e2 | Christos KK Loverdos | def eventBus = apply(EnvKeys.eventBus) |
332 | 695c71e2 | Christos KK Loverdos | |
333 | 2a29acf9 | Christos KK Loverdos | def chargingService = apply(EnvKeys.chargingService) |
334 | 695c71e2 | Christos KK Loverdos | |
335 | 695c71e2 | Christos KK Loverdos | def userStateTimestampThreshold = apply(EnvKeys.userStateTimestampThreshold) |
336 | 695c71e2 | Christos KK Loverdos | |
337 | 695c71e2 | Christos KK Loverdos | def adminCookie = apply(EnvKeys.adminCookie) |
338 | 695c71e2 | Christos KK Loverdos | |
339 | 695c71e2 | Christos KK Loverdos | def converters = apply(EnvKeys.converters) |
340 | 695c71e2 | Christos KK Loverdos | |
341 | 695c71e2 | Christos KK Loverdos | def saveResourceEventsToEventsStoreFolder = apply(EnvKeys.eventsStoreSaveRCEvents) |
342 | 695c71e2 | Christos KK Loverdos | |
343 | 695c71e2 | Christos KK Loverdos | def saveIMEventsToEventsStoreFolder = apply(EnvKeys.eventsStoreSaveIMEvents) |
344 | 695c71e2 | Christos KK Loverdos | |
345 | 695c71e2 | Christos KK Loverdos | def timerService = apply(EnvKeys.timerService) |
346 | 695c71e2 | Christos KK Loverdos | |
347 | 695c71e2 | Christos KK Loverdos | def restPort = apply(EnvKeys.restPort) |
348 | 695c71e2 | Christos KK Loverdos | |
349 | 153e9cb9 | Christos KK Loverdos | def akkaService = apply(EnvKeys.akkaService) |
350 | 153e9cb9 | Christos KK Loverdos | |
351 | 695c71e2 | Christos KK Loverdos | def version = apply(EnvKeys.version) |
352 | 12a4f3c9 | Christos KK Loverdos | } |
353 | 12a4f3c9 | Christos KK Loverdos | |
354 | 70111c64 | Christos KK Loverdos | object Aquarium { |
355 | b30e5a44 | Christos KK Loverdos | final val PropsToShow = List( |
356 | b30e5a44 | Christos KK Loverdos | SysProp.JavaVMName, |
357 | b30e5a44 | Christos KK Loverdos | SysProp.JavaVersion, |
358 | b30e5a44 | Christos KK Loverdos | SysProp.JavaHome, |
359 | b30e5a44 | Christos KK Loverdos | SysProp.JavaClassVersion, |
360 | b30e5a44 | Christos KK Loverdos | SysProp.JavaLibraryPath, |
361 | b30e5a44 | Christos KK Loverdos | SysProp.JavaClassPath, |
362 | b30e5a44 | Christos KK Loverdos | SysProp.JavaIOTmpDir, |
363 | b30e5a44 | Christos KK Loverdos | SysProp.UserName, |
364 | b30e5a44 | Christos KK Loverdos | SysProp.UserHome, |
365 | b30e5a44 | Christos KK Loverdos | SysProp.UserDir, |
366 | b30e5a44 | Christos KK Loverdos | SysProp.FileEncoding |
367 | b30e5a44 | Christos KK Loverdos | ) |
368 | b30e5a44 | Christos KK Loverdos | |
369 | 695c71e2 | Christos KK Loverdos | object HTTP { |
370 | 695c71e2 | Christos KK Loverdos | final val RESTAdminHeaderName = "X-Aquarium-Admin-Cookie" |
371 | 695c71e2 | Christos KK Loverdos | final val RESTAdminHeaderNameLowerCase = RESTAdminHeaderName.toLowerCase |
372 | 695c71e2 | Christos KK Loverdos | } |
373 | 695c71e2 | Christos KK Loverdos | |
374 | 695c71e2 | Christos KK Loverdos | final class AquariumEnvKey[T: Manifest](override val name: String) extends TypedKeySkeleton[T](name) { |
375 | b7b59f6f | Christos KK Loverdos | override def toString = "%s(%s)".format(manifest[T], name) |
376 | 695c71e2 | Christos KK Loverdos | } |
377 | 695c71e2 | Christos KK Loverdos | |
378 | 695c71e2 | Christos KK Loverdos | final val ServiceKeys: List[TypedKey[_ <: Lifecycle]] = List( |
379 | 695c71e2 | Christos KK Loverdos | EnvKeys.timerService, |
380 | 695c71e2 | Christos KK Loverdos | EnvKeys.akkaService, |
381 | 695c71e2 | Christos KK Loverdos | EnvKeys.eventBus, |
382 | 695c71e2 | Christos KK Loverdos | EnvKeys.restService, |
383 | 695c71e2 | Christos KK Loverdos | EnvKeys.rabbitMQService, |
384 | 695c71e2 | Christos KK Loverdos | EnvKeys.storeWatcherService |
385 | 695c71e2 | Christos KK Loverdos | ) |
386 | 49054030 | Georgios Gousios | |
387 | 695c71e2 | Christos KK Loverdos | object EnvKeys { |
388 | 9ce8385e | Christos KK Loverdos | /** |
389 | 9ce8385e | Christos KK Loverdos | * The Aquarium version. Will be reported in any due occasion. |
390 | 9ce8385e | Christos KK Loverdos | */ |
391 | 695c71e2 | Christos KK Loverdos | final val version = StringKey("version") |
392 | 9ce8385e | Christos KK Loverdos | |
393 | 695c71e2 | Christos KK Loverdos | final val originalProps: TypedKey[Props] = |
394 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[Props]("originalProps") |
395 | 6adaafb6 | Christos KK Loverdos | |
396 | 6adaafb6 | Christos KK Loverdos | /** |
397 | 119e4381 | Christos KK Loverdos | * The fully qualified name of the class that implements the `StoreProvider`. |
398 | 119e4381 | Christos KK Loverdos | * Will be instantiated reflectively and should have a public default constructor. |
399 | 119e4381 | Christos KK Loverdos | */ |
400 | 695c71e2 | Christos KK Loverdos | final val storeProvider: TypedKey[StoreProvider] = |
401 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[StoreProvider]("store.provider.class") |
402 | aef7611f | Christos KK Loverdos | |
403 | aef7611f | Christos KK Loverdos | /** |
404 | 695c71e2 | Christos KK Loverdos | * If a value is given to this property, then it represents a folder where all events coming to aquarium are |
405 | 695c71e2 | Christos KK Loverdos | * saved. |
406 | 158cbc5b | Christos KK Loverdos | * |
407 | 695c71e2 | Christos KK Loverdos | * This is for debugging purposes. |
408 | 158cbc5b | Christos KK Loverdos | */ |
409 | 695c71e2 | Christos KK Loverdos | final val eventsStoreFolder: TypedKey[Option[File]] = |
410 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[Option[File]]("events.store.folder") |
411 | 158cbc5b | Christos KK Loverdos | |
412 | 158cbc5b | Christos KK Loverdos | /** |
413 | 695c71e2 | Christos KK Loverdos | * If this is `true` and `events.store.folder` is defined, then all resource events are |
414 | 695c71e2 | Christos KK Loverdos | * also stored in `events.store.folder`. |
415 | 158cbc5b | Christos KK Loverdos | * |
416 | 695c71e2 | Christos KK Loverdos | * This is for debugging purposes. |
417 | 158cbc5b | Christos KK Loverdos | */ |
418 | 158cbc5b | Christos KK Loverdos | |
419 | 695c71e2 | Christos KK Loverdos | final val eventsStoreSaveRCEvents = BooleanKey("events.store.save.rc.events") |
420 | 58be4efe | Georgios Gousios | |
421 | 58be4efe | Georgios Gousios | /** |
422 | 695c71e2 | Christos KK Loverdos | * If this is `true` and `events.store.folder` is defined, then all IM events are |
423 | 695c71e2 | Christos KK Loverdos | * also stored in `events.store.folder`. |
424 | 695c71e2 | Christos KK Loverdos | * |
425 | 695c71e2 | Christos KK Loverdos | * This is for debugging purposes. |
426 | ad8d8db2 | Georgios Gousios | */ |
427 | 695c71e2 | Christos KK Loverdos | final val eventsStoreSaveIMEvents = BooleanKey("events.store.save.im.events") |
428 | ad8d8db2 | Georgios Gousios | |
429 | ad8d8db2 | Georgios Gousios | /** |
430 | 6453d1cf | Christos KK Loverdos | * A time period in milliseconds for which we can tolerate stale parts regarding user state. |
431 | 863efd17 | Christos KK Loverdos | * |
432 | 6453d1cf | Christos KK Loverdos | * The smaller the value, the more accurate the user credits and other state parts are. |
433 | 863efd17 | Christos KK Loverdos | * |
434 | 863efd17 | Christos KK Loverdos | * If a request for user state (e.g. balance) is received and the request timestamp exceeds |
435 | 863efd17 | Christos KK Loverdos | * the timestamp of the last known balance amount by this value, then a re-computation for |
436 | 863efd17 | Christos KK Loverdos | * the balance is triggered. |
437 | 863efd17 | Christos KK Loverdos | */ |
438 | 695c71e2 | Christos KK Loverdos | final val userStateTimestampThreshold = LongKey("user.state.timestamp.threshold") |
439 | 4050a3c9 | Christos KK Loverdos | |
440 | 4050a3c9 | Christos KK Loverdos | /** |
441 | 695c71e2 | Christos KK Loverdos | * REST service listening port. |
442 | 4050a3c9 | Christos KK Loverdos | */ |
443 | 695c71e2 | Christos KK Loverdos | final val restPort = IntKey("rest.port") |
444 | 313f6c96 | Christos KK Loverdos | |
445 | 5e4d8d64 | Christos KK Loverdos | final val restShutdownTimeoutMillis = LongKey("rest.shutdown.timeout.millis") |
446 | 5e4d8d64 | Christos KK Loverdos | |
447 | 03046173 | Christos KK Loverdos | /** |
448 | 695c71e2 | Christos KK Loverdos | * A cookie used in every administrative REST API call, so that Aquarium knows it comes from |
449 | 695c71e2 | Christos KK Loverdos | * an authorised client. |
450 | 03046173 | Christos KK Loverdos | */ |
451 | 695c71e2 | Christos KK Loverdos | final val adminCookie: TypedKey[Option[String]] = |
452 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[Option[String]]("admin.cookie") |
453 | 6bac5d11 | Christos KK Loverdos | |
454 | 07322062 | Christos KK Loverdos | /** |
455 | 695c71e2 | Christos KK Loverdos | * The class that initializes the REST service |
456 | 6bac5d11 | Christos KK Loverdos | */ |
457 | 695c71e2 | Christos KK Loverdos | final val restService: TypedKey[Lifecycle] = |
458 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[Lifecycle]("rest.service.class") |
459 | 3a9638eb | Christos KK Loverdos | |
460 | 695c71e2 | Christos KK Loverdos | final val akkaService: TypedKey[AkkaService] = |
461 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[AkkaService]("akka.service") |
462 | 695c71e2 | Christos KK Loverdos | |
463 | 695c71e2 | Christos KK Loverdos | final val eventBus: TypedKey[EventBusService] = |
464 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[EventBusService]("event.bus.service") |
465 | 695c71e2 | Christos KK Loverdos | |
466 | 695c71e2 | Christos KK Loverdos | final val timerService: TypedKey[TimerService] = |
467 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[TimerService]("timer.service") |
468 | 695c71e2 | Christos KK Loverdos | |
469 | 695c71e2 | Christos KK Loverdos | final val rabbitMQService: TypedKey[RabbitMQService] = |
470 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[RabbitMQService]("rabbitmq.service") |
471 | 695c71e2 | Christos KK Loverdos | |
472 | 695c71e2 | Christos KK Loverdos | final val storeWatcherService: TypedKey[StoreWatcherService] = |
473 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[StoreWatcherService]("store.watcher.service") |
474 | 695c71e2 | Christos KK Loverdos | |
475 | 695c71e2 | Christos KK Loverdos | final val converters: TypedKey[Converters] = |
476 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[Converters]("converters") |
477 | 695c71e2 | Christos KK Loverdos | |
478 | 2a29acf9 | Christos KK Loverdos | final val chargingService: TypedKey[ChargingService] = |
479 | 2a29acf9 | Christos KK Loverdos | new AquariumEnvKey[ChargingService]("charging.service") |
480 | 695c71e2 | Christos KK Loverdos | |
481 | 695c71e2 | Christos KK Loverdos | final val defaultClassLoader: TypedKey[ClassLoader] = |
482 | 695c71e2 | Christos KK Loverdos | new AquariumEnvKey[ClassLoader]("default.class.loader") |
483 | 7ef5958a | Christos KK Loverdos | |
484 | 7dbaeb04 | Christos KK Loverdos | final val defaultPolicyModel: TypedKey[PolicyModel] = |
485 | 7dbaeb04 | Christos KK Loverdos | new AquariumEnvKey[PolicyModel]("default.policy.model") |
486 | 7ef5958a | Christos KK Loverdos | } |
487 | 49054030 | Georgios Gousios | } |