2 * Copyright 2011-2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
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.
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.
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.
36 package gr.grnet.aquarium.message.avro
38 import gr.grnet.aquarium.charging.state.UserStateBootstrap
39 import gr.grnet.aquarium.computation.BillingMonthInfo
40 import gr.grnet.aquarium.event.{CreditsModel, DetailsModel}
41 import gr.grnet.aquarium.message.avro.gen._
42 import java.{util ⇒ ju}
43 import java.util.{ArrayList ⇒ JArrayList}
44 import org.apache.avro.generic.GenericData
45 import scala.collection.JavaConverters.mapAsJavaMapConverter
46 import scala.collection.JavaConverters.seqAsJavaListConverter
47 import scala.Predef.Map
48 import gr.grnet.aquarium.policy.ResourceType
51 * Provides helper methods that construct avro messages.
53 * @author Christos KK Loverdos <loverdos@gmail.com>
55 object MessageFactory {
56 def anyValueMsgOfBoolean(x: Boolean) = {
57 val av = new AnyValueMsg
58 av.setAnyValue(java.lang.Boolean.valueOf(x))
62 def anyValueMsgOfString(x: String) = {
63 val av = new AnyValueMsg
68 def newEffectiveUnitPriceMsg(unitPrice: Double, whenOpt: Option[CronSpecTupleMsg] = None) = {
69 EffectiveUnitPriceMsg.newBuilder().
70 setUnitPrice(unitPrice).
71 setWhen(whenOpt.getOrElse(null)).
75 def newEffectivePriceTableMsg(priceOverrides: EffectiveUnitPriceMsg*) = {
76 EffectivePriceTableMsg.newBuilder().
77 setPriceOverrides(priceOverrides.asJava).
81 def newSelectorValueMsg(ept: EffectivePriceTableMsg): SelectorValueMsg = {
82 SelectorValueMsg.newBuilder().
83 setSelectorValue(ept).
87 def newSelectorValueMsg(map: Map[String, SelectorValueMsg]): SelectorValueMsg = {
88 SelectorValueMsg.newBuilder().
89 setSelectorValue(map.asJava).
93 def newSelectorValueMsg(pairs: (String, SelectorValueMsg)*): SelectorValueMsg = {
94 SelectorValueMsg.newBuilder().
95 setSelectorValue(Map(pairs:_*).asJava).
99 def newFullPriceTableMsg(perResource: (String, Map[String, SelectorValueMsg])*) = {
100 FullPriceTableMsg.newBuilder().
102 Map((for((k, v) ← perResource) yield (k, v.asJava)):_*).asJava
107 def newRoleMappingMsg(map: Map[String, FullPriceTableMsg]): java.util.Map[String, FullPriceTableMsg] = {
111 def newRoleMappingMsg(pairs: (String, FullPriceTableMsg)*): java.util.Map[String, FullPriceTableMsg] = {
115 def newResourceTypeMsg(name: String, unit: String, chargingBehavior: String) = {
116 ResourceTypeMsg.newBuilder().
119 setChargingBehaviorClass(chargingBehavior).
123 def newResourceTypeMsg(model: ResourceType): ResourceTypeMsg = {
124 newResourceTypeMsg(model.name, model.unit, model.chargingBehavior)
127 def newResourceTypeMsgs(rts: ResourceTypeMsg*) = {
131 // def newResourceTypeMsgsMap(rts: ResourceTypeMsg*): java.util.Map[String, ResourceTypeMsg] = {
132 // rts.map(rt ⇒ (rt.getName, rt)).toMap.asJava
135 def newResourceTypeMsgsMap(resourceTypes: Map[String, ResourceType]): java.util.Map[String, ResourceTypeMsg] = {
136 resourceTypes.map(rtt ⇒ (rtt._1, newResourceTypeMsg(rtt._2))).asJava
139 def newChargingBehaviorMsgs(cbs: String*) = {
143 def newBooleanDetail(name: String, value: Boolean) = {
144 (name, anyValueMsgOfBoolean(value))
147 def newStringDetail(name: String, value: String) = {
148 (name, anyValueMsgOfString(value))
151 def newDetails(details: (String, AnyValueMsg)*): DetailsModel.Type = {
152 DetailsModel.fromScalaTuples(details:_*)
155 def newResourceEventMsg(
157 occurredMillis: Long,
158 receivedMillis: Long,
164 eventVersion: String,
165 details: DetailsModel.Type = newDetails(),
166 inStoreID: String = null
168 ResourceEventMsg.newBuilder().
169 setOriginalID(originalID).
170 setOccurredMillis(occurredMillis).
171 setReceivedMillis(receivedMillis).
173 setClientID(clientID).
174 setResource(resource).
175 setInstanceID(instanceID).
177 setEventVersion(eventVersion).
179 setInStoreID(inStoreID).
185 occurredMillis: Long,
186 receivedMillis: Long,
191 eventVersion: String,
193 details: DetailsModel.Type = newDetails(),
194 inStoreID: String = null
196 IMEventMsg.newBuilder().
197 setOriginalID(originalID).
199 setOccurredMillis(occurredMillis).
200 setReceivedMillis(receivedMillis).
202 setClientID(clientID).
203 setIsActive(isActive).
205 setEventVersion(eventVersion).
206 setEventType(eventType).
208 setInStoreID(inStoreID).
212 def newWalletEntryMsg(
214 sumOfCreditsToSubtract: CreditsModel.Type,
215 oldTotalCredits: CreditsModel.Type,
216 newTotalCredits: CreditsModel.Type,
217 whenComputedMillis: Long,
218 referenceStartMillis: Long,
219 referenceStopMillis: Long,
222 billingMonthDay: Int,
223 chargeslots: ju.List[ChargeslotMsg],
224 resourceEvents: ju.List[ResourceEventMsg],
225 resourceType: ResourceTypeMsg,
227 ): WalletEntryMsg = {
228 WalletEntryMsg.newBuilder().
230 setSumOfCreditsToSubtract(CreditsModel.toTypeInMessage(sumOfCreditsToSubtract)).
231 setOldTotalCredits(CreditsModel.toTypeInMessage(oldTotalCredits)).
232 setNewTotalCredits(CreditsModel.toTypeInMessage(newTotalCredits)).
233 setWhenComputedMillis(whenComputedMillis).
234 setReferenceStartMillis(referenceStartMillis).
235 setReferenceStopMillis(referenceStopMillis).
236 setBillingYear(billingYear).
237 setBillingMonth(billingMonth).
238 setBillingMonthDay(billingMonthDay).
239 setChargeslots(chargeslots).
240 setResourceEvents(resourceEvents).
241 setResourceType(resourceType).
242 setIsSynthetic(isSynthetic).
246 def newResourceInstanceChargingStateMsg(
247 details: DetailsModel.Type,
248 previousEvents: ju.List[ResourceEventMsg],
249 implicitlyIssuedStartEvents: ju.List[ResourceEventMsg],
250 oldAccumulatingAmount: Double,
251 accumulatingAmount: Double,
252 previousValue: Double,
254 ): ResourceInstanceChargingStateMsg = {
256 val msg = new ResourceInstanceChargingStateMsg
257 msg.setDetails(details)
258 msg.setPreviousEvents(previousEvents)
259 msg.setImplicitlyIssuedStartEvents(implicitlyIssuedStartEvents)
260 msg.setOldAccumulatingAmount(java.lang.Double.valueOf(oldAccumulatingAmount))
261 msg.setAccumulatingAmount(java.lang.Double.valueOf(accumulatingAmount))
262 msg.setPreviousValue(java.lang.Double.valueOf(previousValue))
263 msg.setCurrentValue(java.lang.Double.valueOf(currentValue))
267 def newEmptyUserAgreementHistoryMsg() = {
268 val msg = new UserAgreementHistoryMsg
269 msg.setAgreements(new ju.ArrayList[UserAgreementMsg]())
273 def newInitialUserAgreementHistoryMsg(initialAgreement: UserAgreementMsg) = {
274 val msg = new UserAgreementHistoryMsg
275 val list = new JArrayList[UserAgreementMsg]()
276 list.add(initialAgreement)
277 msg.setAgreements(list)
281 def newUserAgreementFromIMEventMsg(
283 id: String = MessageHelpers.UserAgreementMsgIDGenerator.nextUID()
286 val msg = new UserAgreementMsg
289 msg.setUserID(imEvent.getUserID)
290 msg.setRelatedIMEventOriginalID(imEvent.getOriginalID)
291 msg.setRole(imEvent.getRole)
292 msg.setValidFromMillis(imEvent.getOccurredMillis)
293 msg.setValidToMillis(java.lang.Long.valueOf(java.lang.Long.MAX_VALUE))
294 msg.setFullPriceTableRef(null) // get from current (= @imEvent.getOccurredMillis) policy
299 def newWalletEntriesMsg(entries: ju.List[WalletEntryMsg] = new ju.ArrayList[WalletEntryMsg]()) = {
300 val msg = new WalletEntriesMsg
301 msg.setEntries(entries)
305 def newDummyPolicyMsgAt(millis: Long) : PolicyMsg = {
306 PolicyMsg.newBuilder().
310 setValidFromMillis(millis).
311 setValidToMillis(Long.MaxValue).
312 setChargingBehaviors(new ju.ArrayList[String]()).
313 setResourceTypes(new ju.ArrayList[ResourceTypeMsg]()).
314 setRoleMapping(new ju.HashMap[String, FullPriceTableMsg]()).
318 def createInitialUserStateMsg(
319 usb: UserStateBootstrap,
323 val bmi = BillingMonthInfo.fromMillis(occurredMillis)
324 val msg = new UserStateMsg
326 msg.setUserID(usb.userID)
327 msg.setOccurredMillis(java.lang.Long.valueOf(occurredMillis))
328 msg.setBillingYear(java.lang.Integer.valueOf(bmi.year))
329 msg.setBillingMonth(java.lang.Integer.valueOf(bmi.month))
330 msg.setBillingMonthDay(java.lang.Integer.valueOf(bmi.day))
331 msg.setTotalCredits(java.lang.Double.valueOf(CreditsModel.toTypeInMessage(usb.initialCredits)))
332 msg.setAgreementHistory(newInitialUserAgreementHistoryMsg(usb.initialAgreement.msg))
333 msg.setLatestUpdateMillis(java.lang.Long.valueOf(occurredMillis))
334 msg.setInStoreID(null)
335 msg.setOriginalID("") // FIXME get a counter here