Slash'em high
authorChristos KK Loverdos <loverdos@gmail.com>
Thu, 19 Jul 2012 18:19:58 +0000 (21:19 +0300)
committerChristos KK Loverdos <loverdos@gmail.com>
Thu, 19 Jul 2012 18:19:58 +0000 (21:19 +0300)
26 files changed:
src/main/scala/gr/grnet/aquarium/actor/service/user/UserActor.scala
src/main/scala/gr/grnet/aquarium/charging/ChargingBehavior.scala
src/main/scala/gr/grnet/aquarium/charging/ChargingService.scala
src/main/scala/gr/grnet/aquarium/charging/state/AgreementHistory.scala [moved from src/main/scala/gr/grnet/aquarium/computation/state/parts/AgreementHistory.scala with 88% similarity]
src/main/scala/gr/grnet/aquarium/charging/state/StdUserState.scala
src/main/scala/gr/grnet/aquarium/charging/state/UserStateBootstrap.scala [moved from src/main/scala/gr/grnet/aquarium/computation/state/UserStateBootstrap.scala with 88% similarity]
src/main/scala/gr/grnet/aquarium/charging/state/UserStateModel.scala
src/main/scala/gr/grnet/aquarium/charging/state/WorkingAgreementHistory.scala
src/main/scala/gr/grnet/aquarium/charging/state/WorkingUserState.scala
src/main/scala/gr/grnet/aquarium/computation/state/UserState.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/UserStateWorker.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/IMStateSnapshot.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/IgnoredFirstResourceEventsSnapshot.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/IgnoredFirstResourceEventsWorker.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/ImplicitlyIssuedResourceEventsSnapshot.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/ImplicitlyIssuedResourceEventsWorker.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/LatestResourceEventsSnapshot.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/LatestResourceEventsWorker.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/OwnedResourcesMap.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/OwnedResourcesSnapshot.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/ResourceInstanceAmount.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/RoleHistory.scala [deleted file]
src/main/scala/gr/grnet/aquarium/computation/state/parts/RoleHistoryItem.scala [deleted file]
src/main/scala/gr/grnet/aquarium/store/mongodb/MongoDBStore.scala
src/main/scala/gr/grnet/aquarium/store/mongodb/MongoDBUserState.scala
src/test/scala/gr/grnet/aquarium/user/UserStateComputationsTest.scala

index 7769783..46f5824 100644 (file)
@@ -47,7 +47,7 @@ import gr.grnet.aquarium.actor.message.{GetUserStateResponse, GetUserBalanceResp
 import gr.grnet.aquarium.util.{LogHelpers, shortClassNameOf}
 import gr.grnet.aquarium.AquariumInternalError
 import gr.grnet.aquarium.computation.BillingMonthInfo
-import gr.grnet.aquarium.computation.state.UserStateBootstrap
+import gr.grnet.aquarium.charging.state.UserStateBootstrap
 import gr.grnet.aquarium.charging.state.{WorkingAgreementHistory, WorkingUserState, UserStateModel}
 import gr.grnet.aquarium.charging.reason.{InitialUserActorSetup, RealtimeChargingReason}
 import gr.grnet.aquarium.policy.{PolicyDefinedFullPriceTableRef, StdUserAgreement}
@@ -170,7 +170,7 @@ class UserActor extends ReflectiveRoleableActor {
     }
 
     if(haveAgreements) {
-      DEBUG("Initial %s", this._workingAgreementHistory.toJsonString)
+      DEBUG("Initial agreement history %s", this._workingAgreementHistory.toJsonString)
       logSeparator()
     }
   }
@@ -216,7 +216,7 @@ class UserActor extends ReflectiveRoleableActor {
     // state this._workingAgreementHistory is always the authoritative source.
     if(haveWorkingUserState) {
       this._workingUserState.workingAgreementHistory.setFrom(this._workingAgreementHistory)
-      DEBUG("Computed %s", this._workingUserState.toJsonString)
+      DEBUG("Computed working user state %s", this._workingUserState.toJsonString)
     }
   }
 
@@ -235,7 +235,7 @@ class UserActor extends ReflectiveRoleableActor {
     loadWorkingUserStateAndUpdateAgreementHistory()
 
     if(haveWorkingUserState) {
-      DEBUG("Initial %s", this._workingUserState.toJsonString)
+      DEBUG("Initial working user state %s", this._workingUserState.toJsonString)
       logSeparator()
     }
   }
index 605aa72..462a750 100644 (file)
@@ -46,7 +46,7 @@ import gr.grnet.aquarium.util._
 import gr.grnet.aquarium.util.date.TimeHelpers
 import gr.grnet.aquarium.charging.wallet.WalletEntry
 import gr.grnet.aquarium.computation.{TimeslotComputations, BillingMonthInfo}
-import gr.grnet.aquarium.computation.state.parts.AgreementHistory
+import gr.grnet.aquarium.charging.state.AgreementHistory
 import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
 import gr.grnet.aquarium.store.PolicyStore
 import gr.grnet.aquarium.charging.ChargingBehavior.EnvKeys
