Skip to content

Commit 67edcbc

Browse files
author
sberberovic
committed
Merge branch 'release/2.1.0'
2 parents 22068bc + 7fb8ea4 commit 67edcbc

File tree

9 files changed

+70
-78
lines changed

9 files changed

+70
-78
lines changed

pom.xml

+9-9
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@
66
<parent>
77
<groupId>eu.openanalytics.phaedra</groupId>
88
<artifactId>phaedra2-parent</artifactId>
9-
<version>2.0.6</version>
9+
<version>2.1.0</version>
1010
</parent>
1111

1212
<artifactId>phaedra2-calculationservice</artifactId>
1313
<name>phaedra2-calculationservice</name>
14-
<version>2.0.6</version>
14+
<version>2.1.0</version>
1515

1616
<properties>
1717
<docker.filter>${docker.imageName}${docker.imageNameSuffix}</docker.filter> <!-- Only build app docker image, no liquibase image -->
18-
<phaedra2-scriptengine-dto.version>2.0.6</phaedra2-scriptengine-dto.version>
19-
<phaedra2-resultdataservice-client.version>2.0.6</phaedra2-resultdataservice-client.version>
20-
<phaedra2-protocolservice-client.version>2.0.6</phaedra2-protocolservice-client.version>
21-
<phaedra2-plateservice-client.version>2.0.6</phaedra2-plateservice-client.version>
22-
<phaedra2-measurementservice-client.version>2.0.6</phaedra2-measurementservice-client.version>
23-
<phaedra2-curvedataservice-client.version>2.0.6</phaedra2-curvedataservice-client.version>
24-
<phaedra2-metadataservice-client.version>2.0.6</phaedra2-metadataservice-client.version>
18+
<phaedra2-scriptengine-dto.version>2.1.0</phaedra2-scriptengine-dto.version>
19+
<phaedra2-resultdataservice-client.version>2.1.0</phaedra2-resultdataservice-client.version>
20+
<phaedra2-protocolservice-client.version>2.1.0</phaedra2-protocolservice-client.version>
21+
<phaedra2-plateservice-client.version>2.1.0</phaedra2-plateservice-client.version>
22+
<phaedra2-measurementservice-client.version>2.1.0</phaedra2-measurementservice-client.version>
23+
<phaedra2-curvedataservice-client.version>2.1.0</phaedra2-curvedataservice-client.version>
24+
<phaedra2-metadataservice-client.version>2.1.0</phaedra2-metadataservice-client.version>
2525
</properties>
2626

2727
<dependencies>

release_project.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ git commit -m "Updated version to $release_version"
3434
# Step 3: gitflow release
3535
# --------------------------------------------------------------
3636

37-
mvn -B -DskipTestProject=true -DpushRemote=false gitflow:release-start gitflow:release-finish
37+
mvn -B -DskipTestProject=true -DpushRemote=false -DversionDigitToIncrement=1 gitflow:release-start gitflow:release-finish
3838

3939
# --------------------------------------------------------------
4040
# Step 4: modify version numbers in the POM files (for the next snapshot)

src/main/java/eu/openanalytics/phaedra/calculationservice/api/CalculationController.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import eu.openanalytics.phaedra.calculationservice.dto.CalculationStatus;
2525
import eu.openanalytics.phaedra.calculationservice.service.CalculationStatusService;
2626
import eu.openanalytics.phaedra.calculationservice.service.protocol.ProtocolExecutorService;
27-
import eu.openanalytics.phaedra.plateservice.client.exception.PlateUnresolvableException;
27+
import eu.openanalytics.phaedra.plateservice.client.exception.UnresolvableObjectException;
2828
import eu.openanalytics.phaedra.protocolservice.client.exception.ProtocolUnresolvableException;
2929
import eu.openanalytics.phaedra.resultdataservice.client.exception.ResultDataUnresolvableException;
3030
import eu.openanalytics.phaedra.resultdataservice.client.exception.ResultFeatureStatUnresolvableException;
@@ -65,7 +65,7 @@ public ResponseEntity<List<Long>> calculate(@RequestBody CalculationRequestDTO c
6565
}
6666

