spring-cloud / spring-cloud-contract

Support for Consumer Driven Contracts in Spring
https://cloud.spring.io/spring-cloud-contract
Apache License 2.0
720 stars 440 forks source link

Improve browsing registered stubs #355

Closed pszymczyk closed 7 years ago

pszymczyk commented 7 years ago

Hi

During my regular work with contracts I often have to resolve some bugs connected with defined contracts (eg 404 caused by missing header ;) ), when I'd like to browse registered stubs I have two options: a) Add break point in spring-cloud-contract internals to read random generated wire mock ports b) Add Thread.sleep(100000000) in my business code c) Evaluate curl http://localhost:{wiremockPort}/__admin (I can't evaluate it without step b) cause thread is blocked) or a) read from logs paths with mappings generated in /tmp/.. b) explore generated files

Both of them (in my opinion) are not user friendly, in first approach I have to remember wiremock ports and modify my code (adding thread.sleep()) which is really not cool. In second approach I have to explore my /tmp catalog, after whole day there is a big mess, and I just don't like to explore spring-cloud-contract internals.

My idea to make it more useful is to create temporary file with content similar to response from wiremock .../__admin and add this file to {project}/build/ - just next to generated Spock tests. This file should contain mappings from all set up wiremock instances.

marcingrzejszczak commented 7 years ago

I also had an idea. On StubTrigger we could add a method that would either

that way every implementor of the stub mechanism (you can inject sth else than WireMock) would have to provide a way to access the mappings.

What do you think about this?

pszymczyk commented 7 years ago

I'm not sure:

  1. If I understand correctly - still I have to debug and add break point, this mappings could be very, very big so probably I have to copy this text to clipboard and next paste it to some online json formatter or some file to find interesting mappings.
  2. Sout sounds great but as you probably know it could be quite big.

File in /build would be nice because I have it in my navigation tree in IDE and I can double click, cmd+f to find interesting data - it's very simple.

marcingrzejszczak commented 7 years ago

So how about doing both (one would be actually required to the other). Meaning we could have

@AutoConfigureStubRunner(..., outputMappingsFolder="build/mappings")

where for each started stub server, a file with all registered mappings would be dumped.

pszymczyk commented 7 years ago

Great! +1

marcingrzejszczak commented 7 years ago

I've implemented the feature please check out the PR https://github.com/spring-cloud/spring-cloud-contract/pull/356 . You can focus on the documentation and tests where I describe the usage. The usage would look like this

Extract from docs:

Viewing registered mappings

Every stubbed collaborator exposes list of defined mappings under __/admin/ endpoint.

You can also use the mappingsOutputFolder property to dump the mappings to files. For annotation based approach it would look like this

@AutoConfigureStubRunner(ids="a.b.c:loanIssuance,a.b.c:fraudDetectionServer",
mappingsOutputFolder = "target/outputmappings/")

and for the JUnit approach like this:

@ClassRule @Shared StubRunnerRule rule = new StubRunnerRule()
            .repoRoot("http://some_url")
            .downloadStub("a.b.c", "loanIssuance")
            .downloadStub("a.b.c:fraudDetectionServer")
            .withMappingsOutputFolder("target/outputmappings")

Then if you check out the folder target/outputmappings you would see the following structure

.
├── fraudDetectionServer_13705
└── loanIssuance_12255

That means that there were two stubs registered. fraudDetectionServer was registered at port 13705 and loanIssuance at port 12255. If we take a look at one of the files we would see (for WireMock) mappings available for the given server:

[{
  "id" : "f9152eb9-bf77-4c38-8289-90be7d10d0d7",
  "request" : {
    "url" : "/name",
    "method" : "GET"
  },
  "response" : {
    "status" : 200,
    "body" : "fraudDetectionServer"
  },
  "uuid" : "f9152eb9-bf77-4c38-8289-90be7d10d0d7"
},
...
]
pilloPl commented 7 years ago

Looking good. I was waiting for this feature :)

pszymczyk commented 7 years ago

Gj, thanks @marcingrzejszczak