@@ -425,9 +425,8 @@ abstract class ChargingBehavior(val alias: String, val inputs: Set[ChargingInput
   }
 
   /**
-   * Given the old amount of a resource instance
-   * (see [[gr.grnet.aquarium.computation.state.parts.ResourceInstanceAmount]]), the
-   * value arriving in a new resource event and the new details, compute the new instance amount.
+   * Given the old amount of a resource instance, the value arriving in a new resource event and the new details,
+   * compute the new instance amount.
    *
    * Note that the `oldAmount` does not make sense for all types of [[gr.grnet.aquarium.charging.ChargingBehavior]],
    * in which case it is ignored.
index 33e1457..7491669 100644 (file)
@@ -37,7 +37,7 @@ package gr.grnet.aquarium.charging
 
 import gr.grnet.aquarium.event.model.resource.ResourceEventModel
 import gr.grnet.aquarium.computation.BillingMonthInfo
-import gr.grnet.aquarium.computation.state.UserStateBootstrap
+import gr.grnet.aquarium.charging.state.UserStateBootstrap
 import gr.grnet.aquarium.policy.ResourceType
 import gr.grnet.aquarium.util.{Lifecycle, Loggable, ContextualLogger}
 import gr.grnet.aquarium.util.date.{MutableDateCalc, TimeHelpers}
  * or implied, of GRNET S.A.
  */
 
-package gr.grnet.aquarium.computation
-package state
-package parts
+package gr.grnet.aquarium.charging.state
 
 import scala.collection.immutable
 import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
 import gr.grnet.aquarium.policy.UserAgreementModel
-import gr.grnet.aquarium.charging.state.WorkingAgreementHistory
 
 /**
  * The whole history of of a user's agreements.
@@ -58,14 +55,6 @@ case class AgreementHistory(agreements: List[UserAgreementModel]) {
   }
 
   /**
-   * Get the user agreement at the specified timestamp
-   */
-  def findForTime(at: Long): Option[UserAgreementModel] = {
-    // FIXME: Refactor and do not make this static call to Policy
-    None
-  }
-
-  /**
    * Returns the first, chronologically, agreement.
    */
   def firstAgreement: Option[UserAgreementModel] = {
@@ -83,7 +72,7 @@ case class AgreementHistory(agreements: List[UserAgreementModel]) {
 object AgreementHistory {
   final val Empty = AgreementHistory(Nil)
 
-  def initial(userAgreement: UserAgreementModel): AgreementHistory ={
+  def initial(userAgreement: UserAgreementModel): AgreementHistory = {
     AgreementHistory(userAgreement :: Nil)
   }
 }
index 0b065c8..990c446 100644 (file)
 package gr.grnet.aquarium.charging.state
 
 import scala.collection.mutable
-import gr.grnet.aquarium.computation.state.UserStateBootstrap
 import gr.grnet.aquarium.policy.{ResourceType, UserAgreementModel}
 import gr.grnet.aquarium.computation.BillingMonthInfo
 import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-import gr.grnet.aquarium.computation.state.parts.{ResourceInstanceAmount, AgreementHistory}
 import gr.grnet.aquarium.charging.wallet.WalletEntry
 import gr.grnet.aquarium.charging.reason.{InitialUserStateSetup, ChargingReason}
 import gr.grnet.aquarium.AquariumInternalError
  * or implied, of GRNET S.A.
  */
 
-package gr.grnet.aquarium.computation.state
+package gr.grnet.aquarium.charging.state
 
 import gr.grnet.aquarium.policy.UserAgreementModel
 
 /**
- * This is used to bootstrap the [[gr.grnet.aquarium.computation.state.UserState]].
+ * This is used to bootstrap the [[gr.grnet.aquarium.charging.state.UserStateModel]].
  *
  * @author Christos KK Loverdos <loverdos@gmail.com>
  */
 
 case class UserStateBootstrap(
-    userID:             String,
+    userID: String,
     userCreationMillis: Long,
-    initialAgreement:   UserAgreementModel,
-    initialCredits:     Double
+    initialAgreement: UserAgreementModel,
+    initialCredits: Double
 )
index 90187e3..a5c40fc 100644 (file)
@@ -38,7 +38,6 @@ package gr.grnet.aquarium.charging.state
 import gr.grnet.aquarium.util.json.JsonSupport
 import gr.grnet.aquarium.computation.BillingMonthInfo
 import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-import gr.grnet.aquarium.computation.state.parts.{ResourceInstanceAmount, AgreementHistory}
 import gr.grnet.aquarium.charging.wallet.WalletEntry
 import gr.grnet.aquarium.charging.reason.ChargingReason
 import gr.grnet.aquarium.policy.ResourceType
@@ -87,6 +86,9 @@ trait UserStateModel extends JsonSupport {
 object UserStateModel {
   trait NamesT {
     final val userID = "userID"
+    final val occurredMillis = "occurredMillis"
+    final val theFullBillingMonth_year = "theFullBillingMonth.year"
+    final val theFullBillingMonth_month = "theFullBillingMonth.month"
   }
 
   object Names extends NamesT
index a397796..2039a25 100644 (file)
@@ -37,7 +37,6 @@ package gr.grnet.aquarium.charging.state
 
 import scala.collection.immutable
 import gr.grnet.aquarium.policy.{PolicyDefinedFullPriceTableRef, StdUserAgreement, UserAgreementModel}
-import gr.grnet.aquarium.computation.state.parts.AgreementHistory
 import gr.grnet.aquarium.util.json.JsonSupport
 
 /**
index 8230faf..90d8083 100644 (file)
 package gr.grnet.aquarium.charging.state
 
 import scala.collection.mutable
-import scala.collection.immutable
-import gr.grnet.aquarium.policy.{UserAgreementModel, ResourceType}
+import gr.grnet.aquarium.policy.ResourceType
 import gr.grnet.aquarium.event.model.resource.ResourceEventModel
 import gr.grnet.aquarium.computation.BillingMonthInfo
 import gr.grnet.aquarium.charging.reason.ChargingReason
 import gr.grnet.aquarium.util.json.JsonSupport
 import gr.grnet.aquarium.charging.ChargingBehavior
 import gr.grnet.aquarium.charging.wallet.WalletEntry
-import gr.grnet.aquarium.computation.state.parts.AgreementHistory
 
 /**
- * A mutable view of the [[gr.grnet.aquarium.computation.state.UserState]], so that intermediate computations are a
- * bit more memory friendly (and probably faster).
+ * A mutable view of the [[gr.grnet.aquarium.charging.state.UserStateModel]].
  *
  * @author Christos KK Loverdos <loverdos@gmail.com>
  */
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/UserState.scala b/src/main/scala/gr/grnet/aquarium/computation/state/UserState.scala
deleted file mode 100644 (file)
index 00b6d25..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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.computation.state
-
-import gr.grnet.aquarium.converter.{JsonTextFormat, StdConverters}
-import gr.grnet.aquarium.charging.wallet.WalletEntry
-import gr.grnet.aquarium.util.json.JsonSupport
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-import gr.grnet.aquarium.computation.BillingMonthInfo
-import gr.grnet.aquarium.computation.parts.RoleHistory
-import gr.grnet.aquarium.computation.state.parts.{OwnedResourcesMap, ResourceInstanceAmount, OwnedResourcesSnapshot, AgreementHistory, ImplicitlyIssuedResourceEventsSnapshot, LatestResourceEventsSnapshot}
-import gr.grnet.aquarium.policy.UserAgreementModel
-import gr.grnet.aquarium.charging.reason.{InitialUserStateSetup, NoSpecificChargingReason, ChargingReason}
-
-/**
- * A comprehensive representation of the User's state.
- *
- * Note that it is made of autonomous parts that are actually parts snapshots.
- *
- * The different snapshots need not agree on the snapshot time, ie. some state
- * part may be stale, while other may be fresh.
- *
- * The user state is meant to be partially updated according to relevant events landing on Aquarium.
- *
- * @define communicatedByIM
- *         This is communicated to Aquarium from the `IM` system.
- *
- *
- * @param userID
- * The user ID. $communicatedByIM
- * @param userCreationMillis
- * When the user was created.
- * $communicatedByIM
- * Set to zero if unknown.
- * @param stateChangeCounter
- * @param isFullBillingMonthState
- * @param theFullBillingMonth
- * @param implicitlyIssuedSnapshot
- * @param latestResourceEventsSnapshot
- * @param billingPeriodOutOfSyncResourceEventsCounter
- * @param agreementHistory
- * @param ownedResourcesSnapshot
- * @param newWalletEntries
- * The wallet entries computed. Not all user states need to holds wallet entries,
- * only those that refer to billing periods (end of billing period).
- * @param lastChangeReason
- * The [[gr.grnet.aquarium.charging.reason.ChargingReason]] for which the usr state has changed.
- * @param parentUserStateIDInStore
- * The `ID` of the parent state. The parent state is the one used as a reference point in order to calculate
- * this user state.
- * @param _id
- * The unique `ID` given by the store.
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-case class UserState(
-    isInitial: Boolean,
-    userID: String,
-
-    userCreationMillis: Long,
-
-    /**
-     * Each time the user state is updated, this must be increased.
-     * The counter is used when accessing user state from the cache (user state store)
-     * in order to get the latest value for a particular billing period.
-     */
-    stateChangeCounter: Long,
-
-    /**
-     * True iff this user state refers to a full billing period, that is a full billing month.
-     */
-    isFullBillingMonthState: Boolean,
-
-    /**
-     * The full billing period for which this user state refers to.
-     * This is set when the user state refers to a full billing period (= month)
-     * and is used to cache the user state for subsequent queries.
-     */
-    theFullBillingMonth: Option[BillingMonthInfo],
-
-    /**
-     * If this is a state for a full billing month, then keep here the implicit OFF
-     * resource events or any other whose cost policy demands an implicit event at the end of the billing period.
-     *
-     * The use case is this: A VM may have been started (ON state) before the end of the billing period
-     * and ended (OFF state) after the beginning of the next billing period. In order to bill this, we must assume
-     * an implicit OFF even right at the end of the billing period and an implicit ON event with the beginning of the
-     * next billing period.
-     */
-    implicitlyIssuedSnapshot: ImplicitlyIssuedResourceEventsSnapshot,
-
-    /**
-     * The latest (previous) resource events per resource instance.
-     */
-    latestResourceEventsSnapshot: LatestResourceEventsSnapshot,
-
-    /**
-     * The out of sync events used to produce this user state for
-     * the billing period recorded by `billingPeriodSnapshot`
-     */
-    billingPeriodOutOfSyncResourceEventsCounter: Long,
-
-    totalCredits: Double,
-
-    roleHistory: RoleHistory,
-
-    agreementHistory: AgreementHistory,
-
-    ownedResourcesSnapshot: OwnedResourcesSnapshot,
-
-    newWalletEntries: List[WalletEntry],
-
-    occurredMillis: Long, // When this user state was computed
-
-    // The last known change reason for this userState
-    lastChangeReason: ChargingReason = NoSpecificChargingReason(),
-    // The user state we used to compute this one. Normally the (cached)
-    // state at the beginning of the billing period.
-    parentUserStateIDInStore: Option[String] = None,
-    _id: String = null
-) extends JsonSupport {
-
-  def idInStore: Option[String] = _id match {
-    case null ⇒ None
-    case _id ⇒ Some(_id.toString)
-  }
-
-  //  def userCreationDate = new Date(userCreationMillis)
-  //
-  //  def userCreationFormatedDate = new MutableDateCalc(userCreationMillis).toString
-
-  def findDSLAgreementForTime(at: Long): Option[UserAgreementModel] = {
-    agreementHistory.findForTime(at)
-  }
-
-  def findResourceInstanceSnapshot(resource: String, instanceId: String): Option[ResourceInstanceAmount] = {
-    ownedResourcesSnapshot.findResourceInstanceSnapshot(resource, instanceId)
-  }
-
-  def getResourceInstanceAmount(resource: String, instanceId: String, defaultValue: Double): Double = {
-    ownedResourcesSnapshot.getResourceInstanceAmount(resource, instanceId, defaultValue)
-  }
-
-  def newWithResourcesSnapshotUpdate(resource: String, // resource name
-                                     instanceId: String, // resource instance id
-                                     newAmount: Double,
-                                     snapshotTime: Long): UserState = {
-
-    val (newResources, _, _) =
-      ownedResourcesSnapshot.computeResourcesSnapshotUpdate(resource, instanceId, newAmount, snapshotTime)
-
-    this.copy(
-      isInitial = false,
-      ownedResourcesSnapshot = newResources,
-      stateChangeCounter = this.stateChangeCounter + 1
-    )
-  }
-
-  def newWithChangeReason(changeReason: ChargingReason) = {
-    this.copy(
-      isInitial = false,
-      lastChangeReason = changeReason,
-      stateChangeCounter = this.stateChangeCounter + 1
-    )
-  }
-
-  def newWithRoleHistory(newRoleHistory: RoleHistory, changeReason: ChargingReason) = {
-    // FIXME: Also update agreement
-    this.copy(
-      isInitial = false,
-      stateChangeCounter = this.stateChangeCounter + 1,
-      roleHistory = newRoleHistory,
-      lastChangeReason = changeReason
-    )
-  }
-
-  def resourcesMap: OwnedResourcesMap = {
-    ownedResourcesSnapshot.toResourcesMap
-  }
-
-  def findLatestResourceEvent: Option[ResourceEventModel] = {
-    latestResourceEventsSnapshot.findTheLatest
-  }
-
-  def findLatestResourceEventID: Option[String] = {
-    latestResourceEventsSnapshot.findTheLatestID
-  }
-
-  def isLatestResourceEventIDEqualTo(toCheckID: String) = {
-    findLatestResourceEventID.map(_ == toCheckID).getOrElse(false)
-  }
-
-  //  def toShortString = "UserState(%s, %s, %s, %s, %s)".format(
-  //    userId,
-  //    _id,
-  //    parentUserStateId,
-  //    totalEventsProcessedCounter,
-  //    calculationReason)
-}
-
-object UserState {
-  def fromJson(json: String): UserState = {
-    StdConverters.AllConverters.convertEx[UserState](JsonTextFormat(json))
-  }
-
-  object JsonNames {
-    final val _id = "_id"
-    final val userID = "userID"
-    final val isFullBillingMonthState = "isFullBillingMonthState"
-    final val occurredMillis = "occurredMillis"
-    final val theFullBillingMonth_year  = "theFullBillingMonth.year"  // FQN
-    final val theFullBillingMonth_month = "theFullBillingMonth.month" // FQN
-
-    object theFullBillingMonth {
-      final val year = "year"
-      final val month = "month"
-    }
-
-  }
-
-  def createInitialUserState(
-      userID: String,
-      userCreationMillis: Long,
-      occurredMillis: Long,
-      totalCredits: Double,
-      initialAgreement: UserAgreementModel,
-      calculationReason: ChargingReason = InitialUserStateSetup(None)
-  ) = {
-
-    UserState(
-      true,
-      userID,
-      userCreationMillis,
-      0L,
-      false,
-      None,
-      ImplicitlyIssuedResourceEventsSnapshot.Empty,
-      LatestResourceEventsSnapshot.Empty,
-      0L,
-      totalCredits,
-      RoleHistory.initial(initialAgreement.role, userCreationMillis),
-      AgreementHistory.initial(initialAgreement),
-      OwnedResourcesSnapshot.Empty,
-      Nil,
-      occurredMillis,
-      calculationReason
-    )
-  }
-
-  def createInitialUserStateFromBootstrap(
-      usb: UserStateBootstrap,
-      occurredMillis: Long,
-      calculationReason: ChargingReason
-  ): UserState = {
-
-    createInitialUserState(
-      usb.userID,
-      usb.userCreationMillis,
-      occurredMillis,
-      usb.initialCredits,
-      usb.initialAgreement,
-      calculationReason
-    )
-  }
-}
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/UserStateWorker.scala b/src/main/scala/gr/grnet/aquarium/computation/state/UserStateWorker.scala
deleted file mode 100644 (file)
index 1b072c5..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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.computation
-package state
-
-import scala.collection.mutable
-import gr.grnet.aquarium.util.ContextualLogger
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-import gr.grnet.aquarium.computation.state.parts.{IgnoredFirstResourceEventsWorker, ImplicitlyIssuedResourceEventsWorker, LatestResourceEventsWorker}
-import gr.grnet.aquarium.policy.ResourceType
-import gr.grnet.aquarium.Aquarium
-
-/**
- * A helper object holding intermediate state/results during resource event processing.
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-case class UserStateWorker(
-    userID: String,
-
-    /**
-     * This is a collection of all the latest resource events.
-     * We want these in order to correlate incoming resource events with their previous (in `occurredMillis` time)
-     * ones. Will be updated on processing the next resource event.
-     */
-    previousResourceEvents: LatestResourceEventsWorker,
-
-    /**
-     * The implicitly issued resource events at the beginning of the billing period.
-     */
-    implicitlyIssuedStartEvents: ImplicitlyIssuedResourceEventsWorker,
-
-    /**
-     * The resource events that were first (and unused) of their kind.
-     */
-    ignoredFirstResourceEvents: IgnoredFirstResourceEventsWorker,
-    resourceTypesMap: Map[String, ResourceType]
-) {
-
-  /**
-   * Finds the previous resource event by checking two possible sources: a) The implicitly terminated resource
-   * events and b) the explicit previous resource events. If the event is found, it is removed from the
-   * respective source.
-   *
-   * If the event is not found, then this must be for a new resource instance.
-   * (and probably then some `zero` resource event must be implied as the previous one)
-   *
-   * @param resource
-   * @param instanceId
-   * @return
-   */
-  def findAndRemovePreviousResourceEvent(resource: String, instanceId: String): Option[ResourceEventModel] = {
-    // implicitly issued events are checked first
-    implicitlyIssuedStartEvents.findAndRemoveResourceEvent(resource, instanceId) match {
-      case some@Some(_) ⇒
-        some
-      case None ⇒
-        // explicit previous resource events are checked second
-        previousResourceEvents.findAndRemoveResourceEvent(resource, instanceId) match {
-          case some@Some(_) ⇒
-            some
-          case _ ⇒
-            None
-        }
-    }
-  }
-
-  def updateIgnored(resourceEvent: ResourceEventModel): Unit = {
-    ignoredFirstResourceEvents.updateResourceEvent(resourceEvent)
-  }
-
-  def updatePrevious(resourceEvent: ResourceEventModel): Unit = {
-    previousResourceEvents.updateResourceEvent(resourceEvent)
-  }
-
-  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)
-    }
-    if(implicitlyIssuedStartEvents.size > 0) {
-      val map = implicitlyIssuedStartEvents.implicitlyIssuedEventsMap.map {
-        case (k, v) => (k, rcDebugInfo(v))
-      }
-      clog.debugMap("implicitlyTerminatedResourceEvents", map, 0)
-    }
-    if(ignoredFirstResourceEvents.size > 0) {
-      val map = ignoredFirstResourceEvents.ignoredFirstEventsMap.map {
-        case (k, v) => (k, rcDebugInfo(v))
-      }
-      clog.debugMap("ignoredFirstResourceEvents", map, 0)
-    }
-  }
-
-  //  private[this]
-  //  def allPreviousAndAllImplicitlyStarted: List[ResourceEvent] = {
-  //    val buffer: FullMutableResourceTypeMap = scala.collection.mutable.Map[FullResourceType, ResourceEvent]()
-  //
-  //    buffer ++= implicitlyIssuedStartEvents.implicitlyIssuedEventsMap
-  //    buffer ++= previousResourceEvents.latestEventsMap
-  //
-  //    buffer.valuesIterator.toList
-  //  }
-
-  /**
-   * Find those events from `implicitlyIssuedStartEvents` and `previousResourceEvents` that will generate implicit
-   * end events along with those implicitly issued events. Before returning, remove the events that generated the
-   * implicit ends from the internal state of this instance.
-   *
-   * @see [[gr.grnet.aquarium.charging.ChargingBehavior]]
-   */
-  def findAndRemoveGeneratorsOfImplicitEndEvents(
-      aquarium: Aquarium,
-      /**
-       * The `occurredMillis` that will be recorded in the synthetic implicit OFFs.
-       * Normally, this will be the end of a billing month.
-       */
-      newOccuredMillis: Long
-  ): (List[ResourceEventModel], List[ResourceEventModel]) = {
-
-    val buffer = mutable.ListBuffer[(ResourceEventModel, ResourceEventModel)]()
-    val checkSet = mutable.Set[ResourceEventModel]()
-
-    def doItFor(map: ResourceEventModel.FullMutableResourceTypeMap): Unit = {
-      val resourceEvents = map.valuesIterator
-      for {
-        resourceEvent ← resourceEvents
-        resourceType ← resourceTypesMap.get(resourceEvent.safeResource)
-        chargingBehavior = aquarium.chargingBehaviorOf(resourceType)
-      } {
-        if(chargingBehavior.supportsImplicitEvents) {
-          if(chargingBehavior.mustConstructImplicitEndEventFor(resourceEvent)) {
-            val implicitEnd = chargingBehavior.constructImplicitEndEventFor(resourceEvent, newOccuredMillis)
-
-            if(!checkSet.contains(resourceEvent)) {
-              checkSet.add(resourceEvent)
-              buffer append ((resourceEvent, implicitEnd))
-            }
-
-            // remove it anyway
-            map.remove((resourceEvent.safeResource, resourceEvent.safeInstanceID))
-          }
-        }
-      }
-    }
-
-    doItFor(previousResourceEvents.latestEventsMap) // we give priority for previous
-    doItFor(implicitlyIssuedStartEvents.implicitlyIssuedEventsMap) // ... over implicitly issued...
-
-    (buffer.view.map(_._1).toList, buffer.view.map(_._2).toList)
-  }
-}
-
-object UserStateWorker {
-  def fromUserState(userState: UserState, resourceTypesMap: Map[String, ResourceType]): UserStateWorker = {
-    UserStateWorker(
-      userState.userID,
-      userState.latestResourceEventsSnapshot.toMutableWorker,
-      userState.implicitlyIssuedSnapshot.toMutableWorker,
-      IgnoredFirstResourceEventsWorker.Empty,
-      resourceTypesMap
-    )
-  }
-}
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/IMStateSnapshot.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/IMStateSnapshot.scala
deleted file mode 100644 (file)
index b4d3193..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-import gr.grnet.aquarium.event.model.im.IMEventModel
-import gr.grnet.aquarium.util.shortClassNameOf
-import gr.grnet.aquarium.util.date.MutableDateCalc
-import gr.grnet.aquarium.computation.parts.RoleHistory
-import gr.grnet.aquarium.util.json.JsonSupport
-
-/**
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-
-case class IMStateSnapshot(
-    /**
-     * This is the latest processed IMEvent
-     */
-    latestIMEvent: IMEventModel,
-
-    /**
-     * The earliest activation time, if it exists.
-     */
-    userEarliestActivationMillis: Option[Long],
-
-    /**
-     * The user creation time, if it exists
-     */
-    userCreationMillis: Option[Long],
-
-    /**
-     * This is the recorded role history
-     */
-    roleHistory: RoleHistory
-) extends JsonSupport {
-
-  /**
-   * True iff the user has ever been activated even once.
-   */
-  def hasBeenActivated: Boolean = {
-    userEarliestActivationMillis.isDefined
-  }
-
-  def hasBeenCreated: Boolean = {
-    userCreationMillis.isDefined
-  }
-
-  /**
-   * Given the newly arrived event, we compute the updated user earliest activation time, if any.
-   * We always update activation time if it is earlier than the currently known activation time.
-   */
-  private[this] def updatedEarliestActivationTime(imEvent: IMEventModel): Option[Long] = {
-    this.userEarliestActivationMillis match {
-      case Some(activationMillis) if imEvent.isStateActive && activationMillis < imEvent.occurredMillis ⇒
-        Some(imEvent.occurredMillis)
-
-      case None if imEvent.isStateActive ⇒
-        Some(imEvent.occurredMillis)
-
-      case other ⇒
-        other
-    }
-  }
-
-  /**
-   * Given the newly arrived event, we compute the updated user creation time, if any.
-   * Only the first `create` event triggers an actual update.
-   */
-  private[this] def updatedCreationTime(imEvent: IMEventModel): Option[Long] = {
-    // Allow only the first `create` event
-    if(this.userCreationMillis.isDefined) {
-      this.userCreationMillis
-    } else if(imEvent.isCreateUser) {
-      Some(imEvent.occurredMillis)
-    } else {
-      None
-    }
-  }
-
-  /**
-   * Given the newly arrived event, we compute the updated role history.
-   */
-  private[this] def updatedRoleHistory(imEvent: IMEventModel): RoleHistory = {
-    this.roleHistory.updatedWithRole(imEvent.role, imEvent.occurredMillis)
-  }
-
-  /**
-   * Computes an updated state and returns a tuple made of four elements:
-   * a) the updated state, b) a `Boolean` indicating whether the user creation
-   * time has changed, c) a `Boolean` indicating whether the user activation
-   * time has changed and d) a `Boolean` indicating whether the user
-   * role history has changed.
-   *
-   * The role history is updated only if the `roleCheck` is not `None` and
-   * the role it represents is different than the role of the `imEvent`.
-   * The motivation for `roleCheck` is to use this method in a loop (as in replaying
-   * events from the [[gr.grnet.aquarium.store.IMEventStore]]).
-   */
-  def updatedWithEvent(imEvent: IMEventModel,
-                       roleCheck: Option[String]): (IMStateSnapshot, Boolean, Boolean, Boolean) = {
-    // Things of interest that may change by the imEvent:
-    // - user creation time
-    // - user activation time
-    // - user role
-
-    val newCreationTime = updatedCreationTime(imEvent)
-    val creationTimeChanged = this.userCreationMillis != newCreationTime
-
-    val newActivationTime = updatedEarliestActivationTime(imEvent)
-    val activationTimeChanged = this.userEarliestActivationMillis != newActivationTime
-
-    val (roleChanged, newRoleHistory) = roleCheck match {
-      case Some(role) if role != imEvent.role ⇒
-        (true, updatedRoleHistory(imEvent))
-
-      case _ ⇒
-        (false, this.roleHistory)
-    }
-
-    val newState = this.copy(
-      latestIMEvent      = imEvent,
-      userCreationMillis = newCreationTime,
-      userEarliestActivationMillis = newActivationTime,
-      roleHistory = newRoleHistory
-    )
-
-    (newState, creationTimeChanged, activationTimeChanged, roleChanged)
-  }
-
-  override def toString = {
-    "%s(\n!! %s\n!! %s\n!! %s\n!! %s)".format(
-      shortClassNameOf(this),
-      latestIMEvent,
-      userCreationMillis.map(new MutableDateCalc(_)),
-      userEarliestActivationMillis.map(new MutableDateCalc(_)),
-      roleHistory
-    )
-  }
-}
-
-object IMStateSnapshot {
-  def initial(imEvent: IMEventModel): IMStateSnapshot = {
-    IMStateSnapshot(
-      imEvent,
-      if(imEvent.isStateActive) Some(imEvent.occurredMillis) else None,
-      if(imEvent.isCreateUser) Some(imEvent.occurredMillis) else None,
-      RoleHistory.initial(imEvent.role, imEvent.occurredMillis))
-  }
-}
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/IgnoredFirstResourceEventsSnapshot.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/IgnoredFirstResourceEventsSnapshot.scala
deleted file mode 100644 (file)
index 285a80e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-
-/**
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-
-case class IgnoredFirstResourceEventsSnapshot(ignoredFirstEvents: List[ResourceEventModel]) {
-  def toMutableWorker = {
-    val map = scala.collection.mutable.Map[ResourceEventModel.ResourceInstance, ResourceEventModel]()
-    for(ignoredFirstEvent <- ignoredFirstEvents) {
-      map(ignoredFirstEvent.safeResourceInstanceInfo) = ignoredFirstEvent
-    }
-
-    IgnoredFirstResourceEventsWorker(map)
-  }
-}
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/IgnoredFirstResourceEventsWorker.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/IgnoredFirstResourceEventsWorker.scala
deleted file mode 100644 (file)
index aaede1a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-import gr.grnet.aquarium.util.findAndRemoveFromMap
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel.FullMutableResourceTypeMap
-
-/**
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-case class IgnoredFirstResourceEventsWorker(ignoredFirstEventsMap: FullMutableResourceTypeMap) {
-  def toImmutableSnapshot(snapshotTime: Long) =
-    IgnoredFirstResourceEventsSnapshot(ignoredFirstEventsMap.valuesIterator.toList)
-
-  def findAndRemoveResourceEvent(resource: String, instanceId: String): Option[ResourceEventModel] = {
-    findAndRemoveFromMap(ignoredFirstEventsMap, (resource, instanceId))
-  }
-
-  def updateResourceEvent(resourceEvent: ResourceEventModel): Unit = {
-    ignoredFirstEventsMap((resourceEvent.resource, resourceEvent.instanceID)) = resourceEvent
-  }
-
-  def size = ignoredFirstEventsMap.size
-
-  def foreach[U](f: ResourceEventModel ⇒ U): Unit = {
-    ignoredFirstEventsMap.valuesIterator.foreach(f)
-  }
-}
-
-object IgnoredFirstResourceEventsWorker {
-  final val Empty = IgnoredFirstResourceEventsWorker(scala.collection.mutable.Map())
-}
\ No newline at end of file
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/ImplicitlyIssuedResourceEventsSnapshot.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/ImplicitlyIssuedResourceEventsSnapshot.scala
deleted file mode 100644 (file)
index 124e320..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-
-/**
- * Keeps the implicit OFF events when a billing period ends.
- * This is normally recorded in the [[gr.grnet.aquarium.computation.state.UserState]].
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-case class ImplicitlyIssuedResourceEventsSnapshot(implicitlyIssuedEvents: List[ResourceEventModel]) {
-  /**
-   * The gateway to playing with mutable state.
-   *
-   * @return A fresh instance of [[gr.grnet.aquarium.computation.state.parts.ImplicitlyIssuedResourceEventsWorker]].
-   */
-  def toMutableWorker = {
-    val map = scala.collection.mutable.Map[ResourceEventModel.ResourceInstance, ResourceEventModel]()
-    for(implicitEvent <- implicitlyIssuedEvents) {
-      map(implicitEvent.safeResourceInstanceInfo) = implicitEvent
-    }
-
-    ImplicitlyIssuedResourceEventsWorker(map)
-  }
-}
-
-object ImplicitlyIssuedResourceEventsSnapshot {
-  final val Empty = ImplicitlyIssuedResourceEventsSnapshot(Nil)
-}
-
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/ImplicitlyIssuedResourceEventsWorker.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/ImplicitlyIssuedResourceEventsWorker.scala
deleted file mode 100644 (file)
index 0c67c9f..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-import gr.grnet.aquarium.util.findAndRemoveFromMap
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel.FullMutableResourceTypeMap
-
-
-/**
- * This is the mutable cousin of [[gr.grnet.aquarium.computation.state.parts.ImplicitlyIssuedResourceEventsSnapshot]].
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-case class ImplicitlyIssuedResourceEventsWorker(implicitlyIssuedEventsMap: FullMutableResourceTypeMap) {
-
-  def toList: scala.List[ResourceEventModel] = {
-    implicitlyIssuedEventsMap.valuesIterator.toList
-  }
-
-  def toImmutableSnapshot(snapshotTime: Long) =
-    ImplicitlyIssuedResourceEventsSnapshot(toList)
-
-  def findAndRemoveResourceEvent(resource: String, instanceId: String): Option[ResourceEventModel] = {
-    findAndRemoveFromMap(implicitlyIssuedEventsMap, (resource, instanceId))
-  }
-
-  def size = implicitlyIssuedEventsMap.size
-
-  def foreach[U](f: ResourceEventModel => U): Unit = {
-    implicitlyIssuedEventsMap.valuesIterator.foreach(f)
-  }
-}
-
-object ImplicitlyIssuedResourceEventsWorker {
-  final val Empty = ImplicitlyIssuedResourceEventsWorker(scala.collection.mutable.Map())
-}
\ No newline at end of file
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/LatestResourceEventsSnapshot.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/LatestResourceEventsSnapshot.scala
deleted file mode 100644 (file)
index eaaebfa..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-
-/**
- * Keeps the latest resource event per resource instance.
- *
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-
-case class LatestResourceEventsSnapshot(resourceEvents: List[ResourceEventModel]) {
-
-  /**
-   * The gateway to playing with mutable state.
-   *
-   * @return A fresh instance of [[gr.grnet.aquarium.computation.state.parts.LatestResourceEventsWorker]].
-   */
-  def toMutableWorker = {
-    val map = scala.collection.mutable.Map[ResourceEventModel.ResourceInstance, ResourceEventModel]()
-    for(latestEvent <- resourceEvents) {
-      map(latestEvent.safeResourceInstanceInfo) = latestEvent
-    }
-    LatestResourceEventsWorker(map)
-  }
-
-  def findTheLatest: Option[ResourceEventModel] = {
-    resourceEvents.sortWith {
-      case (ev1, ev2) ⇒ ev1.occurredMillis <= ev2.occurredMillis
-    }.headOption
-  }
-
-  def findTheLatestID = {
-    findTheLatest.map(_.id)
-  }
-}
-
-object LatestResourceEventsSnapshot {
-  final val Empty = LatestResourceEventsSnapshot(Nil)
-}
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/LatestResourceEventsWorker.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/LatestResourceEventsWorker.scala
deleted file mode 100644 (file)
index fa3594c..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-import gr.grnet.aquarium.util.findAndRemoveFromMap
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-import gr.grnet.aquarium.event.model.resource.ResourceEventModel.FullMutableResourceTypeMap
-
-/**
- * This is the mutable cousin of [[gr.grnet.aquarium.computation.state.parts.LatestResourceEventsSnapshot]].
- *
- * @param latestEventsMap
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-case class LatestResourceEventsWorker(latestEventsMap: FullMutableResourceTypeMap) {
-
-  /**
-   * The gateway to immutable state.
-   *
-   * @param snapshotTime The relevant snapshot time.
-   * @return A fresh instance of [[gr.grnet.aquarium.computation.state.parts.LatestResourceEventsSnapshot]].
-   */
-  def toImmutableSnapshot(snapshotTime: Long) =
-    LatestResourceEventsSnapshot(latestEventsMap.valuesIterator.toList)
-
-  def updateResourceEvent(resourceEvent: ResourceEventModel): Unit = {
-    latestEventsMap((resourceEvent.resource, resourceEvent.instanceID)) = resourceEvent
-  }
-
-  def findResourceEvent(resource: String, instanceId: String): Option[ResourceEventModel] = {
-    latestEventsMap.get((resource, instanceId))
-  }
-
-  def findAndRemoveResourceEvent(resource: String, instanceId: String): Option[ResourceEventModel] = {
-    findAndRemoveFromMap(latestEventsMap, (resource, instanceId))
-  }
-
-  def size = latestEventsMap.size
-
-  def foreach[U](f: ResourceEventModel => U): Unit = {
-    latestEventsMap.valuesIterator.foreach(f)
-  }
-}
-
-object LatestResourceEventsWorker {
-  final val Empty = LatestResourceEventsWorker(scala.collection.mutable.Map())
-
-  /**
-   * Helper factory to construct a worker from a list of events.
-   */
-  def fromList(latestEventsList: List[ResourceEventModel]): LatestResourceEventsWorker = {
-    LatestResourceEventsSnapshot(latestEventsList).toMutableWorker
-  }
-}
-
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/OwnedResourcesMap.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/OwnedResourcesMap.scala
deleted file mode 100644 (file)
index bc91fe6..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-/**
- * A map from (resourceName, resourceInstanceId) to value.
- *
- * This representation is convenient for computations and updating, while the
- * [[gr.grnet.aquarium.computation.state.parts.OwnedResourcesSnapshot]] representation is convenient for JSON
- * serialization.
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-
-class OwnedResourcesMap(resourcesMap: Map[(String, String), Double]) {
-  def toResourcesSnapshot(snapshotTime: Long): OwnedResourcesSnapshot =
-    OwnedResourcesSnapshot(
-      resourcesMap map {
-        case ((name, instanceId), value) ⇒
-          ResourceInstanceAmount(name, instanceId, value) } toList
-    )
-}
\ No newline at end of file
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/OwnedResourcesSnapshot.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/OwnedResourcesSnapshot.scala
deleted file mode 100644 (file)
index 6e024e5..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-/**
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-
-case class OwnedResourcesSnapshot(resourceInstanceSnapshots: List[ResourceInstanceAmount]) {
-
-  def toResourcesMap: OwnedResourcesMap = {
-    val tuples = for(rc <- resourceInstanceSnapshots) yield ((rc.resource, rc.instanceID), (rc.instanceAmount))
-
-    new OwnedResourcesMap(Map(tuples.toSeq: _*))
-  }
-
-  def resourceInstanceSnapshotsExcept(resource: String, instanceId: String) = {
-    // Unfortunately, we have to use a List for parts, since JSON serialization is not as flexible
-    // (at least out of the box). Thus, the update is O(L), where L is the length of the parts List.
-    resourceInstanceSnapshots.filterNot(_.isSameResourceInstance(resource, instanceId))
-  }
-
-  def findResourceInstanceSnapshot(resource: String, instanceId: String): Option[ResourceInstanceAmount] = {
-    resourceInstanceSnapshots.find(x => resource == x.resource && instanceId == x.instanceID)
-  }
-
-  def getResourceInstanceAmount(resource: String, instanceId: String, defaultValue: Double): Double = {
-    findResourceInstanceSnapshot(resource, instanceId).map(_.instanceAmount).getOrElse(defaultValue)
-  }
-
-  def computeResourcesSnapshotUpdate(resource: String,   // resource name
-                                     instanceId: String, // resource instance id
-                                     newAmount: Double,
-                                     snapshotTime: Long): (OwnedResourcesSnapshot,
-                                                          Option[ResourceInstanceAmount],
-    ResourceInstanceAmount) = {
-
-    val newResourceInstance = ResourceInstanceAmount(resource, instanceId, newAmount)
-    val oldResourceInstanceOpt = this.findResourceInstanceSnapshot(resource, instanceId)
-
-    val newResourceInstances = oldResourceInstanceOpt match {
-      case Some(oldResourceInstance) ⇒
-        // Resource instance found, so delete the old one and add the new one
-        newResourceInstance :: resourceInstanceSnapshotsExcept(resource, instanceId)
-
-      case None ⇒
-        // Resource not found, so this is the first time and we just add the new snapshot
-        newResourceInstance :: resourceInstanceSnapshots
-    }
-
-    val newOwnedResources = OwnedResourcesSnapshot(newResourceInstances)
-
-    (newOwnedResources, oldResourceInstanceOpt, newResourceInstance)
- }
-}
-
-object OwnedResourcesSnapshot {
-  final val Empty = OwnedResourcesSnapshot(Nil)
-}
\ No newline at end of file
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/ResourceInstanceAmount.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/ResourceInstanceAmount.scala
deleted file mode 100644 (file)
index 9e55145..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.computation
-package state
-package parts
-
-/**
- * Maintains the current state of a resource instance owned by the user.
- *
- * In order to have a uniform representation of the resource state for all
- * resource types (complex or simple) the following convention applies:
- *
- *  - If the resource is complex, the (name, instanceID) is (DSLResource.name, instance-id)
- *  - If the resource is simple,  the (name, instanceID) is (DSLResource.name, "1")
- *
- * @param resource        Same as `resource` of [[gr.grnet.aquarium.event.model.resource.ResourceEventModel]]
- * @param instanceID      Same as `instanceID` of [[gr.grnet.aquarium.event.model.resource.ResourceEventModel]]
- * @param instanceAmount  This is the amount kept for the resource instance.
-*                         The general rule is that an amount saved in a
- *                        [[gr.grnet.aquarium.computation.parts. ResourceInstanceSnapshot]]
- *                        represents a total value, while a value appearing in a
- *                        [[gr.grnet.aquarium.event .model.resource.ResourceEventModel]]
- *                        represents a difference. How these two values are combined to form the new amount is dictated
- *                        by the underlying [[gr.grnet.aquarium.charging.ChargingBehavior]]
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-case class ResourceInstanceAmount(
-    resource: String,
-    instanceID: String,
-    instanceAmount: Double
-) {
-
-  def isSameResourceInstance(resource: String, instanceId: String) = {
-    this.resource == resource &&
-    this.instanceID == instanceId
-  }
-
-  def toResourceInstanceAmountMapElement = (resource, instanceID) -> this
-}
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/RoleHistory.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/RoleHistory.scala
deleted file mode 100644 (file)
index a7cd961..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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.computation.parts
-
-import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
-import scala.collection.immutable.{TreeMap, SortedMap}
-import scala.collection.mutable.ListBuffer
-import scala.annotation.tailrec
-
-/**
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-
-case class RoleHistory(
-    /**
-     * The head role is the most recent. The same rule applies for the tail.
-     */
-    roles: List[RoleHistoryItem]
-) {
-
-  def roleNamesByTimeslot: SortedMap[Timeslot, String] = {
-    TreeMap(roles.map(role ⇒ (role.timeslot, role.name)): _*)
-  }
-
-  def rolesByTimeslot: SortedMap[Timeslot, RoleHistoryItem] = {
-    TreeMap(roles.map(role ⇒ (role.timeslot, role)): _*)
-  }
-
-  def updatedWithRole(role: String, validFrom: Long) = {
-    // TODO: Review this when Timeslot is also reviewed.
-    //       Currently, we need `fixValidTo` because Timeslot does not validate when `validFrom` and `validTo`
-    //       are equal.
-    def fixValidTo(validFrom: Long, validTo: Long): Long = {
-      if(validTo == validFrom) {
-        // Since validTo is exclusive, make at least 1ms gap
-        validFrom + 1
-      } else {
-        validTo
-      }
-    }
-
-    val newItems = roles match {
-      case Nil ⇒
-        RoleHistoryItem(role, validFrom) :: Nil
-
-      case head :: tail ⇒
-        if(head.startsStrictlyAfter(validFrom)) {
-          // must search history items to find where this fits in
-          @tailrec
-          def check(allChecked: ListBuffer[RoleHistoryItem],
-                    lastCheck: RoleHistoryItem,
-                    toCheck: List[RoleHistoryItem]): List[RoleHistoryItem] = {
-
-            toCheck match {
-              case Nil ⇒
-                allChecked.append(RoleHistoryItem(role, validFrom, fixValidTo(validFrom, lastCheck.validFrom)))
-                allChecked.toList
-
-              case toCheckHead :: toCheckTail ⇒
-                if(toCheckHead.startsStrictlyAfter(validFrom)) {
-                  allChecked.append(toCheckHead)
-
-                  check(allChecked, toCheckHead, toCheckTail)
-                } else {
-                  allChecked.append(RoleHistoryItem(role, validFrom, fixValidTo(validFrom, lastCheck.validFrom)))
-                  allChecked.toList
-                }
-            }
-          }
-
-          val buffer = new ListBuffer[RoleHistoryItem]
-          buffer.append(head)
-          check(buffer, head, tail)
-        } else {
-          // assume head.validTo goes to infinity,
-          RoleHistoryItem(role, validFrom) :: head.copyWithValidTo(fixValidTo(head.validFrom, validFrom)) :: tail
-        }
-    }
-
-    RoleHistory(newItems)
-  }
-
-  /**
-   * Returns the first, chronologically, role.
-   */
-  def firstRole: Option[RoleHistoryItem] = {
-    rolesByTimeslot.valuesIterator.toList.headOption
-  }
-
-  /**
-   * Returns the name of the first, chronologically, role.
-   */
-  def firstRoleName: Option[String] = {
-    roleNamesByTimeslot.valuesIterator.toList.headOption
-  }
-
-  /**
-   * Returns the last, chronologically, role.
-   */
-  def lastRole: Option[RoleHistoryItem] = {
-    rolesByTimeslot.valuesIterator.toList.lastOption
-  }
-
-  /**
-   * Returns the name of the last, chronologically, role.
-   */
-  def lastRoleName: Option[String] = {
-    roleNamesByTimeslot.valuesIterator.toList.lastOption
-  }
-}
-
-object RoleHistory {
-  final val Empty = RoleHistory(Nil)
-
-  def initial(role: String, validFrom: Long): RoleHistory = {
-    RoleHistory(RoleHistoryItem(role, validFrom) :: Nil)
-  }
-}
diff --git a/src/main/scala/gr/grnet/aquarium/computation/state/parts/RoleHistoryItem.scala b/src/main/scala/gr/grnet/aquarium/computation/state/parts/RoleHistoryItem.scala
deleted file mode 100644 (file)
index 59d2344..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.computation.parts
-
-import gr.grnet.aquarium.util.date.MutableDateCalc
-import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
-import gr.grnet.aquarium.Aquarium
-
-/**
- *
- * @author Christos KK Loverdos <loverdos@gmail.com>
- */
-
-case class RoleHistoryItem(
-    /**
-     * The role name.
-     */
-    name: String,
-
-    /**
-     * Validity start time for this role. The time is inclusive.
-     */
-    validFrom: Long,
-
-    /**
-     * Validity stop time for this role. The time is exclusive.
-     */
-    validTo: Long = Long.MaxValue
-) {
-  require(
-    validFrom <= validTo,
-    "validFrom(%s) <= validTo(%s)".format(new MutableDateCalc(validFrom), new MutableDateCalc(validTo)))
-
-  require(name ne null, "Name is not null")
-
-  require(!name.trim.isEmpty, "Name '%s' is not empty".format(name))
-
-  def timeslot = Timeslot(validFrom, validTo)
-
-  def copyWithValidTo(newValidTo: Long) = copy(validTo = newValidTo)
-
-  def isUpperBounded = {
-    validTo != Long.MaxValue
-  }
-
-  def contains(time: Long) = {
-    validFrom <= time && time < validTo
-  }
-
-  def startsStrictlyAfter(time: Long) = {
-    validFrom > time
-  }
-
-  override def toString =
-    "RoleHistoryItem(%s, [%s, %s))".
-      format(name, new MutableDateCalc(validFrom), new MutableDateCalc(validTo))
-}
index 97595a4..630457c 100644 (file)
@@ -47,7 +47,6 @@ import com.mongodb._
 import org.bson.types.ObjectId
 import gr.grnet.aquarium.util._
 import gr.grnet.aquarium.converter.StdConverters
