Skip to content

Commit ff166c2

Browse files
committed
fix(server, engine): Static objectMapper, externalize inner Step classes
1 parent 8e54a2e commit ff166c2

File tree

17 files changed

+313
-262
lines changed

17 files changed

+313
-262
lines changed

chutney/engine/src/main/java/com/chutneytesting/ExecutionConfiguration.java

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,14 @@
4444
import com.chutneytesting.engine.infrastructure.delegation.HttpClient;
4545
import com.chutneytesting.tools.ThrowingFunction;
4646
import com.chutneytesting.tools.loader.ExtensionLoaders;
47-
import com.fasterxml.jackson.annotation.JsonInclude;
48-
import com.fasterxml.jackson.databind.ObjectMapper;
49-
import com.fasterxml.jackson.databind.SerializationFeature;
50-
import com.fasterxml.jackson.databind.module.SimpleModule;
5147
import java.lang.reflect.InvocationTargetException;
5248
import java.util.Map;
5349
import java.util.Set;
5450
import java.util.concurrent.ExecutorService;
5551
import java.util.concurrent.Executors;
5652
import java.util.stream.Collectors;
57-
import org.jdom2.Element;
5853
import org.slf4j.Logger;
5954
import org.slf4j.LoggerFactory;
60-
import org.springframework.core.io.Resource;
6155
import org.springframework.util.ReflectionUtils;
6256

