import gr.grnet.aquarium.user.UserState
import gr.grnet.aquarium.util.json.JsonSupport
import gr.grnet.aquarium.event.im.IMEventModel
-import gr.grnet.aquarium.event.ResourceEvent
import gr.grnet.aquarium.converter.{PrettyJsonTextFormat, StdConverters}
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
*
* Note that the prefix `Process` means that no reply is created or needed.
*/
-case class ProcessResourceEvent(rcEvent: ResourceEvent) extends RouterMessage
+case class ProcessResourceEvent(rcEvent: ResourceEventModel) extends RouterMessage
/**
* Dispatcher message that triggers the user event processing pipeline.
self.lifeCycle = Temporary
- override protected def onThrowable(t: Throwable) = {
+ override protected def onThrowable(t: Throwable, message: AnyRef) = {
logger.error("Terminating due to: %s".format(t.getMessage), t)
UserActorCache.invalidate(this._userID)
def jsonSupportToDBObject(jsonSupport: JsonSupport) =
AllConverters.convertEx[DBObject](jsonSupport)
-
}
import net.liftweb.json.JsonAST.JValue
import net.liftweb.json._
import ext.JodaTimeSerializers
-import gr.grnet.aquarium.event.AquariumEventSkeleton
+import gr.grnet.aquarium.event.ExternalEventSkeleton
/**
* The application-wide JSON formats used from the underlying lift-json library.
*/
implicit val Formats = (DefaultFormats ++ JodaTimeSerializers.all) +
- FieldSerializer[AquariumEventSkeleton]()
+ FieldSerializer[ExternalEventSkeleton]()
/**
* Converts a value to JSON AST (Abstract Syntax Tree) by acting a bit intelligently, depending on the actual type
@scala.throws(classOf[ConverterException])
def convertEx[T: Type](sourceValue: Any) = {
+ // Generic deserializer from json string to a business logic model
JsonConversions.jsonToObject[T](sourceValue.asInstanceOf[JsonTextFormat].value)(manifest[T], JsonConversions.Formats)
}
}
--- /dev/null
+/*
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ */
+
+package gr.grnet.aquarium.event
+
+/**
+ * Basic properties for all events.
+ * An event represents some state change, where state is specific to the use-case.
+ *
+ *@author Christos KK Loverdos <loverdos@gmail.com>
+ */
+
+trait EventModel {
+ /**
+ * The unique event id. The responsibility for the id generation is to the event generator.
+ */
+ def id: String
+
+ /**
+ * The Unix time of the state change occurrence that this event represents.
+ */
+ def occurredMillis: Long
+
+ /**
+ * The ID given to this event if/when persisted to a store.
+ * The exact type of the id is store-specific.
+ */
+ def storeID: Option[AnyRef] = None
+
+ def eventVersion: String
+
+ /**
+ * An extension point that provides even more properties.
+ */
+ def details: Map[String, String]
+
+ def withDetails(newDetails: Map[String, String], newOccurredMillis: Long): EventModel
+}
+
+
+object EventModel {
+ trait NamesT {
+ final val id = "id"
+ final val occurredMillis = "occurredMillis"
+ final val storeID = "storeID"
+ final val eventVersion = "eventVersion"
+ final val details = "details"
+ }
+
+ object Names extends NamesT
+}
\ No newline at end of file
* @author Christos KK Loverdos <loverdos@gmail.com>
*/
-trait AquariumEventModel extends JsonSupport with XmlSupport {
- /**
- * The id at the sender side
- */
- def id: String
-
- /**
- * When it occurred at the sender side
- */
- def occurredMillis: Long
-
+trait ExternalEventModel extends EventModel with JsonSupport with XmlSupport {
/**
* When it was received by Aquarium
*/
def receivedMillis: Long
+
def userID: String
- def eventVersion: String
- def details: Map[String, String]
- /**
- * The ID given to this event if/when persisted to a store.
- * The exact type of the id is store-specific.
- */
- def storeID: Option[AnyRef] = None
def toBytes: Array[Byte] = makeBytes(toJsonString)
- def withReceivedMillis(newReceivedMillis: Long): AquariumEventModel
+ def withReceivedMillis(newReceivedMillis: Long): ExternalEventModel
}
-object AquariumEventModel {
- trait NamesT {
- final val id = "id"
- final val occurredMillis = "occurredMillis"
+object ExternalEventModel {
+ trait NamesT extends EventModel.NamesT {
final val receivedMillis = "receivedMillis"
final val userID = "userID"
- final val eventVersion = "eventVersion"
- final val details = "details"
}
object Names extends NamesT
* @author Georgios Gousios <gousiosg@gmail.com>
* @author Christos KK Loverdos <loverdos@gmail.com>
*/
-abstract class AquariumEventSkeleton(
+abstract class ExternalEventSkeleton(
_id: String, // The id at the client side (the sender) TODO: Rename to remoteId or something...
_occurredMillis: Long, // When it occurred at client side (the sender)
_receivedMillis: Long, // When it was received by Aquarium
_eventVersion: String
)
- extends AquariumEventModel
+ extends ExternalEventModel
with XmlSupport
with Loggable {
import gr.grnet.aquarium.util.date.MutableDateCalc
import gr.grnet.aquarium.logic.accounting.dsl.{Timeslot, DSLResource}
import converter.{JsonTextFormat, StdConverters}
+import resource.ResourceEventModel
/**
* The following equation must hold: `newTotalCredits = oldTotalCredits + entryCredits`.
referenceTimeslot: Timeslot,
yearOfBillingMonth: Int,
billingMonth: Int,
- resourceEvents: List[ResourceEvent], // current is at the head
+ resourceEvents: List[ResourceEventModel], // current is at the head
chargeslots: List[Chargeslot],
resourceDef: DSLResource,
isSynthetic: Boolean) {
eventVersion: String = "1.0",
userID: String = "",
details: Map[String, String] = Map()
- ) extends AquariumEventModel {
+ ) extends ExternalEventModel {
assert(if(validTo != -1) validTo > validFrom else validFrom > 0)
def withReceivedMillis(millis: Long) = copy(receivedMillis = millis)
+ def withDetails(newDetails: Map[String, String], newOccurredMillis: Long) =
+ this.copy(details = newDetails, occurredMillis = newOccurredMillis)
+
def fromToTimeslot = Timeslot(new Date(validFrom), new Date(validTo))
}
* or implied, of GRNET S.A.
*/
-package gr.grnet.aquarium
-package event
-
-import gr.grnet.aquarium.util.makeString
-import gr.grnet.aquarium.logic.accounting.dsl._
-import com.ckkloverdos.maybe.Maybe
-import java.util.Date
-import gr.grnet.aquarium.util.date.MutableDateCalc
-import collection.SeqLike
-import converter.{JsonTextFormat, StdConverters}
+//package gr.grnet.aquarium
+//package event
+//
+//import gr.grnet.aquarium.util.makeString
+//import gr.grnet.aquarium.logic.accounting.dsl._
+//import com.ckkloverdos.maybe.Maybe
+//import java.util.Date
+//import gr.grnet.aquarium.util.date.MutableDateCalc
+//import collection.SeqLike
+//import converter.{JsonTextFormat, StdConverters}
/**
* Event sent to Aquarium by clients for resource accounting.
* @author Christos KK Loverdos <loverdos@gmail.com>.
* @author Georgios Gousios <gousiosg@gmail.com>.
*/
-case class ResourceEvent(
- id: String, // The id at the client side (the sender) TODO: Rename to remoteId or something...
- occurredMillis: Long, // When it occurred at client side (the sender)
- receivedMillis: Long, // When it was received by Aquarium
- userID: String, // The user for which this resource is relevant
- clientID: String, // The unique client identifier (usually some hash)
- resource: String, // String representation of the resource type (e.g. "bndup", "vmtime").
- instanceID: String, // String representation of the resource instance id
- eventVersion: String,
- value: Double,
- details: Map[String, String])
-extends AquariumEventModel {
-
- def validate() : Boolean = {
- !safeResource.isEmpty
- }
-
- def safeResource = if(resource eq null) "" else resource
- def safeInstanceId = if(instanceID eq null) "" else instanceID
-
- def hasResource = !safeResource.isEmpty
- def hasInstanceId = !safeInstanceId.isEmpty
-
- def fullResourceInfo = (safeResource, safeInstanceId)
-
- def occurredDate = new Date(occurredMillis)
-
- def occurredDeltaFrom(that: ResourceEvent): Long = {
- this.occurredMillis - that.occurredMillis
- }
-
- def isOccurredWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
- require(fromMillis <= toMillis, "fromMillis <= toMillis")
- fromMillis <= occurredMillis && occurredMillis <= toMillis
- }
-
- def isOccurredWithinDates(fromDate: Date, toDate: Date): Boolean = {
- isOccurredWithinMillis(fromDate.getTime, toDate.getTime)
- }
-
- def isReceivedWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
- require(fromMillis <= toMillis, "fromMillis <= toMillis")
- fromMillis <= receivedMillis && receivedMillis <= toMillis
- }
-
- def isReceivedWithinDates(fromDate: Date, toDate: Date): Boolean = {
- isReceivedWithinMillis(fromDate.getTime, toDate.getTime)
- }
-
- def isReceivedWithinDateCalcs(fromDate: MutableDateCalc, toDate: MutableDateCalc): Boolean = {
- isReceivedWithinMillis(fromDate.getMillis, toDate.getMillis)
- }
-
- def isOccurredOrReceivedWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
- isOccurredWithinMillis(fromMillis, toMillis) ||
- isReceivedWithinMillis(fromMillis, toMillis)
- }
-
- def isOccurredOrReceivedWithinDates(fromDate: Date, toDate: Date): Boolean = {
- isOccurredWithinDates(fromDate, toDate) ||
- isReceivedWithinDates(fromDate, toDate)
- }
-
- def isOutOfSyncForBillingMonth(yearOfBillingMonth: Int, billingMonth: Int) = {
- val billingStartDateCalc = new MutableDateCalc(yearOfBillingMonth, billingMonth)
- val billingStartMillis = billingStartDateCalc.toMillis
- // NOTE: no need to `copy` the mutable `billingStartDateCalc` here because we use it once
- val billingStopMillis = billingStartDateCalc.goEndOfThisMonth.toMillis
-
- isOutOfSyncForBillingPeriod(billingStartMillis, billingStopMillis)
- }
-
- def isOutOfSyncForBillingPeriod(billingStartMillis: Long, billingStopMillis: Long): Boolean = {
- isReceivedWithinMillis(billingStartMillis, billingStopMillis) &&
- (occurredMillis < billingStartMillis || occurredMillis > billingStopMillis)
- }
-
- def toDebugString(useOnlyInstanceId: Boolean = false): String = {
- val instanceInfo = if(useOnlyInstanceId) instanceID else "%s::%s".format(resource, instanceID)
- val occurredFormatted = new MutableDateCalc(occurredMillis).toYYYYMMDDHHMMSS
- if(occurredMillis == receivedMillis) {
- "%sEVENT(%s, [%s], %s, %s, %s, %s, %s)".format(
- if(isSynthetic) "*" else "",
- id,
- occurredFormatted,
- value,
- instanceInfo,
- details,
- userID,
- clientID
- )
- } else {
- "%sEVENT(%s, [%s], [%s], %s, %s, %s, %s, %s)".format(
- if(isSynthetic) "*" else "",
- id,
- occurredFormatted,
- new MutableDateCalc(receivedMillis),
- value,
- instanceInfo,
- details,
- userID,
- clientID
- )
- }
- }
-
- /**
- * Return `true` iff this is an event regarding a resource with an
- * [[gr.grnet.aquarium.logic.accounting.dsl.OnOffCostPolicy]].
- */
- def isOnOffEvent(policy: DSLPolicy): Boolean = {
- policy.findResource(this.resource).map(_.costPolicy) match {
- case Some(OnOffCostPolicy) ⇒ true
- case _ ⇒ false
- }
- }
-
- /**
- * Return `true` iff this is an event regarding a resource with an
- * [[gr.grnet.aquarium.logic.accounting.dsl.OnOffCostPolicy]] and a
- * `value` of `"on"`.
- */
- def isOnEvent(policy: DSLPolicy): Boolean = {
- policy.findResource(this.resource) match {
- case Some(DSLResource(_, _, OnOffCostPolicy, _, _)) ⇒
- OnOffPolicyResourceState(this.value).isOn
- case _ ⇒
- false
- }
- }
-
- /**
- * Return `true` iff this is an event regarding a resource with an
- * [[gr.grnet.aquarium.logic.accounting.dsl.OnOffCostPolicy]] and a
- * `value` of `"off"`.
- */
- def isOffEvent(policy: DSLPolicy): Boolean = {
- policy.findResource(this.resource) match {
- case Some(DSLResource(_, _, OnOffCostPolicy, _, _)) ⇒
- OnOffPolicyResourceState(this.value).isOff
- case _ ⇒
- false
- }
- }
-
- def withReceivedMillis(millis: Long) = copy(receivedMillis = millis)
+//case class ResourceEvent(
+// id: String, // The id at the client side (the sender) TODO: Rename to remoteId or something...
+// occurredMillis: Long, // When it occurred at client side (the sender)
+// receivedMillis: Long, // When it was received by Aquarium
+// userID: String, // The user for which this resource is relevant
+// clientID: String, // The unique client identifier (usually some hash)
+// resource: String, // String representation of the resource type (e.g. "bndup", "vmtime").
+// instanceID: String, // String representation of the resource instance id
+// eventVersion: String,
+// value: Double,
+// details: Map[String, String])
+//extends ExternalEventModel {
+//
+// def validate() : Boolean = {
+// !safeResource.isEmpty
+// }
+//
+// def safeResource = if(resource eq null) "" else resource
+// def safeInstanceId = if(instanceID eq null) "" else instanceID
+//
+// def fullResourceInfo = (safeResource, safeInstanceId)
+//
+// def occurredDate = new Date(occurredMillis)
+//
+// def isOccurredWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
+// require(fromMillis <= toMillis, "fromMillis <= toMillis")
+// fromMillis <= occurredMillis && occurredMillis <= toMillis
+// }
+//
+// def isReceivedWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
+// require(fromMillis <= toMillis, "fromMillis <= toMillis")
+// fromMillis <= receivedMillis && receivedMillis <= toMillis
+// }
+//
+// def isOccurredOrReceivedWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
+// isOccurredWithinMillis(fromMillis, toMillis) ||
+// isReceivedWithinMillis(fromMillis, toMillis)
+// }
+//
+// def isOutOfSyncForBillingMonth(yearOfBillingMonth: Int, billingMonth: Int) = {
+// val billingStartDateCalc = new MutableDateCalc(yearOfBillingMonth, billingMonth)
+// val billingStartMillis = billingStartDateCalc.toMillis
+// // NOTE: no need to `copy` the mutable `billingStartDateCalc` here because we use it once
+// val billingStopMillis = billingStartDateCalc.goEndOfThisMonth.toMillis
+//
+// isOutOfSyncForBillingPeriod(billingStartMillis, billingStopMillis)
+// }
+//
+// def isOutOfSyncForBillingPeriod(billingStartMillis: Long, billingStopMillis: Long): Boolean = {
+// isReceivedWithinMillis(billingStartMillis, billingStopMillis) &&
+// (occurredMillis < billingStartMillis || occurredMillis > billingStopMillis)
+// }
+//
+// def toDebugString(useOnlyInstanceId: Boolean = false): String = {
+// val instanceInfo = if(useOnlyInstanceId) instanceID else "%s::%s".format(resource, instanceID)
+// val occurredFormatted = new MutableDateCalc(occurredMillis).toYYYYMMDDHHMMSS
+// if(occurredMillis == receivedMillis) {
+// "%sEVENT(%s, [%s], %s, %s, %s, %s, %s)".format(
+// if(isSynthetic) "*" else "",
+// id,
+// occurredFormatted,
+// value,
+// instanceInfo,
+// details,
+// userID,
+// clientID
+// )
+// } else {
+// "%sEVENT(%s, [%s], [%s], %s, %s, %s, %s, %s)".format(
+// if(isSynthetic) "*" else "",
+// id,
+// occurredFormatted,
+// new MutableDateCalc(receivedMillis),
+// value,
+// instanceInfo,
+// details,
+// userID,
+// clientID
+// )
+// }
+// }
+//
+// def withReceivedMillis(millis: Long) = copy(receivedMillis = millis)
/**
* Find the cost policy of the resource named in this resource event.
* Should the need arises to change the cost policy for a resource, this is a good enough
* reason to consider creating another type of resource.
*/
- def findCostPolicyM(defaultPolicy: DSLPolicy): Maybe[DSLCostPolicy] = {
- defaultPolicy.findResource(this.safeResource).map(_.costPolicy): Maybe[DSLCostPolicy]
- }
+// def findCostPolicyM(defaultPolicy: DSLPolicy): Maybe[DSLCostPolicy] = {
+// defaultPolicy.findResource(this.safeResource).map(_.costPolicy): Maybe[DSLCostPolicy]
+// }
/**
* Find the cost policy of the resource named in this resource event.
* Should the need arises to change the cost policy for a resource, this is a good enough
* reason to consider creating another type of resource.
*/
- def findCostPolicyM(resourcesMap: DSLResourcesMap): Maybe[DSLCostPolicy] = {
- for {
- rc <- resourcesMap.findResource(this.safeResource)
- } yield {
- rc.costPolicy
- }
- }
+// def findCostPolicyM(resourcesMap: DSLResourcesMap): Maybe[DSLCostPolicy] = {
+// for {
+// rc <- resourcesMap.findResource(this.safeResource)
+// } yield {
+// rc.costPolicy
+// }
+// }
/**
* `Synthetic` means that Aquarium has manufactured this resource event for some purpose. For example, the implicitly
*
* @return `true` iff this resource event is synthetic.
*/
- def isSynthetic = {
- details contains ResourceEvent.JsonNames.details_aquarium_is_synthetic
- }
-}
+// def isSynthetic = {
+// details contains ResourceEvent.JsonNames.details_aquarium_is_synthetic
+// }
+//}
object ResourceEvent {
- type ResourceType = String
- type ResourceIdType = String
- type FullResourceType = (ResourceType, ResourceIdType)
- type FullResourceTypeMap = Map[FullResourceType, ResourceEvent]
- type FullMutableResourceTypeMap = scala.collection.mutable.Map[FullResourceType, ResourceEvent]
-
- def fromJson(json: String): ResourceEvent = {
- StdConverters.AllConverters.convertEx[ResourceEvent](JsonTextFormat(json))
- }
-
- def fromBytes(bytes: Array[Byte]): ResourceEvent = {
- StdConverters.AllConverters.convertEx[ResourceEvent](JsonTextFormat(makeString(bytes)))
- }
-
- def setAquariumSynthetic(map: Map[String, String]): Map[String, String] = {
- map.updated(JsonNames.details_aquarium_is_synthetic, "true")
- }
-
- def setAquariumSyntheticAndImplicitEnd(map: Map[String, String]): Map[String, String] = {
- map.
- updated(JsonNames.details_aquarium_is_synthetic, "true").
- updated(JsonNames.details_aquarium_is_implicit_end, "true")
- }
-
- def sortByOccurred[S <: Seq[ResourceEvent]](events: S with SeqLike[ResourceEvent, S]): S = {
- events.sortWith(_.occurredMillis <= _.occurredMillis)
- }
-
- object JsonNames {
- final val _id = "_id"
- final val id = "id"
- final val userId = "userId"
- final val occurredMillis = "occurredMillis"
- final val receivedMillis = "receivedMillis"
- final val clientId = "clientId"
- final val resource = "resource"
- final val resourceId = "resourceId"
- final val eventVersion = "eventVersion"
- final val value = "value"
- final val details = "details"
+// type ResourceType = String
+// type ResourceIdType = String
+// type FullResourceType = (ResourceType, ResourceIdType)
+// type FullResourceTypeMap = Map[FullResourceType, ResourceEvent]
+// type FullMutableResourceTypeMap = scala.collection.mutable.Map[FullResourceType, ResourceEvent]
+
+// def fromJson(json: String): ResourceEvent = {
+// StdConverters.AllConverters.convertEx[ResourceEvent](JsonTextFormat(json))
+// }
+//
+// def fromBytes(bytes: Array[Byte]): ResourceEvent = {
+// StdConverters.AllConverters.convertEx[ResourceEvent](JsonTextFormat(makeString(bytes)))
+// }
+//
+// def setAquariumSynthetic(map: Map[String, String]): Map[String, String] = {
+// map.updated(JsonNames.details_aquarium_is_synthetic, "true")
+// }
+
+// def setAquariumSyntheticAndImplicitEnd(map: Map[String, String]): Map[String, String] = {
+// map.
+// updated(JsonNames.details_aquarium_is_synthetic, "true").
+// updated(JsonNames.details_aquarium_is_implicit_end, "true")
+// }
+//
+// def sortByOccurred[S <: Seq[ResourceEvent]](events: S with SeqLike[ResourceEvent, S]): S = {
+// events.sortWith(_.occurredMillis <= _.occurredMillis)
+// }
+//
+// object JsonNames {
+// final val _id = "_id"
+// final val id = "id"
+// final val userId = "userId"
+// final val occurredMillis = "occurredMillis"
+// final val receivedMillis = "receivedMillis"
+// final val clientId = "clientId"
+// final val resource = "resource"
+// final val resourceId = "resourceId"
+// final val eventVersion = "eventVersion"
+// final val value = "value"
+// final val details = "details"
// This is set in the details map to indicate a synthetic resource event (ie not a real one).
// Examples of synthetic resource events are those that are implicitly generated at the
// end of the billing period (e.g. `OFF`s).
- final val details_aquarium_is_synthetic = "__aquarium_is_synthetic__"
-
- final val details_aquarium_is_implicit_end = "__aquarium_is_implicit_end__"
- }
+// final val details_aquarium_is_synthetic = "__aquarium_is_synthetic__"
+//
+// final val details_aquarium_is_implicit_end = "__aquarium_is_implicit_end__"
+// }
}
\ No newline at end of file
eventVersion: String = "1.0",
userID: String = "",
details: Map[String, String] = Map()
-) extends AquariumEventModel {
+) extends ExternalEventModel {
assert(occurredMillis > 0)
def withReceivedMillis(millis: Long) = copy(receivedMillis = millis)
+ def withDetails(newDetails: Map[String, String], newOccurredMillis: Long) =
+ this.copy(details = newDetails, occurredMillis = newOccurredMillis)
+
def occurredDate = new Date(occurredMillis)
def receivedDate = new Date(receivedMillis)
}
package gr.grnet.aquarium.event.im
-import gr.grnet.aquarium.event.AquariumEventModel
+import gr.grnet.aquarium.event.ExternalEventModel
/**
* The model of any event sent from the `Identity Management` (IM) external system.
* @author Christos KK Loverdos <loverdos@gmail.com>
*/
-trait IMEventModel extends AquariumEventModel {
+trait IMEventModel extends ExternalEventModel {
def clientID: String
def isActive: Boolean
}
object IMEventModel {
- trait NamesT extends AquariumEventModel.NamesT {
+ trait NamesT extends ExternalEventModel.NamesT {
final val clientID = "clientID"
final val isActive = "isActive"
final val role = "role"
package gr.grnet.aquarium.event.im
-import gr.grnet.aquarium.event.{AquariumEventModel, AquariumEventSkeleton}
+import gr.grnet.aquarium.util.makeString
+import gr.grnet.aquarium.converter.{JsonTextFormat, StdConverters}
/**
* @author Christos KK Loverdos <loverdos@gmail.com>
*/
-class StdIMEvent(
- val id: String, // The id at the sender side
- val occurredMillis: Long, // When it occurred at the sender side
- val receivedMillis: Long, // When it was received by Aquarium
- val userID: String,
- val clientID: String,
- val isActive: Boolean,
- val role: String,
- val eventVersion: String,
- val eventType: String,
- val details: Map[String, String])
-extends AquariumEventModel with IMEventModel {
- def withReceivedMillis(newReceivedMillis: Long) = new StdIMEvent(
- id,
- occurredMillis,
- newReceivedMillis,
- userID,
- clientID,
- isActive,
- role,
- eventVersion,
- eventType,
- details
- )
+case class StdIMEvent(
+ id: String, // The id at the sender side
+ occurredMillis: Long, // When it occurred at the sender side
+ receivedMillis: Long, // When it was received by Aquarium
+ userID: String,
+ clientID: String,
+ isActive: Boolean,
+ role: String,
+ eventVersion: String,
+ eventType: String,
+ details: Map[String, String])
+extends IMEventModel {
+ def withReceivedMillis(newReceivedMillis: Long) =
+ this.copy(receivedMillis = newReceivedMillis)
+
+ def withDetails(newDetails: Map[String, String], newOccurredMillis: Long) =
+ this.copy(details = newDetails, occurredMillis = newOccurredMillis)
+}
+
+object StdIMEvent {
+ final def fromJsonString(json: String): StdIMEvent = {
+ StdConverters.AllConverters.convertEx[StdIMEvent](JsonTextFormat(json))
+ }
+
+ final def fromJsonBytes(jsonBytes: Array[Byte]): StdIMEvent = {
+ fromJsonString(makeString(jsonBytes))
+ }
+
+ final def fromOther(event: IMEventModel): StdIMEvent = {
+ if(event.isInstanceOf[StdIMEvent]) event.asInstanceOf[StdIMEvent]
+ else new StdIMEvent(
+ event.id,
+ event.occurredMillis,
+ event.receivedMillis,
+ event.userID,
+ event.clientID,
+ event.isActive,
+ event.role,
+ event.eventVersion,
+ event.eventType,
+ event.details
+ )
+ }
+
}
--- /dev/null
+/*
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ */
+
+package gr.grnet.aquarium.event
+package resource
+
+import java.util.Date
+import gr.grnet.aquarium.util.date.MutableDateCalc
+
+/**
+ * The model of any resource event.
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>
+ */
+
+trait ResourceEventModel extends ExternalEventModel {
+ /**
+ * Identifies the client that sent this event.
+ */
+ def clientID: String
+
+ /**
+ * String representation of the resource type (e.g. "bndup", "vmtime").
+ */
+ def resource: String
+
+ /**
+ * String representation of the resource instance id
+ */
+ def instanceID: String
+
+
+ /**
+ * The resource value.
+ */
+ def value: Double
+
+ def withDetails(newDetails: Map[String, String], newOccurredMillis: Long): ResourceEventModel
+
+ def withDetailsAndValue(newDetails: Map[String, String], newValue: Double, newOccurredMillis: Long): ResourceEventModel
+
+ def safeResource = if(resource eq null) "" else resource
+ def safeInstanceId = if(instanceID eq null) "" else instanceID
+
+ def fullResourceInfo = (safeResource, safeInstanceId)
+
+ def occurredDate = new Date(occurredMillis)
+
+ def isOccurredWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
+ require(fromMillis <= toMillis, "fromMillis <= toMillis")
+ fromMillis <= occurredMillis && occurredMillis <= toMillis
+ }
+
+ def isReceivedWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
+ require(fromMillis <= toMillis, "fromMillis <= toMillis")
+ fromMillis <= receivedMillis && receivedMillis <= toMillis
+ }
+
+ def isOccurredOrReceivedWithinMillis(fromMillis: Long, toMillis: Long): Boolean = {
+ isOccurredWithinMillis(fromMillis, toMillis) ||
+ isReceivedWithinMillis(fromMillis, toMillis)
+ }
+
+ def isOutOfSyncForBillingMonth(yearOfBillingMonth: Int, billingMonth: Int) = {
+ val billingStartDateCalc = new MutableDateCalc(yearOfBillingMonth, billingMonth)
+ val billingStartMillis = billingStartDateCalc.toMillis
+ // NOTE: no need to `copy` the mutable `billingStartDateCalc` here because we use it once
+ val billingStopMillis = billingStartDateCalc.goEndOfThisMonth.toMillis
+
+ isOutOfSyncForBillingPeriod(billingStartMillis, billingStopMillis)
+ }
+
+ def isOutOfSyncForBillingPeriod(billingStartMillis: Long, billingStopMillis: Long): Boolean = {
+ isReceivedWithinMillis(billingStartMillis, billingStopMillis) &&
+ (occurredMillis < billingStartMillis || occurredMillis > billingStopMillis)
+ }
+
+ def toDebugString(useOnlyInstanceId: Boolean = false): String = {
+ val instanceInfo = if(useOnlyInstanceId) instanceID else "%s::%s".format(resource, instanceID)
+ val occurredFormatted = new MutableDateCalc(occurredMillis).toYYYYMMDDHHMMSS
+ if(occurredMillis == receivedMillis) {
+ "%sEVENT(%s, [%s], %s, %s, %s, %s, %s)".format(
+ if(isSynthetic) "*" else "",
+ id,
+ occurredFormatted,
+ value,
+ instanceInfo,
+ details,
+ userID,
+ clientID
+ )
+ } else {
+ "%sEVENT(%s, [%s], [%s], %s, %s, %s, %s, %s)".format(
+ if(isSynthetic) "*" else "",
+ id,
+ occurredFormatted,
+ new MutableDateCalc(receivedMillis),
+ value,
+ instanceInfo,
+ details,
+ userID,
+ clientID
+ )
+ }
+ }
+
+ /**
+ * `Synthetic` means that Aquarium has manufactured this resource event for some purpose. For example, the implicitly
+ * issued resource events at the end a a billing period.
+ *
+ * @return `true` iff this resource event is synthetic.
+ */
+ def isSynthetic = {
+ details contains ResourceEventModel.Names.details_aquarium_is_synthetic
+ }
+
+}
+
+object ResourceEventModel {
+ type ResourceType = String
+ type ResourceIdType = String
+ type FullResourceType = (ResourceType, ResourceIdType)
+ type FullResourceTypeMap = Map[FullResourceType, ResourceEventModel]
+ type FullMutableResourceTypeMap = scala.collection.mutable.Map[FullResourceType, ResourceEventModel]
+
+ trait NamesT extends ExternalEventModel.NamesT {
+ final val clientID = "clientID"
+ final val resource = "resource"
+ final val instanceID = "instanceID"
+ final val value = "value"
+
+ // This is set in the details map to indicate a synthetic resource event (ie not a real one).
+ // Examples of synthetic resource events are those that are implicitly generated at the
+ // end of the billing period (e.g. `OFF`s).
+ final val details_aquarium_is_synthetic = "__aquarium_is_synthetic__"
+
+ final val details_aquarium_is_implicit_end = "__aquarium_is_implicit_end__"
+ }
+
+ object Names extends NamesT
+
+ def setAquariumSyntheticAndImplicitEnd(map: Map[String, String]): Map[String, String] = {
+ map.
+ updated(Names.details_aquarium_is_synthetic, "true").
+ updated(Names.details_aquarium_is_implicit_end, "true")
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ */
+
+package gr.grnet.aquarium.event
+package resource
+
+import gr.grnet.aquarium.util.makeString
+import gr.grnet.aquarium.converter.{JsonTextFormat, StdConverters}
+
+
+/**
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>
+ */
+
+case class StdResourceEvent(
+ id: String,
+ occurredMillis: Long,
+ receivedMillis: Long,
+ userID: String,
+ clientID: String,
+ resource: String,
+ instanceID: String,
+ value: Double,
+ eventVersion: String,
+ details: Map[String, String]
+) extends ResourceEventModel {
+ def withReceivedMillis(newReceivedMillis: Long) =
+ this.copy(receivedMillis = newReceivedMillis)
+
+ def withDetails(newDetails: Map[String, String], newOccurredMillis: Long) =
+ this.copy(details = newDetails, occurredMillis = newOccurredMillis)
+
+ def withDetailsAndValue(newDetails: Map[String, String], newValue: Double, newOccurredMillis: Long) =
+ this.copy(details = newDetails, value = newValue, occurredMillis = newOccurredMillis)
+}
+
+object StdResourceEvent {
+ final def fromJsonString(json: String): StdResourceEvent = {
+ StdConverters.AllConverters.convertEx[StdResourceEvent](JsonTextFormat(json))
+ }
+
+ final def fromJsonBytes(jsonBytes: Array[Byte]): StdResourceEvent = {
+ fromJsonString(makeString(jsonBytes))
+ }
+
+ final def fromOther(event: ResourceEventModel): StdResourceEvent = {
+ if(event.isInstanceOf[StdResourceEvent]) event.asInstanceOf[StdResourceEvent]
+ else {
+ import event._
+ new StdResourceEvent(
+ id,
+ occurredMillis,
+ receivedMillis,
+ userID,
+ clientID,
+ resource,
+ instanceID,
+ value,
+ event.eventVersion,
+ event.details
+ )
+ }
+}
+}
\ No newline at end of file
import gr.grnet.aquarium.util.{ContextualLogger, CryptoUtils, Loggable}
import gr.grnet.aquarium.store.PolicyStore
import gr.grnet.aquarium.AquariumException
-import gr.grnet.aquarium.event.{WalletEntry, ResourceEvent}
+import gr.grnet.aquarium.event.{WalletEntry}
import gr.grnet.aquarium.util.date.{TimeHelpers, MutableDateCalc}
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
* A timeslot together with the algorithm and unit price that apply for this particular timeslot.
* Compute the charge slots generated by a particular resource event.
*
*/
- def computeFullChargeslots(previousResourceEventM: Maybe[ResourceEvent],
- currentResourceEvent: ResourceEvent,
+ def computeFullChargeslots(previousResourceEventM: Maybe[ResourceEventModel],
+ currentResourceEvent: ResourceEventModel,
oldCredits: Double,
oldTotalAmount: Double,
newTotalAmount: Double,
* @param previousAmount The current state of the resource
* @param previousOccurred The last time the resource state was updated
*/
- def chargeEvent(currentResourceEvent: ResourceEvent,
+ def chargeEvent(currentResourceEvent: ResourceEventModel,
agreements: SortedMap[Timeslot, String],
previousAmount: Double,
previousOccurred: Date,
* resource event boundaries
* @return A list of wallet entries, one for each
*/
- def chargeEvent(event: ResourceEvent,
+ def chargeEvent(event: ResourceEventModel,
agr: DSLAgreement,
previousAmount: Double,
previousOccurred: Date,
chargeFor.map{x => assert(true,
Timeslot(previousOccurred, new Date(event.occurredMillis)))}
- if (!event.validate())
- return Failed(new AccountingException("Event not valid"))
+// if (!event.validate())
+// return Failed(new AccountingException("Event not valid"))
val policy = Policy.policy
val dslResource = policy.findResource(event.resource) match {
package gr.grnet.aquarium.logic.accounting.dsl
import com.ckkloverdos.maybe.{NoVal, Failed, Just, Maybe}
-import gr.grnet.aquarium.event.ResourceEvent
import gr.grnet.aquarium.AquariumException
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
* A cost policy indicates how charging for a resource will be done
* in which case it is ignored.
*
* @param oldAmount the old accumulating amount
- * @param newEventValue the value contained in a newly arrived [[gr.grnet.aquarium.event.ResourceEvent]]
+ * @param newEventValue the value contained in a newly arrived [[gr.grnet.aquarium.event.resource.ResourceEventModel]]
* @return
*/
def computeNewAccumulatingAmount(oldAmount: Double, newEventValue: Double): Double
*/
def supportsImplicitEvents: Boolean
- def mustConstructImplicitEndEventFor(resourceEvent: ResourceEvent): Boolean
+ def mustConstructImplicitEndEventFor(resourceEvent: ResourceEventModel): Boolean
@throws(classOf[Exception])
- def constructImplicitEndEventFor(resourceEvent: ResourceEvent, newOccurredMillis: Long): ResourceEvent
+ def constructImplicitEndEventFor(resourceEvent: ResourceEventModel, newOccurredMillis: Long): ResourceEventModel
@throws(classOf[Exception])
- def constructImplicitStartEventFor(resourceEvent: ResourceEvent): ResourceEvent
+ def constructImplicitStartEventFor(resourceEvent: ResourceEventModel): ResourceEventModel
}
object DSLCostPolicyNames {
def supportsImplicitEvents = false
- def mustConstructImplicitEndEventFor(resourceEvent: ResourceEvent) = false
+ def mustConstructImplicitEndEventFor(resourceEvent: ResourceEventModel) = false
- def constructImplicitEndEventFor(resourceEvent: ResourceEvent, occurredMillis: Long) = {
+ def constructImplicitEndEventFor(resourceEvent: ResourceEventModel, occurredMillis: Long) = {
throw new AquariumException("constructImplicitEndEventFor() Not compliant with %s".format(this))
}
- def constructImplicitStartEventFor(resourceEvent: ResourceEvent) = {
+ def constructImplicitStartEventFor(resourceEvent: ResourceEventModel) = {
throw new AquariumException("constructImplicitStartEventFor() Not compliant with %s".format(this))
}
}
true
}
- def mustConstructImplicitEndEventFor(resourceEvent: ResourceEvent) = {
+ def mustConstructImplicitEndEventFor(resourceEvent: ResourceEventModel) = {
true
}
- def constructImplicitEndEventFor(resourceEvent: ResourceEvent, newOccurredMillis: Long) = {
+ def constructImplicitEndEventFor(resourceEvent: ResourceEventModel, newOccurredMillis: Long) = {
assert(supportsImplicitEvents && mustConstructImplicitEndEventFor(resourceEvent))
val details = resourceEvent.details
- val newDetails = ResourceEvent.setAquariumSyntheticAndImplicitEnd(details)
- val newValue = resourceEvent.value
+ val newDetails = ResourceEventModel.setAquariumSyntheticAndImplicitEnd(details)
- resourceEvent.copy(
- occurredMillis = newOccurredMillis,
- details = newDetails,
- value = newValue
- )
+ resourceEvent.withDetails(newDetails, newOccurredMillis)
}
- def constructImplicitStartEventFor(resourceEvent: ResourceEvent) = {
+ def constructImplicitStartEventFor(resourceEvent: ResourceEventModel) = {
throw new AquariumException("constructImplicitStartEventFor() Not compliant with %s".format(this))
}
}
}
- def mustConstructImplicitEndEventFor(resourceEvent: ResourceEvent) = {
+ def mustConstructImplicitEndEventFor(resourceEvent: ResourceEventModel) = {
// If we have ON events with no OFF companions at the end of the billing period,
// then we must generate implicit OFF events.
OnOffCostPolicyValues.isONValue(resourceEvent.value)
}
- def constructImplicitEndEventFor(resourceEvent: ResourceEvent, newOccurredMillis: Long) = {
+ def constructImplicitEndEventFor(resourceEvent: ResourceEventModel, newOccurredMillis: Long) = {
assert(supportsImplicitEvents && mustConstructImplicitEndEventFor(resourceEvent))
assert(OnOffCostPolicyValues.isONValue(resourceEvent.value))
val details = resourceEvent.details
- val newDetails = ResourceEvent.setAquariumSyntheticAndImplicitEnd(details)
+ val newDetails = ResourceEventModel.setAquariumSyntheticAndImplicitEnd(details)
val newValue = OnOffCostPolicyValues.OFF
- resourceEvent.copy(
- occurredMillis = newOccurredMillis,
- details = newDetails,
- value = newValue
- )
+ resourceEvent.withDetailsAndValue(newDetails, newValue, newOccurredMillis)
}
- def constructImplicitStartEventFor(resourceEvent: ResourceEvent) = {
+ def constructImplicitStartEventFor(resourceEvent: ResourceEventModel) = {
throw new AquariumException("constructImplicitStartEventFor() Not compliant with %s".format(this))
}
}
false
}
- def mustConstructImplicitEndEventFor(resourceEvent: ResourceEvent) = {
+ def mustConstructImplicitEndEventFor(resourceEvent: ResourceEventModel) = {
false
}
- def constructImplicitEndEventFor(resourceEvent: ResourceEvent, occurredMillis: Long) = {
+ def constructImplicitEndEventFor(resourceEvent: ResourceEventModel, occurredMillis: Long) = {
throw new AquariumException("constructImplicitEndEventFor() Not compliant with %s".format(this))
}
- def constructImplicitStartEventFor(resourceEvent: ResourceEvent) = {
+ def constructImplicitStartEventFor(resourceEvent: ResourceEventModel) = {
throw new AquariumException("constructImplicitStartEventFor() Not compliant with %s".format(this))
}
}
import com.ckkloverdos.maybe._
import gr.grnet.aquarium.util.date.TimeHelpers
import gr.grnet.aquarium.{AquariumException, Configurator}
-import gr.grnet.aquarium.event.AquariumEventModel
+import gr.grnet.aquarium.event.ExternalEventModel
/**
* An abstract service that retrieves Aquarium events from a queue,
*
* @author Georgios Gousios <gousiosg@gmail.com>
*/
-abstract class EventProcessorService[E <: AquariumEventModel] extends AkkaAMQP with Loggable with Lifecycle {
+abstract class EventProcessorService[E <: ExternalEventModel] extends AkkaAMQP with Loggable with Lifecycle {
/* Messages exchanged between the persister and the queuereader */
case class AckData(msgId: String, deliveryTag: Long, queue: ActorRef)
import gr.grnet.aquarium.util.date.TimeHelpers
import gr.grnet.aquarium.util.makeString
import com.ckkloverdos.maybe._
-import gr.grnet.aquarium.event.im.IMEventModel
import gr.grnet.aquarium.store.memory.MemStore
+import gr.grnet.aquarium.event.im.{StdIMEvent, IMEventModel}
/**
* An event processor service for user events coming from the IM system
class IMEventProcessorService extends EventProcessorService[IMEventModel] {
override def parseJsonBytes(data: Array[Byte]) = {
- MemStore.createIMEventFromJsonBytes(data)
+ StdIMEvent.fromJsonBytes(data)
}
override def forward(event: IMEventModel) = {
import gr.grnet.aquarium.actor.RouterRole
import gr.grnet.aquarium.Configurator.Keys
import gr.grnet.aquarium.store.LocalFSEventStore
-import com.ckkloverdos.maybe.{Maybe, Just, Failed, NoVal}
+import com.ckkloverdos.maybe.Maybe
import gr.grnet.aquarium.actor.message.service.router.ProcessResourceEvent
-import gr.grnet.aquarium.event.ResourceEvent
import gr.grnet.aquarium.util.date.TimeHelpers
+import gr.grnet.aquarium.event.resource.{StdResourceEvent, ResourceEventModel}
/**
*
* @author Georgios Gousios <gousiosg@gmail.com>
*/
-final class ResourceEventProcessorService extends EventProcessorService[ResourceEvent] {
+final class ResourceEventProcessorService extends EventProcessorService[ResourceEventModel] {
- override def parseJsonBytes(data: Array[Byte]) = ResourceEvent.fromBytes(data)
+ override def parseJsonBytes(data: Array[Byte]) = {
+ StdResourceEvent.fromJsonBytes(data)
+ }
- override def forward(event: ResourceEvent): Unit = {
+ override def forward(event: ResourceEventModel): Unit = {
if(event ne null) {
val businessLogicDispacther = _configurator.actorProvider.actorForRole(RouterRole)
businessLogicDispacther ! ProcessResourceEvent(event)
}
}
- override def existsInStore(event: ResourceEvent): Boolean =
- _configurator.resourceEventStore.findResourceEventById(event.id).isJust
+ override def existsInStore(event: ResourceEventModel): Boolean =
+ _configurator.resourceEventStore.findResourceEventById(event.id).isDefined
- override def storeParsedEvent(event: ResourceEvent, initialPayload: Array[Byte]): Unit = {
+ override def storeParsedEvent(event: ResourceEventModel, initialPayload: Array[Byte]): Unit = {
// 1. Store to local FS for debugging purposes.
// BUT be resilient to errors, since this is not critical
if(_configurator.eventsStoreFolder.isJust) {
}
// 2. Store to DB
- _configurator.resourceEventStore.storeResourceEvent(event)
+ _configurator.resourceEventStore.insertResourceEvent(event)
}
package gr.grnet.aquarium.simulation
-import gr.grnet.aquarium.event.ResourceEvent
+import gr.grnet.aquarium.event.resource.StdResourceEvent
/**
details: Map[String, String],
eventVersion: String = "1.0") = {
- val event = ResourceEvent(
+ val event = StdResourceEvent(
uidGen.nextUID(),
occurredMillis,
receivedMillis,
client.clientId,
resource.name,
instanceId,
- eventVersion,
value,
+ eventVersion,
details
)
package gr.grnet.aquarium.simulation
import java.util.Date
-import com.ckkloverdos.maybe.Maybe
import gr.grnet.aquarium.store.RecordID
-import gr.grnet.aquarium.event.ResourceEvent
/**
* A simulator for an instance of the standard `bandwidth` resource.
def useBandwidth(occurredDate: Date,
megaBytes: Double,
details: Map[String, String] = Map(),
- eventVersion: String = "1.0"): RecordID = {
+ eventVersion: String = "1.0") = {
newResourceEvent(
occurredDate.getTime,
package gr.grnet.aquarium.simulation
-import gr.grnet.aquarium.event.ResourceEvent
import gr.grnet.aquarium.store.RecordID
import com.ckkloverdos.maybe.Maybe
import java.util.Date
def consumeMB(occurredDate: Date,
megaBytes: Double,
details: Map[String, String] = Map(),
- eventVersion: String = "1.0"): RecordID = {
+ eventVersion: String = "1.0") = {
newResourceEvent(
occurredDate.getTime,
occurredDate.getTime,
def freeMB(occurredDate: Date,
megaBytes: Double,
details: Map[String, String] = Map(),
- eventVersion: String = "1.0"): RecordID = {
+ eventVersion: String = "1.0") = {
consumeMB(occurredDate, -megaBytes)
}
outOfSyncHours: Int,
megaBytes: Double,
details: Map[String, String] = Map(),
- eventVersion: String = "1.0"): RecordID = {
+ eventVersion: String = "1.0") = {
val occurredDateCalc = new MutableDateCalc(occurredDate)
val occurredTime = occurredDateCalc.toMillis
outOfSyncHours: Int,
megaBytes: Double,
details: Map[String, String] = Map(),
- eventVersion: String = "1.0"): RecordID = {
+ eventVersion: String = "1.0") = {
consumeMB_OutOfSync(occurredDate, outOfSyncHours, -megaBytes)
}
import gr.grnet.aquarium.logic.accounting.dsl.OnOffCostPolicyValues
import gr.grnet.aquarium.store.RecordID
-import com.ckkloverdos.maybe.Maybe
import java.util.Date
import gr.grnet.aquarium.util.date.MutableDateCalc
-import gr.grnet.aquarium.event.ResourceEvent
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
* A simulator for an instance of the standard `vmtime` resource.
def newON(occurredDate: Date,
details: Map[String, String] = Map(),
- eventVersion: String = "1.0"): RecordID = {
+ eventVersion: String = "1.0") = {
newResourceEvent(
occurredDate.getTime,
occurredDate.getTime,
def newOFF(occurredDate: Date,
details: Map[String, String] = Map(),
- eventVersion: String = "1.0"): RecordID = {
+ eventVersion: String = "1.0") = {
newResourceEvent(
occurredDate.getTime,
occurredDate.getTime,
)
}
- def newONOFF(occurredDateForON: Date, totalVMTimeInHours: Int): (RecordID, RecordID) = {
+ def newONOFF(occurredDateForON: Date, totalVMTimeInHours: Int): (ResourceEventModel, ResourceEventModel) = {
val onID = newON(occurredDateForON)
val offDate = new MutableDateCalc(occurredDateForON).goPlusHours(totalVMTimeInHours).toDate
val offID = newOFF(offDate)
def newOFF_OutOfSync(occuredDate: Date,
outOfSyncHours: Int,
details: Map[String, String] = Map(),
- eventVersion: String = "1.0"): RecordID = {
+ eventVersion: String = "1.0") = {
val occurredDateCalc = new MutableDateCalc(occuredDate)
val occurredTime = occurredDateCalc.toMillis
import java.util.Date
import gr.grnet.aquarium.store.RecordID
import math.Ordering
-import gr.grnet.aquarium.event.ResourceEvent
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
* A simulator for a user.
def resourceEventStore = aquarium.resourceEventStore
private[simulation]
- def _addResourceEvent(resourceEvent: ResourceEvent): RecordID = {
- resourceEventStore.storeResourceEvent(resourceEvent)
+ def _addResourceEvent(resourceEvent: ResourceEventModel): ResourceEventModel = {
+ resourceEventStore.insertResourceEvent(resourceEvent)
}
- def myResourceEvents: List[ResourceEvent] = {
+ def myResourceEvents: List[ResourceEventModel] = {
resourceEventStore.findResourceEventsByUserId(userId)(None)
}
- def myResourceEventsByReceivedDate: List[ResourceEvent] = {
- myResourceEvents.sorted(new Ordering[ResourceEvent] {
- def compare(x: ResourceEvent, y: ResourceEvent) = {
+ def myResourceEventsByReceivedDate: List[ResourceEventModel] = {
+ myResourceEvents.sorted(new Ordering[ResourceEventModel] {
+ def compare(x: ResourceEventModel, y: ResourceEventModel) = {
if(x.receivedMillis < y.receivedMillis)
-1
else if(x.receivedMillis == y.receivedMillis)
})
}
- def myResourceEventsByOccurredDate: List[ResourceEvent] = {
- myResourceEvents.sorted(new Ordering[ResourceEvent] {
- def compare(x: ResourceEvent, y: ResourceEvent) = {
+ def myResourceEventsByOccurredDate: List[ResourceEventModel] = {
+ myResourceEvents.sorted(new Ordering[ResourceEventModel] {
+ def compare(x: ResourceEventModel, y: ResourceEventModel) = {
if(x.occurredMillis < y.occurredMillis)
-1
else if(x.occurredMillis == y.occurredMillis)
package gr.grnet.aquarium.store
-import com.ckkloverdos.maybe.Maybe
import gr.grnet.aquarium.event.im.IMEventModel
import gr.grnet.aquarium.util.makeString
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
* Store for external user events
*/
trait IMEventStore {
type IMEvent <: IMEventModel
-
- def isLocalIMEvent(event: IMEventModel): Boolean
+ type ResourceEvent <: ResourceEventModel
def createIMEventFromJson(json: String): IMEvent
def createIMEventFromOther(event: IMEventModel): IMEvent
-// def storeUnparsed(json: String): Maybe[RecordID]
-
/**
* Insert a new event into the store.
*/
/**
* Find a user event by event ID
*/
- def findIMEventById(id: String): Maybe[IMEvent]
-
- /**
- * Find all user events by user ID
- */
- def findIMEventsByUserId(userId: String): List[IMEvent]
+ def findIMEventById(id: String): Option[IMEvent]
}
\ No newline at end of file
import java.io.{FileOutputStream, File}
import gr.grnet.aquarium.util.{Loggable, stringOfStackTrace}
import gr.grnet.aquarium.util.date.{TimeHelpers, MutableDateCalc}
-import gr.grnet.aquarium.event.ResourceEvent
import gr.grnet.aquarium.event.im.IMEventModel
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
* This is used whenever the property `events.store.folder` is setup in aquarium configuration.
}
}
- def storeResourceEvent(mc: Configurator, event: ResourceEvent, initialPayload: Array[Byte]): Unit = {
+ def storeResourceEvent(mc: Configurator, event: ResourceEventModel, initialPayload: Array[Byte]): Unit = {
require(event ne null, "Resource event must be not null")
for(root <- mc.eventsStoreFolder) {
package gr.grnet.aquarium.store
import com.ckkloverdos.maybe.Maybe
-import gr.grnet.aquarium.event.ResourceEvent
import gr.grnet.aquarium.AquariumException
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
* An abstraction for Aquarium `ResourceEvent` stores.
* @author Georgios Gousios <gousiosg@gmail.com>.
*/
trait ResourceEventStore {
+ type ResourceEvent <: ResourceEventModel
+
+ def createResourceEventFromOther(event: ResourceEventModel): ResourceEvent
+
def clearResourceEvents(): Unit = {
throw new AquariumException("Unsupported operation")
}
- def storeResourceEvent(event: ResourceEvent): RecordID
+ def insertResourceEvent(event: ResourceEventModel): ResourceEvent
- def findResourceEventById(id: String): Maybe[ResourceEvent]
+ def findResourceEventById(id: String): Option[ResourceEvent]
def findResourceEventsByUserId(userId: String)(sortWith: Option[(ResourceEvent, ResourceEvent) => Boolean]): List[ResourceEvent]
import gr.grnet.aquarium.user.UserState
import gr.grnet.aquarium.uid.ConcurrentVMLocalUIDGenerator
import gr.grnet.aquarium.{AquariumException, Configurable}
-import gr.grnet.aquarium.event.{WalletEntry, ResourceEvent, PolicyEntry}
+import gr.grnet.aquarium.event.{WalletEntry, PolicyEntry}
import gr.grnet.aquarium.converter.JsonTextFormat
import gr.grnet.aquarium.util._
import gr.grnet.aquarium.event.im.{StdIMEvent, IMEventModel}
import org.bson.types.ObjectId
+import gr.grnet.aquarium.event.resource.{StdResourceEvent, ResourceEventModel}
/**
* An implementation of various stores that persists data in memory.
with StoreProvider {
override type IMEvent = MemIMEvent
+ override type ResourceEvent = MemResourceEvent
private[this] val idGen = new ConcurrentVMLocalUIDGenerator(1000)
//- WalletEntryStore
//+ ResourceEventStore
+ def createResourceEventFromOther(event: ResourceEventModel): ResourceEvent = {
+ if(event.isInstanceOf[MemResourceEvent]) event.asInstanceOf[MemResourceEvent]
+ else {
+ import event._
+ new StdResourceEvent(
+ id,
+ occurredMillis,
+ receivedMillis,
+ userID,
+ clientID,
+ resource,
+ instanceID,
+ value,
+ eventVersion,
+ details
+ ): MemResourceEvent
+ }
+ }
override def clearResourceEvents() = {
_resourceEvents = Nil
}
- def storeResourceEvent(event: ResourceEvent) = {
- _resourceEvents ::= event
- RecordID(event.id)
+ def insertResourceEvent(event: ResourceEventModel) = {
+ val localEvent = createResourceEventFromOther(event)
+ _resourceEvents ::= localEvent
+ localEvent
}
def findResourceEventById(id: String) = {
- _resourceEvents.find(ev ⇒ ev.id == id) match {
- case Some(ev) ⇒ Just(ev)
- case None ⇒ NoVal
- }
+ _resourceEvents.find(ev ⇒ ev.id == id)
}
def findResourceEventsByUserId(userId: String)
//+ IMEventStore
def createIMEventFromJson(json: String) = {
- MemStore.createIMEventFromJson(json)
- }
-
- def isLocalIMEvent(event: IMEventModel) = {
- MemStore.isLocalIMEvent(event)
+ StdIMEvent.fromJsonString(json)
}
def createIMEventFromOther(event: IMEventModel) = {
- MemStore.createIMEventFromOther(event)
+ StdIMEvent.fromOther(event)
}
- def storeUnparsed(json: String) = throw new AquariumException("Not implemented")
-
def insertIMEvent(event: IMEventModel) = {
val localEvent = createIMEventFromOther(event)
imEventById += (event.id -> localEvent)
localEvent
}
- def findIMEventById(id: String) = Maybe{imEventById.getOrElse(id, null)}
-
- def findIMEventsByUserId(userId: String) = imEventById.valuesIterator.filter{v => v.userID == userId}.toList
+ def findIMEventById(id: String) = imEventById.get(id)
//- IMEventStore
def loadPolicyEntriesAfter(after: Long) =
}
object MemStore {
- def createIMEventFromOther(event: IMEventModel) = {
- if(event.isInstanceOf[MemIMEvent]) event.asInstanceOf[MemIMEvent]
- else new StdIMEvent(
- event.id,
- event.occurredMillis,
- event.receivedMillis,
- event.userID,
- event.clientID,
- event.isActive,
- event.role,
- event.eventVersion,
- event.eventType,
- event.details
- ): MemIMEvent
- }
-
- final def createIMEventFromJson(json: String) = {
- import gr.grnet.aquarium.converter.StdConverters.AllConverters
- AllConverters.convertEx[MemIMEvent](JsonTextFormat(json))
- }
-
- final def createIMEventFromJsonBytes(jsonBytes: Array[Byte]) = {
- createIMEventFromJson(makeString(jsonBytes))
- }
-
final def isLocalIMEvent(event: IMEventModel) = event match {
case _: MemIMEvent ⇒ true
case _ ⇒ false
package gr.grnet.aquarium.store
import gr.grnet.aquarium.event.im.StdIMEvent
+import gr.grnet.aquarium.event.resource.StdResourceEvent
package object memory {
type MemIMEvent = StdIMEvent
+ type MemResourceEvent = StdResourceEvent
}
package gr.grnet.aquarium.store.mongodb
import org.bson.types.ObjectId
-import gr.grnet.aquarium.event.AquariumEventModel
+import gr.grnet.aquarium.event.ExternalEventModel
/**
*
* @author Christos KK Loverdos <loverdos@gmail.com>
*/
-trait MongoDBEventModel extends AquariumEventModel {
+trait MongoDBEventModel extends ExternalEventModel {
def _id: ObjectId
override def storeID: Option[ObjectId] = Option(_id)
import gr.grnet.aquarium.converter.{JsonTextFormat, StdConverters}
import gr.grnet.aquarium.util._
import gr.grnet.aquarium.event.im.{IMEventModel, StdIMEvent}
-import gr.grnet.aquarium.event.AquariumEventModel
+import gr.grnet.aquarium.event.ExternalEventModel
+import com.mongodb.DBObject
+import com.mongodb.util.JSON
/**
eventType: String,
details: Map[String, String],
_id: ObjectId
- ) extends AquariumEventModel with IMEventModel with MongoDBEventModel {
+) extends IMEventModel with MongoDBEventModel {
- override def withReceivedMillis(newReceivedMillis: Long) = this.copy(receivedMillis = newReceivedMillis)
+ def withReceivedMillis(newReceivedMillis: Long) =
+ this.copy(receivedMillis = newReceivedMillis)
+
+ def withDetails(newDetails: Map[String, String], newOccurredMillis: Long) =
+ this.copy(details = newDetails, occurredMillis = newOccurredMillis)
}
object MongoDBIMEvent {
- final def fromJson(json: String): MongoDBIMEvent = {
+ final def fromJsonString(json: String): MongoDBIMEvent = {
StdConverters.AllConverters.convertEx[MongoDBIMEvent](JsonTextFormat(json))
}
final def fromJsonBytes(jsonBytes: Array[Byte]): MongoDBIMEvent = {
- fromJson(makeString(jsonBytes))
+ fromJsonString(makeString(jsonBytes))
+ }
+
+ final def fromDBObject(dbObject: DBObject): MongoDBIMEvent = {
+ fromJsonString(JSON.serialize(dbObject))
}
- final def fromOther(event: IMEventModel, _id: ObjectId = null): MongoDBIMEvent = {
+ final def fromOther(event: IMEventModel, _id: ObjectId): MongoDBIMEvent = {
MongoDBIMEvent(
event.id,
event.occurredMillis,
--- /dev/null
+/*
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ */
+
+package gr.grnet.aquarium.store.mongodb
+
+import org.bson.types.ObjectId
+import com.mongodb.DBObject
+
+import gr.grnet.aquarium.util.makeString
+import gr.grnet.aquarium.event.resource.ResourceEventModel
+import gr.grnet.aquarium.converter.{StdConverters, JsonTextFormat}
+import com.mongodb.util.JSON
+
+/**
+ * A [[gr.grnet.aquarium.event.resource.ResourceEventModel]] as represented for MongoDB.
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>
+ */
+
+case class MongoDBResourceEvent(
+ id: String,
+ occurredMillis: Long,
+ receivedMillis: Long,
+ userID: String,
+ clientID: String,
+ resource: String,
+ instanceID: String,
+ value: Double,
+ eventVersion: String,
+ details: Map[String, String],
+ _id: ObjectId
+) extends ResourceEventModel with MongoDBEventModel {
+
+ def withReceivedMillis(newReceivedMillis: Long) =
+ this.copy(receivedMillis = newReceivedMillis)
+
+ def withDetails(newDetails: Map[String, String], newOccurredMillis: Long) =
+ this.copy(details = newDetails, occurredMillis = newOccurredMillis)
+
+ def withDetailsAndValue(newDetails: Map[String, String], newValue: Double, newOccurredMillis: Long) =
+ this.copy(details = newDetails, value = newValue, occurredMillis = newOccurredMillis)
+}
+
+object MongoDBResourceEvent {
+ final def fromJsonString(json: String): MongoDBResourceEvent = {
+ StdConverters.AllConverters.convertEx[MongoDBResourceEvent](JsonTextFormat(json))
+ }
+
+ final def fromJsonBytes(bytes: Array[Byte]): MongoDBResourceEvent = {
+ fromJsonString(makeString(bytes))
+ }
+
+ final def fromDBObject(dbObject: DBObject): MongoDBResourceEvent = {
+ fromJsonString(JSON.serialize(dbObject))
+ }
+
+
+ final def fromOther(rcEvent: ResourceEventModel, _id: ObjectId): MongoDBResourceEvent = {
+ import rcEvent._
+ MongoDBResourceEvent(
+ id,
+ occurredMillis,
+ receivedMillis,
+ userID,
+ clientID,
+ resource,
+ instanceID,
+ value,
+ eventVersion,
+ details,
+ _id
+ )
+ }
+}
\ No newline at end of file
import com.mongodb.util.JSON
import gr.grnet.aquarium.user.UserState
-import gr.grnet.aquarium.user.UserState.{JsonNames => UserStateJsonNames}
+import gr.grnet.aquarium.user.UserState.{JsonNames ⇒ UserStateJsonNames}
import gr.grnet.aquarium.util.json.JsonSupport
import collection.mutable.ListBuffer
-import gr.grnet.aquarium.event.im.IMEventModel.{Names => IMEventNames}
+import gr.grnet.aquarium.event._
+import gr.grnet.aquarium.event.im.IMEventModel
+import gr.grnet.aquarium.event.im.IMEventModel.{Names ⇒ IMEventNames}
+import gr.grnet.aquarium.event.resource.ResourceEventModel
+import gr.grnet.aquarium.event.resource.ResourceEventModel.{Names ⇒ ResourceEventNames}
import gr.grnet.aquarium.store._
-import gr.grnet.aquarium.event.ResourceEvent.{JsonNames => ResourceJsonNames}
-import gr.grnet.aquarium.event.WalletEntry.{JsonNames => WalletJsonNames}
-import gr.grnet.aquarium.event.PolicyEntry.{JsonNames => PolicyJsonNames}
+import gr.grnet.aquarium.event.WalletEntry.{JsonNames ⇒ WalletJsonNames}
+import gr.grnet.aquarium.event.PolicyEntry.{JsonNames ⇒ PolicyJsonNames}
import java.util.Date
import gr.grnet.aquarium.logic.accounting.Policy
import com.mongodb._
import org.bson.types.ObjectId
-import gr.grnet.aquarium.event._
-import com.ckkloverdos.maybe.{NoVal, Maybe}
-import im.IMEventModel
+import com.ckkloverdos.maybe.Maybe
import gr.grnet.aquarium.util._
-import gr.grnet.aquarium.converter.{Conversions, StdConverters}
+import gr.grnet.aquarium.converter.Conversions
/**
* Mongodb implementation of the various aquarium stores.
with Loggable {
override type IMEvent = MongoDBIMEvent
+ override type ResourceEvent = MongoDBResourceEvent
private[store] lazy val resourceEvents = getCollection(MongoDBStore.RESOURCE_EVENTS_COLLECTION)
private[store] lazy val userStates = getCollection(MongoDBStore.USER_STATES_COLLECTION)
db.getCollection(name)
}
- private[this] def _sortByTimestampAsc[A <: AquariumEventModel](one: A, two: A): Boolean = {
+ private[this] def _sortByTimestampAsc[A <: ExternalEventModel](one: A, two: A): Boolean = {
if (one.occurredMillis > two.occurredMillis) false
else if (one.occurredMillis < two.occurredMillis) true
else true
}
- private[this] def _sortByTimestampDesc[A <: AquariumEventSkeleton](one: A, two: A): Boolean = {
- if (one.occurredMillis < two.occurredMillis) false
- else if (one.occurredMillis > two.occurredMillis) true
- else true
+ //+ResourceEventStore
+ def createResourceEventFromOther(event: ResourceEventModel): ResourceEvent = {
+ MongoDBResourceEvent.fromOther(event, null)
}
- //+ResourceEventStore
- def storeResourceEvent(event: ResourceEvent) = {
- MongoDBStore.storeAny[ResourceEvent](
- event,
- resourceEvents,
- ResourceJsonNames.id,
- (e) => e.id,
- MongoDBStore.jsonSupportToDBObject)
+ def insertResourceEvent(event: ResourceEventModel) = {
+ val localEvent = MongoDBResourceEvent.fromOther(event, new ObjectId())
+ MongoDBStore.insertObject(localEvent, resourceEvents, MongoDBStore.jsonSupportToDBObject)
+ localEvent
}
- def findResourceEventById(id: String): Maybe[ResourceEvent] =
- MongoDBStore.findById(id, resourceEvents, MongoDBStore.dbObjectToResourceEvent)
+ def findResourceEventById(id: String): Option[ResourceEvent] = {
+ MongoDBStore.findBy(ResourceEventNames.id, id, resourceEvents, MongoDBResourceEvent.fromDBObject)
+ }
def findResourceEventsByUserId(userId: String)
(sortWith: Option[(ResourceEvent, ResourceEvent) => Boolean]): List[ResourceEvent] = {
- val query = new BasicDBObject(ResourceJsonNames.userId, userId)
+ val query = new BasicDBObject(ResourceEventNames.userID, userId)
- MongoDBStore.runQuery(query, resourceEvents)(MongoDBStore.dbObjectToResourceEvent)(sortWith)
+ MongoDBStore.runQuery(query, resourceEvents)(MongoDBResourceEvent.fromDBObject)(sortWith)
}
def findResourceEventsByUserIdAfterTimestamp(userId: String, timestamp: Long): List[ResourceEvent] = {
val query = new BasicDBObject()
- query.put(ResourceJsonNames.userId, userId)
- query.put(ResourceJsonNames.occurredMillis, new BasicDBObject("$gt", timestamp))
+ query.put(ResourceEventNames.userID, userId)
+ query.put(ResourceEventNames.occurredMillis, new BasicDBObject("$gt", timestamp))
- val sort = new BasicDBObject(ResourceJsonNames.occurredMillis, 1)
+ val sort = new BasicDBObject(ResourceEventNames.occurredMillis, 1)
val cursor = resourceEvents.find(query).sort(sort)
try {
val buffer = new scala.collection.mutable.ListBuffer[ResourceEvent]
while(cursor.hasNext) {
- buffer += MongoDBStore.dbObjectToResourceEvent(cursor.next())
+ buffer += MongoDBResourceEvent.fromDBObject(cursor.next())
}
buffer.toList.sortWith(_sortByTimestampAsc)
} finally {
def findResourceEventHistory(userId: String, resName: String,
instid: Option[String], upTo: Long) : List[ResourceEvent] = {
val query = new BasicDBObject()
- query.put(ResourceJsonNames.userId, userId)
- query.put(ResourceJsonNames.occurredMillis, new BasicDBObject("$lt", upTo))
- query.put(ResourceJsonNames.resource, resName)
+ query.put(ResourceEventNames.userID, userId)
+ query.put(ResourceEventNames.occurredMillis, new BasicDBObject("$lt", upTo))
+ query.put(ResourceEventNames.resource, resName)
instid match {
case Some(id) =>
Policy.policy.findResource(resName) match {
- case Some(y) => query.put(ResourceJsonNames.details,
+ case Some(y) => query.put(ResourceEventNames.details,
new BasicDBObject(y.descriminatorField, instid.get))
case None =>
}
case None =>
}
- val sort = new BasicDBObject(ResourceJsonNames.occurredMillis, 1)
+ val sort = new BasicDBObject(ResourceEventNames.occurredMillis, 1)
val cursor = resourceEvents.find(query).sort(sort)
try {
val buffer = new scala.collection.mutable.ListBuffer[ResourceEvent]
while(cursor.hasNext) {
- buffer += MongoDBStore.dbObjectToResourceEvent(cursor.next())
+ buffer += MongoDBResourceEvent.fromDBObject(cursor.next())
}
buffer.toList.sortWith(_sortByTimestampAsc)
} finally {
def findResourceEventsForReceivedPeriod(userId: String, startTimeMillis: Long, stopTimeMillis: Long): List[ResourceEvent] = {
val query = new BasicDBObject()
- query.put(ResourceJsonNames.userId, userId)
- query.put(ResourceJsonNames.receivedMillis, new BasicDBObject("$gte", startTimeMillis))
- query.put(ResourceJsonNames.receivedMillis, new BasicDBObject("$lte", stopTimeMillis))
+ query.put(ResourceEventNames.userID, userId)
+ query.put(ResourceEventNames.receivedMillis, new BasicDBObject("$gte", startTimeMillis))
+ query.put(ResourceEventNames.receivedMillis, new BasicDBObject("$lte", stopTimeMillis))
// Sort them by increasing order for occurred time
- val orderBy = new BasicDBObject(ResourceJsonNames.occurredMillis, 1)
+ val orderBy = new BasicDBObject(ResourceEventNames.occurredMillis, 1)
- MongoDBStore.runQuery[ResourceEvent](query, resourceEvents, orderBy)(MongoDBStore.dbObjectToResourceEvent)(None)
+ MongoDBStore.runQuery[ResourceEvent](query, resourceEvents, orderBy)(MongoDBResourceEvent.fromDBObject)(None)
}
def countOutOfSyncEventsForBillingPeriod(userId: String, startMillis: Long, stopMillis: Long): Maybe[Long] = {
MongoDBStore.storeAny[WalletEntry](
entry,
walletEntries,
- ResourceJsonNames.id,
+ WalletJsonNames.id,
(e) => e.id,
MongoDBStore.jsonSupportToDBObject)
}
}
- def findWalletEntryById(id: String): Maybe[WalletEntry] =
- MongoDBStore.findById[WalletEntry](id, walletEntries, MongoDBStore.dbObjectToWalletEntry)
+ def findWalletEntryById(id: String): Maybe[WalletEntry] = {
+ MongoDBStore.findBy(WalletJsonNames.id, id, walletEntries, MongoDBStore.dbObjectToWalletEntry): Maybe[WalletEntry]
+ }
def findUserWalletEntries(userId: String) = {
// TODO: optimize
//-WalletEntryStore
//+IMEventStore
- def isLocalIMEvent(event: IMEventModel) = {
- MongoDBStore.isLocalIMEvent(event)
- }
-
def createIMEventFromJson(json: String) = {
MongoDBStore.createIMEventFromJson(json)
}
localEvent
}
- def findIMEventById(id: String): Maybe[IMEvent] =
- MongoDBStore.findById[IMEvent](id, imEvents, MongoDBStore.dbObjectToIMEvent)
-
- def findIMEventsByUserId(userId: String): List[IMEvent] = {
- val query = new BasicDBObject(IMEventNames.userID, userId)
- MongoDBStore.runQuery(query, imEvents)(MongoDBStore.dbObjectToIMEvent)(Some(_sortByTimestampAsc))
+ def findIMEventById(id: String): Option[IMEvent] = {
+ MongoDBStore.findBy(IMEventNames.id, id, imEvents, MongoDBIMEvent.fromDBObject)
}
//-IMEventStore
policyEntries.update(query, policyObject, true, false)
}
- def findPolicyEntry(id: String) =
- MongoDBStore.findById[PolicyEntry](id, policyEntries, MongoDBStore.dbObjectToPolicyEntry)
+ def findPolicyEntry(id: String) = {
+ MongoDBStore.findBy(PolicyJsonNames.id, id, policyEntries, MongoDBStore.dbObjectToPolicyEntry)
+ }
//-PolicyStore
}
*/
final val POLICY_ENTRIES_COLLECTION = "policyEntries"
- /* TODO: Some of the following methods rely on JSON (de-)serialization).
- * A method based on proper object serialization would be much faster.
- */
- def dbObjectToResourceEvent(dbObject: DBObject): ResourceEvent = {
- ResourceEvent.fromJson(JSON.serialize(dbObject))
- }
-
def dbObjectToUserState(dbObj: DBObject): UserState = {
UserState.fromJson(JSON.serialize(dbObj))
}
WalletEntry.fromJson(JSON.serialize(dbObj))
}
- def dbObjectToIMEvent(dbObj: DBObject): MongoDBIMEvent = {
- MongoDBIMEvent.fromJson(JSON.serialize(dbObj))
- }
-
def dbObjectToPolicyEntry(dbObj: DBObject): PolicyEntry = {
PolicyEntry.fromJson(JSON.serialize(dbObj))
}
- def findById[A >: Null <: AnyRef](id: String, collection: DBCollection, deserializer: (DBObject) => A) : Maybe[A] =
- Maybe {
- val query = new BasicDBObject(ResourceJsonNames.id, id)
+ def findBy[A >: Null <: AnyRef](name: String,
+ value: String,
+ collection: DBCollection,
+ deserializer: (DBObject) => A) : Option[A] = {
+ val query = new BasicDBObject(name, value)
val cursor = collection find query
- try {
+ withCloseable(cursor) { cursor ⇒
if(cursor.hasNext)
- deserializer apply cursor.next
+ Some(deserializer apply cursor.next)
else
- null: A // will be transformed to NoVal by the Maybe polymorphic constructor
- } finally {
- cursor.close()
+ None
}
}
- def runQuery[A <: AquariumEventModel](query: DBObject, collection: DBCollection, orderBy: DBObject = null)
+ def runQuery[A <: ExternalEventModel](query: DBObject, collection: DBCollection, orderBy: DBObject = null)
(deserializer: (DBObject) => A)
(sortWith: Option[(A, A) => Boolean]): List[A] = {
val cursor0 = collection find query
}
def storeUserState(userState: UserState, collection: DBCollection) = {
- storeAny[UserState](userState, collection, ResourceJsonNames.userId, _.userID, MongoDBStore.jsonSupportToDBObject)
+ storeAny[UserState](userState, collection, ResourceEventNames.userID, _.userID, MongoDBStore.jsonSupportToDBObject)
}
def storePolicyEntry(policyEntry: PolicyEntry, collection: DBCollection): Maybe[RecordID] = {
}
final def createIMEventFromJson(json: String) = {
- MongoDBIMEvent.fromJson(json)
+ MongoDBIMEvent.fromJsonString(json)
}
final def createIMEventFromOther(event: IMEventModel) = {
- MongoDBIMEvent.fromOther(event)
+ MongoDBIMEvent.fromOther(event, null)
}
final def createIMEventFromJsonBytes(jsonBytes: Array[Byte]) = {
import gr.grnet.aquarium.logic.accounting.Policy
import java.util.Date
import com.ckkloverdos.maybe.{NoVal, Maybe, Just}
-import gr.grnet.aquarium.event.ResourceEvent
-import gr.grnet.aquarium.event.ResourceEvent.FullMutableResourceTypeMap
+import gr.grnet.aquarium.event.resource.ResourceEventModel.FullMutableResourceTypeMap
import logic.accounting.dsl.{Timeslot, DSLAgreement}
import collection.immutable.{TreeMap, SortedMap}
import util.date.MutableDateCalc
+import event.resource.ResourceEventModel
/**
* Snapshot of data that are user-related.
*
* @author Christos KK Loverdos <loverdos@gmail.com>
*/
-case class LatestResourceEventsSnapshot(resourceEvents: List[ResourceEvent],
+case class LatestResourceEventsSnapshot(resourceEvents: List[ResourceEventModel],
snapshotTime: Long) extends DataSnapshot {
/**
* @return A fresh instance of [[gr.grnet.aquarium.user.LatestResourceEventsWorker]].
*/
def toMutableWorker = {
- val map = scala.collection.mutable.Map[ResourceEvent.FullResourceType, ResourceEvent]()
+ val map = scala.collection.mutable.Map[ResourceEventModel.FullResourceType, ResourceEventModel]()
for(latestEvent <- resourceEvents) {
map(latestEvent.fullResourceInfo) = latestEvent
}
def toImmutableSnapshot(snapshotTime: Long) =
LatestResourceEventsSnapshot(latestEventsMap.valuesIterator.toList, snapshotTime)
- def updateResourceEvent(resourceEvent: ResourceEvent): Unit = {
+ def updateResourceEvent(resourceEvent: ResourceEventModel): Unit = {
latestEventsMap((resourceEvent.resource, resourceEvent.instanceID)) = resourceEvent
}
- def findResourceEvent(resource: String, instanceId: String): Maybe[ResourceEvent] = {
+ def findResourceEvent(resource: String, instanceId: String): Maybe[ResourceEventModel] = {
findFromMapAsMaybe(latestEventsMap, (resource, instanceId))
}
- def findAndRemoveResourceEvent(resource: String, instanceId: String): Maybe[ResourceEvent] = {
+ def findAndRemoveResourceEvent(resource: String, instanceId: String): Maybe[ResourceEventModel] = {
findAndRemoveFromMap(latestEventsMap, (resource, instanceId))
}
def size = latestEventsMap.size
- def foreach[U](f: ResourceEvent => U): Unit = {
+ def foreach[U](f: ResourceEventModel => U): Unit = {
latestEventsMap.valuesIterator.foreach(f)
}
}
/**
* Helper factory to construct a worker from a list of events.
*/
- def fromList(latestEventsList: List[ResourceEvent]): LatestResourceEventsWorker = {
+ def fromList(latestEventsList: List[ResourceEventModel]): LatestResourceEventsWorker = {
LatestResourceEventsSnapshot(latestEventsList, 0L).toMutableWorker
}
}
*
* @author Christos KK Loverdos <loverdos@gmail.com>
*/
-case class ImplicitlyIssuedResourceEventsSnapshot(implicitlyIssuedEvents: List[ResourceEvent],
+case class ImplicitlyIssuedResourceEventsSnapshot(implicitlyIssuedEvents: List[ResourceEventModel],
snapshotTime: Long) extends DataSnapshot {
/**
* The gateway to playing with mutable state.
* @return A fresh instance of [[gr.grnet.aquarium.user.ImplicitlyIssuedResourceEventsWorker]].
*/
def toMutableWorker = {
- val map = scala.collection.mutable.Map[ResourceEvent.FullResourceType, ResourceEvent]()
+ val map = scala.collection.mutable.Map[ResourceEventModel.FullResourceType, ResourceEventModel]()
for(implicitEvent <- implicitlyIssuedEvents) {
map(implicitEvent.fullResourceInfo) = implicitEvent
}
*/
case class ImplicitlyIssuedResourceEventsWorker(implicitlyIssuedEventsMap: FullMutableResourceTypeMap) {
- def toList: scala.List[ResourceEvent] = {
+ def toList: scala.List[ResourceEventModel] = {
implicitlyIssuedEventsMap.valuesIterator.toList
}
def toImmutableSnapshot(snapshotTime: Long) =
ImplicitlyIssuedResourceEventsSnapshot(toList, snapshotTime)
- def findAndRemoveResourceEvent(resource: String, instanceId: String): Maybe[ResourceEvent] = {
+ def findAndRemoveResourceEvent(resource: String, instanceId: String): Maybe[ResourceEventModel] = {
findAndRemoveFromMap(implicitlyIssuedEventsMap, (resource, instanceId))
}
def size = implicitlyIssuedEventsMap.size
- def foreach[U](f: ResourceEvent => U): Unit = {
+ def foreach[U](f: ResourceEventModel => U): Unit = {
implicitlyIssuedEventsMap.valuesIterator.foreach(f)
}
}
* @param ignoredFirstEvents
* @param snapshotTime
*/
-case class IgnoredFirstResourceEventsSnapshot(ignoredFirstEvents: List[ResourceEvent],
+case class IgnoredFirstResourceEventsSnapshot(ignoredFirstEvents: List[ResourceEventModel],
snapshotTime: Long) extends DataSnapshot {
def toMutableWorker = {
- val map = scala.collection.mutable.Map[ResourceEvent.FullResourceType, ResourceEvent]()
+ val map = scala.collection.mutable.Map[ResourceEventModel.FullResourceType, ResourceEventModel]()
for(ignoredFirstEvent <- ignoredFirstEvents) {
map(ignoredFirstEvent.fullResourceInfo) = ignoredFirstEvent
}
def toImmutableSnapshot(snapshotTime: Long) =
IgnoredFirstResourceEventsSnapshot(ignoredFirstEventsMap.valuesIterator.toList, snapshotTime)
- def findAndRemoveResourceEvent(resource: String, instanceId: String): Maybe[ResourceEvent] = {
+ def findAndRemoveResourceEvent(resource: String, instanceId: String): Maybe[ResourceEventModel] = {
findAndRemoveFromMap(ignoredFirstEventsMap, (resource, instanceId))
}
- def updateResourceEvent(resourceEvent: ResourceEvent): Unit = {
+ def updateResourceEvent(resourceEvent: ResourceEventModel): Unit = {
ignoredFirstEventsMap((resourceEvent.resource, resourceEvent.instanceID)) = resourceEvent
}
def size = ignoredFirstEventsMap.size
- def foreach[U](f: ResourceEvent => U): Unit = {
+ def foreach[U](f: ResourceEventModel => U): Unit = {
ignoredFirstEventsMap.valuesIterator.foreach(f)
}
}
import gr.grnet.aquarium.logic.accounting.Accounting
import gr.grnet.aquarium.logic.accounting.algorithm.CostPolicyAlgorithmCompiler
import gr.grnet.aquarium.AquariumException
-import gr.grnet.aquarium.event.{NewWalletEntry, ResourceEvent}
+import gr.grnet.aquarium.event.{NewWalletEntry}
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
*
}
//+ Utility methods
- def rcDebugInfo(rcEvent: ResourceEvent) = {
+ def rcDebugInfo(rcEvent: ResourceEventModel) = {
rcEvent.toDebugString(false)
}
//- Utility methods
def processResourceEvent(startingUserState: UserState,
userStateWorker: UserStateWorker,
- currentResourceEvent: ResourceEvent,
+ currentResourceEvent: ResourceEventModel,
policyStore: PolicyStore,
stateChangeReason: UserStateChangeReason,
billingMonthInfo: BillingMonthInfo,
_workingUserState
}
- def processResourceEvents(resourceEvents: Traversable[ResourceEvent],
+ def processResourceEvents(resourceEvents: Traversable[ResourceEventModel],
startingUserState: UserState,
userStateWorker: UserStateWorker,
policyStore: PolicyStore,
* @param instanceId
* @return
*/
- def findAndRemovePreviousResourceEvent(resource: String, instanceId: String): Maybe[ResourceEvent] = {
+ def findAndRemovePreviousResourceEvent(resource: String, instanceId: String): Maybe[ResourceEventModel] = {
// implicitly issued events are checked first
implicitlyIssuedStartEvents.findAndRemoveResourceEvent(resource, instanceId) match {
case just @ Just(_) ⇒
}
}
- def updateIgnored(resourceEvent: ResourceEvent): Unit = {
+ def updateIgnored(resourceEvent: ResourceEventModel): Unit = {
ignoredFirstResourceEvents.updateResourceEvent(resourceEvent)
}
- def updatePrevious(resourceEvent: ResourceEvent): Unit = {
+ def updatePrevious(resourceEvent: ResourceEventModel): Unit = {
previousResourceEvents.updateResourceEvent(resourceEvent)
}
- def debugTheMaps(clog: ContextualLogger)(rcDebugInfo: ResourceEvent ⇒ String): Unit = {
+ def debugTheMaps(clog: ContextualLogger)(rcDebugInfo: ResourceEventModel ⇒ String): Unit = {
if(previousResourceEvents.size > 0) {
val map = previousResourceEvents.latestEventsMap.map { case (k, v) => (k, rcDebugInfo(v)) }
clog.debugMap("previousResourceEvents", map, 0)
* @see [[gr.grnet.aquarium.logic.accounting.dsl.DSLCostPolicy]]
*/
def findAndRemoveGeneratorsOfImplicitEndEvents(newOccuredMillis: Long
- ): (List[ResourceEvent], List[ResourceEvent]) = {
- val buffer = mutable.ListBuffer[(ResourceEvent, ResourceEvent)]()
- val checkSet = mutable.Set[ResourceEvent]()
+ ): (List[ResourceEventModel], List[ResourceEventModel]) = {
+ val buffer = mutable.ListBuffer[(ResourceEventModel, ResourceEventModel)]()
+ val checkSet = mutable.Set[ResourceEventModel]()
- def doItFor(map: ResourceEvent.FullMutableResourceTypeMap): Unit = {
+ def doItFor(map: ResourceEventModel.FullMutableResourceTypeMap): Unit = {
val resourceEvents = map.valuesIterator
for {
resourceEvent <- resourceEvents
import akka.amqp._
import util.Random
-import gr.grnet.aquarium.event.ResourceEvent
import scopt.OptionParser
import gr.grnet.aquarium.messaging.AkkaAMQP
import java.lang.StringBuffer
import gr.grnet.aquarium.logic.accounting.Policy
-import gr.grnet.aquarium.store.memory.MemIMEvent
import gr.grnet.aquarium.event.im.{StdIMEvent, IMEventModel}
+import gr.grnet.aquarium.event.resource.{StdResourceEvent, ResourceEventModel}
/**
* Generates random resource events to use as input for testing and
/**
* Get the next random resource event
*/
- def nextResourceEvent() : ResourceEvent = {
+ def nextResourceEvent() : ResourceEventModel = {
val res = rnd.shuffle(resources).head
val extra = res match {
val ts = tsFrom + (scala.math.random * ((tsTo - tsFrom) + 1)).asInstanceOf[Long]
val str = genRndAsciiString(35)
- ResourceEvent(
+ new StdResourceEvent(
CryptoUtils.sha1(str),
ts, ts,
rnd.nextInt(userIds.max).toString,
rnd.nextInt(clientIds.max).toString,
- res, "1", 1.toString, value, extra)
+ res, "1", value, 1.toString, extra)
}
def genRndAsciiString(size: Int): String = {
import java.util.Date
import junit.framework.Assert._
import gr.grnet.aquarium.logic.accounting.{Accounting}
-import gr.grnet.aquarium.event.{WalletEntry, ResourceEvent}
+import gr.grnet.aquarium.event.{WalletEntry}
import com.ckkloverdos.maybe.Just
+import gr.grnet.aquarium.event.resource.StdResourceEvent
/**
* Tests for the methods that do accounting
val agr = dsl.findAgreement("scaledbandwidth").get
//Simple, continuous resource
- var evt = ResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "bandwidthup", "1", "1", 123, Map())
+ var evt = StdResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "bandwidthup", "1", 123, "1", Map())
var wallet = chargeEvent(evt, agr, 112, new Date(1325755902000L), List(), None)
wallet match {
case Just(x) => assertEquals(2, x.size)
}
//Complex resource event without details, should fail
- evt = ResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "vmtime", "1", "1", 1, Map())
+ evt = StdResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "vmtime", "1", 1, "1", Map())
assertFailed[Exception, List[WalletEntry]](chargeEvent(evt, agr, 1, new Date(1325755902000L), List(), None))
//Complex, onoff resource
- evt = ResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "vmtime", "1", "1", 1, Map("vmid" -> "3"))
+ evt = StdResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "vmtime", "1", 1, "1", Map("vmid" -> "3"))
wallet = chargeEvent(evt, agr, 0, new Date(1325755902000L), List(), None)
wallet match {
case Just(x) => assertEquals(2, x.size)
}
//Complex, onoff resource, with wrong states, should fail
- evt = ResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "vmtime", "1", "1", 1, Map("vmid" -> "3"))
+ evt = StdResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "vmtime", "1", 1, "1", Map("vmid" -> "3"))
assertFailed[Exception, List[WalletEntry]](chargeEvent(evt, agr, 1, new Date(1325755902000L), List(), None))
//Simple, discrete resource
- evt = ResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "bookpages", "1", "1", 120, Map())
+ evt = StdResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "bookpages", "1", 120, "1", Map())
wallet = chargeEvent(evt, agr, 15, new Date(1325755902000L), List(), None)
wallet match {
case Just(x) => assertEquals(1, x.size)
}
//Simple, discrete resource, time of last update equal to current event's occurred time
- evt = ResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "bookpages", "1", "1", 120, Map())
+ evt = StdResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "bookpages", "1", 120, "1", Map())
wallet = chargeEvent(evt, agr, 15, new Date(1325762772000L), List(), None)
assertEquals(1, wallet.getOr(List(WalletEntry.zero, WalletEntry.zero)).size)
//Simple, continuous resource, time of last update equal to current event's occurred time
- evt = ResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "bandwidthup", "1", "1", 123, Map())
+ evt = StdResourceEvent("123", 1325762772000L, 1325762774000L, "12", "1", "bandwidthup", "1", 123, "1", Map())
wallet = chargeEvent(evt, agr, 15, new Date(1325762772000L), List(), None)
assertEquals(0, wallet.getOr(List(WalletEntry.zero)).size)
}
import org.junit.Assume._
import gr.grnet.aquarium.Configurator._
import gr.grnet.aquarium.util.{RandomEventGenerator, TestMethods}
-import gr.grnet.aquarium.event.ResourceEvent
import collection.mutable.ArrayBuffer
import org.junit.{After, Test, Before}
import gr.grnet.aquarium.{StoreConfigurator, LogicTestsAssumptions}
import gr.grnet.aquarium.store.memory.MemStore
+import gr.grnet.aquarium.event.resource.ResourceEventModel
/**
* @author Georgios Gousios <gousiosg@gmail.com>
val event = nextResourceEvent()
val store = config.resourceEventStore
- val result = store.storeResourceEvent(event)
+ val result = store.insertResourceEvent(event)
}
@Test
val event = nextResourceEvent()
val store = config.resourceEventStore
- store.storeResourceEvent(event)
+ store.insertResourceEvent(event)
store.findResourceEventById(event.id)
}
@Test
def testfindEventsByUserId(): Unit = {
assumeTrue(LogicTestsAssumptions.EnableStoreTests)
- val events = new ArrayBuffer[ResourceEvent]()
+ val events = new ArrayBuffer[ResourceEventModel]()
val store = config.resourceEventStore
(1 to 100).foreach {
n =>
val e = nextResourceEvent
events += e
- store.storeResourceEvent(e)
+ store.insertResourceEvent(e)
}
val mostUsedId = events