-import gr.grnet.aquarium.computation.state.UserState
 import gr.grnet.aquarium.event.model.ExternalEventModel
 import gr.grnet.aquarium.computation.BillingMonthInfo
 import gr.grnet.aquarium.policy.PolicyModel
@@ -55,7 +54,6 @@ import gr.grnet.aquarium.{Aquarium, AquariumException}
 import collection.immutable.SortedMap
 import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
 import collection.immutable
-import java.util.Date
 import gr.grnet.aquarium.charging.state.UserStateModel
 
 /**
@@ -184,14 +182,14 @@ class MongoDBStore(
 
   def findLatestUserStateForFullMonthBilling(userID: String, bmi: BillingMonthInfo): Option[UserState] = {
     val query = new BasicDBObjectBuilder().
-      add(UserState.JsonNames.userID, userID).
-      add(UserState.JsonNames.isFullBillingMonthState, true).
-      add(UserState.JsonNames.theFullBillingMonth_year, bmi.year).
-      add(UserState.JsonNames.theFullBillingMonth_month, bmi.month).
+      add(UserStateModel.Names.userID, userID).
+//      add(UserStateModel.Names.isFullBillingMonthState, true). FIXME
+      add(UserStateModel.Names.theFullBillingMonth_year, bmi.year).
+      add(UserStateModel.Names.theFullBillingMonth_month, bmi.month).
       get()
 
     // Descending order, so that the latest comes first
-    val sorter = new BasicDBObject(UserState.JsonNames.occurredMillis, -1)
+    val sorter = new BasicDBObject(UserStateModel.Names.occurredMillis, -1)
 
     val cursor = userStates.find(query).sort(sorter)
 
@@ -317,10 +315,10 @@ object MongoDBStore {
   final val RESOURCE_EVENTS_COLLECTION = "resevents"
 
   /**
-   * Collection holding the snapshots of [[gr.grnet.aquarium.computation.state.UserState]].
+   * Collection holding the snapshots of [[gr.grnet.aquarium.charging.state.UserStateModel]].
    *
-   * [[gr.grnet.aquarium.computation.state.UserState]] is held internally within
-   * [[gr.grnet.aquarium.actor.service.user .UserActor]]s.
+   * [[gr.grnet.aquarium.charging.state.UserStateModel]] is held internally within
+   * [[gr.grnet.aquarium.actor.service.user.UserActor]]s.
    */
   final val USER_STATES_COLLECTION = "userstates"
 
