Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplifying ParticipantConfigUtil #274

Merged
merged 7 commits into from
Jul 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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