6357
public class ExecutionConfiguration {
@@ -71,7 +65,6 @@ public class ExecutionConfiguration {
7165

7266
private final SpelFunctions spelFunctions;
7367
private final Set<StepExecutionStrategy> stepExecutionStrategies;
74-
private static ObjectMapper objectMapper;
7568
private final Long reporterTTL;
7669

7770
public ExecutionConfiguration() {
@@ -111,20 +104,6 @@ public ExecutionEngine executionEngine() {
111104
return executionEngine;
112105
}
113106

114-
public static ObjectMapper reportObjectMapper() {
115-
if (objectMapper == null) {
116-
SimpleModule jdomElementModule = new SimpleModule();
117-
jdomElementModule.addSerializer(Element.class, new JDomElementSerializer());
118-
objectMapper = new ObjectMapper()
119-
.addMixIn(Resource.class, MyMixInForIgnoreType.class)
120-
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
121-
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
122-
.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
123-
.registerModule(jdomElementModule)
124-
.findAndRegisterModules();
125-
}
126-
return objectMapper;
127-
}
128107

129108
private ActionTemplateLoader createActionTemplateLoaderV2() {
130109
return new DefaultActionTemplateLoader<>(

chutney/engine/src/main/java/com/chutneytesting/engine/domain/execution/engine/step/Step.java

Lines changed: 4 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,27 @@
2121
import static java.util.Collections.unmodifiableMap;
2222
import static java.util.Optional.ofNullable;
2323

24-
import com.chutneytesting.ExecutionConfiguration;
2524
import com.chutneytesting.action.spi.ActionExecutionResult;
2625
import com.chutneytesting.action.spi.injectable.Target;
2726
import com.chutneytesting.engine.domain.environment.TargetImpl;
2827
import com.chutneytesting.engine.domain.execution.RxBus;
2928
import com.chutneytesting.engine.domain.execution.ScenarioExecution;
3029
import com.chutneytesting.engine.domain.execution.StepDefinition;
3130
import com.chutneytesting.engine.domain.execution.engine.StepExecutor;
32-
import com.chutneytesting.engine.domain.execution.engine.evaluation.EvaluationException;
3331
import com.chutneytesting.engine.domain.execution.engine.evaluation.StepDataEvaluator;
3432
import com.chutneytesting.engine.domain.execution.engine.scenario.ScenarioContext;
35-
import com.chutneytesting.engine.domain.execution.engine.scenario.ScenarioContextImpl;
3633
import com.chutneytesting.engine.domain.execution.event.BeginStepExecutionEvent;
3734
import com.chutneytesting.engine.domain.execution.event.EndStepExecutionEvent;
3835
import com.chutneytesting.engine.domain.execution.event.PauseStepExecutionEvent;
3936
import com.chutneytesting.engine.domain.execution.report.Status;
4037
import com.chutneytesting.engine.domain.execution.report.StepExecutionReport;
4138
import com.chutneytesting.engine.domain.execution.strategies.StepStrategyDefinition;
4239
import com.chutneytesting.tools.Try;
43-
import com.fasterxml.jackson.core.JsonProcessingException;
44-
import com.fasterxml.jackson.databind.ObjectMapper;
4540
import com.google.common.collect.Lists;
46-
import com.google.common.collect.Maps;
4741
import java.time.Duration;
4842
import java.time.Instant;
4943
import java.util.Collections;
5044
import java.util.HashMap;
51-
import java.util.LinkedHashMap;
5245
import java.util.List;
5346
import java.util.Map;
5447
import java.util.Optional;
@@ -70,7 +63,6 @@ public class Step {
7063
private Target target;
7164
private final StepExecutor executor;
7265
private final StepDataEvaluator dataEvaluator;
73-
private static final ObjectMapper objectMapper = ExecutionConfiguration.reportObjectMapper();
7466
private StepContext stepContext;
7567

7668
public Step(StepDataEvaluator dataEvaluator, StepDefinition definition, StepExecutor executor, List<Step> steps) {
@@ -80,7 +72,7 @@ public Step(StepDataEvaluator dataEvaluator, StepDefinition definition, StepExec
8072
this.executor = executor;
8173
this.steps = steps;
8274
this.state = new StepState(definition.name);
83-
this.stepContext = new StepContext(objectMapper);
75+
this.stepContext = new StepContext();
8476
}
8577

8678
public static Step nonExecutable(StepDefinition definition) {
@@ -114,7 +106,7 @@ public Status execute(ScenarioExecution scenarioExecution, ScenarioContext scena
114106
target = dataEvaluator.evaluateTarget(target, evaluationContext);
115107
resolveName(evaluationContext);
116108
Try
117-
.exec(() -> this.stepContext = new StepContext(scenarioContext, localContext, evaluatedInputs, objectMapper))
109+
.exec(() -> this.stepContext = new StepContext(scenarioContext, localContext, evaluatedInputs))
118110
.ifSuccess(stepContextExecuted -> {
119111
executor.execute(scenarioExecution, target, this);
120112
if (Status.SUCCESS.equals(this.state.status())) {
@@ -157,10 +149,6 @@ public String name() {
157149
return this.state.name();
158150
}
159151

160-
public ObjectMapper getObjectMapper() {
161-
return objectMapper;
162-
}
163-
164152
public void resolveName(Map<String, Object> context) {
165153
this.state.setName(dataEvaluator.silentEvaluateString(state.name(), context));
166154
}
@@ -349,120 +337,15 @@ public Map<String, Object> getStepOutputs() {
349337
}
350338

351339
public Map<String, Object> getStepContextInputSnapshot() {
352-
return this.stepContext.stepContextSnapshot.getInputsSnapshot();
340+
return this.stepContext.getStepContextSnapshot().getInputsSnapshot();
353341
}
354342

355343
public Map<String, Object> getStepContextOutputSnapshot() {
356-
return this.stepContext.stepContextSnapshot.getOutputsSnapshot();
344+
return this.stepContext.getStepContextSnapshot().getOutputsSnapshot();
357345
}
358346

359347
public void removeStepExecution() {
360348
this.steps.clear();
361349
}
362350

363-
364-
private static class StepContext {
365-
366-
private final ScenarioContext scenarioContext;
367-
private final Map<String, Object> localContext;
368-
private final Map<String, Object> evaluatedInputs;
369-
private final Map<String, Object> stepOutputs;
370-
private StepContextSnapshot stepContextSnapshot;
371-
372-
private StepContext(ObjectMapper objectMapper) {
373-
this(new ScenarioContextImpl(), new LinkedHashMap<>(), new LinkedHashMap<>(), objectMapper);
374-
}
375-
376-
private StepContext(ScenarioContext scenarioContext, Map<String, Object> localContext, Map<String, Object> evaluatedInputs, ObjectMapper objectMapper) throws EvaluationException {
377-
this(scenarioContext, localContext, evaluatedInputs, new LinkedHashMap<>(), objectMapper);
378-
}
379-
380-
private StepContext(ScenarioContext scenarioContext, Map<String, Object> localContext, Map<String, Object> evaluatedInputs, Map<String, Object> stepOutputs, ObjectMapper objectMapper) {
381-
this.scenarioContext = scenarioContext;
382-
this.localContext = localContext;
383-
this.evaluatedInputs = evaluatedInputs;
384-
this.stepOutputs = stepOutputs;
385-
this.stepContextSnapshot = new StepContextSnapshot(objectMapper);
386-
}
387-
388-
private StepContext copySnapshotsInputOutput() {
389-
this.stepContextSnapshot = new StepContextSnapshot(evaluatedInputs, stepOutputs, objectMapper);
390-
return this;
391-
}
392-
393-
private Map<String, Object> evaluationContext() {
394-
final Map<String, Object> allResults = Maps.newLinkedHashMap(scenarioContext);
395-
allResults.putAll(localContext);
396-
allResults.putAll(stepOutputs);
397-
return allResults;
398-
}
399-
400-
private ScenarioContext getScenarioContext() {
401-
return scenarioContext;
402-
}
403-
404-
private Map<String, Object> getEvaluatedInputs() {
405-
return ofNullable(evaluatedInputs).orElse(emptyMap());
406-
}
407-
408-
private void addStepOutputs(Map<String, Object> stepOutputs) {
409-
if (stepOutputs != null) {
410-
this.stepOutputs.putAll(stepOutputs);
411-
}
412-
}
413-
414-
private void addScenarioContext(Map<String, Object> context) {
415-
if (context != null) {
416-
this.scenarioContext.putAll(context);
417-
}
418-
}
419-
420-
private Map<String, Object> getStepOutputs() {
421-
return ofNullable(stepOutputs).orElse(emptyMap());
422-
}
423-
424-
private StepContext copy() {
425-
return new StepContext(scenarioContext.unmodifiable(), unmodifiableMap(localContext), unmodifiableMap(evaluatedInputs), unmodifiableMap(stepOutputs), objectMapper).copySnapshotsInputOutput();
426-
}
427-
}
428-
429-
public static class StepContextSnapshot {
430-
private final Map<String, Object> inputsSnapshot;
431-
private final Map<String, Object> outputsSnapshot;
432-
private final ObjectMapper objectMapper;
433-
434-
public StepContextSnapshot(ObjectMapper objectMapper) {
435-
this.objectMapper = objectMapper;
436-
this.inputsSnapshot = emptyMap();
437-
this.outputsSnapshot = emptyMap();
438-
}
439-
440-
public StepContextSnapshot(Map<String, Object> inputsSnapshot, Map<String, Object> outputsSnapshot, ObjectMapper objectMapper) {
441-
this.objectMapper = objectMapper;
442-
this.inputsSnapshot = mapStringObjectToString(inputsSnapshot);
443-
this.outputsSnapshot = mapStringObjectToString(outputsSnapshot);
444-
}
445-
446-
public Map<String, Object> getInputsSnapshot() {
447-
return unmodifiableMap(inputsSnapshot);
448-
}
449-
450-
public Map<String, Object> getOutputsSnapshot() {
451-
return unmodifiableMap(outputsSnapshot);
452-
}
453-
454-
private Map<String, Object> mapStringObjectToString(Map<String, Object> originalMap) {
455-
Map<String, Object> stringMap = new HashMap<>();
456-
originalMap.forEach((key, value) -> {
457-
try {
458-
String stringObject = objectMapper.writeValueAsString(value);
459-
Object jsonObject = objectMapper.readTree(stringObject);
460-
stringMap.put(key, jsonObject);
461-
} catch (JsonProcessingException e) {
462-
throw new RuntimeException(e);
463-
}
464-
});
465-
return stringMap;
466-
}
467-
}
468351
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright 2017-2023 Enedis
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package com.chutneytesting.engine.domain.execution.engine.step;
19+
20+
import static java.util.Collections.emptyMap;
21+
import static java.util.Collections.unmodifiableMap;
22+
import static java.util.Optional.ofNullable;
23+
24+
import com.chutneytesting.engine.domain.execution.engine.evaluation.EvaluationException;
25+
import com.chutneytesting.engine.domain.execution.engine.scenario.ScenarioContext;
26+
import com.chutneytesting.engine.domain.execution.engine.scenario.ScenarioContextImpl;
27+
import com.chutneytesting.engine.domain.execution.engine.step.jackson.ReportObjectMapperConfiguration;
28+
import com.fasterxml.jackson.core.JsonProcessingException;
29+
import com.google.common.collect.Maps;
30+
import java.util.HashMap;
31+
import java.util.LinkedHashMap;
32+
import java.util.Map;
33+
34+
class StepContext {
35+
36+
private final ScenarioContext scenarioContext;
37+
private final Map<String, Object> localContext;
38+
private final Map<String, Object> evaluatedInputs;
39+
private final Map<String, Object> stepOutputs;
40+
private StepContextSnapshot stepContextSnapshot;
41+
42+
StepContext() {
43+
this(new ScenarioContextImpl(), new LinkedHashMap<>(), new LinkedHashMap<>());
44+
}
45+
46+
StepContext(ScenarioContext scenarioContext, Map<String, Object> localContext, Map<String, Object> evaluatedInputs) throws EvaluationException {
47+
this(scenarioContext, localContext, evaluatedInputs, new LinkedHashMap<>());
48+
}
49+
50+
private StepContext(ScenarioContext scenarioContext, Map<String, Object> localContext, Map<String, Object> evaluatedInputs, Map<String, Object> stepOutputs) {
51+
this.scenarioContext = scenarioContext;
52+
this.localContext = localContext;
53+
this.evaluatedInputs = evaluatedInputs;
54+
this.stepOutputs = stepOutputs;
55+
this.stepContextSnapshot = new StepContextSnapshot();
56+
}
57+
58+
private StepContext copySnapshotsInputOutput() {
59+
this.stepContextSnapshot = new StepContextSnapshot(evaluatedInputs, stepOutputs);
60+
return this;
61+
}
62+
63+
public StepContextSnapshot getStepContextSnapshot() {
64+
return stepContextSnapshot;
65+
}
66+
67+
Map<String, Object> evaluationContext() {
68+
final Map<String, Object> allResults = Maps.newLinkedHashMap(scenarioContext);
69+
allResults.putAll(localContext);
70+
allResults.putAll(stepOutputs);
71+
return allResults;
72+
}
73+
74+
ScenarioContext getScenarioContext() {
75+
return scenarioContext;
76+
}
77+
78+
Map<String, Object> getEvaluatedInputs() {
79+
return ofNullable(evaluatedInputs).orElse(emptyMap());
80+
}
81+
82+
void addStepOutputs(Map<String, Object> stepOutputs) {
83+
if (stepOutputs != null) {
84+
this.stepOutputs.putAll(stepOutputs);
85+
}
86+
}
87+
88+
void addScenarioContext(Map<String, Object> context) {
89+
if (context != null) {
90+
this.scenarioContext.putAll(context);
91+
}
92+
}
93+
94+
Map<String, Object> getStepOutputs() {
95+
return ofNullable(stepOutputs).orElse(emptyMap());
96+
}
97+
98+
StepContext copy() {
99+
return new StepContext(scenarioContext.unmodifiable(), unmodifiableMap(localContext), unmodifiableMap(evaluatedInputs), unmodifiableMap(stepOutputs)).copySnapshotsInputOutput();
100+
}
101+
}

0 commit comments

Comments
 (0)