diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..53490d4a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,102 @@ +# © 2025. TU Dortmund University, +# Institute of Energy Systems, Energy Efficiency and Energy Economics, +# Research group Distribution grid planning and operation +# + +name: CI + +on: + push: + paths-ignore: + - 'docs/**' + branches: + - main + - dev + - 'hotfix/*' + - 'rel/*' + - 'dependabot/*' + pull_request: + branches: + - main + - dev + +jobs: + buildAndTest: + runs-on: ubuntu-latest + + steps: + - name: Checkout Source + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Check Branch + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + BRANCH_NAME="${{ github.head_ref }}" + else + BRANCH_NAME="${{ github.ref_name }}" + fi + + if [[ "$BRANCH_NAME" == refs/heads/* ]]; then + BRANCH_NAME="${BRANCH_NAME#refs/heads/}" + fi + + export BRANCH_NAME + + echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV + + ./gradlew checkBranchName -PbranchName="$BRANCH_NAME" --warning-mode=none + + bash scripts/branch_type.sh + + - name: Version Check + if: ${{ github.event_name == 'pull_request' }} + env: + BASE_BRANCH: ${{ github.event.pull_request.base.ref }} + run: bash scripts/run-version-check.sh + + - name: Build Project + run: ./gradlew --refresh-dependencies clean assemble spotlessCheck + + - name: Run Tests + run: ./gradlew pmdMain pmdTest test jacocoTestReport jacocoTestCoverageVerification + + - name: Build Java-Docs + run: ./gradlew javadoc + + - name: SonarQube + run: | + ./gradlew sonar \ + -Dsonar.projectKey=${{ vars.SONAR_PROJECT_KEY }} \ + -Dsonar.host.url=${{ vars.SONAR_HOST_URL }} \ + -Dsonar.login=${{ secrets.SONAR_TOKEN }} \ + -Dsonar.qualitygate.wait=true + + #Deployment + - name: Deploy + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' + env: + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.MAVENCENTRAL_SIGNINGKEY }} + ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.MAVENCENTRAL_SIGNINGPASS }} + ORG_GRADLE_PROJECT_user: ${{ secrets.MAVENCENTRAL_USER }} + ORG_GRADLE_PROJECT_password: ${{ secrets.MAVENCENTRAL_PASS }} + run: | + if [ "${GITHUB_REF}" == "refs/heads/main" ]; then + currentVersion=$(./gradlew -q currentVersion) + else + currentVersion=$(./gradlew -q devVersion) + fi + + echo "currentVersion=$currentVersion" + + ./gradlew publish -PdeployVersion=$currentVersion diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 00000000..a9dceb7a --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,24 @@ +name: Dependabot auto-merge +on: pull_request + +permissions: + contents: write + pull-requests: write + +jobs: + dependabot: + runs-on: ubuntu-latest + if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'ie3-institute/simonaAPI' + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@d7267f607e9d3fb96fc2fbe83e0af444713e90b7 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - name: Enable auto-merge for Dependabot PRs + if: steps.metadata.outputs.update-type == 'version-update:semver-patch' + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index ee954f77..eaed6a16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased/Snapshot] +## [0.8.0] - 2025-04-17 + +### Added +- Implementing auto-merge for dependabot PRs [#273](https://github.com/ie3-institute/simonaAPI/issues/273) +- Implemented GitHub Actions pipeline [#247](https://github.com/ie3-institute/simonaAPI/issues/247) + +### Changed +- Converting pekko classic to typed [#232](https://github.com/ie3-institute/simonaAPI/issues/232) + ## [0.7.0] - 2025-03-11 ### Added @@ -56,7 +65,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Renamed messages to ease understanding [#62](https://github.com/ie3-institute/simonaAPI/issues/62) - Separating departures and arrivals in message protocol, properly handling exceptions [#77](https://github.com/ie3-institute/simonaAPI/issues/77) -[Unreleased/Snapshot]: https://github.com/ie3-institute/simonaapi/compare/0.7.0...HEAD +[Unreleased/Snapshot]: https://github.com/ie3-institute/simonaapi/compare/0.8.0...HEAD +[0.8.0]: https://github.com/ie3-institute/powersystemdatamodel/compare/0.7.0...0.8.0 [0.7.0]: https://github.com/ie3-institute/powersystemdatamodel/compare/0.6.0...0.7.0 [0.6.0]: https://github.com/ie3-institute/powersystemdatamodel/compare/0.5.0...0.6.0 [0.5.0]: https://github.com/ie3-institute/powersystemdatamodel/compare/0.4.0...0.5.0 diff --git a/build.gradle b/build.gradle index e2707c9f..77f4e9aa 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,10 @@ plugins { id 'groovy' // groovy support id 'java' // java support - id 'com.diffplug.spotless' version '7.0.2'//code format + id 'com.diffplug.spotless' version '7.0.3'//code format id 'pmd' // code check, working on source code id 'com.github.spotbugs' version '6.1.7' // code check, working on byte code - id "org.sonarqube" version "6.0.1.5171" // sonarqube + id "org.sonarqube" version "6.1.0.5360" // sonarqube id 'signing' id 'maven-publish' // publish to a maven repo (local or mvn central, has to be defined) id 'jacoco' // java code coverage plugin @@ -40,6 +40,7 @@ apply from: scriptsLocation + 'mavenCentralPublish.gradle' apply from: scriptsLocation + 'jacoco.gradle' apply from: scriptsLocation + 'documentation.gradle' apply from: scriptsLocation + 'test.gradle' +apply from: scriptsLocation + 'branchName.gradle' repositories { mavenCentral() @@ -75,8 +76,9 @@ dependencies{ implementation 'org.apache.logging.log4j:log4j-slf4j-impl' // log4j -> slf4j // pekko - implementation "org.apache.pekko:pekko-actor_${scalaVersion}:${pekkoVersion}" - testImplementation "org.apache.pekko:pekko-testkit_${scalaVersion}:${pekkoVersion}" // pekko testkit + implementation "org.apache.pekko:pekko-actor-typed_${scalaVersion}:${pekkoVersion}" + + testImplementation "org.apache.pekko:pekko-actor-testkit-typed_${scalaVersion}:${pekkoVersion}" // pekko typed testkit // TESTING testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' diff --git a/gradle/scripts/branchName.gradle b/gradle/scripts/branchName.gradle new file mode 100644 index 00000000..99ba2c50 --- /dev/null +++ b/gradle/scripts/branchName.gradle @@ -0,0 +1,26 @@ +tasks.register('checkBranchName') { + doLast { + if (!project.hasProperty('branchName')) { + throw new GradleException("Error: Missing required property 'branchName'.") + } + + def branchName = project.property('branchName') + + def patterns = [ + ~/^(developer|develop|dev)$/, + ~/.*rel\/.*/, + ~/^dependabot\/.*$/, + ~/.*hotfix\/\pL{2}\/#\d+.*/, + ~/.*main/, + ~/^[a-z]{2}\/#[0-9]+(?:-.+)?$/ + ] + + def isValid = patterns.any { pattern -> branchName ==~ pattern } + + if (!isValid) { + throw new GradleException("Error: Check Branch name format (e.g., ps/#1337-FeatureName). Current branch name is $branchName.") + } + + println "Branch name is $branchName" + } +} diff --git a/gradle/scripts/semVer.gradle b/gradle/scripts/semVer.gradle index ec680a48..c3300893 100644 --- a/gradle/scripts/semVer.gradle +++ b/gradle/scripts/semVer.gradle @@ -1,13 +1,13 @@ // tasks for semantic versioning using semver-gradle https://github.com/ethauvin/semver-gradle -task currentVersion { - doFirst{ +tasks.register('currentVersion') { + doFirst { println semver.semver } } -task devVersion { - doFirst{ +tasks.register('devVersion') { + doFirst { println "${semver.major}.${semver.minor}-SNAPSHOT" } } diff --git a/scripts/branch_type.sh b/scripts/branch_type.sh new file mode 100755 index 00000000..e1c27248 --- /dev/null +++ b/scripts/branch_type.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ -z "${BRANCH_NAME:-}" ]; then + echo "Error: BRANCH_NAME variable is not set." + exit 1 +fi + + +pattern_dev='^(developer|develop|dev)$' +pattern_release='.*rel/.*' +pattern_dependabot='^dependabot/.*' +pattern_hotfix='.*hotfix/.*' +pattern_main='.*main' +pattern_feature='^[a-z]{2}/#[0-9]+(-.+)?$' + +BRANCH_TYPE="unknown" + +if [[ "$BRANCH_NAME" =~ $pattern_dev ]]; then + BRANCH_TYPE="dev" +elif [[ "$BRANCH_NAME" =~ $pattern_release ]]; then + BRANCH_TYPE="release" +elif [[ "$BRANCH_NAME" =~ $pattern_dependabot ]]; then + BRANCH_TYPE="dependabot" +elif [[ "$BRANCH_NAME" =~ $pattern_hotfix ]]; then + BRANCH_TYPE="hotfix" +elif [[ "$BRANCH_NAME" =~ $pattern_main ]]; then + BRANCH_TYPE="main" +elif [[ "$BRANCH_NAME" =~ $pattern_feature ]]; then + BRANCH_TYPE="feature" +else + echo "Error:'$BRANCH_NAME' does not match any pattern." + exit 1 +fi + +echo "=========================" +echo "Branch type: $BRANCH_TYPE" +echo "BRANCH_TYPE=$BRANCH_TYPE" >> "$GITHUB_ENV" +echo "=========================" diff --git a/scripts/get_versions.sh b/scripts/get_versions.sh new file mode 100755 index 00000000..7001c49d --- /dev/null +++ b/scripts/get_versions.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -euo pipefail + +cd "$(dirname "$0")/.." + +REPO_URL=$(git config --get remote.origin.url) +export REPO_URL +echo "REPO_URL=$REPO_URL" >> $GITHUB_ENV + +echo "Fetching current version of PR..." +PR_VERSION=$(./gradlew -q currentVersion) +echo "PR_VERSION=$PR_VERSION" +echo "export PR_VERSION=$PR_VERSION" >> versions.env +echo "PR_VERSION=$PR_VERSION" >> "$GITHUB_ENV" + +get_branch_version() { + local BRANCH_NAME=$1 + local DIR_NAME="${BRANCH_NAME}-branch" + + git clone --depth 1 --branch "$BRANCH_NAME" "$REPO_URL" "$DIR_NAME" + cd "$DIR_NAME" + + echo "Fetching version from $BRANCH_NAME branch..." + BRANCH_VERSION=$(./gradlew -q currentVersion) + cd .. + + echo "${BRANCH_NAME^^}_VERSION=$BRANCH_VERSION" + echo "export ${BRANCH_NAME^^}_VERSION=$BRANCH_VERSION" >> versions.env + echo "${BRANCH_NAME^^}_VERSION=$BRANCH_VERSION" >> "$GITHUB_ENV" + + rm -rf "$DIR_NAME" +} + + +get_branch_version "dev" +get_branch_version "main" + +echo "Get Versions: OK!" diff --git a/scripts/run-version-check.sh b/scripts/run-version-check.sh new file mode 100755 index 00000000..ebd2bb25 --- /dev/null +++ b/scripts/run-version-check.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -euo pipefail + +rm -f versions.env + +scripts/get_versions.sh + +source versions.env + +scripts/version_check.sh diff --git a/scripts/version_check.sh b/scripts/version_check.sh new file mode 100755 index 00000000..bfa3328c --- /dev/null +++ b/scripts/version_check.sh @@ -0,0 +1,76 @@ +#!/bin/bash +set -euo pipefail + +cd "$(dirname "$0")/.." + +echo "=========================" +echo "LOADED ENV VARIABLES:" +echo "PR_VERSION: $PR_VERSION" +echo "DEV_VERSION: $DEV_VERSION" +echo "MAIN_VERSION: $MAIN_VERSION" +echo "BASE_BRANCH: $BASE_BRANCH" +echo "=========================" + +semver_gt() { + IFS='.' read -r major1 minor1 patch1 <<< "$1" + IFS='.' read -r major2 minor2 patch2 <<< "$2" + + # Compare major version + if [ "$major1" -gt "$major2" ]; then + return 0 + elif [ "$major1" -lt "$major2" ]; then + return 1 + fi + + # Compare minor version + if [ "$minor1" -gt "$minor2" ]; then + return 0 + elif [ "$minor1" -lt "$minor2" ]; then + return 1 + fi + + # Compare patch version + if [ "$patch1" -gt "$patch2" ]; then + return 0 + else + return 1 + fi +} + +# Version Checking Logic +if [ "$BASE_BRANCH" = "dev" ]; then + echo "PR into dev => applying dev rules" + if [ "$DEV_VERSION" = "$PR_VERSION" ]; then + echo "OK: PR version ($PR_VERSION) matches the current dev version ($DEV_VERSION)." + exit 0 + else + if [ "$MAIN_VERSION" = "$DEV_VERSION" ]; then + if semver_gt "$PR_VERSION" "$DEV_VERSION"; then + echo "OK: Increasing working version in dev from $DEV_VERSION to $PR_VERSION" + exit 0 + else + echo "FAIL: Release and working version are $MAIN_VERSION, but PR is not increasing the working version in dev" + exit 1 + fi + else + echo "FAIL: PR version ($PR_VERSION) does not match the current dev version ($DEV_VERSION)." + echo "Regular PRs must not update the working version. The working version should only change in controlled updates." + exit 1 + fi + fi + +elif [ "$BASE_BRANCH" = "main" ]; then + echo "PR into main => applying main rules" + if semver_gt "$PR_VERSION" "$MAIN_VERSION"; then + echo "OK: PR version ($PR_VERSION) is greater than the current main version ($MAIN_VERSION)." + exit 0 + else + echo "FAIL: PR version ($PR_VERSION) is NOT greater than the current main version ($MAIN_VERSION)." + echo "A new release must have a higher version than the existing main version." + exit 1 + fi + +else + echo "Skipping version check: Base branch is '$BASE_BRANCH'. No version enforcement required." + exit 0 +fi diff --git a/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java b/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java index d8a29a75..0a1430b6 100644 --- a/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java +++ b/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java @@ -6,8 +6,14 @@ package edu.ie3.simona.api.data; -import org.apache.pekko.actor.ActorRef; +import edu.ie3.simona.api.data.ontology.DataMessageFromExt; +import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; +import org.apache.pekko.actor.typed.ActorRef; +/** + * Interface for a connection between SIMONA and an external simulation with data flow from external + * to SIMONA. + */ public interface ExtInputDataConnection extends ExtDataConnection { /** @@ -17,5 +23,7 @@ public interface ExtInputDataConnection extends ExtDataConnection { * messages * @param extSimAdapter actor ref to the extSimAdapter */ - void setActorRefs(ActorRef dataService, ActorRef extSimAdapter); + void setActorRefs( + ActorRef dataService, + ActorRef extSimAdapter); } diff --git a/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java b/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java index 6ac15e75..4d9ea51a 100644 --- a/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java +++ b/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java @@ -6,11 +6,13 @@ package edu.ie3.simona.api.data; -import org.apache.pekko.actor.ActorRef; +import edu.ie3.simona.api.data.ontology.DataMessageFromExt; +import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; +import org.apache.pekko.actor.typed.ActorRef; /** * Interface for a connection between SIMONA and an external simulation with data flow from SIMONA - * to external + * to external. */ public interface ExtOutputDataConnection extends ExtDataConnection { @@ -23,5 +25,7 @@ public interface ExtOutputDataConnection extends ExtDataConnection { * @param extSimAdapter actor ref to the extSimAdapter */ void setActorRefs( - ActorRef extResultDataService, ActorRef dataServiceActivation, ActorRef extSimAdapter); + ActorRef extResultDataService, + ActorRef dataServiceActivation, + ActorRef extSimAdapter); } diff --git a/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java b/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java index 5a0bbaa6..6079a2eb 100644 --- a/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java +++ b/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java @@ -11,20 +11,25 @@ import edu.ie3.simona.api.data.ExtInputDataConnection; import edu.ie3.simona.api.data.em.ontology.EmDataMessageFromExt; import edu.ie3.simona.api.data.em.ontology.ProvideEmSetPointData; +import edu.ie3.simona.api.data.ontology.DataMessageFromExt; import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage; -import java.util.*; +import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; import java.util.stream.Collectors; -import org.apache.pekko.actor.ActorRef; +import org.apache.pekko.actor.typed.ActorRef; import org.slf4j.Logger; /** Enables data connection of em data between SIMONA and SimonaAPI */ public class ExtEmDataConnection implements ExtInputDataConnection { /** Actor reference to service that handles ev data within SIMONA */ - private ActorRef emDataService; + private ActorRef emDataService; /** Actor reference to adapter that handles scheduler control flow in SIMONA */ - private ActorRef extSimAdapter; + private ActorRef extSimAdapter; /** Assets that provide primary data to SIMONA */ private final Map extEmMapping; @@ -34,7 +39,9 @@ public ExtEmDataConnection(Map extEmMapping) { } @Override - public void setActorRefs(ActorRef emDataService, ActorRef extSimAdapter) { + public void setActorRefs( + ActorRef emDataService, + ActorRef extSimAdapter) { this.emDataService = emDataService; this.extSimAdapter = extSimAdapter; } @@ -74,8 +81,8 @@ public void provideEmData(Long tick, Map emData, Optional ma * @param msg the data/information that is sent to SIMONA's external primary data service */ public void sendExtMsg(EmDataMessageFromExt msg) { - emDataService.tell(msg, ActorRef.noSender()); + emDataService.tell(msg); // we need to schedule data receiver activation with scheduler - extSimAdapter.tell(new ScheduleDataServiceMessage(emDataService), ActorRef.noSender()); + extSimAdapter.tell(new ScheduleDataServiceMessage(emDataService)); } } diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java b/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java index 53a71e87..564a87ad 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java +++ b/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java @@ -9,13 +9,15 @@ import edu.ie3.simona.api.data.ExtInputDataConnection; import edu.ie3.simona.api.data.ev.model.EvModel; import edu.ie3.simona.api.data.ev.ontology.*; +import edu.ie3.simona.api.data.ontology.DataMessageFromExt; import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage; +import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.LinkedBlockingQueue; -import org.apache.pekko.actor.ActorRef; +import org.apache.pekko.actor.typed.ActorRef; public class ExtEvDataConnection implements ExtInputDataConnection { /** Data message queue containing messages from SIMONA */ @@ -23,13 +25,15 @@ public class ExtEvDataConnection implements ExtInputDataConnection { new LinkedBlockingQueue<>(); /** Actor reference to service that handles ev data within SIMONA */ - private ActorRef dataService; + private ActorRef dataService; /** Actor reference to adapter that handles scheduler control flow in SIMONA */ - private ActorRef extSimAdapter; + private ActorRef extSimAdapter; @Override - public void setActorRefs(ActorRef dataService, ActorRef extSimAdapter) { + public void setActorRefs( + ActorRef dataService, + ActorRef extSimAdapter) { this.dataService = dataService; this.extSimAdapter = extSimAdapter; } @@ -99,9 +103,9 @@ public void provideArrivingEvs(Map> arrivals, Optional * @param msg the data/information that is sent to SIMONA's ev data service */ public void sendExtMsg(EvDataMessageFromExt msg) { - dataService.tell(msg, ActorRef.noSender()); + dataService.tell(msg); // we need to schedule data receiver activation with scheduler - extSimAdapter.tell(new ScheduleDataServiceMessage(dataService), ActorRef.noSender()); + extSimAdapter.tell(new ScheduleDataServiceMessage(dataService)); } /** diff --git a/src/main/java/edu/ie3/simona/api/data/ontology/ScheduleDataServiceMessage.java b/src/main/java/edu/ie3/simona/api/data/ontology/ScheduleDataServiceMessage.java index 903e5e03..029b840d 100644 --- a/src/main/java/edu/ie3/simona/api/data/ontology/ScheduleDataServiceMessage.java +++ b/src/main/java/edu/ie3/simona/api/data/ontology/ScheduleDataServiceMessage.java @@ -6,30 +6,8 @@ package edu.ie3.simona.api.data.ontology; -import java.util.Objects; -import org.apache.pekko.actor.ActorRef; +import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; +import org.apache.pekko.actor.typed.ActorRef; -public class ScheduleDataServiceMessage { - private final ActorRef dataService; - - public ScheduleDataServiceMessage(ActorRef dataService) { - this.dataService = dataService; - } - - public ActorRef getDataService() { - return dataService; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ScheduleDataServiceMessage that = (ScheduleDataServiceMessage) o; - return dataService.equals(that.dataService); - } - - @Override - public int hashCode() { - return Objects.hash(dataService); - } -} +public record ScheduleDataServiceMessage(ActorRef dataService) + implements ControlResponseMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java b/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java index 10fe1842..ce03e274 100644 --- a/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java +++ b/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java @@ -8,22 +8,27 @@ import edu.ie3.datamodel.models.value.Value; import edu.ie3.simona.api.data.ExtInputDataConnection; +import edu.ie3.simona.api.data.ontology.DataMessageFromExt; import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage; import edu.ie3.simona.api.data.primarydata.ontology.PrimaryDataMessageFromExt; import edu.ie3.simona.api.data.primarydata.ontology.ProvidePrimaryData; -import java.util.*; +import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; import java.util.stream.Collectors; -import org.apache.pekko.actor.ActorRef; +import org.apache.pekko.actor.typed.ActorRef; import org.slf4j.Logger; /** Enables data connection of primary data between SIMONA and SimonaAPI */ public class ExtPrimaryDataConnection implements ExtInputDataConnection { /** Actor reference to service that handles primary data within SIMONA */ - private ActorRef dataService; + private ActorRef dataService; /** Actor reference to adapter that handles scheduler control flow in SIMONA */ - private ActorRef extSimAdapter; + private ActorRef extSimAdapter; /** Assets that provide primary data to SIMONA */ private final Map extPrimaryDataMapping; @@ -33,7 +38,9 @@ public ExtPrimaryDataConnection(Map extPrimaryDataMapping) { } @Override - public void setActorRefs(ActorRef dataService, ActorRef extSimAdapter) { + public void setActorRefs( + ActorRef dataService, + ActorRef extSimAdapter) { this.dataService = dataService; this.extSimAdapter = extSimAdapter; } @@ -74,8 +81,8 @@ public void providePrimaryData( * @param msg the data/information that is sent to SIMONA's external primary data service */ public void sendExtMsg(PrimaryDataMessageFromExt msg) { - dataService.tell(msg, ActorRef.noSender()); + dataService.tell(msg); // we need to schedule data receiver activation with scheduler - extSimAdapter.tell(new ScheduleDataServiceMessage(dataService), ActorRef.noSender()); + extSimAdapter.tell(new ScheduleDataServiceMessage(dataService)); } } diff --git a/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java b/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java index a5414e26..3a93a7f2 100644 --- a/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java +++ b/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java @@ -10,17 +10,19 @@ import edu.ie3.datamodel.models.result.ResultEntity; import edu.ie3.datamodel.models.result.system.SystemParticipantResult; import edu.ie3.simona.api.data.ExtOutputDataConnection; +import edu.ie3.simona.api.data.ontology.DataMessageFromExt; import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage; import edu.ie3.simona.api.data.results.ontology.ProvideResultEntities; import edu.ie3.simona.api.data.results.ontology.RequestResultEntities; import edu.ie3.simona.api.data.results.ontology.ResultDataMessageFromExt; import edu.ie3.simona.api.data.results.ontology.ResultDataResponseMessageToExt; +import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.LinkedBlockingQueue; -import org.apache.pekko.actor.ActorRef; +import org.apache.pekko.actor.typed.ActorRef; /** Enables data connection of results between SIMONA and SimonaAPI */ public class ExtResultDataConnection implements ExtOutputDataConnection { @@ -30,13 +32,13 @@ public class ExtResultDataConnection implements ExtOutputDataConnection { new LinkedBlockingQueue<>(); /** Actor reference to service that handles result data within SIMONA */ - private ActorRef extResultDataService; + private ActorRef extResultDataService; /** Actor reference to the dataServiceAdapter */ - private ActorRef dataServiceActivation; + private ActorRef dataServiceActivation; /** Actor reference to adapter that handles scheduler control flow in SIMONA */ - private ActorRef extSimAdapter; + private ActorRef extSimAdapter; /** Map uuid to external id of grid related entities */ private final Map gridResultAssetMapping; @@ -59,7 +61,9 @@ public ExtResultDataConnection( * @param extSimAdapter actor ref to the extSimAdapter */ public void setActorRefs( - ActorRef extResultDataService, ActorRef dataServiceActivation, ActorRef extSimAdapter) { + ActorRef extResultDataService, + ActorRef dataServiceActivation, + ActorRef extSimAdapter) { this.extResultDataService = extResultDataService; this.dataServiceActivation = dataServiceActivation; this.extSimAdapter = extSimAdapter; @@ -112,9 +116,9 @@ protected Map createResultMap(List results) * @param msg the data/information that is sent to SIMONA's result data service */ public void sendExtMsg(ResultDataMessageFromExt msg) { - extResultDataService.tell(msg, ActorRef.noSender()); + extResultDataService.tell(msg); // we need to schedule data receiver activation with scheduler - extSimAdapter.tell(new ScheduleDataServiceMessage(dataServiceActivation), ActorRef.noSender()); + extSimAdapter.tell(new ScheduleDataServiceMessage(dataServiceActivation)); } /** Queues message from SIMONA that should be handled by the external simulation. */ diff --git a/src/main/java/edu/ie3/simona/api/simulation/ExtSimAdapterData.java b/src/main/java/edu/ie3/simona/api/simulation/ExtSimAdapterData.java index e0906ce8..59f81b1e 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ExtSimAdapterData.java +++ b/src/main/java/edu/ie3/simona/api/simulation/ExtSimAdapterData.java @@ -9,7 +9,7 @@ import edu.ie3.simona.api.simulation.ontology.ControlMessageToExt; import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; import java.util.concurrent.LinkedBlockingQueue; -import org.apache.pekko.actor.ActorRef; +import org.apache.pekko.actor.typed.ActorRef; public class ExtSimAdapterData { @@ -18,19 +18,20 @@ public class ExtSimAdapterData { new LinkedBlockingQueue<>(); /** Actor reference to the adapter for the phases that handles scheduler control flow in SIMONA */ - private final ActorRef extSimAdapter; + private final ActorRef extSimAdapter; /** CLI arguments with which SIMONA is initiated */ private final String[] mainArgs; // important trigger queue must be the same as held in actor // to make it safer one might consider asking the actor for a reference on its trigger queue?! - public ExtSimAdapterData(ActorRef extSimAdapter, String[] mainArgs) { + public ExtSimAdapterData( + ActorRef extSimAdapter, String[] mainArgs) { this.extSimAdapter = extSimAdapter; this.mainArgs = mainArgs; } - public ActorRef getAdapter() { + public ActorRef getAdapter() { return extSimAdapter; } @@ -52,7 +53,7 @@ public void queueExtMsg(ControlMessageToExt msg) throws InterruptedException { * @param msg the message to send */ public void send(ControlResponseMessageFromExt msg) { - extSimAdapter.tell(msg, ActorRef.noSender()); + extSimAdapter.tell(msg); } public String[] getMainArgs() { diff --git a/src/test/groovy/edu/ie3/simona/api/data/em/ExtEmDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/em/ExtEmDataConnectionTest.groovy index d8f798f5..7b0f4ecb 100644 --- a/src/test/groovy/edu/ie3/simona/api/data/em/ExtEmDataConnectionTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/data/em/ExtEmDataConnectionTest.groovy @@ -3,21 +3,17 @@ package edu.ie3.simona.api.data.em import edu.ie3.datamodel.models.value.PValue import edu.ie3.datamodel.models.value.Value import edu.ie3.simona.api.data.em.ontology.ProvideEmSetPointData +import edu.ie3.simona.api.data.ontology.DataMessageFromExt import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage -import edu.ie3.simona.api.data.primarydata.ontology.ProvidePrimaryData import edu.ie3.simona.api.test.common.DataServiceTestData -import org.apache.pekko.actor.ActorSystem -import org.apache.pekko.testkit.TestProbe -import org.apache.pekko.testkit.javadsl.TestKit -import org.slf4j.Logger -import org.slf4j.LoggerFactory +import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit import spock.lang.Shared import spock.lang.Specification class ExtEmDataConnectionTest extends Specification implements DataServiceTestData { @Shared - ActorSystem actorSystem + ActorTestKit testKit @Shared Map extEmDataMapping = Map.of( @@ -26,18 +22,18 @@ class ExtEmDataConnectionTest extends Specification implements DataServiceTestDa ) def setupSpec() { - actorSystem = ActorSystem.create() + testKit = ActorTestKit.create() } def cleanupSpec() { - TestKit.shutdownActorSystem(actorSystem) - actorSystem = null + testKit.shutdownTestKit() + testKit = null } def "ExtEmDataConnection should provide em data correctly"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extEmDataConnection = new ExtEmDataConnection(extEmDataMapping) extEmDataConnection.setActorRefs( dataService.ref(), @@ -54,14 +50,14 @@ class ExtEmDataConnectionTest extends Specification implements DataServiceTestDa extEmDataConnection.provideEmData(0L, convertedEmData, Optional.of(900L)) then: - dataService.expectMsg(new ProvideEmSetPointData(0, convertedEmData, Optional.of(900L))) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new ProvideEmSetPointData(0, convertedEmData, Optional.of(900L))) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) } def "ExtEmDataConnection should convert input data correctly"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extEmDataConnection = new ExtEmDataConnection(extEmDataMapping) extEmDataConnection.setActorRefs( dataService.ref(), @@ -73,14 +69,14 @@ class ExtEmDataConnectionTest extends Specification implements DataServiceTestDa extEmDataConnection.convertAndSend(0L, inputDataMap, Optional.of(900L), log) then: - dataService.expectMsg(new ProvideEmSetPointData(0L, Map.of(inputUuid, pValue), Optional.of(900L))) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new ProvideEmSetPointData(0L, Map.of(inputUuid, pValue), Optional.of(900L))) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) } def "ExtEmDataConnection should send no message, if input data for a not requested asset was provided"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extEmDataConnection = new ExtEmDataConnection(extEmDataMapping) extEmDataConnection.setActorRefs( dataService.ref(), diff --git a/src/test/groovy/edu/ie3/simona/api/data/ev/ExtEvDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/ev/ExtEvDataConnectionTest.groovy index 8487efc3..ea925b95 100644 --- a/src/test/groovy/edu/ie3/simona/api/data/ev/ExtEvDataConnectionTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/data/ev/ExtEvDataConnectionTest.groovy @@ -1,38 +1,31 @@ package edu.ie3.simona.api.data.ev -import org.apache.pekko.actor.ActorSystem -import org.apache.pekko.testkit.TestProbe -import org.apache.pekko.testkit.javadsl.TestKit import edu.ie3.simona.api.data.ev.model.EvModel -import edu.ie3.simona.api.data.ev.ontology.ProvideArrivingEvs -import edu.ie3.simona.api.data.ev.ontology.ProvideCurrentPrices -import edu.ie3.simona.api.data.ev.ontology.ProvideDepartingEvs -import edu.ie3.simona.api.data.ev.ontology.ProvideEvcsFreeLots -import edu.ie3.simona.api.data.ev.ontology.RequestCurrentPrices -import edu.ie3.simona.api.data.ev.ontology.RequestDepartingEvs -import edu.ie3.simona.api.data.ev.ontology.RequestEvcsFreeLots +import edu.ie3.simona.api.data.ev.ontology.* +import edu.ie3.simona.api.data.ontology.DataMessageFromExt import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage +import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit import spock.lang.Shared import spock.lang.Specification class ExtEvDataConnectionTest extends Specification { @Shared - ActorSystem actorSystem + ActorTestKit testKit def setupSpec() { - actorSystem = ActorSystem.create() + testKit = ActorTestKit.create() } def cleanupSpec() { - TestKit.shutdownActorSystem(actorSystem) - actorSystem = null + testKit.shutdownTestKit() + testKit = null } def "ExtEvDataConnection should request and receive free evcs lots correctly"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extEvDataConnection = new ExtEvDataConnection() extEvDataConnection.setActorRefs(dataService.ref(), extSimAdapter.ref()) @@ -44,15 +37,15 @@ class ExtEvDataConnectionTest extends Specification { def actualReceivedEvcs = extEvDataConnection.requestAvailablePublicEvcs() then: - dataService.expectMsg(new RequestEvcsFreeLots()) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new RequestEvcsFreeLots()) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) actualReceivedEvcs == sentMsg.evcs() } def "ExtEvDataConnection should request and receive current charging prices correctly"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extEvDataConnection = new ExtEvDataConnection() extEvDataConnection.setActorRefs(dataService.ref(), extSimAdapter.ref()) @@ -64,15 +57,15 @@ class ExtEvDataConnectionTest extends Specification { def actualReceivedPrices = extEvDataConnection.requestCurrentPrices() then: - dataService.expectMsg(new RequestCurrentPrices()) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new RequestCurrentPrices()) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) actualReceivedPrices == sentMsg.prices() } def "ExtEvDataConnection should request and receive departing EVs correctly"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extEvDataConnection = new ExtEvDataConnection() extEvDataConnection.setActorRefs(dataService.ref(), extSimAdapter.ref()) @@ -86,15 +79,15 @@ class ExtEvDataConnectionTest extends Specification { def actualReceivedEvs = extEvDataConnection.requestDepartingEvs(requestedDepartingEvs) then: - dataService.expectMsg(new RequestDepartingEvs(requestedDepartingEvs)) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new RequestDepartingEvs(requestedDepartingEvs)) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) actualReceivedEvs == sentMsg.departedEvs() } def "ExtEvDataConnection should provide arriving EVs correctly"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extEvDataConnection = new ExtEvDataConnection() extEvDataConnection.setActorRefs(dataService.ref(), extSimAdapter.ref()) @@ -105,14 +98,14 @@ class ExtEvDataConnectionTest extends Specification { extEvDataConnection.provideArrivingEvs(arrivingEvs, Optional.of(60L)) then: - dataService.expectMsg(new ProvideArrivingEvs(arrivingEvs, Optional.of(60L))) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new ProvideArrivingEvs(arrivingEvs, Optional.of(60L))) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) } def "ExtEvDataConnection should fail if wrong response is sent"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extEvDataConnection = new ExtEvDataConnection() extEvDataConnection.setActorRefs(dataService.ref(), extSimAdapter.ref()) @@ -124,8 +117,8 @@ class ExtEvDataConnectionTest extends Specification { extEvDataConnection.requestAvailablePublicEvcs() then: - dataService.expectMsg(new RequestEvcsFreeLots()) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new RequestEvcsFreeLots()) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) thrown RuntimeException } } diff --git a/src/test/groovy/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnectionTest.groovy index 5aba77d4..8cc119a1 100644 --- a/src/test/groovy/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnectionTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnectionTest.groovy @@ -1,19 +1,18 @@ package edu.ie3.simona.api.data.primarydata import edu.ie3.datamodel.models.value.Value +import edu.ie3.simona.api.data.ontology.DataMessageFromExt import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage import edu.ie3.simona.api.data.primarydata.ontology.ProvidePrimaryData import edu.ie3.simona.api.test.common.DataServiceTestData -import org.apache.pekko.actor.ActorSystem -import org.apache.pekko.testkit.TestProbe -import org.apache.pekko.testkit.javadsl.TestKit +import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit import spock.lang.Shared import spock.lang.Specification class ExtPrimaryDataConnectionTest extends Specification implements DataServiceTestData { @Shared - ActorSystem actorSystem + ActorTestKit testKit @Shared Map extPrimaryDataMapping = Map.of( @@ -22,18 +21,18 @@ class ExtPrimaryDataConnectionTest extends Specification implements DataServiceT ) def setupSpec() { - actorSystem = ActorSystem.create() + testKit = ActorTestKit.create() } def cleanupSpec() { - TestKit.shutdownActorSystem(actorSystem) - actorSystem = null + testKit.shutdownTestKit() + testKit = null } def "ExtPrimaryDataConnection should provide primary data correctly"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extPrimaryDataConnection = new ExtPrimaryDataConnection(extPrimaryDataMapping) extPrimaryDataConnection.setActorRefs( dataService.ref(), @@ -50,14 +49,14 @@ class ExtPrimaryDataConnectionTest extends Specification implements DataServiceT extPrimaryDataConnection.providePrimaryData(0L, convertedPrimaryData, Optional.of(900L)) then: - dataService.expectMsg(new ProvidePrimaryData(0L, convertedPrimaryData, Optional.of(900L))) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new ProvidePrimaryData(0L, convertedPrimaryData, Optional.of(900L))) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) } def "ExtPrimaryDataConnection should convert input data correctly"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extPrimaryDataConnection = new ExtPrimaryDataConnection(extPrimaryDataMapping) extPrimaryDataConnection.setActorRefs( dataService.ref(), @@ -69,14 +68,14 @@ class ExtPrimaryDataConnectionTest extends Specification implements DataServiceT extPrimaryDataConnection.convertAndSend(0L, inputDataMap, Optional.of(900L), log) then: - dataService.expectMsg(new ProvidePrimaryData(0L, Map.of(inputUuid, pValue), Optional.of(900L))) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataService.ref())) + dataService.expectMessage(new ProvidePrimaryData(0L, Map.of(inputUuid, pValue), Optional.of(900L))) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) } def "ExtPrimaryDataConnection should send no message, if input data for a not requested asset was provided"() { given: - def dataService = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extPrimaryDataConnection = new ExtPrimaryDataConnection(extPrimaryDataMapping) extPrimaryDataConnection.setActorRefs( dataService.ref(), diff --git a/src/test/groovy/edu/ie3/simona/api/data/results/ExtResultDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/results/ExtResultDataConnectionTest.groovy index 7dc0dc22..3bf9a64f 100644 --- a/src/test/groovy/edu/ie3/simona/api/data/results/ExtResultDataConnectionTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/data/results/ExtResultDataConnectionTest.groovy @@ -2,12 +2,15 @@ package edu.ie3.simona.api.data.results import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.connector.LineResult +import edu.ie3.simona.api.data.ontology.DataMessageFromExt import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage import edu.ie3.simona.api.data.results.ontology.ProvideResultEntities import edu.ie3.simona.api.data.results.ontology.RequestResultEntities import edu.ie3.simona.api.data.results.ontology.ResultDataResponseMessageToExt +import edu.ie3.simona.api.simulation.ExtSimulation import edu.ie3.simona.api.test.common.DataServiceTestData import org.apache.pekko.actor.ActorSystem +import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit import org.apache.pekko.testkit.TestProbe import org.apache.pekko.testkit.javadsl.TestKit import spock.lang.Shared @@ -22,7 +25,7 @@ import java.time.ZonedDateTime class ExtResultDataConnectionTest extends Specification implements DataServiceTestData { @Shared - ActorSystem actorSystem + ActorTestKit testKit @Shared Map participantResultAssetMapping = Map.of(inputUuid, "Load") @@ -33,19 +36,19 @@ class ExtResultDataConnectionTest extends Specification implements DataServiceTe class WrongResultDataResponseMessageToExt implements ResultDataResponseMessageToExt {} def setupSpec() { - actorSystem = ActorSystem.create() + testKit = ActorTestKit.create() } def cleanupSpec() { - TestKit.shutdownActorSystem(actorSystem) - actorSystem = null + testKit.shutdownTestKit() + testKit = null } def "ExtResultsData should request and receive results correctly as ModelResultEntity"() { given: - def dataService = new TestProbe(actorSystem) - def dataServiceActivation = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def dataServiceActivation = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extResultDataConnection = new ExtResultDataConnection(participantResultAssetMapping, gridResultAssetMapping) extResultDataConnection.setActorRefs( dataService.ref(), @@ -61,16 +64,16 @@ class ExtResultDataConnectionTest extends Specification implements DataServiceTe def receivedResults = extResultDataConnection.requestResults(0L) then: - dataService.expectMsg(new RequestResultEntities(0L)) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataServiceActivation.ref())) + dataService.expectMessage(new RequestResultEntities(0L)) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataServiceActivation.ref())) receivedResults.get("Load") == loadResult } def "ExtResultsData should fail if wrong response is sent"() { given: - def dataService = new TestProbe(actorSystem) - def dataServiceActivation = new TestProbe(actorSystem) - def extSimAdapter = new TestProbe(actorSystem) + def dataService = testKit.createTestProbe(DataMessageFromExt) + def dataServiceActivation = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) def extResultDataConnection = new ExtResultDataConnection(participantResultAssetMapping, gridResultAssetMapping) extResultDataConnection.setActorRefs( dataService.ref(), @@ -86,8 +89,8 @@ class ExtResultDataConnectionTest extends Specification implements DataServiceTe extResultDataConnection.requestResults(0L) then: - dataService.expectMsg(new RequestResultEntities(0L)) - extSimAdapter.expectMsg(new ScheduleDataServiceMessage(dataServiceActivation.ref())) + dataService.expectMessage(new RequestResultEntities(0L)) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataServiceActivation.ref())) thrown RuntimeException } diff --git a/src/test/groovy/edu/ie3/simona/api/simulation/ExtSimulationSpec.groovy b/src/test/groovy/edu/ie3/simona/api/simulation/ExtSimulationSpec.groovy index 029056ff..7b24d955 100644 --- a/src/test/groovy/edu/ie3/simona/api/simulation/ExtSimulationSpec.groovy +++ b/src/test/groovy/edu/ie3/simona/api/simulation/ExtSimulationSpec.groovy @@ -1,14 +1,8 @@ package edu.ie3.simona.api.simulation -import org.apache.pekko.actor.ActorSystem -import org.apache.pekko.testkit.TestProbe -import org.apache.pekko.testkit.javadsl.TestKit import edu.ie3.simona.api.data.ExtDataConnection -import edu.ie3.simona.api.simulation.ontology.ActivationMessage -import edu.ie3.simona.api.simulation.ontology.CompletionMessage -import edu.ie3.simona.api.simulation.ontology.ControlMessageToExt -import edu.ie3.simona.api.simulation.ontology.TerminationMessage -import edu.ie3.simona.api.simulation.ontology.TerminationCompleted +import edu.ie3.simona.api.simulation.ontology.* +import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit import spock.lang.Shared import spock.lang.Specification @@ -17,7 +11,7 @@ import java.lang.reflect.Method class ExtSimulationSpec extends Specification { @Shared - ActorSystem actorSystem + ActorTestKit testKit @Shared Method handleMessage @@ -54,7 +48,7 @@ class ExtSimulationSpec extends Specification { } def setupSpec() { - actorSystem = ActorSystem.create() + testKit = ActorTestKit.create() // setup private method handleMessage = ExtSimulation.getDeclaredMethod("takeAndHandleMessage", null) @@ -62,15 +56,15 @@ class ExtSimulationSpec extends Specification { } def cleanupSpec() { - TestKit.shutdownActorSystem(actorSystem) - actorSystem = null + testKit.shutdownTestKit() + testKit = null } def "An ExtSimulation should handle initialization"() { given: def tick = -1L def newTick = 0L - def extSimAdapter = new TestProbe(actorSystem) + def extSimAdapter = testKit.createTestProbe(ControlResponseMessageFromExt) def extSimData = new ExtSimAdapterData(extSimAdapter.ref(), new String[0]) def extSim = new TestSimulation(newTick, Optional.of(-2L)) extSim.setAdapterData(extSimData) @@ -81,12 +75,12 @@ class ExtSimulationSpec extends Specification { then: finishedActual == false - extSimAdapter.expectMsg(new CompletionMessage(Optional.of(newTick))) + extSimAdapter.expectMessage(new CompletionMessage(Optional.of(newTick))) } def "An ExtSimulation should handle activation and return given new triggers"() { given: - def extSimAdapter = new TestProbe(actorSystem) + def extSimAdapter = testKit.createTestProbe(ControlResponseMessageFromExt) def extSimData = new ExtSimAdapterData(extSimAdapter.ref(), new String[0]) def newTickOpt = newTick.isEmpty() ? Optional.empty() : Optional.of(newTick.first()) @@ -99,7 +93,7 @@ class ExtSimulationSpec extends Specification { then: finishedActual == finished - extSimAdapter.expectMsg(new CompletionMessage(newTickOpt)) + extSimAdapter.expectMessage(new CompletionMessage(newTickOpt)) where: tick | newTick || finished @@ -111,7 +105,7 @@ class ExtSimulationSpec extends Specification { def "An ExtSimulation should handle termination properly"() { given: - def extSimAdapter = new TestProbe(actorSystem) + def extSimAdapter = testKit.createTestProbe(ControlResponseMessageFromExt) def extSimData = new ExtSimAdapterData(extSimAdapter.ref(), new String[0]) def extSim = new TestSimulation(-1L, Optional.empty()) extSim.setAdapterData(extSimData) @@ -122,7 +116,7 @@ class ExtSimulationSpec extends Specification { then: finishedActual == finished - extSimAdapter.expectMsg(new TerminationCompleted()) + extSimAdapter.expectMessage(new TerminationCompleted()) where: simlulationSuccessful || finished @@ -134,7 +128,7 @@ class ExtSimulationSpec extends Specification { def "An ExtSimulation should handle unknown messages by throwing an exception"() { given: - def extSimAdapter = new TestProbe(actorSystem) + def extSimAdapter = testKit.createTestProbe(ControlResponseMessageFromExt) def extSimData = new ExtSimAdapterData(extSimAdapter.ref(), new String[0]) def extSim = new TestSimulation(-1L, Optional.empty()) extSim.setAdapterData(extSimData) diff --git a/version.properties b/version.properties index e0fffb42..c3b49187 100644 --- a/version.properties +++ b/version.properties @@ -1,8 +1,8 @@ #Generated by the Semver Plugin for Gradle -#Mon Dec 02 15:26:40 CET 2024 +#Tue Mar 11 17:00:20 CET 2025 version.buildmeta= version.major=0 -version.minor=7 +version.minor=8 version.patch=0 version.prerelease= -version.semver=0.7.0 +version.semver=0.8.0