package gr.grnet.aquarium
-import java.io.File
-
-import com.ckkloverdos.maybe._
+import com.ckkloverdos.env.Env
+import com.ckkloverdos.key.{IntKey, StringKey, LongKey, TypedKeySkeleton, TypedKey, BooleanKey}
import com.ckkloverdos.props.Props
-import com.ckkloverdos.convert.Converters.{DefaultConverters => TheDefaultConverters}
-
-import gr.grnet.aquarium.service._
-import gr.grnet.aquarium.util.{Lifecycle, Loggable, shortNameOfClass}
-import gr.grnet.aquarium.store._
-import gr.grnet.aquarium.connector.rabbitmq.service.RabbitMQService
-import gr.grnet.aquarium.converter.StdConverters
-import gr.grnet.aquarium.util.date.TimeHelpers
+import connector.rabbitmq.RabbitMQProducer
+import gr.grnet.aquarium.store.{PolicyStore, StoreProvider}
+import java.io.File
+import gr.grnet.aquarium.util.{Loggable, Lifecycle}
+import gr.grnet.aquarium.service.{StoreWatcherService, RabbitMQService, TimerService, EventBusService, AkkaService}
+import com.ckkloverdos.convert.Converters
import java.util.concurrent.atomic.AtomicBoolean
-import gr.grnet.aquarium.ResourceLocator._
+import org.slf4j.{LoggerFactory, Logger}
+import com.ckkloverdos.maybe._
import com.ckkloverdos.sys.SysProp
+import gr.grnet.aquarium.service.event.AquariumCreatedEvent
+import gr.grnet.aquarium.policy.{FullPriceTable, PolicyModel, CachingPolicyStore, PolicyDefinedFullPriceTableRef, StdUserAgreement, UserAgreementModel, ResourceType}
+import gr.grnet.aquarium.charging.{ChargingService, ChargingBehavior}
+import gr.grnet.aquarium.util.date.TimeHelpers
/**
- * This is the Aquarium entry point.
- *
- * Responsible to load all of application configuration and provide the relevant services.
*
- * @author Christos KK Loverdos <loverdos@gmail.com>.
+ * @author Christos KK Loverdos <loverdos@gmail.com>
*/
-final class Aquarium(val props: Props) extends Lifecycle with Loggable {
- import Aquarium.Keys
- private[this] val _isStopping = new AtomicBoolean(false)
+final class Aquarium(env: Env) extends Lifecycle with Loggable {
+ import Aquarium.EnvKeys
- def isStopping() = _isStopping.get()
+ @volatile private[this] var _chargingBehaviorMap = Map[String, ChargingBehavior]()
- /**
- * Reflectively provide a new instance of a class and configure it appropriately.
- */
- private[this] def newInstance[C : Manifest](_className: String = ""): C = {
- val className = _className match {
- case "" ⇒
- manifest[C].erasure.getName
-
- case name ⇒
- name
- }
+ private[this] lazy val cachingPolicyStore = new CachingPolicyStore(
+ apply(EnvKeys.defaultPolicyModel),
+ apply(EnvKeys.storeProvider).policyStore
+ )
- val instanceM = MaybeEither(defaultClassLoader.loadClass(className).newInstance().asInstanceOf[C])
- instanceM match {
- case Just(instance) ⇒ instance match {
- case configurable: Configurable ⇒
- val localProps = configurable.propertyPrefix match {
- case Some(prefix) ⇒
- props.subsetForKeyPrefix(prefix)
-
- case None ⇒
- props
- }
+ private[this] val _isStopping = new AtomicBoolean(false)
- MaybeEither(configurable configure localProps) match {
- case Just(_) ⇒
- logger.debug("Configured {} with props", configurable.getClass.getName)
- instance
+ override def toString = "%s/v%s".format(getClass.getName, version)
- case Failed(e) ⇒
- throw new AquariumInternalError("Could not configure instance of %s".format(className), e)
- }
+ def isStopping() = _isStopping.get()
- case _ ⇒
- instance
- }
+ @inline
+ def getClientLogger(client: AnyRef): Logger = {
+ client match {
+ case null ⇒
+ this.logger
- case Failed(e) ⇒
- throw new AquariumInternalError("Could not instantiate %s".format(className), e)
+ case _ ⇒
+ LoggerFactory.getLogger(client.getClass)
}
+ }
+ def debug(client: AnyRef, fmt: String, args: Any*) = {
+ getClientLogger(client).debug(fmt.format(args: _*))
}
- private[this] lazy val _actorProvider = newInstance[RoleableActorProviderService](props(Keys.actor_provider_class))
+ def info(client: AnyRef, fmt: String, args: Any*) = {
+ getClientLogger(client).info(fmt.format(args: _*))
+ }
- /**
- * Initializes a store provider, according to the value configured
- * in the configuration file. The
- */
- private[this] lazy val _storeProvider = newInstance[StoreProvider](props(Keys.store_provider_class))
-
- private[this] lazy val _restService = newInstance[Lifecycle](props(Keys.rest_service_class))
-
- private[this] lazy val _userStateStoreM: Maybe[UserStateStore] = {
- // If there is a specific `UserStateStore` implementation specified in the
- // properties, then this implementation overrides the user store given by
- // `StoreProvider`.
- props.get(Keys.user_state_store_class) map { className ⇒
- val instance = newInstance[UserStateStore](className)
- logger.info("Overriding %s provisioning. Implementation given by: %s".format(
- shortNameOfClass(classOf[UserStateStore]),
- instance.getClass))
- instance
- }
+ def warn(client: AnyRef, fmt: String, args: Any*) = {
+ getClientLogger(client).warn(fmt.format(args: _*))
}
- private[this] lazy val _resourceEventStoreM: Maybe[ResourceEventStore] = {
- // If there is a specific `EventStore` implementation specified in the
- // properties, then this implementation overrides the event store given by
- // `StoreProvider`.
- props.get(Keys.resource_event_store_class) map { className ⇒
- val instance = newInstance[ResourceEventStore](className)
- logger.info("Overriding EventStore provisioning. Implementation given by: %s".format(instance.getClass))
- instance
+ @throws(classOf[AquariumInternalError])
+ def apply[T: Manifest](key: TypedKey[T]): T = {
+ try {
+ env.getEx(key)
+ } catch {
+ case e: Exception ⇒
+ throw new AquariumInternalError("Could not locate %s in Aquarium environment".format(key))
}
}
- private[this] lazy val _imEventStoreM: Maybe[IMEventStore] = {
- props.get(Keys.user_event_store_class) map { className ⇒
- val instance = newInstance[IMEventStore](className)
- logger.info("Overriding IMEventStore provisioning. Implementation given by: %s".format(instance.getClass))
- instance
+ private[this] lazy val _allServices = Aquarium.ServiceKeys.map(this.apply(_))
+
+ private[this] def startServices(): Unit = {
+ for(service ← _allServices) {
+ logStartingF(service.toString) {
+ service.start()
+ } {}
}
}
- private[this] lazy val _WalletEventStoreM: Maybe[WalletEntryStore] = {
- // If there is a specific `IMStore` implementation specified in the
- // properties, then this implementation overrides the event store given by
- // `IMProvider`.
- props.get(Keys.wallet_entry_store_class) map {
- className ⇒
- val instance = newInstance[WalletEntryStore](className)
- logger.info("Overriding WalletEntryStore provisioning. Implementation given by: %s".format(instance.getClass))
- instance
+ private[this] def stopServices(): Unit = {
+ val services = _allServices.reverse
+
+ for(service ← services) {
+ logStoppingF(service.toString) {
+ safeUnit(service.stop())
+ } {}
}
}
- private[this] lazy val _policyStoreM: Maybe[PolicyStore] = {
- props.get(Keys.policy_store_class) map {
- className ⇒
- val instance = newInstance[PolicyStore](className)
- logger.info("Overriding PolicyStore provisioning. Implementation given by: %s".format(instance.getClass))
- instance
+ private[this] def showBasicConfiguration(): Unit = {
+ for(folder ← this.eventsStoreFolder) {
+ logger.info("{} = {}", EnvKeys.eventsStoreFolder.name, folder)
}
+ this.eventsStoreFolder.throwMe // on error
+
+ logger.info("default policy = {}", defaultPolicyModel.toJsonString)
}
- private[this] lazy val _eventsStoreFolder: Maybe[File] = {
- props.get(Keys.events_store_folder) map {
- folderName ⇒
- val canonicalFolder = {
- val folder = new File(folderName)
- if(folder.isAbsolute) {
- folder.getCanonicalFile
- } else {
- logger.info("{} is not absolute, making it relative to AQUARIUM_HOME", Keys.events_store_folder)
- new File(ResourceLocator.Homes.Folders.AquariumHome, folderName).getCanonicalFile
- }
+ private[this] def addShutdownHooks(): Unit = {
+ Runtime.getRuntime.addShutdownHook(new Thread(new Runnable {
+ def run = {
+ if(!_isStopping.get()) {
+ logStoppingF("Aquarium") {
+ stop()
+ } {}
}
+ }
+ }))
+ }
- val canonicalPath = canonicalFolder.getCanonicalPath
+ def start(): Unit = {
+ this._isStopping.set(false)
+ showBasicConfiguration()
+ addShutdownHooks()
+ startServices()
+ }
- logger.info("{} = {}", Keys.events_store_folder, canonicalPath)
+ def stop(): Unit = {
+ this._isStopping.set(true)
+ stopServices()
+ }
- if(canonicalFolder.exists() && !canonicalFolder.isDirectory) {
- throw new AquariumInternalError("%s = %s is not a folder".format(Keys.events_store_folder, canonicalFolder))
- }
+ /**
+ * Stops Aquarium after the given millis. Used during testing.
+ */
+ def stopAfterMillis(millis: Long) {
+ Thread sleep millis
+ stop()
+ }
- // Now, events folder must be outside AQUARIUM_HOME, since AQUARIUM_HOME can be wiped out for an upgrade but
- // we still want to keep the events.
- val ahCanonicalPath = ResourceLocator.Homes.Folders.AquariumHome.getCanonicalPath
- if(canonicalPath.startsWith(ahCanonicalPath)) {
- throw new AquariumException(
- "%s = %s is under Aquarium Home = %s".format(
- Keys.events_store_folder,
- canonicalFolder,
- ahCanonicalPath
- ))
- }
+ /**
+ * Reflectively provide a new instance of a class and configure it appropriately.
+ */
+ def newInstance[C <: AnyRef](_class: Class[C]): C = {
+ newInstance(_class.getName)
+ }
- canonicalFolder.mkdirs()
+ /**
+ * Reflectively provide a new instance of a class and configure it appropriately.
+ */
+ def newInstance[C <: AnyRef](className: String): C = {
+ val originalProps = apply(EnvKeys.originalProps)
- canonicalFolder
- }
- }
+ val instanceM = MaybeEither(defaultClassLoader.loadClass(className).newInstance().asInstanceOf[C])
+ instanceM match {
+ case Just(instance) ⇒
+// eventBus.addSubscriber[C](instance)
+ instance match {
+ case aquariumAware: AquariumAware ⇒
+ aquariumAware.awareOfAquarium(AquariumCreatedEvent(this))
- private[this] lazy val _converters = StdConverters.AllConverters
+ case _ ⇒
+ }
- private[this] lazy val _timerService: TimerService = newInstance[SimpleTimerService]()
+ instance match {
+ case configurable: Configurable if (originalProps ne null) ⇒
+ val localProps = configurable.propertyPrefix match {
+ case somePrefix @ Some(prefix) ⇒
+ if(prefix.length == 0) {
+ logger.warn(
+ "Property prefix for %s is %s. Consider using None".format(instance, somePrefix))
+ }
- private[this] lazy val _akka = newInstance[AkkaService]()
+ originalProps.subsetForKeyPrefix(prefix)
- private[this] lazy val _eventBus = newInstance[EventBusService]()
+ case None ⇒
+ originalProps
+ }
- private[this] lazy val _rabbitmqService = newInstance[RabbitMQService]()
+ logger.debug("Configuring {} with props (prefix={})", configurable.getClass.getName, configurable.propertyPrefix)
+ MaybeEither(configurable configure localProps) match {
+ case Just(_) ⇒
+ logger.info("Configured {} with props (prefix={})", configurable.getClass.getName, configurable.propertyPrefix)
- private[this] lazy val _allServices = List(
- _timerService,
- _akka,
- _actorProvider,
- _eventBus,
- _restService,
- _rabbitmqService
- )
+ case Failed(e) ⇒
+ throw new AquariumInternalError("Could not configure instance of %s".format(className), e)
+ }
- def get(key: String, default: String = ""): String = props.getOr(key, default)
+ case _ ⇒
+ }
- def defaultClassLoader = Thread.currentThread().getContextClassLoader
+ instance
- /**
- * FIXME: This must be ditched.
- *
- * Find a file whose location can be overiden in
- * the configuration file (e.g. policy.yaml)
- *
- * @param name Name of the file to search for
- * @param prop Name of the property that defines the file path
- * @param default Name to return if no file is found
- */
- def findConfigFile(name: String, prop: String, default: String): File = {
- // Check for the configured value first
- val configured = new File(get(prop))
- if (configured.exists)
- return configured
-
- // Look into the configuration context
- ResourceLocator.getResource(name) match {
- case Just(policyResource) ⇒
- val path = policyResource.url.getPath
- new File(path)
- case _ ⇒
- new File(default)
+ case Failed(e) ⇒
+ throw new AquariumInternalError("Could not instantiate %s".format(className), e)
}
+
}
- private[this] def startServices(): Unit = {
- for(service ← _allServices) {
- service.start()
+ def currentResourceTypesMap: Map[String, ResourceType] = {
+ val policyOpt = policyStore.loadValidPolicyAt(TimeHelpers.nowMillis())
+ if(policyOpt.isEmpty) {
+ throw new AquariumInternalError("Not even the default policy found")
}
- }
- private[this] def stopServices(): Unit = {
- _allServices.reverse.foreach(service ⇒ safeUnit(service.stop()))
+ policyOpt.get.resourceTypesMap
}
- def stopWithDelay(millis: Long) {
- Thread sleep millis
- stop()
- }
+ def unsafeValidPolicyAt(referenceTimeMillis: Long): PolicyModel = {
+ policyStore.loadValidPolicyAt(referenceTimeMillis) match {
+ case None ⇒
+ throw new AquariumInternalError(
+ "No policy found at %s".format(TimeHelpers.toYYYYMMDDHHMMSSSSS(referenceTimeMillis))
+ )
- private[this] def configure(): Unit = {
- for(folder ← this.eventsStoreFolder) {
- logger.info("{} = {}", Aquarium.Keys.events_store_folder, folder)
+ case Some(policy) ⇒
+ policy
}
- this.eventsStoreFolder.throwMe // on error
+ }
- for(prop ← Aquarium.PropsToShow) {
- logger.info("{} = {}", prop.name, prop.rawValue)
+ def unsafePriceTableForRoleAt(role: String, referenceTimeMillis: Long): FullPriceTable = {
+ val policyAtReferenceTime = unsafeValidPolicyAt(referenceTimeMillis)
+ policyAtReferenceTime.roleMapping.get(role) match {
+ case None ⇒
+ throw new AquariumInternalError("Unknown price table for role %s at %s".format(
+ role,
+ TimeHelpers.toYYYYMMDDHHMMSSSSS(referenceTimeMillis)
+ ))
+
+ case Some(fullPriceTable) ⇒
+ fullPriceTable
}
+ }
- logger.info("Aquarium Home = %s".format(
- if(Homes.Folders.AquariumHome.isAbsolute)
- Homes.Folders.AquariumHome
- else
- "%s [=%s]".format(Homes.Folders.AquariumHome, Homes.Folders.AquariumHome.getCanonicalPath)
- ))
+ /**
+ * Computes the initial user agreement for the given role and reference time. Also,
+ * records the ID from a potential related IMEvent.
+ *
+ * @param role The role in the agreement
+ * @param referenceTimeMillis The reference time to consider for the agreement
+ */
+ def initialUserAgreement(
+ role: String,
+ referenceTimeMillis: Long,
+ relatedIMEventID: Option[String]
+ ): UserAgreementModel = {
+
+ // Just checking
+ assert(null ne unsafePriceTableForRoleAt(role, referenceTimeMillis))
+
+ StdUserAgreement(
+ "<StandardUserAgreement>",
+ relatedIMEventID,
+ 0,
+ Long.MaxValue,
+ role,
+ PolicyDefinedFullPriceTableRef()
+ )
+ }
- logger.info("CONF_HERE = {}", CONF_HERE)
+ def initialUserBalance(role: String, referenceTimeMillis: Long): Double = {
+ // FIXME: Where is the mapping?
+ 0.0
}
- private[this] def addShutdownHooks(): Unit = {
- Runtime.getRuntime.addShutdownHook(new Thread(new Runnable {
- def run = {
- logStopping()
- val (ms0, ms1, _) = TimeHelpers.timed {
- stopServices()
+ def chargingBehaviorOf(resourceType: ResourceType): ChargingBehavior = {
+ // A resource type never changes charging behavior. By definition.
+ val className = resourceType.chargingBehavior
+ _chargingBehaviorMap.get(className) match {
+ case Some(chargingBehavior) ⇒
+ chargingBehavior
+
+ case _ ⇒
+ try {
+ _chargingBehaviorMap synchronized {
+ val chargingBehavior = newInstance[ChargingBehavior](className)
+ _chargingBehaviorMap = _chargingBehaviorMap.updated(className, chargingBehavior)
+ chargingBehavior
+ }
}
- logStopped(ms0, ms1)
- }
- }))
+ catch {
+ case e: Exception ⇒
+ throw new AquariumInternalError("Could not load charging behavior %s".format(className), e)
+ }
+ }
}
- def start() = {
- configure()
- startServices()
- addShutdownHooks()
- }
+ def defaultPolicyModel = apply(EnvKeys.defaultPolicyModel)
- def stop() = {
- this._isStopping.set(true)
- stopServices()
- }
+ def defaultClassLoader = apply(EnvKeys.defaultClassLoader)
- def converters = _converters
-
- def actorProvider = _actorProvider
+ def resourceEventStore = apply(EnvKeys.storeProvider).resourceEventStore
- def eventBus = _eventBus
+ def imEventStore = apply(EnvKeys.storeProvider).imEventStore
- def timerService = _timerService
+ def userStateStore = apply(EnvKeys.storeProvider).userStateStore
- def userStateStore = {
- _userStateStoreM match {
- case Just(us) ⇒ us
- case _ ⇒ storeProvider.userStateStore
- }
- }
+ def policyStore = this.cachingPolicyStore
- def resourceEventStore = {
- _resourceEventStoreM match {
- case Just(es) ⇒ es
- case _ ⇒ storeProvider.resourceEventStore
- }
- }
+ def eventsStoreFolder = apply(EnvKeys.eventsStoreFolder)
- def walletStore = {
- _WalletEventStoreM match {
- case Just(es) ⇒ es
- case _ ⇒ storeProvider.walletEntryStore
- }
- }
+ def eventBus = apply(EnvKeys.eventBus)
- def imEventStore = {
- _imEventStoreM match {
- case Just(es) ⇒ es
- case _ ⇒ storeProvider.imEventStore
- }
- }
+ def chargingService = apply(EnvKeys.chargingService)
- def policyStore = {
- _policyStoreM match {
- case Just(es) ⇒ es
- case _ ⇒ storeProvider.policyStore
- }
- }
+ def userStateTimestampThreshold = apply(EnvKeys.userStateTimestampThreshold)
- def storeProvider = _storeProvider
-
- def withStoreProviderClass[C <: StoreProvider](spc: Class[C]): Aquarium = {
- val map = this.props.map
- val newMap = map.updated(Keys.store_provider_class, spc.getName)
- val newProps = new Props(newMap)
- new Aquarium(newProps)
- }
+ def adminCookie = apply(EnvKeys.adminCookie)
- def eventsStoreFolder = _eventsStoreFolder
+ def converters = apply(EnvKeys.converters)
- def adminCookie: MaybeOption[String] = props.get(Aquarium.Keys.admin_cookie) match {
- case just @ Just(_) ⇒ just
- case _ ⇒ NoVal
- }
+ def saveResourceEventsToEventsStoreFolder = apply(EnvKeys.eventsStoreSaveRCEvents)
+
+ def saveIMEventsToEventsStoreFolder = apply(EnvKeys.eventsStoreSaveIMEvents)
+
+ def timerService = apply(EnvKeys.timerService)
+
+ def restPort = apply(EnvKeys.restPort)
+
+ def akkaService = apply(EnvKeys.akkaService)
+
+ def version = apply(EnvKeys.version)
}
object Aquarium {
SysProp.FileEncoding
)
- implicit val DefaultConverters = TheDefaultConverters
-
- final val PolicyConfName = ResourceLocator.ResourceNames.POLICY_YAML
-
- final val RolesAgreementsName = ResourceLocator.ResourceNames.ROLE_AGREEMENTS_MAP
-
- final lazy val AquariumPropertiesResource = ResourceLocator.Resources.AquariumPropertiesResource
-
- final lazy val AquariumProperties = {
- val maybeProps = Props(AquariumPropertiesResource)
- maybeProps match {
- case Just(props) ⇒
- props
-
- case NoVal ⇒
- throw new AquariumInternalError(
- "Could not load %s from %s".format(
- ResourceLocator.ResourceNames.AQUARIUM_PROPERTIES,
- AquariumPropertiesResource))
-
-
- case Failed(e) ⇒
- throw new AquariumInternalError(
- "Could not load %s from %s".format(
- ResourceLocator.ResourceNames.AQUARIUM_PROPERTIES,
- AquariumPropertiesResource),
- e)
- }
- }
-
- /**
- * The main [[gr.grnet.aquarium.Aquarium]] instance.
- */
- final lazy val Instance = {
- Maybe(new Aquarium(AquariumProperties)) match {
- case Just(masterConf) ⇒
- masterConf
-
- case NoVal ⇒
- throw new AquariumInternalError(
- "Could not create Aquarium configuration from %s".format(
- AquariumPropertiesResource))
+ object HTTP {
+ final val RESTAdminHeaderName = "X-Aquarium-Admin-Cookie"
+ final val RESTAdminHeaderNameLowerCase = RESTAdminHeaderName.toLowerCase
+ }
- case Failed(e) ⇒
- throw new AquariumInternalError(
- "Could not create Aquarium configuration from %s".format(
- AquariumPropertiesResource),
- e)
- }
+ final class AquariumEnvKey[T: Manifest](override val name: String) extends TypedKeySkeleton[T](name) {
+ override def toString = "%s(%s)".format(manifest[T], name)
}
- /**
- * Defines the names of all the known keys inside the master properties file.
- */
- final object Keys {
+ final val ServiceKeys: List[TypedKey[_ <: Lifecycle]] = List(
+ EnvKeys.timerService,
+ EnvKeys.akkaService,
+ EnvKeys.eventBus,
+ EnvKeys.restService,
+ EnvKeys.rabbitMQService,
+ EnvKeys.storeWatcherService
+ )
+ object EnvKeys {
/**
* The Aquarium version. Will be reported in any due occasion.
*/
- final val version = "version"
+ final val version = StringKey("version")
- /**
- * The fully qualified name of the class that implements the `RoleableActorProviderService`.
- * Will be instantiated reflectively and should have a public default constructor.
- */
- final val actor_provider_class = "actor.provider.class"
-
- /**
- * The class that initializes the REST service
- */
- final val rest_service_class = "rest.service.class"
+ final val originalProps: TypedKey[Props] =
+ new AquariumEnvKey[Props]("originalProps")
/**
* The fully qualified name of the class that implements the `StoreProvider`.
* Will be instantiated reflectively and should have a public default constructor.
*/
- final val store_provider_class = "store.provider.class"
-
- /**
- * The class that implements the User store
- */
- final val user_state_store_class = "user.state.store.class"
-
- /**
- * The class that implements the resource event store
- */
- final val resource_event_store_class = "resource.event.store.class"
+ final val storeProvider: TypedKey[StoreProvider] =
+ new AquariumEnvKey[StoreProvider]("store.provider.class")
/**
- * The class that implements the IM event store
- */
- final val user_event_store_class = "user.event.store.class"
-
- /**
- * The class that implements the wallet entries store
- */
- final val wallet_entry_store_class = "wallet.entry.store.class"
-
- /**
- * The class that implements the wallet entries store
- */
- final val policy_store_class = "policy.store.class"
-
-
- /** The lower mark for the UserActors' LRU.
- *
- * The terminology is borrowed from the (also borrowed) Apache-lucene-solr-based implementation.
+ * If a value is given to this property, then it represents a folder where all events coming to aquarium are
+ * saved.
*
+ * This is for debugging purposes.
*/
- final val user_actors_lru_lower_mark = "user.actors.LRU.lower.mark"
+ final val eventsStoreFolder: TypedKey[Option[File]] =
+ new AquariumEnvKey[Option[File]]("events.store.folder")
/**
- * The upper mark for the UserActors' LRU.
+ * If this is `true` and `events.store.folder` is defined, then all resource events are
+ * also stored in `events.store.folder`.
*
- * The terminology is borrowed from the (also borrowed) Apache-lucene-solr-based implementation.
+ * This is for debugging purposes.
*/
- final val user_actors_lru_upper_mark = "user.actors.LRU.upper.mark"
- /**
- * REST service listening port.
- *
- * Default is 8080.
- */
- final val rest_port = "rest.port"
+ final val eventsStoreSaveRCEvents = BooleanKey("events.store.save.rc.events")
/**
- * Location of the Aquarium accounting policy config file
+ * If this is `true` and `events.store.folder` is defined, then all IM events are
+ * also stored in `events.store.folder`.
+ *
+ * This is for debugging purposes.
*/
- final val aquarium_policy = "aquarium.policy"
+ final val eventsStoreSaveIMEvents = BooleanKey("events.store.save.im.events")
/**
- * Location of the role-agreement mapping file
- */
- final val aquarium_role_agreement_map = "aquarium.role-agreement.map"
-
- /**
- * A time period in milliseconds for which we can tolerate stale data regarding user state.
+ * A time period in milliseconds for which we can tolerate stale parts regarding user state.
*
- * The smaller the value, the more accurate the user credits and other state data are.
+ * The smaller the value, the more accurate the user credits and other state parts are.
*
* If a request for user state (e.g. balance) is received and the request timestamp exceeds
* the timestamp of the last known balance amount by this value, then a re-computation for
* the balance is triggered.
*/
- final val user_state_timestamp_threshold = "user.state.timestamp.threshold"
+ final val userStateTimestampThreshold = LongKey("user.state.timestamp.threshold")
/**
- * The time unit is the lowest billable time period.
- * For example, with a time unit of ten seconds, if a VM is started up and shut down in nine
- * seconds, then the user will be billed for ten seconds.
- *
- * This is an overall constant. We use it as a property in order to prepare ourselves for
- * multi-cloud setup, where the same Aquarium instance is used to bill several distinct cloud
- * infrastructures.
+ * REST service listening port.
*/
- final val time_unit_in_millis = "time.unit.in.seconds"
+ final val restPort = IntKey("rest.port")
- /**
- * If a value is given to this property, then it represents a folder where all events coming to aquarium are
- * stored.
- */
- final val events_store_folder = "events.store.folder"
+ final val restShutdownTimeoutMillis = LongKey("rest.shutdown.timeout.millis")
/**
- * If set to `true`, then an IM event that cannot be parsed to [[gr.grnet.aquarium.event.model.im.IMEventModel]] is
- * saved to the [[gr.grnet.aquarium.store.IMEventStore]].
+ * A cookie used in every administrative REST API call, so that Aquarium knows it comes from
+ * an authorised client.
*/
- final val save_unparsed_event_im = "save.unparsed.event.im"
+ final val adminCookie: TypedKey[Option[String]] =
+ new AquariumEnvKey[Option[String]]("admin.cookie")
/**
- * A cookie used in every administrative REST API call, so that Aquarium knows it comes from
- * an authorised client.
+ * The class that initializes the REST service
*/
- final val admin_cookie = "admin.cookie"
- }
+ final val restService: TypedKey[Lifecycle] =
+ new AquariumEnvKey[Lifecycle]("rest.service.class")
- object HTTP {
- final val RESTAdminHeaderName = "X-Aquarium-Admin-Cookie"
- final val RESTAdminHeaderNameLowerCase = RESTAdminHeaderName.toLowerCase
+ final val akkaService: TypedKey[AkkaService] =
+ new AquariumEnvKey[AkkaService]("akka.service")
+
+ final val eventBus: TypedKey[EventBusService] =
+ new AquariumEnvKey[EventBusService]("event.bus.service")
+
+ final val timerService: TypedKey[TimerService] =
+ new AquariumEnvKey[TimerService]("timer.service")
+
+ final val rabbitMQService: TypedKey[RabbitMQService] =
+ new AquariumEnvKey[RabbitMQService]("rabbitmq.service")
+
+ final val rabbitMQProducer: TypedKey[RabbitMQProducer] =
+ new AquariumEnvKey[RabbitMQProducer]("rabbitmq.client")
+
+ final val storeWatcherService: TypedKey[StoreWatcherService] =
+ new AquariumEnvKey[StoreWatcherService]("store.watcher.service")
+
+ final val converters: TypedKey[Converters] =
+ new AquariumEnvKey[Converters]("converters")
+
+ final val chargingService: TypedKey[ChargingService] =
+ new AquariumEnvKey[ChargingService]("charging.service")
+
+ final val defaultClassLoader: TypedKey[ClassLoader] =
+ new AquariumEnvKey[ClassLoader]("default.class.loader")
+
+ final val defaultPolicyModel: TypedKey[PolicyModel] =
+ new AquariumEnvKey[PolicyModel]("default.policy.model")
}
}