From 9a220c03de810f57652dd8823811c2aaad426f41 Mon Sep 17 00:00:00 2001 From: Luc Weinbrecht Date: Fri, 3 Jan 2025 10:02:52 +0100 Subject: [PATCH] calculateSavedCarbonDelta and calculateSavedCarbonPercentage return null if no calculation possible --- .../CarbonReductorVariableMapper.java | 2 +- .../CarbonReductorVariableMapperTest.java | 4 +-- .../CarbonReductorOutputVariable.java | 2 +- .../CarbonReductorVariableMapper.java | 2 +- .../zeebe/test/utils/TestDataGenerator.java | 2 +- .../CarbonReductorVariableMapperTest.java | 2 +- .../core/domain/model/CarbonReduction.java | 1 - .../core/domain/model/EmissionTimeframe.java | 8 +++--- .../service/DelayCalculatorService.java | 6 ++-- .../domain/model/CarbonReductionTest.java | 6 ---- .../domain/model/EmissionTimeframeTest.java | 8 +++--- .../service/DelayCalculatorServiceTest.java | 28 +++++++++++++++++++ 12 files changed, 46 insertions(+), 25 deletions(-) diff --git a/camunda-carbon-reductor-c7/src/main/java/de/envite/greenbpm/carbonreductorconnector/CarbonReductorVariableMapper.java b/camunda-carbon-reductor-c7/src/main/java/de/envite/greenbpm/carbonreductorconnector/CarbonReductorVariableMapper.java index cfbf1e5..bf1dad8 100644 --- a/camunda-carbon-reductor-c7/src/main/java/de/envite/greenbpm/carbonreductorconnector/CarbonReductorVariableMapper.java +++ b/camunda-carbon-reductor-c7/src/main/java/de/envite/greenbpm/carbonreductorconnector/CarbonReductorVariableMapper.java @@ -63,7 +63,7 @@ public Map mapFromDomain(CarbonReduction output, Map variables = Map.of("milestone", mileStoneDateString); @@ -113,7 +113,7 @@ void should_map_mandatory_fields_to_map() { softAssertions.assertThat(result.get("executionDelayed")).isEqualTo(carbonReduction.getDelay().isExecutionDelayed()); softAssertions.assertThat(result.get("carbonWithoutOptimization")).isNull(); softAssertions.assertThat(result.get("optimalForecastedCarbon")).isEqualTo(carbonReduction.getOptimalForecastedCarbon().getValue()); - softAssertions.assertThat(result.get("savedCarbonPercentage")).isEqualTo(carbonReduction.getSavedCarbonPercentage().getValue()); + softAssertions.assertThat(result.get("savedCarbonPercentage")).isNull(); softAssertions.assertThat(result.get("reducedCarbon")).isNull(); softAssertions.assertThat(result.get("delayedBy")).isEqualTo(carbonReduction.getDelay().getDelayedBy()); softAssertions.assertThat(result.get("milestone")).isEqualTo(mileStoneDateString); diff --git a/camunda-carbon-reductor-c8/src/main/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorOutputVariable.java b/camunda-carbon-reductor-c8/src/main/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorOutputVariable.java index 7c49f9c..921b410 100644 --- a/camunda-carbon-reductor-c8/src/main/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorOutputVariable.java +++ b/camunda-carbon-reductor-c8/src/main/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorOutputVariable.java @@ -8,7 +8,7 @@ public class CarbonReductorOutputVariable { private boolean executionDelayed; private Double carbonWithoutOptimization; private double optimalForecastedCarbon; - private double savedCarbonPercentage; + private Double savedCarbonPercentage; private Double carbonReduction; private long delayedBy; diff --git a/camunda-carbon-reductor-c8/src/main/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorVariableMapper.java b/camunda-carbon-reductor-c8/src/main/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorVariableMapper.java index 1cf7a9e..cc43c38 100644 --- a/camunda-carbon-reductor-c8/src/main/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorVariableMapper.java +++ b/camunda-carbon-reductor-c8/src/main/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorVariableMapper.java @@ -65,7 +65,7 @@ public CarbonReductorOutputVariable mapFromDomain(CarbonReduction output) { outputVariable.setDelayedBy(output.getDelay().getDelayedBy()); outputVariable.setOptimalForecastedCarbon(output.getOptimalForecastedCarbon().getValue()); outputVariable.setCarbonWithoutOptimization(carbonWithoutOptimization); - outputVariable.setSavedCarbonPercentage(output.getSavedCarbonPercentage().getValue()); + outputVariable.setSavedCarbonPercentage(Optional.ofNullable(output.getSavedCarbonPercentage()).map(ValueObject::getValue).orElse(null)); outputVariable.setCarbonReduction(Optional.ofNullable(output.calculateReduction()).map(ValueObject::getValue).orElse(null)); return outputVariable; } diff --git a/camunda-carbon-reductor-c8/src/test/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/test/utils/TestDataGenerator.java b/camunda-carbon-reductor-c8/src/test/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/test/utils/TestDataGenerator.java index fff7da2..0f6ad46 100644 --- a/camunda-carbon-reductor-c8/src/test/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/test/utils/TestDataGenerator.java +++ b/camunda-carbon-reductor-c8/src/test/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/test/utils/TestDataGenerator.java @@ -39,7 +39,7 @@ public static CarbonReduction createCarbonReductorOutputWithoutCurrentValue() { new Delay(true, 3), null, new Carbon(2.0), - new Percentage(3.0) + null ); } diff --git a/camunda-carbon-reductor-c8/src/test/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorVariableMapperTest.java b/camunda-carbon-reductor-c8/src/test/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorVariableMapperTest.java index 7e5cb61..d131d4f 100644 --- a/camunda-carbon-reductor-c8/src/test/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorVariableMapperTest.java +++ b/camunda-carbon-reductor-c8/src/test/java/de/envite/greenbpm/carbonreductorconnector/adapter/in/zeebe/variable/CarbonReductorVariableMapperTest.java @@ -83,7 +83,7 @@ void should_map_mandatory_fields_from_domain() { softAssertions.assertThat(result.getDelayedBy()).isEqualTo(outputDDD.getDelay().getDelayedBy()); softAssertions.assertThat(result.getOptimalForecastedCarbon()).isEqualTo(outputDDD.getOptimalForecastedCarbon().getValue()); softAssertions.assertThat(result.getCarbonWithoutOptimization()).isNull(); - softAssertions.assertThat(result.getSavedCarbonPercentage()).isEqualTo(outputDDD.getSavedCarbonPercentage().getValue()); + softAssertions.assertThat(result.getSavedCarbonPercentage()).isNull(); softAssertions.assertThat(result.getCarbonReduction()).isNull(); softAssertions.assertAll(); } diff --git a/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/model/CarbonReduction.java b/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/model/CarbonReduction.java index 2ea1f63..f22f0c8 100644 --- a/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/model/CarbonReduction.java +++ b/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/model/CarbonReduction.java @@ -31,7 +31,6 @@ public CarbonReduction(Delay delay, Carbon carbonWithoutOptimization, Carbon opt protected void validate() { validateNotNull(delay, "Delay"); validateNotNull(optimalForecastedCarbon, "actual Carbon"); - validateNotNull(savedCarbonPercentage, "saved Carbon"); evaluateValidations(); } diff --git a/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/model/EmissionTimeframe.java b/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/model/EmissionTimeframe.java index 335d355..f9c4164 100644 --- a/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/model/EmissionTimeframe.java +++ b/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/model/EmissionTimeframe.java @@ -51,16 +51,16 @@ public boolean isCleanerEnergyInFuture() { return emissionReduction && optimalTime.isInFuture(); } - public double calculateSavedCarbonDelta() { + public Double calculateSavedCarbonDelta() { if (earliestForecastedValue == null) { - return 0.0; + return null; } return earliestForecastedValue.getValue() - optimalValue.getValue(); } - public double calculateSavedCarbonPercentage() { + public Double calculateSavedCarbonPercentage() { if (earliestForecastedValue == null) { - return 100; + return null; } double difference = earliestForecastedValue.getValue() - optimalValue.getValue(); return (difference / earliestForecastedValue.getValue()) * 100; diff --git a/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/service/DelayCalculatorService.java b/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/service/DelayCalculatorService.java index f7a74bd..ceeb736 100644 --- a/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/service/DelayCalculatorService.java +++ b/carbon-reductor-core/src/main/java/de/envite/greenbpm/carbonreductor/core/domain/service/DelayCalculatorService.java @@ -48,9 +48,9 @@ public CarbonReduction calculateDelay(CarbonReductorConfiguration input) throws } boolean isDelayNecessary = input.isDelayStillRelevant() && emissionTimeframe.isCleanerEnergyInFuture(); - boolean isGreaterThanMinimumThreshold = input.getThreshold().isGreaterThanMinimumThreshold( - emissionTimeframe.calculateSavedCarbonDelta() - ); + boolean isGreaterThanMinimumThreshold = Optional.ofNullable(emissionTimeframe.calculateSavedCarbonDelta()) + .map(savedCarbonDelta -> input.getThreshold().isGreaterThanMinimumThreshold(savedCarbonDelta)) + .orElse(false); final Carbon carbonWithoutOptimization = Optional.ofNullable(emissionTimeframe.getEarliestForecastedValue()) .map(ValueObject::getValue) diff --git a/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/model/CarbonReductionTest.java b/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/model/CarbonReductionTest.java index 830af44..33b9794 100644 --- a/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/model/CarbonReductionTest.java +++ b/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/model/CarbonReductionTest.java @@ -29,12 +29,6 @@ void should_throw_if_no_actual_carbon() { assertThatThrownBy(() -> new CarbonReduction(delay, carbon, null, percentage)) .isInstanceOf(InvariantException.class); } - - @Test - void should_throw_if_no_saved_carbon() { - assertThatThrownBy(() -> new CarbonReduction(delay, carbon, carbon, null)) - .isInstanceOf(InvariantException.class); - } } @Nested diff --git a/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/model/EmissionTimeframeTest.java b/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/model/EmissionTimeframeTest.java index 2f3e2e9..1f816b7 100644 --- a/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/model/EmissionTimeframeTest.java +++ b/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/model/EmissionTimeframeTest.java @@ -88,10 +88,10 @@ void should_calculate_saved_carbon_delta() { } @Test - void should_return_zero_on_calculate_saved_carbon_delta_if_earliest_is_null() { + void should_return_null_on_calculate_saved_carbon_delta_if_earliest_is_null() { EmissionTimeframe emissionTimeframe = new EmissionTimeframe(optimalTime, null, forecastedValue); - assertThat(emissionTimeframe.calculateSavedCarbonDelta()).isZero(); + assertThat(emissionTimeframe.calculateSavedCarbonDelta()).isNull(); } } @@ -106,10 +106,10 @@ void should_calculate_saved_carbon_in_percentage() { } @Test - void should_return_optimal_on_calculate_saved_carbon_in_percentage_if_earliest_is_null() { + void should_return_null_on_calculate_saved_carbon_in_percentage_if_earliest_is_null() { EmissionTimeframe emissionTimeframe = new EmissionTimeframe(optimalTime, null, forecastedValue); - assertThat(emissionTimeframe.calculateSavedCarbonPercentage()).isEqualTo(100); + assertThat(emissionTimeframe.calculateSavedCarbonPercentage()).isNull(); } } } \ No newline at end of file diff --git a/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/service/DelayCalculatorServiceTest.java b/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/service/DelayCalculatorServiceTest.java index 2086470..bf20db8 100644 --- a/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/service/DelayCalculatorServiceTest.java +++ b/carbon-reductor-core/src/test/java/de/envite/greenbpm/carbonreductor/core/domain/service/DelayCalculatorServiceTest.java @@ -147,6 +147,33 @@ void shouldNotCalculateDelayBecauseBelowThreshold() throws CarbonReductorExcepti Assertions.assertThat(result.getSavedCarbonPercentage().getValue()).isCloseTo(0, offset(0.1)); } + @Test + void shouldNotCalculateDelayBecauseNoThresholdPossible() throws CarbonReductorException, CarbonEmissionQueryException { + EmissionTimeframe emissionTimeframeIn3HoursWithoutActualCarbon = new EmissionTimeframe( + new OptimalTime(java.time.OffsetDateTime.now().plusHours(3)), + null, + new ForecastedValue(15.0) + ); + CarbonReductorConfiguration inputConfig = new CarbonReductorConfiguration( + Locations.NORWAY_EAST.asLocation(), + new Milestone(createTimestamp(1)), + new ProcessDuration("PT5H"), + new ProcessDuration("PT10H"), + null, + false, + new Threshold(true, 200.0f)); + when(carbonEmissionQueryMock.getEmissionTimeframe(eq(inputConfig.getLocation()), + any(ProcessDuration.class), eq(inputConfig.getRemainingProcessDuration()))).thenReturn(emissionTimeframeIn3HoursWithoutActualCarbon); + + CarbonReduction result = classUnderTest.calculateDelay(inputConfig); + + Assertions.assertThat(result.getDelay().isExecutionDelayed()).isFalse(); + Assertions.assertThat(result.getDelay().getDelayedBy()).isZero(); + Assertions.assertThat(result.getOptimalForecastedCarbon().getValue()).isEqualTo(emissionTimeframeIn3HoursWithoutActualCarbon.getOptimalValue().getValue()); + Assertions.assertThat(result.getCarbonWithoutOptimization()).isNull(); + Assertions.assertThat(result.getSavedCarbonPercentage().getValue()).isCloseTo(0, offset(0.1)); + } + @Test @DisplayName("should calculate no delay because maximumDuration would be breached") void shouldCalculateNoDelayBecauseProcessIsRunningVeryLong() throws CarbonReductorException, CarbonEmissionQueryException { @@ -181,6 +208,7 @@ void shouldCalculateNoDelayBecauseEnergyIsOptimal() throws CarbonReductorExcepti Assertions.assertThat(result.getSavedCarbonPercentage().getValue()).isZero(); } + @ParameterizedTest(name = "{0}") @DisplayName("should calculate delay duration") @MethodSource("provideDelayDurationInput")