Fix some casting errors that had never appeared during compilation before. Ever
[aquarium] / src / main / scala / gr / grnet / aquarium / message / avro / MessageFactory.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.message.avro
37
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
49
50 /**
51  * Provides helper methods that construct avro messages.
52  *
53  * @author Christos KK Loverdos <loverdos@gmail.com>
54  */
55 object MessageFactory {
56   def anyValueMsgOfBoolean(x: Boolean) = {
57     val av = new AnyValueMsg
58     av.setAnyValue(java.lang.Boolean.valueOf(x))
59     av
60   }
61
62   def anyValueMsgOfString(x: String) = {
63     val av = new AnyValueMsg
64     av.setAnyValue(x)
65     av
66   }
67
68   def newEffectiveUnitPriceMsg(unitPrice: Double, whenOpt: Option[CronSpecTupleMsg] = None) = {
69     EffectiveUnitPriceMsg.newBuilder().
70       setUnitPrice(unitPrice).
71       setWhen(whenOpt.getOrElse(null)).
72     build()
73   }
74
75   def newEffectivePriceTableMsg(priceOverrides: EffectiveUnitPriceMsg*) = {
76     EffectivePriceTableMsg.newBuilder().
77       setPriceOverrides(priceOverrides.asJava).
78     build()
79   }
80
81   def newSelectorValueMsg(ept: EffectivePriceTableMsg): SelectorValueMsg = {
82     SelectorValueMsg.newBuilder().
83       setSelectorValue(ept).
84     build()
85   }
86
87   def newSelectorValueMsg(map: Map[String, SelectorValueMsg]): SelectorValueMsg = {
88     SelectorValueMsg.newBuilder().
89       setSelectorValue(map.asJava).
90     build()
91   }
92
93   def newSelectorValueMsg(pairs: (String, SelectorValueMsg)*): SelectorValueMsg = {
94     SelectorValueMsg.newBuilder().
95       setSelectorValue(Map(pairs:_*).asJava).
96     build()
97   }
98
99   def newFullPriceTableMsg(perResource: (String, Map[String, SelectorValueMsg])*) = {
100     FullPriceTableMsg.newBuilder().
101       setPerResource(
102         Map((for((k, v) ← perResource) yield (k, v.asJava)):_*).asJava
103       ).
104     build()
105   }
106
107   def newRoleMappingMsg(map: Map[String, FullPriceTableMsg]): java.util.Map[String, FullPriceTableMsg] = {
108     map.asJava
109   }
110
111   def newRoleMappingMsg(pairs: (String, FullPriceTableMsg)*): java.util.Map[String, FullPriceTableMsg] = {
112     Map(pairs:_*).asJava
113   }
114
115   def newResourceTypeMsg(name: String, unit: String, chargingBehavior: String) = {
116     ResourceTypeMsg.newBuilder().
117       setName(name).
118       setUnit(unit).
119       setChargingBehaviorClass(chargingBehavior).
120     build()
121   }
122
123   def newResourceTypeMsg(model: ResourceType): ResourceTypeMsg = {
124     newResourceTypeMsg(model.name, model.unit, model.chargingBehavior)
125   }
126
127   def newResourceTypeMsgs(rts: ResourceTypeMsg*) = {
128     rts.asJava
129   }
130
131 //  def newResourceTypeMsgsMap(rts: ResourceTypeMsg*): java.util.Map[String, ResourceTypeMsg] = {
132 //    rts.map(rt ⇒ (rt.getName, rt)).toMap.asJava
133 //  }
134
135   def newResourceTypeMsgsMap(resourceTypes: Map[String, ResourceType]): java.util.Map[String, ResourceTypeMsg] = {
136     resourceTypes.map(rtt ⇒ (rtt._1, newResourceTypeMsg(rtt._2))).asJava
137   }
138
139   def newChargingBehaviorMsgs(cbs: String*) = {
140     cbs.asJava
141   }
142
143   def newBooleanDetail(name: String, value: Boolean) = {
144     (name, anyValueMsgOfBoolean(value))
145   }
146
147   def newStringDetail(name: String, value: String) = {
148     (name, anyValueMsgOfString(value))
149   }
150
151   def newDetails(details: (String, AnyValueMsg)*): DetailsModel.Type = {
152     DetailsModel.fromScalaTuples(details:_*)
153   }
154
155   def newResourceEventMsg(
156       originalID: String,
157       occurredMillis: Long,
158       receivedMillis: Long,
159       userID: String,
160       clientID: String,
161       resource: String,
162       instanceID: String,
163       value: String,
164       eventVersion: String,
165       details: DetailsModel.Type = newDetails(),
166       inStoreID: String = null
167   ) = {
168     ResourceEventMsg.newBuilder().
169       setOriginalID(originalID).
170       setOccurredMillis(occurredMillis).
171       setReceivedMillis(receivedMillis).
172       setUserID(userID).
173       setClientID(clientID).
174       setResource(resource).
175       setInstanceID(instanceID).
176       setValue(value).
177       setEventVersion(eventVersion).
178       setDetails(details).
179       setInStoreID(inStoreID).
180     build()
181   }
182
183   def newIMEventMsg(
184       originalID: String,
185       occurredMillis: Long,
186       receivedMillis: Long,
187       userID: String,
188       clientID: String,
189       isActive: Boolean,
190       role: String,
191       eventVersion: String,
192       eventType: String,
193       details: DetailsModel.Type = newDetails(),
194       inStoreID: String = null
195   ) = {
196     IMEventMsg.newBuilder().
197       setOriginalID(originalID).
198       setInStoreID(null).
199       setOccurredMillis(occurredMillis).
200       setReceivedMillis(receivedMillis).
201       setUserID(userID).
202       setClientID(clientID).
203       setIsActive(isActive).
204       setRole(role).
205       setEventVersion(eventVersion).
206       setEventType(eventType).
207       setDetails(details).
208       setInStoreID(inStoreID).
209     build()
210   }
211
212   def newWalletEntryMsg(
213       userID: String,
214       sumOfCreditsToSubtract: CreditsModel.Type,
215       oldTotalCredits: CreditsModel.Type,
216       newTotalCredits: CreditsModel.Type,
217       whenComputedMillis: Long,
218       referenceStartMillis: Long,
219       referenceStopMillis: Long,
220       billingYear: Int,
221       billingMonth: Int,
222       billingMonthDay: Int,
223       chargeslots: ju.List[ChargeslotMsg],
224       resourceEvents: ju.List[ResourceEventMsg],
225       resourceType: ResourceTypeMsg,
226       isSynthetic: Boolean
227   ): WalletEntryMsg = {
228     WalletEntryMsg.newBuilder().
229       setUserID(userID).
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).
243     build()
244   }
245
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,
253       currentValue: Double
254   ): ResourceInstanceChargingStateMsg = {
255
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))
264     msg
265   }
266
267   def newEmptyUserAgreementHistoryMsg() = {
268     val msg = new UserAgreementHistoryMsg
269     msg.setAgreements(new ju.ArrayList[UserAgreementMsg]())
270     msg
271   }
272
273   def newInitialUserAgreementHistoryMsg(initialAgreement: UserAgreementMsg) = {
274     val msg = new UserAgreementHistoryMsg
275     val list = new JArrayList[UserAgreementMsg]()
276     list.add(initialAgreement)
277     msg.setAgreements(list)
278     msg
279   }
280
281   def newUserAgreementFromIMEventMsg(
282       imEvent: IMEventMsg,
283       id: String = MessageHelpers.UserAgreementMsgIDGenerator.nextUID()
284   ) = {
285
286     val msg = new UserAgreementMsg
287
288     msg.setId(id)
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
295
296     msg
297   }
298
299   def newWalletEntriesMsg(entries: ju.List[WalletEntryMsg] = new ju.ArrayList[WalletEntryMsg]()) = {
300     val msg = new WalletEntriesMsg
301     msg.setEntries(entries)
302     msg
303   }
304
305   def newDummyPolicyMsgAt(millis: Long) : PolicyMsg = {
306     PolicyMsg.newBuilder().
307       setOriginalID("").
308       setInStoreID(null).
309       setParentID(null).
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]()).
315       build()
316   }
317
318   def createInitialUserStateMsg(
319       usb: UserStateBootstrap,
320       occurredMillis: Long
321   ): UserStateMsg = {
322
323     val bmi = BillingMonthInfo.fromMillis(occurredMillis)
324     val msg = new UserStateMsg
325
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
336
337     msg
338   }
339
340 }