<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
- <version>3.0.1</version>
+ <version>3.1.0</version>
<configuration>
+ <recompileMode>incremental</recompileMode>
+
<charset>${project.build.sourceEncoding}</charset>
<jvmArgs>
<jvmArg>-Xmx1024m</jvmArg>
-{
- "id":"policy-1",
+{ "jsonClass":"gr.grnet.aquarium.policy.StdPolicy",
+
+ "id":"default-policy",
+
"validityTimespan":{
"fromMillis":0,
"toMillis":9223372036854775807
},
- "resourceTypes":[
- {
- "name":"vmtime",
- "unit":"Hr",
- "chargingBehavior":"gr.grnet.aquarium.charging.VMChargingBehavior"
- },
- {
- "name":"diskspace",
- "unit":"MB/Hr",
- "chargingBehavior":"gr.grnet.aquarium.charging.ContinuousChargingBehavior"
- }
- ],
+ "resourceTypes":[{
+ "jsonClass":"gr.grnet.aquarium.policy.ResourceType",
+ "name":"diskspace",
+ "unit":"MB/Hr",
+ "chargingBehavior":"gr.grnet.aquarium.charging.ContinuousChargingBehavior"
+ },{
+ "jsonClass":"gr.grnet.aquarium.policy.ResourceType",
+ "name":"vmtime",
+ "unit":"Hr",
+ "chargingBehavior":"gr.grnet.aquarium.charging.VMChargingBehavior"
+ }],
"chargingBehaviors":[
"gr.grnet.aquarium.charging.VMChargingBehavior",
"roleMapping":{
"default":{
+ "jsonClass":"gr.grnet.aquarium.policy.FullPriceTable",
+
"perResource":{
- "vmtime": { "priceOverrides":[ { "unitPrice":0.01 } ] },
- "diskspace": { "priceOverrides":[ { "unitPrice":0.01 } ] }
+ "diskspace":{
+ "default":{ "jsonClass":"gr.grnet.aquarium.policy.EffectivePriceTable",
+ "priceOverrides":[{ "jsonClass":"gr.grnet.aquarium.policy.EffectiveUnitPrice",
+ "unitPrice":0.01
+ }]
+ }
+ },
+
+ "vmtime":{
+ "powerOn":{ "jsonClass":"gr.grnet.aquarium.policy.EffectivePriceTable",
+ "priceOverrides":[{ "jsonClass":"gr.grnet.aquarium.policy.EffectiveUnitPrice",
+ "unitPrice":0.01
+ }]
+ },
+ "powerOff":{ "jsonClass":"gr.grnet.aquarium.policy.EffectivePriceTable",
+ "priceOverrides":[{ "jsonClass":"gr.grnet.aquarium.policy.EffectiveUnitPrice",
+ "unitPrice":0.0010
+ }]
+ }
+ }
}
}
}
import gr.grnet.aquarium.event.model.resource.ResourceEventModel
import gr.grnet.aquarium.{Aquarium, AquariumInternalError, AquariumException}
-import gr.grnet.aquarium.policy.{UserAgreementModel, ResourceType}
+import gr.grnet.aquarium.policy.{FullPriceTable, EffectivePriceTable, UserAgreementModel, ResourceType}
import com.ckkloverdos.key.{TypedKey, TypedKeySkeleton}
import gr.grnet.aquarium.util._
import gr.grnet.aquarium.util.date.TimeHelpers
referenceTimeslot.to.getTime
)
- val selectorPath = computeSelectorPath(
- chargingData,
- currentResourceEvent,
- referenceTimeslot,
- previousValue,
- totalCredits,
- _oldAccumulatingAmount,
- _newAccumulatingAmount
- )
+ val effectivePriceTableSelector: FullPriceTable ⇒ EffectivePriceTable = fullPriceTable ⇒ {
+ this.selectEffectivePriceTable(
+ fullPriceTable,
+ chargingData,
+ currentResourceEvent,
+ referenceTimeslot,
+ previousValue,
+ totalCredits,
+ _oldAccumulatingAmount,
+ _newAccumulatingAmount
+ )
+ }
val initialChargeslots = TimeslotComputations.computeInitialChargeslots(
referenceTimeslot,
resourceType,
policyByTimeslot,
agreementByTimeslot,
- selectorPath
+ effectivePriceTableSelector
)
val fullChargeslots = initialChargeslots.map {
chargingData(envKey.name) = value
}
+ def selectEffectivePriceTable(
+ fullPriceTable: FullPriceTable,
+ chargingData: mutable.Map[String, Any],
+ currentResourceEvent: ResourceEventModel,
+ referenceTimeslot: Timeslot,
+ previousValue: Double,
+ totalCredits: Double,
+ oldAccumulatingAmount: Double,
+ newAccumulatingAmount: Double
+ ): EffectivePriceTable = {
+
+ val selectorPath = computeSelectorPath(
+ chargingData,
+ currentResourceEvent,
+ referenceTimeslot,
+ previousValue,
+ totalCredits,
+ oldAccumulatingAmount,
+ newAccumulatingAmount
+ )
+
+ fullPriceTable.effectivePriceTableOfSelectorForResource(selectorPath, currentResourceEvent.safeResource)
+ }
+
/**
*
* @param aquarium
import gr.grnet.aquarium.AquariumException
import scala.collection.mutable
import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
+import gr.grnet.aquarium.policy.FullPriceTable
/**
* A charging behavior for which resource events just carry a credit amount that will be added to the total one.
oldAccumulatingAmount: Double,
newAccumulatingAmount: Double
): List[String] = {
- Nil
+ List(FullPriceTable.DefaultSelectorKey)
}
/**
* This is called when we have the very first event for a particular resource instance, and we want to know
import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
import scala.collection.mutable
import VMChargingBehavior.Selectors.Power
+import gr.grnet.aquarium.policy.{FullPriceTable, EffectivePriceTable}
/**
* The new [[gr.grnet.aquarium.charging.ChargingBehavior]] for VMs usage.
policy: PolicyModel,
agreement: UserAgreementModel,
resourceType: ResourceType,
- selectorPath: List[String],
+ effectivePriceTableSelector: FullPriceTable ⇒ EffectivePriceTable,
clogOpt: Option[ContextualLogger] = None
): SortedMap[Timeslot, Double] = {
val clog = ContextualLogger.fromOther(clogOpt, logger, "resolveEffectiveUnitPrices()")
// Note that most of the code is taken from calcChangeChunks()
- val ret = resolveEffectiveUnitPricesForTimeslot(alignedTimeslot, policy, agreement, resourceType, selectorPath)
+ val ret = resolveEffectiveUnitPricesForTimeslot(alignedTimeslot, policy, agreement, resourceType, effectivePriceTableSelector)
ret map {case (t,p) => (t,p.unitPrice)}
}
resourceType: ResourceType,
policyByTimeslot: SortedMap[Timeslot, PolicyModel],
agreementByTimeslot: SortedMap[Timeslot, UserAgreementModel],
- selectorPath: List[String],
+ effectivePriceTableSelector: FullPriceTable ⇒ EffectivePriceTable,
clogOpt: Option[ContextualLogger] = None
): List[Chargeslot] = {
policy,
userAgreement,
resourceType,
- selectorPath,
+ effectivePriceTableSelector,
Some(clog)
)
* Resolves the effective price list for each chunk of the
* provided timeslot and returns it as a Map
*/
- private def resolveEffectiveUnitPricesForTimeslot(
+ private[this] def resolveEffectiveUnitPricesForTimeslot(
alignedTimeslot: Timeslot,
policy: PolicyModel,
agreement: UserAgreementModel,
resourceType: ResourceType,
- selectorPath: List[String]
+ effectivePriceTableSelector: FullPriceTable ⇒ EffectivePriceTable
): PriceMap = {
- val effectivePriceTable = agreement.effectivePriceTableOfResourceTypeForSelector(
- resourceType.name,
- selectorPath,
- policy
- )
+ val fullPriceTable = agreement.computeFullPriceTable(policy)
+ val effectivePriceTable = effectivePriceTableSelector(fullPriceTable)
resolveEffective(alignedTimeslot, effectivePriceTable.priceOverrides)
//immutable.SortedMap(alignedTimeslot -> effectivePriceTable.priceOverrides.head)
import gr.grnet.aquarium.util.{makeString, UTF_8_Charset}
import java.nio.charset.Charset
-import gr.grnet.aquarium.policy.PolicyModel
+import gr.grnet.aquarium.policy.{ResourceType, EffectiveUnitPrice, EffectivePriceTable, FullPriceTable, StdPolicy}
+import gr.grnet.aquarium.charging.state.WorkingUserState
/**
* Provides conversion methods from and to JSON.
* The application-wide JSON formats used from the underlying lift-json library.
*/
// implicit final val Formats = (DefaultFormats ++ JodaTimeSerializers.all)
- implicit final val Formats = (DefaultFormats.withHints(FullTypeHints(List(classOf[AnyRef]))) ++ JodaTimeSerializers.all)
+ final val StdPolicyFormats = Serialization.formats(FullTypeHints(List(
+ // gather here all the "difficult" classes
+
+ // [[PolicyModel]]
+ classOf[StdPolicy],
+ classOf[ResourceType], // It is OK to leave this out
+ classOf[FullPriceTable],
+ classOf[EffectivePriceTable],
+ classOf[EffectiveUnitPrice],
+
+ // [[WorkingUserState]]
+ classOf[WorkingUserState]
+ )))
+ final val JodaFormats = JodaTimeSerializers.all
+// implicit final val Formats = (DefaultFormats.withHints(FullTypeHints(List(classOf[AnyRef]))) ++ JodaTimeSerializers.all)
+ implicit final val Formats: Formats = StdPolicyFormats ++ JodaFormats
// Serialization.formats(FullTypeHints(List(classOf[AnyRef])))
// final val PolicyModelSerializer: Serializer[PolicyModel] = new Serializer[PolicyModel] {
// def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, _root_.net.liftweb.json.JValue), PolicyModel] = {
import java.util.Date
import gr.grnet.aquarium.util.date.MutableDateCalc
import gr.grnet.aquarium.event.model.ExternalEventModel
+import gr.grnet.aquarium.converter.{JsonTextFormat, StdConverters}
+import gr.grnet.aquarium.policy.StdPolicy
/**
* The model of any resource event.
package gr.grnet.aquarium.policy
import gr.grnet.aquarium.{AquariumInternalError, Timespan}
+import gr.grnet.aquarium.charging.ChargingBehavior
/**
*
}
}
- def effectivePriceTableOfResourceTypeForSelector(
- resource: String,
- selectorPath: List[String],
- policy: PolicyModel
- ): EffectivePriceTable = {
-
- val fullPriceTable = this.fullPriceTableRef match {
+ def computeFullPriceTable(policy: PolicyModel): FullPriceTable = {
+ this.fullPriceTableRef match {
case PolicyDefinedFullPriceTableRef ⇒
policy.roleMapping.get(role) match {
case Some(fullPriceTable) ⇒
case AdHocFullPriceTableRef(fullPriceTable) ⇒
fullPriceTable
}
-
- fullPriceTable.effectivePriceTableOfSelectorForResource(selectorPath, resource)
}
}
<logger name="ch.qos.logback" level="DEBUG"/>
- <logger name="com.ckkloverdos" level="DEBUG"/>
+ <logger name="com.ckkloverdos" level="INFO"/>
<logger name="gr.grnet" level="DEBUG"/>
-{
- "id":"3F8A9777-8C12-4529-B8E4-256AD840BEF2",
+{ "jsonClass":"gr.grnet.aquarium.policy.StdPolicy",
+
+ "id":"test-default-policy",
"validityTimespan":{
"fromMillis":0,
"toMillis":9223372036854775807
},
- "resourceTypes":[
- {
- "name":"bandwidth",
- "unit":"MB/Hr",
- "chargingBehavior":"gr.grnet.aquarium.charging.DiscreteChargingBehavior"
- },
- {
- "name":"vmtime",
- "unit":"Hr",
- "chargingBehavior":"gr.grnet.aquarium.charging.VMChargingBehavior"
- },
- {
- "name":"diskspace",
- "unit":"MB/Hr",
- "chargingBehavior":"gr.grnet.aquarium.charging.ContinuousChargingBehavior"
- }
- ],
+ "resourceTypes":[{
+ "jsonClass":"gr.grnet.aquarium.policy.ResourceType",
+ "name":"diskspace",
+ "unit":"MB/Hr",
+ "chargingBehavior":"gr.grnet.aquarium.charging.ContinuousChargingBehavior"
+ },{
+ "jsonClass":"gr.grnet.aquarium.policy.ResourceType",
+ "name":"vmtime",
+ "unit":"Hr",
+ "chargingBehavior":"gr.grnet.aquarium.charging.VMChargingBehavior"
+ }],
"chargingBehaviors":[
- "gr.grnet.aquarium.charging.DiscreteChargingBehavior",
"gr.grnet.aquarium.charging.VMChargingBehavior",
"gr.grnet.aquarium.charging.ContinuousChargingBehavior",
"gr.grnet.aquarium.charging.OnceChargingBehavior"
],
-
+
"roleMapping":{
"default":{
+ "jsonClass":"gr.grnet.aquarium.policy.FullPriceTable",
+
"perResource":{
- "bandwidth":{
- "priceOverrides":[
- {
+ "diskspace":{
+ "default":{ "jsonClass":"gr.grnet.aquarium.policy.EffectivePriceTable",
+ "priceOverrides":[{ "jsonClass":"gr.grnet.aquarium.policy.EffectiveUnitPrice",
"unitPrice":0.01
- }
- ]
+ }]
+ }
},
+
"vmtime":{
- "priceOverrides":[
- {
- "unitPrice":0.01
- }
- ]
- },
- "diskspace":{
- "priceOverrides":[
- {
+ "powerOn":{ "jsonClass":"gr.grnet.aquarium.policy.EffectivePriceTable",
+ "priceOverrides":[{ "jsonClass":"gr.grnet.aquarium.policy.EffectiveUnitPrice",
"unitPrice":0.01
- }
- ]
+ }]
+ },
+ "powerOff":{ "jsonClass":"gr.grnet.aquarium.policy.EffectivePriceTable",
+ "priceOverrides":[{ "jsonClass":"gr.grnet.aquarium.policy.EffectiveUnitPrice",
+ "unitPrice":0.0010
+ }]
+ }
}
}
}
--- /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.model
+
+import org.junit.Test
+import gr.grnet.aquarium.event.model.resource.StdResourceEvent
+
+/**
+ *
+ * @author Christos KK Loverdos <loverdos@gmail.com>
+ */
+
+class StdResourceEventTest {
+ @Test
+ def testJson() {
+ val rc = StdResourceEvent("id-2", 1000L, 1000L, "luv@g.com", "pithos", "disk", "/disk1", 1.0, "1.0", Map())
+ val json = rc.toJsonString
+ val obj = StdResourceEvent.fromJsonString(json)
+
+ assert(rc == obj)
+ }
+}
class StdPolicyTest {
final lazy val policy = StdPolicy(
- id = "policy-1",
+ id = "default-policy",
parentID = None,
validityTimespan = Timespan(0),
@Test
def testJson(): Unit = {
val json = policy.toJsonString
- println(json)
-
val obj = PolicyModel.fromJsonString(json)
+ println(json)
+
assert(policy == obj)
}
}
),
roleMapping = Map(
"default" -> FullPriceTable(Map(
- "bandwidth" -> Map(DefaultSelectorKey -> EffectivePriceTable(EffectiveUnitPrice(0.01) :: Nil)),
"diskspace" -> Map(DefaultSelectorKey -> EffectivePriceTable(EffectiveUnitPrice(0.01) :: Nil)),
"vmtime" -> Map(DefaultSelectorKey -> EffectivePriceTable(EffectiveUnitPrice(0.01) :: Nil))
))