committed by
GitHub
parent
2c5b71222a
commit
a2fac97148
@@ -439,3 +439,188 @@ Contract.make {
|
||||
|
||||
The generated document (formatted in Asciidoc in this case) contains a formatted
|
||||
contract. The location of this file would be `index/dsl-contract.adoc`.
|
||||
|
||||
[[features-graphql]]
|
||||
=== GraphQL
|
||||
|
||||
Since https://graphql.org/[GraphQL] is essentially HTTP you can write a contract for it by creating a standard HTTP contract with an additional `metadata` entry with key `verifier` and a mapping `tool=graphql`.
|
||||
|
||||
====
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Groovy
|
||||
----
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
|
||||
Contract.make {
|
||||
|
||||
request {
|
||||
method(POST())
|
||||
url("/graphql")
|
||||
headers {
|
||||
contentType("application/json")
|
||||
}
|
||||
body('''
|
||||
{
|
||||
"query":"query queryName($personName: String!) {\\n personToCheck(name: $personName) {\\n name\\n age\\n }\\n}\\n\\n\\n\\n",
|
||||
"variables":{"personName":"Old Enough"},
|
||||
"operationName":"queryName"
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
response {
|
||||
status(200)
|
||||
headers {
|
||||
contentType("application/json")
|
||||
}
|
||||
body('''\
|
||||
{
|
||||
"data": {
|
||||
"personToCheck": {
|
||||
"name": "Old Enough",
|
||||
"age": "40"
|
||||
}
|
||||
}
|
||||
}
|
||||
''')
|
||||
}
|
||||
metadata(verifier: [
|
||||
tool: "graphql"
|
||||
])
|
||||
}
|
||||
----
|
||||
|
||||
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.YAML
|
||||
----
|
||||
---
|
||||
request:
|
||||
method: "POST"
|
||||
url: "/graphql"
|
||||
headers:
|
||||
Content-Type: "application/json"
|
||||
body:
|
||||
query: "query queryName($personName: String!) { personToCheck(name: $personName)
|
||||
{ name age } }"
|
||||
variables:
|
||||
personName: "Old Enough"
|
||||
operationName: "queryName"
|
||||
matchers:
|
||||
headers:
|
||||
- key: "Content-Type"
|
||||
regex: "application/json.*"
|
||||
regexType: "as_string"
|
||||
response:
|
||||
status: 200
|
||||
headers:
|
||||
Content-Type: "application/json"
|
||||
body:
|
||||
data:
|
||||
personToCheck:
|
||||
name: "Old Enough"
|
||||
age: "40"
|
||||
matchers:
|
||||
headers:
|
||||
- key: "Content-Type"
|
||||
regex: "application/json.*"
|
||||
regexType: "as_string"
|
||||
name: "shouldRetrieveOldEnoughPerson"
|
||||
metadata:
|
||||
verifier:
|
||||
tool: "graphql"
|
||||
----
|
||||
====
|
||||
|
||||
Adding the metadata section will change the way the default, WireMock stub is built. It will now use the Spring Cloud Contract request matcher, so that e.g. the `query` part of the GraphQL request gets compared against the real request by ignoring whitespaces.
|
||||
|
||||
[[features-graphql-producer]]
|
||||
==== Producer Side Setup
|
||||
|
||||
On the producer side your configuration can look as follows.
|
||||
|
||||
====
|
||||
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Maven
|
||||
----
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<version>${spring-cloud-contract.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<testMode>EXPLICIT</testMode>
|
||||
<baseClassForTests>com.example.BaseClass</baseClassForTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
----
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.Gradle
|
||||
----
|
||||
contracts {
|
||||
testMode = "EXPLICIT"
|
||||
baseClassForTests = "com.example.BaseClass"
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The base class would set up the applicatoin running on a random port.
|
||||
|
||||
====
|
||||
[source,java,indent=0,subs="verbatim,attributes"]
|
||||
.Base Class
|
||||
----
|
||||
@SpringBootTest(classes = ProducerApplication.class,
|
||||
properties = "graphql.servlet.websocket.enabled=false",
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public abstract class BaseClass {
|
||||
|
||||
@LocalServerPort int port;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
RestAssured.baseURI = "http://localhost:" + port;
|
||||
}
|
||||
}
|
||||
|
||||
----
|
||||
====
|
||||
|
||||
[[features-graphql-consumer]]
|
||||
==== Consumer Side Setup
|
||||
|
||||
Example of a consumer side test of the GraphQL API.
|
||||
|
||||
====
|
||||
[source,java,indent=0,subs="verbatim,attributes"]
|
||||
.Consumer Side Test
|
||||
----
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.NONE)
|
||||
public class BeerControllerGraphQLTest {
|
||||
|
||||
@RegisterExtension
|
||||
static StubRunnerExtension rule = new StubRunnerExtension()
|
||||
.downloadStub("com.example","beer-api-producer-graphql")
|
||||
.stubsMode(StubRunnerProperties.StubsMode.LOCAL);
|
||||
|
||||
private static final String REQUEST_BODY = "{\n"
|
||||
+ "\"query\":\"query queryName($personName: String!) {\\n personToCheck(name: $personName) {\\n name\\n age\\n }\\n}\","
|
||||
+ "\"variables\":{\"personName\":\"Old Enough\"},\n"
|
||||
+ "\"operationName\":\"queryName\"\n"
|
||||
+ "}";
|
||||
|
||||
@Test
|
||||
public void should_send_a_graphql_request() {
|
||||
ResponseEntity<String> responseEntity = new RestTemplate()
|
||||
.exchange(RequestEntity
|
||||
.post(URI.create("http://localhost:" + rule.findStubUrl("beer-api-producer-graphql").getPort() + "/graphql"))
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(REQUEST_BODY), String.class);
|
||||
|
||||
BDDAssertions.then(responseEntity.getStatusCodeValue()).isEqualTo(200);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
----
|
||||
====
|
||||
@@ -81,7 +81,7 @@ You can pick from the following options of acquiring stubs:
|
||||
- Classpath-scanning solution that searches the classpath with a pattern to retrieve stubs
|
||||
- Writing your own implementation of the `org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder` for full customization
|
||||
|
||||
The latter example is described in the <<advanced.adoc#customization-custom-stub-runner, Custom Stub Runner>> section.
|
||||
The latter example is described in the <<advanced.html#customization-custom-stub-runner, Custom Stub Runner>> section.
|
||||
|
||||
[[features-stub-runner-downloading-stub]]
|
||||
===== Downloading Stubs
|
||||
|
||||
@@ -111,18 +111,18 @@ link:docker-project.html[Docker]
|
||||
Finally, we have a few topics for more advanced users:
|
||||
|
||||
* *Customizing the DSL:*
|
||||
<<advanced.adoc#contract-dsl-customization, DSL Customization>> |
|
||||
<<advanced.adoc#contract-dsl-extending-common-jar, Common JAR>> |
|
||||
<<advanced.adoc#contract-dsl-test-dep, Test Dependency>> |
|
||||
<<advanced.adoc#contract-dsl-plugin-dep, Plugin Dependency>> |
|
||||
<<advanced.adoc#contract-dsl-referencing, Referencing the DSL>>
|
||||
<<advanced.html#contract-dsl-customization, DSL Customization>> |
|
||||
<<advanced.html#contract-dsl-extending-common-jar, Common JAR>> |
|
||||
<<advanced.html#contract-dsl-test-dep, Test Dependency>> |
|
||||
<<advanced.html#contract-dsl-plugin-dep, Plugin Dependency>> |
|
||||
<<advanced.html#contract-dsl-referencing, Referencing the DSL>>
|
||||
* *Customizing WireMock:*
|
||||
<<advanced.adoc#customization-wiremock-extension, Extensions>> |
|
||||
<<advanced.adoc#customization-wiremock-configuration, Configuration>>
|
||||
<<advanced.html#customization-wiremock-extension, Extensions>> |
|
||||
<<advanced.html#customization-wiremock-configuration, Configuration>>
|
||||
* *Customizing {project-full-name}:*
|
||||
<<advanced.adoc#contract-dsl-pluggable-architecture, Pluggable Architecture>> |
|
||||
<<advanced.adoc#contract-dsl-custom-contract-converter, Contract Converter>> |
|
||||
<<advanced.adoc#contract-dsl-custom-test-generator, Test Generator>> |
|
||||
<<advanced.adoc#contract-dsl-custom-stub-generator, Stub Generator>> |
|
||||
<<advanced.adoc#contract-dsl-custom-stub-runner, Stub Runner>> |
|
||||
<<advanced.adoc#contract-dsl-custom-stub-downloader, Stub Downloader>>
|
||||
<<advanced.html#contract-dsl-pluggable-architecture, Pluggable Architecture>> |
|
||||
<<advanced.html#contract-dsl-custom-contract-converter, Contract Converter>> |
|
||||
<<advanced.html#contract-dsl-custom-test-generator, Test Generator>> |
|
||||
<<advanced.html#contract-dsl-custom-stub-generator, Stub Generator>> |
|
||||
<<advanced.html#contract-dsl-custom-stub-runner, Stub Runner>> |
|
||||
<<advanced.html#contract-dsl-custom-stub-downloader, Stub Downloader>>
|
||||
|
||||
@@ -37,4 +37,4 @@ If you want to learn more about any of the classes discussed in this section, yo
|
||||
|
||||
If you are comfortable with {project-full-name}'s core features, you can continue on and read
|
||||
about
|
||||
<<advanced.adoc, {project-full-name}'s advanced features>>.
|
||||
<<advanced.html, {project-full-name}'s advanced features>>.
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2012-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.docs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
|
||||
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
|
||||
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
|
||||
import org.springframework.cloud.contract.verifier.converter.YamlContract;
|
||||
import org.springframework.cloud.contract.verifier.util.SpringCloudContractMetadata;
|
||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Main.class);
|
||||
|
||||
private final File rootPath;
|
||||
|
||||
public Main(File rootPath) {
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
File rootPath = new File(args[0]);
|
||||
Main main = new Main(rootPath);
|
||||
main.produceJsonSchemaOfAYamlModel();
|
||||
main.produceAdocWithAllOfMetadataClasses();
|
||||
}
|
||||
|
||||
void produceJsonSchemaOfAYamlModel() throws IOException {
|
||||
log.info("Generating schema...");
|
||||
String schemaString = generateJsonSchemaForClass(YamlContract.class);
|
||||
File schemaFile = new File(this.rootPath, "target/contract_schema.json");
|
||||
Files.write(schemaFile.toPath(), schemaString.getBytes());
|
||||
log.info("Generated schema!");
|
||||
}
|
||||
|
||||
private String generateJsonSchemaForClass(Class clazz)
|
||||
throws JsonProcessingException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
|
||||
JsonSchema schema = schemaGen.generateSchema(clazz);
|
||||
return mapper.writeValueAsString(schema);
|
||||
}
|
||||
|
||||
void produceAdocWithAllOfMetadataClasses() throws Exception {
|
||||
log.info("Produce adoc with all metadata...");
|
||||
List<Class> metadata = metadataClasses();
|
||||
File doc = new File(this.rootPath, "target/metadata.adoc");
|
||||
StringBuilder sb = adocWithMetadata(metadata);
|
||||
Files.write(doc.toPath(), sb.toString().getBytes());
|
||||
log.info("Produced adoc with all metadata!");
|
||||
}
|
||||
|
||||
private StringBuilder adocWithMetadata(List<Class> metadata) throws Exception {
|
||||
YAMLMapper mapper = new YAMLMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Class metadatum : metadata) {
|
||||
SpringCloudContractMetadata newInstance = (SpringCloudContractMetadata) metadatum
|
||||
.newInstance();
|
||||
String description = newInstance.description();
|
||||
String key = newInstance.key();
|
||||
List<Class> additionalClasses = classesToLookAt(metadatum, newInstance);
|
||||
// @formatter:off
|
||||
sb
|
||||
.append("[[metadata-").append(key).append("]]\n")
|
||||
.append("##### Metadata `").append(key).append("`\n\n")
|
||||
.append("* key: `").append(key).append("`").append("\n")
|
||||
.append("* description:\n\n").append(description).append("\n\n")
|
||||
.append("Example:\n\n")
|
||||
.append("```yaml\n").append(mapper.writeValueAsString(newInstance)).append("\n```\n\n")
|
||||
// To make the schema collapsable
|
||||
.append("+++ <details><summary> +++\nClick here to expand the JSON schema:\n+++ </summary><div> +++\n")
|
||||
.append("```json\n").append(generateJsonSchemaForClass(metadatum)).append("\n```\n")
|
||||
.append("+++ </div></details> +++\n\n")
|
||||
.append("If you are interested in learning more about the types and its properties, check out the following classes:\n\n")
|
||||
.append(additionalClasses.stream().map(aClass -> "* `" + aClass.getName() + "`").collect(Collectors.joining("\n")))
|
||||
.append("\n\n");
|
||||
// @formatter:on
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
private List<Class> classesToLookAt(Class metadatum,
|
||||
SpringCloudContractMetadata newInstance) {
|
||||
List<Class> additionalClasses = new ArrayList<>();
|
||||
additionalClasses.add(metadatum);
|
||||
additionalClasses.addAll(newInstance.additionalClassesToLookAt());
|
||||
return additionalClasses;
|
||||
}
|
||||
|
||||
private List<Class> metadataClasses() throws ClassNotFoundException {
|
||||
BeanDefinitionRegistry bdr = new SimpleBeanDefinitionRegistry();
|
||||
ClassPathBeanDefinitionScanner s = new ClassPathBeanDefinitionScanner(bdr, false);
|
||||
TypeFilter tf = new AssignableTypeFilter(SpringCloudContractMetadata.class);
|
||||
s.addIncludeFilter(tf);
|
||||
String basePackage = "org.springframework.cloud.contract";
|
||||
s.scan(basePackage);
|
||||
String[] beans = bdr.getBeanDefinitionNames();
|
||||
List<Class> metadata = new ArrayList<>();
|
||||
for (String bean : beans) {
|
||||
BeanDefinition beanDefinition = bdr.getBeanDefinition(bean);
|
||||
String beanClassName = beanDefinition.getBeanClassName();
|
||||
if (beanClassName != null && !beanClassName.contains(basePackage)) {
|
||||
continue;
|
||||
}
|
||||
metadata.add(Class.forName(beanClassName));
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,36 +19,14 @@ package org.springframework.cloud.contract.docs;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
|
||||
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
|
||||
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
|
||||
import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.verifier.converter.YamlContract;
|
||||
import org.springframework.cloud.contract.verifier.converter.YamlContractConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.SpringCloudContractMetadata;
|
||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
||||
/**
|
||||
* This test generates additional resources in the `target` folder that are then
|
||||
* referenced by the documentation.
|
||||
*/
|
||||
class AdditionalResourcesGenerationTests {
|
||||
|
||||
// @formatter:off
|
||||
@@ -113,22 +91,6 @@ class AdditionalResourcesGenerationTests {
|
||||
+ " predefined:\n";
|
||||
// @formatter:on
|
||||
|
||||
@Test
|
||||
void should_produce_a_json_schema_of_a_yaml_model() throws IOException {
|
||||
String schemaString = generateJsonSchemaForClass(YamlContract.class);
|
||||
File schemaFile = new File("target/contract_schema.json");
|
||||
Files.write(schemaFile.toPath(), schemaString.getBytes());
|
||||
}
|
||||
|
||||
private String generateJsonSchemaForClass(Class clazz)
|
||||
throws JsonProcessingException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
|
||||
JsonSchema schema = schemaGen.generateSchema(clazz);
|
||||
return mapper.writeValueAsString(schema);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_convert_yaml_to_contract() throws IOException {
|
||||
File ymlFile = new File("target/contract.yml");
|
||||
@@ -139,73 +101,4 @@ class AdditionalResourcesGenerationTests {
|
||||
BDDAssertions.then(contracts).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_produce_an_adoc_with_all_of_metadata_classes() throws Exception {
|
||||
List<Class> metadata = metadataClasses();
|
||||
File doc = new File("target/metadata.adoc");
|
||||
|
||||
StringBuilder sb = adocWithMetadata(metadata);
|
||||
|
||||
Files.write(doc.toPath(), sb.toString().getBytes());
|
||||
}
|
||||
|
||||
private StringBuilder adocWithMetadata(List<Class> metadata) throws Exception {
|
||||
YAMLMapper mapper = new YAMLMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Class metadatum : metadata) {
|
||||
SpringCloudContractMetadata newInstance = (SpringCloudContractMetadata) metadatum
|
||||
.newInstance();
|
||||
String description = newInstance.description();
|
||||
String key = newInstance.key();
|
||||
List<Class> additionalClasses = classesToLookAt(metadatum, newInstance);
|
||||
// @formatter:off
|
||||
sb
|
||||
.append("[[metadata-").append(key).append("]]\n")
|
||||
.append("##### Metadata `").append(key).append("`\n\n")
|
||||
.append("* key: `").append(key).append("`").append("\n")
|
||||
.append("* description:\n\n").append(description).append("\n\n")
|
||||
.append("Example:\n\n")
|
||||
.append("```yaml\n").append(mapper.writeValueAsString(newInstance)).append("\n```\n\n")
|
||||
// To make the schema collapsable
|
||||
.append("+++ <details><summary> +++\nClick here to expand the JSON schema:\n+++ </summary><div> +++\n")
|
||||
.append("```json\n").append(generateJsonSchemaForClass(metadatum)).append("\n```\n")
|
||||
.append("+++ </div></details> +++\n\n")
|
||||
.append("If you are interested in learning more about the types and its properties, check out the following classes:\n\n")
|
||||
.append(additionalClasses.stream().map(aClass -> "* `" + aClass.getName() + "`").collect(Collectors.joining("\n")))
|
||||
.append("\n\n");
|
||||
// @formatter:on
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
private List<Class> classesToLookAt(Class metadatum,
|
||||
SpringCloudContractMetadata newInstance) {
|
||||
List<Class> additionalClasses = new ArrayList<>();
|
||||
additionalClasses.add(metadatum);
|
||||
additionalClasses.addAll(newInstance.additionalClassesToLookAt());
|
||||
return additionalClasses;
|
||||
}
|
||||
|
||||
private List<Class> metadataClasses() throws ClassNotFoundException {
|
||||
BeanDefinitionRegistry bdr = new SimpleBeanDefinitionRegistry();
|
||||
ClassPathBeanDefinitionScanner s = new ClassPathBeanDefinitionScanner(bdr, false);
|
||||
TypeFilter tf = new AssignableTypeFilter(SpringCloudContractMetadata.class);
|
||||
s.addIncludeFilter(tf);
|
||||
String basePackage = "org.springframework.cloud.contract";
|
||||
s.scan(basePackage);
|
||||
String[] beans = bdr.getBeanDefinitionNames();
|
||||
List<Class> metadata = new ArrayList<>();
|
||||
for (String bean : beans) {
|
||||
BeanDefinition beanDefinition = bdr.getBeanDefinition(bean);
|
||||
String beanClassName = beanDefinition.getBeanClassName();
|
||||
if (beanClassName != null && !beanClassName.contains(basePackage)) {
|
||||
continue;
|
||||
}
|
||||
metadata.add(Class.forName(beanClassName));
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user