Skip to content

Commit

Permalink
Merge pull request #274 from ie3-institute/sp/#273-simplify-Participa…
Browse files Browse the repository at this point in the history
…ntConfigUtil

Simplifying ParticipantConfigUtil
  • Loading branch information
danielfeismann authored Jul 31, 2022
2 parents a5b7992 + 4629335 commit 7e4efb6
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 318 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update Sphinx to 4.5.0 as well as extensions [#214](https://github.com/ie3-institute/simona/issues/214)
- Improved code quality in and around DBFS algorithm [#265](https://github.com/ie3-institute/simona/issues/265)
- Adapt test to new PowerSystemUtils snapshot [#294](https://github.com/ie3-institute/simona/issues/294)
- Simplified ParticipantConfigUtil [#273](https://github.com/ie3-institute/simona/issues/273)

### Fixed
- Location of `vn_simona` test grid (was partially in Berlin and Dortmund) [#72](https://github.com/ie3-institute/simona/issues/72)
Expand Down
20 changes: 15 additions & 5 deletions src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ class GridAgentController(
case input: FixedFeedInInput =>
buildFixedFeedIn(
input,
participantConfigUtil.getFixedFeedConfigOrDefault(input.getUuid),
participantConfigUtil.getOrDefault[FixedFeedInRuntimeConfig](
input.getUuid
),
environmentRefs.primaryServiceProxy,
simulationStartDate,
simulationEndDate,
Expand All @@ -232,7 +234,9 @@ class GridAgentController(
case input: LoadInput =>
buildLoad(
input,
participantConfigUtil.getLoadConfigOrDefault(input.getUuid),
participantConfigUtil.getOrDefault[LoadRuntimeConfig](
input.getUuid
),
environmentRefs.primaryServiceProxy,
simulationStartDate,
simulationEndDate,
Expand All @@ -243,7 +247,9 @@ class GridAgentController(
case input: PvInput =>
buildPV(
input,
participantConfigUtil.getPvConfigOrDefault(input.getUuid),
participantConfigUtil.getOrDefault[PvRuntimeConfig](
input.getUuid
),
environmentRefs.primaryServiceProxy,
environmentRefs.weather,
simulationStartDate,
Expand All @@ -255,7 +261,9 @@ class GridAgentController(
case input: WecInput =>
buildWec(
input,
participantConfigUtil.getWecConfigOrDefault(input.getUuid),
participantConfigUtil.getOrDefault[WecRuntimeConfig](
input.getUuid
),
environmentRefs.primaryServiceProxy,
environmentRefs.weather,
simulationStartDate,
Expand All @@ -267,7 +275,9 @@ class GridAgentController(
case input: EvcsInput =>
buildEvcs(
input,
participantConfigUtil.getEvcsConfigOrDefault(input.getUuid),
participantConfigUtil.getOrDefault[EvcsRuntimeConfig](
input.getUuid
),
environmentRefs.primaryServiceProxy,
environmentRefs.evDataService.getOrElse(
throw new GridAgentInitializationException(
Expand Down
166 changes: 59 additions & 107 deletions src/main/scala/edu/ie3/simona/util/ConfigUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import edu.ie3.datamodel.io.connectors.{
InfluxDbConnector,
SqlConnector
}

import java.util.{Properties, UUID}
import edu.ie3.datamodel.models.result.connector.{
LineResult,
SwitchResult,
Expand All @@ -30,91 +28,43 @@ import org.apache.kafka.common.KafkaException

import java.io.File
import java.util.concurrent.ExecutionException
import java.util.{Properties, UUID}
import scala.collection.mutable
import scala.jdk.CollectionConverters._
import scala.reflect.ClassTag
import scala.util.{Failure, Success, Try, Using}

object ConfigUtil {

final case class ParticipantConfigUtil private (
private val configs: Map[UUID, SimonaConfig.BaseRuntimeConfig],
private val defaultLoadConfig: LoadRuntimeConfig,
private val defaultFixedFeedInConfig: FixedFeedInRuntimeConfig,
private val defaultPvConfig: PvRuntimeConfig,
private val defaultWecConfig: WecRuntimeConfig,
private val defaultEvcsConfig: EvcsRuntimeConfig
private val defaultConfigs: Map[Class[_], BaseRuntimeConfig]
) {

/** Queries for a [[LoadRuntimeConfig]], that applies for the given uuid and
* either returns the config for the requested uuid or the default config.
* If the requested uuid is valid, but the return type is not of type
* [[LoadRuntimeConfig]] the default config for this type is returned.
*
* @param uuid
* Identifier of the requested load model
* @return
* the requested [[LoadRuntimeConfig]] or a default value
*/
def getLoadConfigOrDefault(uuid: UUID): LoadRuntimeConfig =
configs.get(uuid) match {
case Some(loadConfig: LoadRuntimeConfig) => loadConfig
case _ => defaultLoadConfig
}

/** Queries for a [[PvRuntimeConfig]], that applies for the given uuid and
* either returns the config for the requested uuid or the default config.
* If the requested uuid is valid, but the return type is not of type
* [[PvRuntimeConfig]] the default config for this type is returned.
/** Queries for a [[BaseRuntimeConfig]] of type [[T]], that applies for the
* given uuid and either returns the config for the requested uuid or the
* default config for type [[T]].
*
* @param uuid
* Identifier of the requested load model
* @return
* the requested [[PvRuntimeConfig]] or a default value
* the requested config or a default value of type [[T]]
*/
def getPvConfigOrDefault(uuid: UUID): PvRuntimeConfig =
def getOrDefault[T <: BaseRuntimeConfig](
uuid: UUID
)(implicit tag: ClassTag[T]): T =
configs.get(uuid) match {
case Some(pvRuntimeConfig: PvRuntimeConfig) => pvRuntimeConfig
case _ => defaultPvConfig
}

def getWecConfigOrDefault(uuid: UUID): WecRuntimeConfig =
configs.get(uuid) match {
case Some(wecRuntimeConfig: WecRuntimeConfig) => wecRuntimeConfig
case _ => defaultWecConfig
}

/** Queries for a [[FixedFeedInRuntimeConfig]], that applies for the given
* uuid and either returns the config for the requested uuid or the default
* config. If the requested uuid is valid, but the return type is not of
* type [[FixedFeedInRuntimeConfig]] the default config for this type is
* returned.
*
* @param uuid
* Identifier of the requested fixed feed in model
* @return
* the requested [[FixedFeedInRuntimeConfig]] or a default value
*/
def getFixedFeedConfigOrDefault(uuid: UUID): FixedFeedInRuntimeConfig =
configs.get(uuid) match {
case Some(ffinConfig: FixedFeedInRuntimeConfig) => ffinConfig
case _ => defaultFixedFeedInConfig
case Some(conf: T) => conf
case _ =>
defaultConfigs.get(tag.runtimeClass) match {
case Some(conf: T) => conf
case _ =>
throw new RuntimeException(
s"No config found for $uuid of type ${tag.runtimeClass.getSimpleName}."
)
}
}

/** Queries for a [[EvcsRuntimeConfig]], that applies for the given uuid and
* either returns the config for the requested uuid or the default config.
* If the requested uuid is valid, but the return type is not of type
* [[EvcsRuntimeConfig]] the default config for this type is returned.
*
* @param uuid
* Identifier of the requested Evcs model
* @return
* the requested [[EvcsRuntimeConfig]] or a default value
*/
def getEvcsConfigOrDefault(uuid: UUID): EvcsRuntimeConfig =
configs.get(uuid) match {
case Some(evcsConfig: EvcsRuntimeConfig) => evcsConfig
case _ => defaultEvcsConfig
}
}

object ParticipantConfigUtil {
Expand All @@ -131,24 +81,28 @@ object ConfigUtil {
def apply(
subConfig: SimonaConfig.Simona.Runtime.Participant
): ParticipantConfigUtil = {
new ParticipantConfigUtil(
ParticipantConfigUtil(
buildUuidMapping(
subConfig.load.individualConfigs ++
subConfig.fixedFeedIn.individualConfigs ++
subConfig.pv.individualConfigs ++
subConfig.evcs.individualConfigs ++
Seq(
subConfig.load.individualConfigs,
subConfig.fixedFeedIn.individualConfigs,
subConfig.pv.individualConfigs,
subConfig.evcs.individualConfigs,
subConfig.wec.individualConfigs
).reduceOption(_ ++ _).getOrElse(Seq.empty)
),
subConfig.load.defaultConfig,
subConfig.fixedFeedIn.defaultConfig,
subConfig.pv.defaultConfig,
subConfig.wec.defaultConfig,
subConfig.evcs.defaultConfig
Seq(
subConfig.load.defaultConfig,
subConfig.fixedFeedIn.defaultConfig,
subConfig.pv.defaultConfig,
subConfig.evcs.defaultConfig,
subConfig.wec.defaultConfig
).map { conf => conf.getClass -> conf }.toMap
)
}

private def buildUuidMapping(
configs: List[BaseRuntimeConfig]
configs: Seq[BaseRuntimeConfig]
): Map[UUID, BaseRuntimeConfig] =
configs
.flatMap(modelConfig =>
Expand Down Expand Up @@ -480,33 +434,31 @@ object ConfigUtil {
properties.put("bootstrap.servers", kafkaParams.bootstrapServers)
properties.put("default.api.timeout.ms", 2000)
properties.put("request.timeout.ms", 1000)
try {
Using(AdminClient.create(properties)) { client =>
val existingTopics = client.listTopics.names().get().asScala
topics.filterNot(existingTopics.contains)
} match {
case Failure(ke: KafkaException) =>
throw new InvalidConfigParameterException(
s"Exception creating kafka client for broker ${kafkaParams.bootstrapServers}.",
ke
)
case Failure(ee: ExecutionException) =>
throw new InvalidConfigParameterException(
s"Connection with kafka broker ${kafkaParams.bootstrapServers} failed.",
ee
)
case Failure(other) =>
throw new InvalidConfigParameterException(
s"Checking kafka config failed with unexpected exception.",
other
)
case Success(missingTopics) if missingTopics.nonEmpty =>
throw new InvalidConfigParameterException(
s"Required kafka topics {${missingTopics.mkString}} do not exist."
)
case Success(_) =>
// testing connection succeeded, do nothing
}
Using(AdminClient.create(properties)) { client =>
val existingTopics = client.listTopics.names().get().asScala
topics.filterNot(existingTopics.contains)
} match {
case Failure(ke: KafkaException) =>
throw new InvalidConfigParameterException(
s"Exception creating kafka client for broker ${kafkaParams.bootstrapServers}.",
ke
)
case Failure(ee: ExecutionException) =>
throw new InvalidConfigParameterException(
s"Connection with kafka broker ${kafkaParams.bootstrapServers} failed.",
ee
)
case Failure(other) =>
throw new InvalidConfigParameterException(
s"Checking kafka config failed with unexpected exception.",
other
)
case Success(missingTopics) if missingTopics.nonEmpty =>
throw new InvalidConfigParameterException(
s"Required kafka topics {${missingTopics.mkString}} do not exist."
)
case Success(_) =>
// testing connection succeeded, do nothing
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ class FixedFeedInAgentModelCalculationSpec
private val fixedFeedConfigUtil = ConfigUtil.ParticipantConfigUtil(
simonaConfig.simona.runtime.participant
)
private val modelConfig = fixedFeedConfigUtil.getFixedFeedConfigOrDefault(
voltageSensitiveInput.getUuid
)
private val modelConfig =
fixedFeedConfigUtil.getOrDefault[FixedFeedInRuntimeConfig](
voltageSensitiveInput.getUuid
)
private val services = None
private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ class LoadAgentFixedModelCalculationSpec
private val loadConfigUtil = ConfigUtil.ParticipantConfigUtil(
simonaConfig.simona.runtime.participant
)
private val modelConfig = loadConfigUtil.getLoadConfigOrDefault(
voltageSensitiveInput.getUuid
)
private val modelConfig =
loadConfigUtil.getOrDefault[LoadRuntimeConfig](
voltageSensitiveInput.getUuid
)
private val services = None
private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ class LoadAgentProfileModelCalculationSpec
private val loadConfigUtil = ConfigUtil.ParticipantConfigUtil(
simonaConfig.simona.runtime.participant
)
private val modelConfig = loadConfigUtil.getLoadConfigOrDefault(
voltageSensitiveInput.getUuid
)
private val modelConfig =
loadConfigUtil.getOrDefault[LoadRuntimeConfig](
voltageSensitiveInput.getUuid
)
private val services = None
private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class PVAgentModelCalculationSpec
private val configUtil = ConfigUtil.ParticipantConfigUtil(
simonaConfig.simona.runtime.participant
)
private val modelConfig = configUtil.getPvConfigOrDefault(
private val modelConfig = configUtil.getOrDefault[PvRuntimeConfig](
voltageSensitiveInput.getUuid
)
private val noServices = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ class WecAgentModelCalculationSpec
simonaConfig.simona.runtime.participant
)
private val modelConfig =
configUtil.getWecConfigOrDefault(voltageSensitiveInput.getUuid)
configUtil.getOrDefault[WecRuntimeConfig](
voltageSensitiveInput.getUuid
)

private val withServices = Some(
Vector(ActorWeatherService(weatherService.ref))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package edu.ie3.simona.model.participant

import edu.ie3.simona.config.SimonaConfig
import edu.ie3.simona.config.SimonaConfig.FixedFeedInRuntimeConfig
import edu.ie3.simona.model.participant.control.QControl
import edu.ie3.simona.model.participant.load.{LoadModelBehaviour, LoadReference}
import edu.ie3.simona.test.common.input.FixedFeedInputTestData
Expand Down Expand Up @@ -39,7 +40,7 @@ class FixedFeedInModelSpec
.ParticipantConfigUtil(
simonaConfig.simona.runtime.participant
)
.getFixedFeedConfigOrDefault(fixedFeedInput.getUuid)
.getOrDefault[FixedFeedInRuntimeConfig](fixedFeedInput.getUuid)

val actualModel = FixedFeedInModel.apply(
fixedFeedInput,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ trait EvcsInputTestData extends DefaultTestData with NodeInputTestData {
)

protected val modelConfig: SimonaConfig.EvcsRuntimeConfig =
configUtil.getEvcsConfigOrDefault(
configUtil.getOrDefault[SimonaConfig.EvcsRuntimeConfig](
evcsInputModel.getUuid
)

Expand Down
Loading

0 comments on commit 7e4efb6

Please sign in to comment.