@@ -399,25 +397,6 @@ object MongoDBStore {
     }
   }
 
-  def storeUserState(userState: UserState, collection: DBCollection) = {
-    storeAny[UserState](userState, collection, ResourceEventNames.userID, _.userID, MongoDBStore.jsonSupportToDBObject)
-  }
-
-  def storeAny[A](any: A,
-                  collection: DBCollection,
-                  idName: String,
-                  idValueProvider: (A) => String,
-                  serializer: (A) => DBObject) : RecordID = {
-
-    val dbObject = serializer apply any
-    val _id = new ObjectId()
-    dbObject.put("_id", _id)
-    val writeResult = collection.insert(dbObject, WriteConcern.JOURNAL_SAFE)
-    writeResult.getLastError().throwOnError()
-
-    RecordID(dbObject.get("_id").toString)
-  }
-
   def insertObject[A <: AnyRef](obj: A, collection: DBCollection, serializer: A ⇒ DBObject) : A = {
     collection.insert(serializer apply obj, WriteConcern.JOURNAL_SAFE)
     obj
index 23f14e7..a1de9a6 100644 (file)
 
 package gr.grnet.aquarium.store.mongodb
 
-import gr.grnet.aquarium.charging.state.{WorkingUserState, UserStateModel}
+import gr.grnet.aquarium.charging.state.{AgreementHistory, WorkingUserState, UserStateModel}
 import gr.grnet.aquarium.computation.BillingMonthInfo
 import gr.grnet.aquarium.charging.reason.ChargingReason
 import gr.grnet.aquarium.event.model.resource.ResourceEventModel
-import gr.grnet.aquarium.computation.state.parts.AgreementHistory
 import gr.grnet.aquarium.charging.wallet.WalletEntry
 import gr.grnet.aquarium.converter.{JsonTextFormat, StdConverters}
 import gr.grnet.aquarium.policy.ResourceType
index dfd2957..2834534 100644 (file)
@@ -44,11 +44,10 @@ import gr.grnet.aquarium.logic.accounting.algorithm.{ExecutableChargingBehaviorA
 import gr.grnet.aquarium.{Aquarium, ResourceLocator, AquariumBuilder, AquariumException}
 import gr.grnet.aquarium.util.date.MutableDateCalc
 import gr.grnet.aquarium.computation.BillingMonthInfo
-import gr.grnet.aquarium.computation.state.UserState
 import gr.grnet.aquarium.charging._
 import gr.grnet.aquarium.policy.{PolicyDefinedFullPriceTableRef, StdUserAgreement, EffectiveUnitPrice, EffectivePriceTable, FullPriceTable, ResourceType, StdPolicy, PolicyModel}
 import gr.grnet.aquarium.Timespan
-import gr.grnet.aquarium.computation.state.UserStateBootstrap
+import gr.grnet.aquarium.charging.state.UserStateBootstrap
 import gr.grnet.aquarium.charging.reason.{NoSpecificChargingReason, MonthlyBillChargingReason}
 import gr.grnet.aquarium.charging.state.WorkingUserState