Skip to content
This repository was archived by the owner on Sep 9, 2024. It is now read-only.

Commit f2d16f6

Browse files
committed
feat: Get runExample working
1 parent e902547 commit f2d16f6

5 files changed

Lines changed: 228 additions & 139 deletions

File tree

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ repositories {
1313
mavenLocal()
1414
}
1515

16-
def caseCoreVersion = "0.13.0"
16+
def caseCoreVersion = "0.15.2"
1717
def grpcVersion = "1.60.1"
1818

1919
dependencies {
@@ -27,7 +27,7 @@ dependencies {
2727
implementation "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
2828
implementation "io.grpc:grpc-core:${grpcVersion}"
2929
implementation "io.grpc:grpc-stub:${grpcVersion}"
30-
implementation "io.grpc:grpc-netty-shaded:${grpcVersion}"
30+
implementation "io.grpc:grpc-okhttp:${grpcVersion}"
3131
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
3232
implementation 'com.fasterxml.jackson.core:jackson-databind:2.16.1'
3333
implementation 'org.jetbrains:annotations:23.0.0'

src/main/java/io/contract_testing/contractcase/ExampleDefinition.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package io.contract_testing.contractcase;
22

3-
import com.fasterxml.jackson.core.TreeNode;
3+
import com.fasterxml.jackson.core.JsonProcessingException;
44
import com.fasterxml.jackson.databind.JsonNode;
55
import com.fasterxml.jackson.databind.ObjectMapper;
66
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -29,7 +29,11 @@ public List<? extends Object> getStates() {
2929
public JsonNode toJSON() {
3030
var mapper = new ObjectMapper();
3131
ObjectNode node = mapper.createObjectNode();
32-
node.set("definition", mapper.valueToTree(definition.toJSON()));
32+
try {
33+
node.set("definition", mapper.valueToTree(mapper.readTree(definition.stringify())));
34+
} catch (JsonProcessingException e) {
35+
throw new RuntimeException(e);
36+
}
3337
node.set("states",
3438
mapper.createArrayNode()
3539
.addAll(this.states.stream()

src/main/java/io/contract_testing/contractcase/client/InternalDefinerClient.java

Lines changed: 98 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,26 @@ public class InternalDefinerClient {
6363

6464
public static final String CONTRACT_CASE_JAVA_WRAPPER = "ContractCase Java DSL";
6565
private static final int DEFAULT_PORT = 50200;
66+
public static final String CONTRACT_CASE_TRIGGER_AND_TEST = "ContractCase::TriggerAndTest";
6667
private final ILogPrinter logPrinter;
6768
private final IResultPrinter resultPrinter;
6869
private final List<String> parentVersions;
69-
private final ContractCaseConfig config;
7070
private final StreamObserver<DefinitionRequest> requestObserver;
7171

7272
private final ConcurrentMap<String, CompletableFuture<ContractCaseStream.BoundaryResult>> responseFutures = new ConcurrentHashMap<>();
7373

7474
private final AtomicInteger nextId = new AtomicInteger();
75+
private ContractCaseBoundaryConfig boundaryConfig;
7576

7677
private Status errorStatus;
7778

7879

79-
public InternalDefinerClient(final @NotNull ContractCaseBoundaryConfig config,
80+
public InternalDefinerClient(final @NotNull ContractCaseBoundaryConfig boundaryConfig,
8081
final @NotNull ILogPrinter logPrinter,
8182
final @NotNull IResultPrinter resultPrinter,
8283
final @NotNull List<String> parentVersions) {
8384
ResultTypeConstantsCopy.validate();
84-
this.config = mapConfig(config);
85+
8586
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", DEFAULT_PORT)
8687
.usePlaintext()
8788
.build();
@@ -91,76 +92,77 @@ public InternalDefinerClient(final @NotNull ContractCaseBoundaryConfig config,
9192
this.resultPrinter = resultPrinter;
9293
this.parentVersions = parentVersions;
9394

94-
BoundaryResultMapper.map(begin());
95+
BoundaryResultMapper.map(begin(mapConfig(boundaryConfig)));
9596
}
9697

9798
private ContractCaseConfig mapConfig(final @NotNull ContractCaseBoundaryConfig config) {
99+
this.boundaryConfig = config;
98100
var builder = ContractCaseConfig.newBuilder();
99101

100102
if (config.getBrokerBasicAuth() != null) {
101103
var auth = config.getBrokerBasicAuth();
102104
builder.setBrokerBasicAuth(UsernamePassword.newBuilder()
103-
.setPassword(auth.getPassword())
104-
.setUsername(auth.getUsername())
105+
.setPassword(ValueMapper.map(auth.getPassword()))
106+
.setUsername(ValueMapper.map(auth.getUsername()))
105107
.build());
106108
}
107109

108110
if (config.getPrintResults() != null) {
109-
builder.setPrintResults(config.getPrintResults());
111+
builder.setPrintResults(ValueMapper.map(config.getPrintResults()));
110112
}
111113
if (config.getThrowOnFail() != null) {
112-
builder.setThrowOnFail(config.getThrowOnFail());
114+
builder.setThrowOnFail(ValueMapper.map(config.getThrowOnFail()));
113115
}
114116
if (config.getTriggerAndTests() != null) {
115117
config.getTriggerAndTests()
116118
.forEach((key, value) -> builder.putTriggerAndTests(key,
117-
TriggerFunctionHandle.newBuilder().setHandle(key).build()));
119+
TriggerFunctionHandle.newBuilder().setHandle(ValueMapper.map(key)).build()));
118120
}
119121
if (config.getTriggerAndTest() != null) {
120122
builder.setTriggerAndTest(TriggerFunctionHandle.newBuilder()
121-
.setHandle("ContractCase::TriggerAndTest")
123+
.setHandle(ValueMapper.map(CONTRACT_CASE_TRIGGER_AND_TEST))
122124
.build());
123125
}
124126

125127
if (config.getStateHandlers() != null) {
126128
// TODO: TEARDOWN FUNCTION
127129
config.getStateHandlers().forEach((key, value) -> {
128130
builder.addStateHandlers(StateHandlerHandle.newBuilder()
129-
.setHandle(key)
131+
.setHandle(ValueMapper.map(key))
130132
.setStage(Stage.STAGE_SETUP_UNSPECIFIED)
131133
.build());
132134
});
133135
}
134136

135137
if (config.getBaseUrlUnderTest() != null) {
136-
builder.setBaseUrlUnderTest(config.getBaseUrlUnderTest());
138+
builder.setBaseUrlUnderTest(ValueMapper.map(config.getBaseUrlUnderTest()));
137139
}
138140

139141
if (config.getBrokerBaseUrl() != null) {
140-
builder.setBrokerBaseUrl(config.getBrokerBaseUrl());
142+
builder.setBrokerBaseUrl(ValueMapper.map(config.getBrokerBaseUrl()));
141143
}
142144
if (config.getBrokerCiAccessToken() != null) {
143-
builder.setBrokerCiAccessToken(config.getBrokerCiAccessToken());
145+
builder.setBrokerCiAccessToken(ValueMapper.map(config.getBrokerCiAccessToken()));
144146
}
145147

146148
if (config.getConsumerName() != null) {
147-
builder.setConsumerName(config.getConsumerName());
149+
builder.setConsumerName(ValueMapper.map(config.getConsumerName()));
148150
}
149151
if (config.getContractDir() != null) {
150-
builder.setContractDir(config.getContractDir());
152+
builder.setContractDir(ValueMapper.map(config.getContractDir()));
151153
}
152154
if (config.getContractFilename() != null) {
153-
builder.setContractFilename(config.getContractFilename());
155+
builder.setContractFilename(ValueMapper.map(config.getContractFilename()));
154156
}
155157
if (config.getLogLevel() != null) {
156-
builder.setLogLevel(config.getLogLevel());
158+
builder.setLogLevel(ValueMapper.map(config.getLogLevel()));
157159
}
158160
if (config.getProviderName() != null) {
159-
builder.setProviderName(config.getProviderName());
161+
builder.setProviderName(ValueMapper.map(config.getProviderName()));
160162
}
161163

162164
if (config.getPublish() != null) {
163-
builder.setPublish(config.getPublish());
165+
builder.setPublish(ValueMapper.map(config.getPublish()));
164166
}
165167

166168
return builder.build();
@@ -176,7 +178,7 @@ private BoundaryResult executeCallAndWait(Builder builder) {
176178

177179
var future = new CompletableFuture<ContractCaseStream.BoundaryResult>();
178180
responseFutures.put(id, future);
179-
requestObserver.onNext(builder.setId(id).build());
181+
requestObserver.onNext(builder.setId(ValueMapper.map(id)).build());
180182

181183
try {
182184
return mapBoundaryResult(future.get(3, TimeUnit.SECONDS));
@@ -211,7 +213,7 @@ private void completeWait(String id, ContractCaseStream.BoundaryResult result) {
211213
}
212214

213215
private void sendResponse(Builder builder, String id) {
214-
requestObserver.onNext(builder.setId(id).build());
216+
requestObserver.onNext(builder.setId(ValueMapper.map(id)).build());
215217
}
216218

217219
private BoundaryResult mapBoundaryResult(ContractCaseStream.BoundaryResult wireBoundaryResult) {
@@ -229,9 +231,9 @@ private BoundaryResult mapBoundaryResult(ContractCaseStream.BoundaryResult wireB
229231
"undefined wireFailure in a boundary result. This is probably an error in the connector server library.",
230232
CONTRACT_CASE_JAVA_WRAPPER);
231233
}
232-
return new BoundaryFailure(wireFailure.getKind(),
233-
wireFailure.getMessage(),
234-
wireFailure.getLocation());
234+
return new BoundaryFailure(ValueMapper.map(wireFailure.getKind()),
235+
ValueMapper.map(wireFailure.getMessage()),
236+
ValueMapper.map(wireFailure.getLocation()));
235237
}
236238
case SUCCESS -> {
237239
return new BoundarySuccess();
@@ -271,15 +273,16 @@ private Map<String, Object> mapJson(Value payload) {
271273

272274

273275
private Map<String, Object> mapJsonMap(Struct map) {
276+
var m = map.getFieldsMap();
274277
// TODO
275278
throw new RuntimeException("Not implemented");
276279
}
277280

278-
private BoundaryResult begin() {
281+
private BoundaryResult begin(ContractCaseConfig wireConfig) {
279282
return executeCallAndWait(DefinitionRequest.newBuilder()
280283
.setBeginDefinition(BeginDefinitionRequest.newBuilder()
281-
.addAllCallerVersions(parentVersions)
282-
.setConfig(config)
284+
.addAllCallerVersions(parentVersions.stream().map(ValueMapper::map).toList())
285+
.setConfig(wireConfig)
283286
.build()));
284287
}
285288

@@ -297,12 +300,12 @@ private BoundaryResult begin() {
297300

298301
public @NotNull BoundaryResult runExample(JsonNode definition,
299302
@NotNull ContractCaseBoundaryConfig runConfig) {
300-
301303
var structBuilder = Struct.newBuilder();
302304

303305
try {
306+
var string = new ObjectMapper().writeValueAsString(definition);
304307
JsonFormat.parser()
305-
.merge(new ObjectMapper().writeValueAsString(definition), structBuilder);
308+
.merge(string, structBuilder);
306309
} catch (JsonProcessingException | InvalidProtocolBufferException e) {
307310
throw new RuntimeException(e);
308311
}
@@ -337,9 +340,9 @@ private static ContractCaseStream.BoundaryResult mapResult(@NotNull BoundaryResu
337340
var failure = ((BoundaryFailure) result);
338341
yield ContractCaseStream.BoundaryResult.newBuilder()
339342
.setFailure(ResultFailure.newBuilder()
340-
.setKind(failure.getKind())
341-
.setLocation(failure.getLocation())
342-
.setMessage(failure.getMessage())
343+
.setKind(ValueMapper.map(failure.getKind()))
344+
.setLocation(ValueMapper.map(failure.getLocation()))
345+
.setMessage(ValueMapper.map(failure.getMessage()))
343346
.build())
344347
.build();
345348
}
@@ -357,9 +360,10 @@ private static ContractCaseStream.BoundaryResult mapResult(@NotNull BoundaryResu
357360
.build();
358361
default -> ContractCaseStream.BoundaryResult.newBuilder()
359362
.setFailure(ResultFailure.newBuilder()
360-
.setKind(BoundaryFailureKindConstants.CASE_CORE_ERROR)
361-
.setLocation(CONTRACT_CASE_JAVA_WRAPPER)
362-
.setMessage("Tried to map an unknown result type: " + result.getResultType())
363+
.setKind(ValueMapper.map(BoundaryFailureKindConstants.CASE_CORE_ERROR))
364+
.setLocation(ValueMapper.map(CONTRACT_CASE_JAVA_WRAPPER))
365+
.setMessage(ValueMapper.map(
366+
"Tried to map an unknown result type: " + result.getResultType()))
363367
.build())
364368
.build();
365369
};
@@ -389,84 +393,104 @@ public void onNext(DefinitionResponse note) {
389393
.setStateHandlerResponse(StateHandlerResponse.newBuilder()
390394
.setResult(ContractCaseStream.BoundaryResult.newBuilder()
391395
.setSuccess(ResultSuccess.newBuilder().build())
392-
.build())), note.getId());
396+
.build())), ValueMapper.map(note.getId()));
393397
}
394398
case LOG_REQUEST -> {
395399
var logRequest = note.getLogRequest();
396400
sendResponse(DefinitionRequest.newBuilder()
397-
.setLogPrinterResponse(LogPrinterResponse.newBuilder()
398-
.setResult(mapResult(logPrinter.log(logRequest.getLevel(),
399-
logRequest.getTimestamp(),
400-
logRequest.getVersion(),
401-
logRequest.getTypeString(),
402-
logRequest.getLocation(),
403-
logRequest.getMessage(),
404-
logRequest.getAdditional())))), note.getId());
401+
.setLogPrinterResponse(LogPrinterResponse.newBuilder()
402+
.setResult(mapResult(logPrinter.log(ValueMapper.map(logRequest.getLevel()),
403+
ValueMapper.map(logRequest.getTimestamp()),
404+
ValueMapper.map(logRequest.getVersion()),
405+
ValueMapper.map(logRequest.getTypeString()),
406+
ValueMapper.map(logRequest.getLocation()),
407+
ValueMapper.map(logRequest.getMessage()),
408+
ValueMapper.map(logRequest.getAdditional()))))),
409+
ValueMapper.map(note.getId()));
405410
}
406411
case PRINT_MATCH_ERROR_REQUEST -> {
407412
var printMatchErrorRequest = note.getPrintMatchErrorRequest();
408413
sendResponse(DefinitionRequest.newBuilder()
409414
.setResultPrinterResponse(ResultPrinterResponse.newBuilder()
410415
.setResult(mapResult(resultPrinter.printMatchError(PrintableMatchError.builder()
411-
.kind(printMatchErrorRequest.getKind())
412-
.expected(printMatchErrorRequest.getExpected())
413-
.actual(printMatchErrorRequest.getActual())
414-
.errorTypeTag(printMatchErrorRequest.getErrorTypeTag())
415-
.location(printMatchErrorRequest.getLocation())
416-
.message(printMatchErrorRequest.getMessage())
417-
.build())))), note.getId());
416+
.kind(ValueMapper.map(printMatchErrorRequest.getKind()))
417+
.expected(ValueMapper.map(printMatchErrorRequest.getExpected()))
418+
.actual(ValueMapper.map(printMatchErrorRequest.getActual()))
419+
.errorTypeTag(ValueMapper.map(printMatchErrorRequest.getErrorTypeTag()))
420+
.location(ValueMapper.map(printMatchErrorRequest.getLocation()))
421+
.message(ValueMapper.map(printMatchErrorRequest.getMessage()))
422+
.build())))), ValueMapper.map(note.getId()));
418423
}
419424
case PRINT_MESSAGE_ERROR_REQUEST -> {
420425
var printMessageErrorRequest = note.getPrintMessageErrorRequest();
421426
sendResponse(DefinitionRequest.newBuilder()
422427
.setResultPrinterResponse(ResultPrinterResponse.newBuilder()
423428
.setResult(mapResult(resultPrinter.printMessageError(PrintableMessageError.builder()
424-
.errorTypeTag(printMessageErrorRequest.getErrorTypeTag())
425-
.kind(printMessageErrorRequest.getKind())
426-
.location(printMessageErrorRequest.getLocation())
427-
.locationTag(printMessageErrorRequest.getLocationTag())
428-
.message(printMessageErrorRequest.getMessage())
429-
.build())))), note.getId());
429+
.errorTypeTag(ValueMapper.map(printMessageErrorRequest.getErrorTypeTag()))
430+
.kind(ValueMapper.map(printMessageErrorRequest.getKind()))
431+
.location(ValueMapper.map(printMessageErrorRequest.getLocation()))
432+
.locationTag(ValueMapper.map(printMessageErrorRequest.getLocationTag()))
433+
.message(ValueMapper.map(printMessageErrorRequest.getMessage()))
434+
.build())))), ValueMapper.map(note.getId()));
430435
}
431436
case PRINT_TEST_TITLE_REQUEST -> {
432437
var printTestTitleRequest = note.getPrintTestTitleRequest();
433438
sendResponse(DefinitionRequest.newBuilder()
434439
.setResultPrinterResponse(ResultPrinterResponse.newBuilder()
435440
.setResult(mapResult(resultPrinter.printTestTitle(PrintableTestTitle.builder()
436-
.title(printTestTitleRequest.getTitle())
437-
.kind(printTestTitleRequest.getKind())
438-
.additionalText(printTestTitleRequest.getAdditionalText())
439-
.icon(printTestTitleRequest.getIcon())
440-
.build())))), note.getId());
441+
.title(ValueMapper.map(printTestTitleRequest.getTitle()))
442+
.kind(ValueMapper.map(printTestTitleRequest.getKind()))
443+
.additionalText(ValueMapper.map(printTestTitleRequest.getAdditionalText()))
444+
.icon(ValueMapper.map(printTestTitleRequest.getIcon()))
445+
.build())))), ValueMapper.map(note.getId()));
441446
}
442447
case TRIGGER_FUNCTION_REQUEST -> {
443448
var triggerFunctionRequest = note.getTriggerFunctionRequest();
444-
// TODO Implement this properly
445-
sendResponse(DefinitionRequest.newBuilder()
446-
.setTriggerFunctionResponse(TriggerFunctionResponse.newBuilder()
447-
.setResult(ContractCaseStream.BoundaryResult.newBuilder()
448-
.setSuccess(ResultSuccess.newBuilder().build())
449-
.build())), note.getId());
449+
var handle = ValueMapper.map(triggerFunctionRequest.getTriggerFunction().getHandle());
450+
if (handle == null) {
451+
throw new ContractCaseCoreError(
452+
"Received a trigger request message with a null trigger handle",
453+
"Java Internal Connector");
454+
}
455+
456+
if (handle.equals(CONTRACT_CASE_TRIGGER_AND_TEST)) {
457+
sendResponse(DefinitionRequest.newBuilder()
458+
.setTriggerFunctionResponse(TriggerFunctionResponse.newBuilder()
459+
// TODO fix null case
460+
.setResult(mapResult(boundaryConfig.getTriggerAndTest()
461+
.trigger(ValueMapper.map(triggerFunctionRequest.getConfig()))
462+
))), ValueMapper.map(note.getId()));
463+
} else {
464+
sendResponse(DefinitionRequest.newBuilder()
465+
.setTriggerFunctionResponse(TriggerFunctionResponse.newBuilder()
466+
.setResult(mapResult(boundaryConfig.getTriggerAndTests()
467+
.get(handle)
468+
// TODO fix null case
469+
.trigger(ValueMapper.map(triggerFunctionRequest.getConfig()))
470+
))), ValueMapper.map(note.getId()));
471+
}
472+
473+
450474
}
451475
case BEGIN_DEFINITION_RESPONSE -> {
452476
var beginDefinitionResponse = note.getBeginDefinitionResponse();
453-
completeWait(note.getId(), beginDefinitionResponse.getResult());
477+
completeWait(ValueMapper.map(note.getId()), beginDefinitionResponse.getResult());
454478
}
455479
case RUN_EXAMPLE_RESPONSE -> {
456480
var runExampleResponse = note.getRunExampleResponse();
457-
completeWait(note.getId(), runExampleResponse.getResult());
481+
completeWait(ValueMapper.map(note.getId()), runExampleResponse.getResult());
458482
}
459483
case RUN_REJECTING_EXAMPLE_RESPONSE -> {
460484
var runRejectingExampleResponse = note.getRunRejectingExampleResponse();
461-
completeWait(note.getId(), runRejectingExampleResponse.getResult());
485+
completeWait(ValueMapper.map(note.getId()), runRejectingExampleResponse.getResult());
462486
}
463487
case STRIP_MATCHERS_RESPONSE -> {
464488
var stripMatchersResponse = note.getStripMatchersResponse();
465-
completeWait(note.getId(), stripMatchersResponse.getResult());
489+
completeWait(ValueMapper.map(note.getId()), stripMatchersResponse.getResult());
466490
}
467491
case END_DEFINITION_RESPONSE -> {
468492
var endDefinitionResponse = note.getEndDefinitionResponse();
469-
completeWait(note.getId(), endDefinitionResponse.getResult());
493+
completeWait(ValueMapper.map(note.getId()), endDefinitionResponse.getResult());
470494
}
471495
case KIND_NOT_SET -> {
472496
throw new ContractCaseCoreError("Received a message with no kind set",

0 commit comments

Comments
 (0)