6767
@GetMapping("/status")
68-
public ResponseEntity<Map<Long, CalculationStatus>> status(@RequestParam(value = "resultSetId") List<Long> resultSetIds) throws ResultSetUnresolvableException, ResultDataUnresolvableException, ResultFeatureStatUnresolvableException, ProtocolUnresolvableException, PlateUnresolvableException {
68+
public ResponseEntity<Map<Long, CalculationStatus>> status(@RequestParam(value = "resultSetId") List<Long> resultSetIds) throws ResultSetUnresolvableException, ResultDataUnresolvableException, ResultFeatureStatUnresolvableException, ProtocolUnresolvableException, UnresolvableObjectException {
6969
Map<Long, CalculationStatus> result = new HashMap<>();
7070
for (Long resultSetId: resultSetIds) {
7171
result.put(resultSetId, calculationStatusService.getStatus(resultSetId));

src/main/java/eu/openanalytics/phaedra/calculationservice/execution/input/CalculationInputHelper.java

+8-9
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
import eu.openanalytics.phaedra.calculationservice.execution.CalculationContext;
2929
import eu.openanalytics.phaedra.plateservice.dto.WellDTO;
30-
import eu.openanalytics.phaedra.util.WellNumberUtils;
3130

3231
public class CalculationInputHelper {
3332

@@ -48,14 +47,8 @@ public static void addWellInfo(Map<String, Object> inputMap, CalculationContext
4847
}
4948

5049
if (wells != null) {
51-
// Sort wells by wellNumber
52-
List<WellDTO> sortedWells = new ArrayList<>(wells);
53-
int columnCount = ctx.getPlate().getColumns();
54-
sortedWells.sort((w1, w2) -> {
55-
return WellNumberUtils.getWellNr(w1.getRow(), w1.getColumn(), columnCount) - WellNumberUtils.getWellNr(w2.getRow(), w2.getColumn(), columnCount);
56-
});
57-
58-
inputMap.put(InputName.wellNumbers.name(), sortedWells.stream().map(w -> WellNumberUtils.getWellNr(w.getRow(), w.getColumn(), columnCount)).toList());
50+
List<WellDTO> sortedWells = sortByNr(wells);
51+
inputMap.put(InputName.wellNumbers.name(), sortedWells.stream().map(WellDTO::getWellNr).toList());
5952
inputMap.put(InputName.wellTypes.name(), sortedWells.stream().map(WellDTO::getWellType).toList());
6053
inputMap.put(InputName.wellRows.name(), sortedWells.stream().map(WellDTO::getRow).toList());
6154
inputMap.put(InputName.wellColumns.name(), sortedWells.stream().map(WellDTO::getColumn).toList());
@@ -70,4 +63,10 @@ public static List<String> getReservedInputNames() {
7063
public static boolean isReservedInputName(String name) {
7164
return getReservedInputNames().contains(name);
7265
}
66+
67+
public static List<WellDTO> sortByNr(List<WellDTO> wells) {
68+
List<WellDTO> sortedWells = new ArrayList<>(wells);
69+
sortedWells.sort((w1, w2) -> w1.getWellNr() - w2.getWellNr());
70+
return sortedWells;
71+
}
7372
}

src/main/java/eu/openanalytics/phaedra/calculationservice/service/CalculationStatusService.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import eu.openanalytics.phaedra.calculationservice.model.ModelMapper;
3939
import eu.openanalytics.phaedra.calculationservice.service.protocol.ProtocolDataCollector;
4040
import eu.openanalytics.phaedra.plateservice.client.PlateServiceClient;
41-
import eu.openanalytics.phaedra.plateservice.client.exception.PlateUnresolvableException;
41+
import eu.openanalytics.phaedra.plateservice.client.exception.UnresolvableObjectException;
4242
import eu.openanalytics.phaedra.plateservice.dto.WellDTO;
4343
import eu.openanalytics.phaedra.protocolservice.client.exception.ProtocolUnresolvableException;
4444
import eu.openanalytics.phaedra.protocolservice.dto.FeatureDTO;
@@ -104,9 +104,9 @@ public CalculationStatusService(ProtocolDataCollector protocolInfoCollector, Pla
104104
* @throws ResultSetUnresolvableException
105105
* @throws ResultFeatureStatUnresolvableException
106106
* @throws ProtocolUnresolvableException
107-
* @throws PlateUnresolvableException
107+
* @throws UnresolvableObjectException
108108
*/
109-
public CalculationStatus getStatus(Long resultSetId) throws ResultDataUnresolvableException, ResultSetUnresolvableException, ResultFeatureStatUnresolvableException, ProtocolUnresolvableException, PlateUnresolvableException {
109+
public CalculationStatus getStatus(Long resultSetId) throws ResultDataUnresolvableException, ResultSetUnresolvableException, ResultFeatureStatUnresolvableException, ProtocolUnresolvableException, UnresolvableObjectException {
110110
var resultSet = resultDataServiceClient.getResultSet(resultSetId);
111111
var protocolData = protocolInfoCollector.getProtocolData(resultSet.getProtocolId());
112112
var wells = plateServiceClient.getWells(resultSet.getPlateId());

src/main/java/eu/openanalytics/phaedra/calculationservice/service/protocol/CurveFittingExecutorService.java

+18-16
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,13 @@
2525
import static java.util.stream.IntStream.range;
2626
import static org.apache.commons.lang3.math.NumberUtils.isCreatable;
2727

28-
import eu.openanalytics.phaedra.calculationservice.enumeration.FormulaCategory;
2928
import java.util.ArrayList;
3029
import java.util.Date;
3130
import java.util.HashMap;
3231
import java.util.List;
3332
import java.util.Optional;
3433

3534
import org.apache.commons.lang3.ArrayUtils;
36-
import org.apache.commons.lang3.ObjectUtils;
3735
import org.apache.commons.lang3.StringUtils;
3836
import org.apache.commons.math3.util.Precision;
3937
import org.slf4j.Logger;
@@ -49,6 +47,7 @@
4947
import eu.openanalytics.curvedataservice.dto.CurvePropertyDTO;
5048
import eu.openanalytics.phaedra.calculationservice.dto.CurveFittingRequestDTO;
5149
import eu.openanalytics.phaedra.calculationservice.dto.DRCInputDTO;
50+
import eu.openanalytics.phaedra.calculationservice.enumeration.FormulaCategory;
5251
import eu.openanalytics.phaedra.calculationservice.enumeration.ScriptLanguage;
5352
import eu.openanalytics.phaedra.calculationservice.exception.NoDRCModelDefinedForFeature;
5453
import eu.openanalytics.phaedra.calculationservice.execution.CalculationContext;
@@ -99,7 +98,7 @@ public CurveFittingExecutorService(
9998

10099
public void execute(CalculationContext ctx, FeatureDTO feature) {
101100
List<String> substanceNames = ctx.getWells().stream()
102-
.filter(w -> w.getWellSubstance() != null)
101+
.filter(w -> w.getWellSubstance() != null && w.getWellSubstance().getName() != null)
103102
.map(w -> w.getWellSubstance().getName())
104103
.distinct().toList();
105104

@@ -172,19 +171,22 @@ public void execute(CurveFittingRequestDTO request) {
172171
PlateDTO plate = plateServiceClient.getPlate(request.getPlateId());
173172
List<WellDTO> wells = plateServiceClient.getWells(plate.getId());
174173

175-
List<String> substanceNames = wells.stream().filter(w -> w.getWellSubstance() != null)
176-
.map(w -> w.getWellSubstance().getName()).distinct().toList();
177-
for (String substance : substanceNames) {
178-
DRCInputDTO drcInput = collectCurveFitInputData(plate, wells, resultData, feature, substance);
179-
ScriptExecutionRequest scriptRequest = executeReceptor2CurveFit(drcInput);
180-
scriptRequest.addCallback(output -> {
181-
logger.info("Execute Receptor2 Curve Fit script request callback");
182-
DRCOutputDTO drcOutput = collectCurveFitOutputData(output);
183-
if (drcOutput != null) {
184-
createNewCurve(drcInput, drcOutput);
185-
}
186-
});
187-
}
174+
List<String> substanceNames = wells.stream()
175+
.filter(w -> w.getWellSubstance() != null && w.getWellSubstance().getName() != null)
176+
.map(w -> w.getWellSubstance().getName())
177+
.distinct().toList();
178+
179+
for (String substanceName : substanceNames) {
180+
DRCInputDTO drcInput = collectCurveFitInputData(plate, wells, resultData, feature, substanceName);
181+
ScriptExecutionRequest scriptRequest = executeReceptor2CurveFit(drcInput);
182+
scriptRequest.addCallback(output -> {
183+
logger.info("Execute Receptor2 Curve Fit script request callback");
184+
DRCOutputDTO drcOutput = collectCurveFitOutputData(output);
185+
if (drcOutput != null) {
186+
createNewCurve(drcInput, drcOutput);
187+
}
188+
});
189+
}
188190
} catch (Exception e) {
189191
logger.error(String.format("Curve fit failed on plate %d, feature %d", request.getPlateId(), request.getFeatureId()), e);
190192
}

src/main/java/eu/openanalytics/phaedra/calculationservice/service/protocol/FeatureStatExecutorService.java

+17-36
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,12 @@
3232
import org.slf4j.LoggerFactory;
3333
import org.springframework.stereotype.Service;
3434

35-
import com.fasterxml.jackson.annotation.JsonCreator;
36-
import com.fasterxml.jackson.annotation.JsonProperty;
3735
import com.fasterxml.jackson.core.JsonProcessingException;
3836
import com.fasterxml.jackson.databind.ObjectMapper;
3937

4038
import eu.openanalytics.phaedra.calculationservice.exception.CalculationException;
4139
import eu.openanalytics.phaedra.calculationservice.execution.CalculationContext;
40+
import eu.openanalytics.phaedra.calculationservice.execution.input.CalculationInputHelper;
4241
import eu.openanalytics.phaedra.calculationservice.execution.progress.CalculationStage;
4342
import eu.openanalytics.phaedra.calculationservice.execution.progress.CalculationStateEventCode;
4443
import eu.openanalytics.phaedra.calculationservice.execution.script.ScriptExecutionRequest;
@@ -60,6 +59,8 @@
6059
* but also stats for each welltype present in the plate.
6160
*
6261
* Feature Stats can be calculated as soon as the Feature itself has been calculated.
62+
*
63+
* TODO: wellType is still named "welltype" in protocol-service and resultdata-service. Fix naming across all services
6364
*/
6465
@Service
6566
public class FeatureStatExecutorService {
@@ -133,31 +134,36 @@ private FeatureStatDTO findStat(CalculationContext ctx, long featureId, long sta
133134

134135
private Map<String, Object> collectStatInputData(CalculationContext ctx, FeatureDTO feature, FeatureStatDTO featureStat) {
135136
Map<String, Object> input = new HashMap<String, Object>();
136-
input.put("lowWelltype", ctx.getProtocolData().protocol.getLowWelltype());
137-
input.put("highWelltype", ctx.getProtocolData().protocol.getHighWelltype());
138-
input.put("welltypes", ctx.getWells().stream().map(WellDTO::getWellType).toList());
137+
CalculationInputHelper.addWellInfo(input, ctx, ctx.getWells());
138+
// Note: assuming here that the feature values are already sorted by well nr
139139
input.put("featureValues", ctx.getFeatureResults().get(feature.getId()).getValues());
140140
input.put("isPlateStat", featureStat.getPlateStat());
141-
input.put("isWelltypeStat", featureStat.getWelltypeStat());
141+
input.put("isWellTypeStat", featureStat.getWelltypeStat());
142142
return input;
143143
}
144144

145-
private List<ResultFeatureStatDTO> parseResults(CalculationContext ctx, FeatureDTO feature, FeatureStatDTO featureStat, ScriptExecutionOutputDTO output) {
145+
private List<ResultFeatureStatDTO> parseResults(CalculationContext ctx, FeatureDTO feature, FeatureStatDTO featureStat, ScriptExecutionOutputDTO output) {
146146
List<ResultFeatureStatDTO> results = new ArrayList<>();
147147

148148
float plateValue = Float.NaN;
149-
Map<String, Float> wellTypeValues = null;
149+
Map<String, Float> wellTypeValues = new HashMap<>();
150+
150151
try {
151-
OutputWrapper outputWrapper = objectMapper.readValue(output.getOutput(), OutputWrapper.class);
152-
plateValue = outputWrapper.getPlateValue().orElse(Float.NaN);
153-
wellTypeValues = outputWrapper.getWelltypeOutputs();
152+
Map<?,?> outputMap = objectMapper.readValue(output.getOutput(), Map.class);
153+
outputMap = (Map<?,?>) outputMap.get("output"); // Output string contains a nested 'output' key, e.g. output = "{\"output\":{\"plateValue\":384,\"wellTypeValues\":{\"HC\":32,\"LC\":32,\"SAMPLE\":320}}}\n"
154+
if (outputMap.get("plateValue") instanceof Number) plateValue = ((Number) outputMap.get("plateValue")).floatValue();
155+
if (outputMap.get("wellTypeValues") instanceof Map) {
156+
Map<?,?> wellTypeValuesMap = (Map<?,?>) outputMap.get("wellTypeValues");
157+
wellTypeValuesMap.entrySet().stream().filter(e -> e.getValue() instanceof Number).forEach(e -> wellTypeValues.put((String) e.getKey(), ((Number) e.getValue()).floatValue()));
158+
}
154159
} catch (JsonProcessingException e) {
155160
throw new CalculationException("Invalid response JSON", e);
156161
}
157162

158163
if (featureStat.getPlateStat()) {
159164
results.add(createResultStatDTO(feature, featureStat, output, plateValue, null));
160165
}
166+
161167
if (featureStat.getWelltypeStat()) {
162168
List<String> wellTypes = ctx.getWells().stream().map(WellDTO::getWellType).distinct().toList();
163169
for (String wellType : wellTypes) {
@@ -181,29 +187,4 @@ private ResultFeatureStatDTO createResultStatDTO(FeatureDTO feature, FeatureStat
181187
.exitCode(output.getExitCode())
182188
.build();
183189
}
184-
185-
private static class OutputWrapper {
186-
187-
private final Float plateValue;
188-
private final Map<String, Float> welltypeValues;
189-
190-
@JsonCreator
191-
private OutputWrapper(
192-
@JsonProperty(value = "plateValue", required = true) Float plateValue,
193-
@JsonProperty(value = "welltypeValues", required = true) Map<String, Float> welltypeValues) {
194-
this.plateValue = plateValue;
195-
this.welltypeValues = welltypeValues;
196-
}
197-
198-
public Optional<Float> getPlateValue() {
199-
return Optional.ofNullable(plateValue);
200-
}
201-
202-
203-
public Map<String, Float> getWelltypeOutputs() {
204-
return welltypeValues;
205-
}
206-
207-
}
208-
209190
}

src/main/java/eu/openanalytics/phaedra/calculationservice/service/protocol/ProtocolExecutorService.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import eu.openanalytics.phaedra.calculationservice.execution.progress.CalculationStateEventCode;
4040
import eu.openanalytics.phaedra.calculationservice.service.KafkaProducerService;
4141
import eu.openanalytics.phaedra.plateservice.client.PlateServiceClient;
42-
import eu.openanalytics.phaedra.plateservice.client.exception.PlateUnresolvableException;
42+
import eu.openanalytics.phaedra.plateservice.client.exception.UnresolvableObjectException;
4343
import eu.openanalytics.phaedra.plateservice.dto.PlateCalculationStatusDTO;
4444
import eu.openanalytics.phaedra.plateservice.enumeration.CalculationStatus;
4545
import eu.openanalytics.phaedra.protocolservice.client.exception.ProtocolUnresolvableException;
@@ -106,7 +106,7 @@ public void handleResultSetUpdate(Long resultSetId, Object payload) {
106106
ctx.getStateTracker().handleResultSetUpdate(payload);
107107
}
108108

109-
private void triggerProtocolExecution(CompletableFuture<Long> resultSetIdFuture, long protocolId, long plateId, long measId) throws ProtocolUnresolvableException, ResultSetUnresolvableException, PlateUnresolvableException {
109+
private void triggerProtocolExecution(CompletableFuture<Long> resultSetIdFuture, long protocolId, long plateId, long measId) throws ProtocolUnresolvableException, ResultSetUnresolvableException, UnresolvableObjectException {
110110
// Collect all required input data and create a ResultSet instance
111111
var protocolData = protocolDataCollector.getProtocolData(protocolId);
112112
var plate = plateServiceClient.getPlate(plateId);

src/test/java/eu/openanalytics/phaedra/calculationservice/support/InMemoryResultDataServiceClient.java

+10
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,14 @@ public List<ResultFeatureStatDTO> getLatestResultFeatureStatsForPlateId(long pla
149149
return null;
150150
}
151151

152+
@Override
153+
public List<ResultFeatureStatDTO> getResultFeatureStatByResultSetIdAndFeatureId(long resultSetId, long featureId) throws ResultFeatureStatUnresolvableException {
154+
return null;
155+
}
156+
157+
@Override
158+
public List<ResultFeatureStatDTO> getLatestResultFeatureStatsForPlateIdAndFeatureId(long plateId, long featureId) throws ResultFeatureStatUnresolvableException {
159+
return null;
160+
}
161+
152162
}

0 commit comments

Comments
 (0)