Add capability to set provider states for RequestResponsePact. Fixes gh-1740 (#1743)
Co-authored-by: U118971 <U118971@mobi.ch> fixes gh-1740
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.verifier.spec.pact;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import au.com.dius.pact.core.model.ProviderState;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.util.MetadataUtil;
|
||||
import org.springframework.cloud.contract.verifier.util.SpringCloudContractMetadata;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
public class PactMetaData implements SpringCloudContractMetadata {
|
||||
|
||||
/**
|
||||
* Key under which this metadata entry can be found in contract's metadata.
|
||||
*/
|
||||
public static final String METADATA_KEY = "pact";
|
||||
|
||||
/**
|
||||
* Metadata for adding {@link ProviderState} in Pact contract.
|
||||
*/
|
||||
private List<ProviderStateMetadata> providerStates = new ArrayList<>();
|
||||
|
||||
public List<ProviderStateMetadata> getProviderStates() {
|
||||
return this.providerStates;
|
||||
}
|
||||
|
||||
public void setProviderStates(List<ProviderStateMetadata> providerStates) {
|
||||
this.providerStates = providerStates;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static PactMetaData fromMetadata(Map<String, Object> metadata) {
|
||||
return MetadataUtil.fromMetadata(metadata, PactMetaData.METADATA_KEY, new PactMetaData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return METADATA_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Metadata for converting Contract to Pact";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ProviderState} metadata.
|
||||
*/
|
||||
public static class ProviderStateMetadata {
|
||||
|
||||
/**
|
||||
* If set, will be added to PACT provider states.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
private Map<String, Object> params;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams() {
|
||||
return this.params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -30,6 +31,7 @@ import au.com.dius.pact.consumer.dsl.DslPart;
|
||||
import au.com.dius.pact.consumer.dsl.PactDslRequestWithPath;
|
||||
import au.com.dius.pact.consumer.dsl.PactDslResponse;
|
||||
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
|
||||
import au.com.dius.pact.consumer.dsl.PactDslWithState;
|
||||
import au.com.dius.pact.core.model.RequestResponsePact;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -107,14 +109,10 @@ class RequestResponsePactCreator {
|
||||
}
|
||||
|
||||
private PactDslRequestWithPath createPactDslRequestWithPath(Contract contract, PactDslResponse pactDslResponse) {
|
||||
PactDslRequestWithPath pactDslRequest = getPactDslRequest(contract,
|
||||
getPactDslWithStateFunction(pactDslResponse),
|
||||
getPactDslRequestWithPathBiFunction(pactDslResponse));
|
||||
Request request = contract.getRequest();
|
||||
PactDslRequestWithPath pactDslRequest = pactDslResponse
|
||||
.uponReceiving(StringUtils.isNotBlank(contract.getDescription()) ? contract.getDescription() : "")
|
||||
.path(url(request)).method(request.getMethod().getServerValue().toString());
|
||||
String query = query(request);
|
||||
if (StringUtils.isNotBlank(query)) {
|
||||
pactDslRequest = pactDslRequest.encodedQuery(query);
|
||||
}
|
||||
final PactDslRequestWithPath finalPactDslRequest = pactDslRequest;
|
||||
if (request.getHeaders() != null) {
|
||||
request.getHeaders().getEntries().forEach(h -> processHeader(finalPactDslRequest, h));
|
||||
@@ -134,23 +132,27 @@ class RequestResponsePactCreator {
|
||||
return pactDslRequest;
|
||||
}
|
||||
|
||||
private Function<PactMetaData.ProviderStateMetadata, PactDslWithState> getPactDslWithStateFunction(
|
||||
PactDslResponse pactDslResponse) {
|
||||
return stateMetadata -> pactDslResponse.given(stateMetadata.getName(), stateMetadata.getParams());
|
||||
}
|
||||
|
||||
private BiFunction<String, Request, PactDslRequestWithPath> getPactDslRequestWithPathBiFunction(
|
||||
PactDslResponse pactDslResponse) {
|
||||
return (description, request) -> pactDslResponse.uponReceiving(description).path(url(request))
|
||||
.method(request.getMethod().getServerValue().toString());
|
||||
}
|
||||
|
||||
private PactDslRequestWithPath createPactDslRequestWithPath(Contract contract,
|
||||
PactDslWithProvider pactDslWithProvider) {
|
||||
PactDslRequestWithPath pactDslRequest = getPactDslRequest(contract,
|
||||
getPactDslWithStateFunction(pactDslWithProvider),
|
||||
getPactDslRequestWithPathBiFunction(pactDslWithProvider));
|
||||
Request request = contract.getRequest();
|
||||
PactDslRequestWithPath pactDslRequest = pactDslWithProvider
|
||||
.uponReceiving(StringUtils.isNotBlank(contract.getDescription()) ? contract.getDescription() : "")
|
||||
.path(url(request)).method(request.getMethod().getServerValue().toString());
|
||||
String query = query(request);
|
||||
if (StringUtils.isNotBlank(query)) {
|
||||
pactDslRequest = pactDslRequest.encodedQuery(query);
|
||||
}
|
||||
final PactDslRequestWithPath finalPactDslRequest = pactDslRequest;
|
||||
if (request.getHeaders() != null) {
|
||||
request.getHeaders().getEntries().forEach(h -> {
|
||||
processHeader(finalPactDslRequest, h);
|
||||
});
|
||||
request.getHeaders().getEntries().forEach(h -> processHeader(finalPactDslRequest, h));
|
||||
}
|
||||
|
||||
if (request.getBody() != null) {
|
||||
DslPart pactRequestBody = BodyConverter.toPactBody(request.getBody(), DslProperty::getServerValue);
|
||||
if (request.getBodyMatchers() != null) {
|
||||
@@ -163,6 +165,57 @@ class RequestResponsePactCreator {
|
||||
return pactDslRequest;
|
||||
}
|
||||
|
||||
private Function<PactMetaData.ProviderStateMetadata, PactDslWithState> getPactDslWithStateFunction(
|
||||
PactDslWithProvider pactDslWithProvider) {
|
||||
return stateMetadata -> pactDslWithProvider.given(stateMetadata.getName(), stateMetadata.getParams());
|
||||
}
|
||||
|
||||
private BiFunction<String, Request, PactDslRequestWithPath> getPactDslRequestWithPathBiFunction(
|
||||
PactDslWithProvider pactDslWithProvider) {
|
||||
return (description, request) -> pactDslWithProvider.uponReceiving(description).path(url(request))
|
||||
.method(request.getMethod().getServerValue().toString());
|
||||
}
|
||||
|
||||
private PactDslRequestWithPath getPactDslRequest(Contract contract,
|
||||
Function<PactMetaData.ProviderStateMetadata, PactDslWithState> pactDslWithStateFunction,
|
||||
BiFunction<String, Request, PactDslRequestWithPath> pactDslRequestWithPathBiFunction) {
|
||||
PactDslWithState pactDslWithState = getPactDslWithState(contract, pactDslWithStateFunction);
|
||||
String description = StringUtils.isNotBlank(contract.getDescription()) ? contract.getDescription() : "";
|
||||
Request request = contract.getRequest();
|
||||
PactDslRequestWithPath pactDslRequest;
|
||||
if (pactDslWithState != null) {
|
||||
pactDslRequest = pactDslWithState.uponReceiving(description).path(url(request))
|
||||
.method(request.getMethod().getServerValue().toString());
|
||||
}
|
||||
else {
|
||||
pactDslRequest = pactDslRequestWithPathBiFunction.apply(description, request);
|
||||
}
|
||||
String query = query(request);
|
||||
if (StringUtils.isNotBlank(query)) {
|
||||
pactDslRequest = pactDslRequest.encodedQuery(query);
|
||||
}
|
||||
return pactDslRequest;
|
||||
}
|
||||
|
||||
private PactDslWithState getPactDslWithState(Contract contract,
|
||||
Function<PactMetaData.ProviderStateMetadata, PactDslWithState> pactDslWithStateFunction) {
|
||||
PactDslWithState pactDslWithState = null;
|
||||
if (contract.getMetadata().containsKey(PactMetaData.METADATA_KEY)) {
|
||||
PactMetaData metadata = PactMetaData.fromMetadata(contract.getMetadata());
|
||||
if (!metadata.getProviderStates().isEmpty()) {
|
||||
for (PactMetaData.ProviderStateMetadata stateMetadata : metadata.getProviderStates()) {
|
||||
if (pactDslWithState == null) {
|
||||
pactDslWithState = pactDslWithStateFunction.apply(stateMetadata);
|
||||
}
|
||||
else {
|
||||
pactDslWithState = pactDslWithState.given(stateMetadata.getName(), stateMetadata.getParams());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return pactDslWithState;
|
||||
}
|
||||
|
||||
private String url(Request request) {
|
||||
if (request.getUrlPath() != null) {
|
||||
return request.getUrlPath().getServerValue().toString();
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.verifier.spec.pact;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class PactMetaDataTests {
|
||||
|
||||
YAMLMapper mapper = new YAMLMapper();
|
||||
|
||||
@Test
|
||||
void should_parse_the_metadata_entry() throws JsonProcessingException {
|
||||
// @formatter:off
|
||||
String yamlEntry = ""
|
||||
+ "pact:\n"
|
||||
+ " providerStates:\n"
|
||||
+ " - name: state1\n"
|
||||
+ " params:\n"
|
||||
+ " id: 1\n"
|
||||
+ " value: value1\n"
|
||||
+ " - name: state2\n"
|
||||
+ " params:\n"
|
||||
+ " id: 2\n"
|
||||
+ " value: value2";
|
||||
// @formatter:on
|
||||
|
||||
PactMetaData metadata = PactMetaData
|
||||
.fromMetadata(this.mapper.readerForMapOf(Object.class).readValue(yamlEntry));
|
||||
|
||||
String serialized = this.mapper.writer().forType(PactMetaData.class).writeValueAsString(metadata);
|
||||
BDDAssertions.then(serialized).isEqualToNormalizingPunctuationAndWhitespace(yamlEntry.replace("pact:\n", ""));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,4 +56,25 @@ org.springframework.cloud.contract.spec.Contract.make {
|
||||
contentType('application/json')
|
||||
}
|
||||
}
|
||||
metadata([
|
||||
pact: [
|
||||
providerStates:
|
||||
[
|
||||
[
|
||||
name: "someState1",
|
||||
params: [
|
||||
id: 1,
|
||||
value: "someValue1"
|
||||
]
|
||||
],
|
||||
[
|
||||
name: "someState2",
|
||||
params: [
|
||||
id: 2,
|
||||
value: "someValue2"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
])
|
||||
}
|
||||
|
||||
@@ -266,7 +266,23 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "someState1",
|
||||
"params": {
|
||||
"id": 1,
|
||||
"value": "someValue1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "someState2",
|
||||
"params": {
|
||||
"id": 2,
|
||||
"value": "someValue2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
Reference in New Issue
Block a user