spring-cloud-samples / spring-cloud-contract-samples

Samples for Spring Cloud Contract project
Apache License 2.0
381 stars 310 forks source link

spring-cloud-stub-runner issue with downloading pact contracts #264

Open naushadamin opened 3 years ago

naushadamin commented 3 years ago

Describe the bug I've a consumer project which published a Pact contract to a remote pact repo successfully. Now I am trying to auto-generate the verifier test in Producer project using spring-cloud-contract-pact project. I added the following bits in by build.gradle file to configure test generation:

contractsMode = "REMOTE"
        // Base package for generated tests
        baseClassForTests = "somebaseclass"
        contractRepository {
            repositoryUrl = "pact://https://namin.pactflow.io"
        }

When I build my project it fails. Upon further investigation, I found the copyContract gradle task is failing with the following:

2021-06-23T07:01:10.922-0400 [DEBUG] [org.springframework.cloud.contract.stubrunner.StubRunnerOptions] File not found
java.io.FileNotFoundException: class path resource [pact://https://namin.pactflow.io] cannot be resolved to URL because it does not exist
    at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:202)
    at org.springframework.core.io.AbstractResource.getURI(AbstractResource.java:123)
    at org.springframework.cloud.contract.stubrunner.StubRunnerOptions.getStubRepositoryRootAsString(StubRunnerOptions.java:263)
    at org.springframework.cloud.contract.stubrunner.AetherStubDownloader.remoteRepositories(AetherStubDownloader.java:144)
    at org.springframework.cloud.contract.stubrunner.AetherStubDownloader.<init>(AetherStubDownloader.java:83)
    at org.springframework.cloud.contract.stubrunner.AetherStubDownloaderBuilder.build(AetherStubDownloaderBuilder.java:38)

I am following the example from your sample producer-pact directory here. Not sure what needs to be configured to resolve the issue. Also, I noticed that currently username/password based authentication is supported. However, I have configured authentication to my pact repo using bearer token. Is token based authentication supported?

marcingrzejszczak commented 3 years ago

That's DEBUG you shouldn't worry about this. You can debug the Pact downloader and see if the connection is occurring properly.

naushadamin commented 3 years ago

running 'gradlew build' generates the below error:

Execution failed for task ':copyContracts'.

Remote repositories for stubs are not specified and work offline flag wasn't passed

Having difficulty debugging locally. IntelliJ detects source and class out of sync despite manually synching the jar

naushadamin commented 3 years ago

Getting back on this one. Upon further investigations, the below stacktrace results in an empty string being returned as remote repository which generates the IllegalStateException with 'Remote repositories for stubs are not specified and work offline flag wasn't passed' : java.io.FileNotFoundException: class path resource [pact://https://namin.pactflow.io] cannot be resolved to URL because it does not exist at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:202) at org.springframework.core.io.AbstractResource.getURI(AbstractResource.java:123) at org.springframework.cloud.contract.stubrunner.StubRunnerOptions.getStubRepositoryRootAsString(StubRunnerOptions.java:263) at org.springframework.cloud.contract.stubrunner.AetherStubDownloader.remoteRepositories(AetherStubDownloader.java:144) In looking at the above trace, my question is why the framework is trying to look for a classpath resource based on the url? Am I missing some dependencies in my classpath so runtime is using an incorrect implementation? I am blocked at this point. Relevant dependencies from my build.gradle:

testImplementation ("org.springframework.cloud:spring-cloud-starter-contract-verifier:${springCloudVerifierVersion}") testImplementation "org.springframework.cloud:spring-cloud-contract-wiremock:${springCloudVerifierVersion}" testImplementation("org.springframework.cloud:spring-cloud-contract-pact:${springCloudVerifierVersion}")

I am using 2.2.6.RELEASE version. Also I need to know if the framework will support token based authentication. Thanks in advance!

marcingrzejszczak commented 3 years ago

It tries to use various stub downloaders. If you scroll the logs up you will see that the PACT one failed. We do support token based auth in 3.0.x https://github.com/spring-cloud/spring-cloud-contract/blob/v3.0.3/spring-cloud-contract-tools/spring-cloud-contract-pact/src/main/java/org/springframework/cloud/contract/stubrunner/PactStubDownloaderBuilder.java#L293

naushadamin commented 3 years ago

There is no indication on the log that i think there was an attempt. i upgraded 3.0.3 and updated the plugin config in gradle to following:

contractRepository { repositoryUrl = "pact://https://namin.pactflow.io" token = "sometoken" }

However, I still get error 'Could not set unknown property 'token' for ContractRepository'. I assume that is right way to configure token value. Can you confirm?

marcingrzejszczak commented 3 years ago

Have you added spring-cloud-contract-pact to the plugin's classpath?

marcingrzejszczak commented 3 years ago

Also what is token? We don't provide such a field to configure the Gradle plugin

naushadamin commented 3 years ago

Also what is token? We don't provide such a field to configure the Gradle plugin

Do you have any documentation on how to to configure the token value? I was looking that source reference and your documentation here https://docs.spring.io/spring-cloud-contract/docs/3.0.0-SNAPSHOT/reference/htmlsingle/#how-to-use-pact-broker and assumed I can set the token attribute along with repo url. If that is not correct then please provide example of how to set the value. Thanks

naushadamin commented 3 years ago

Any update on this issue? I am unable to determine how to correctly set auth token for pact broker.

marcingrzejszczak commented 3 years ago

This is how we set up the pact properties https://github.com/spring-cloud/spring-cloud-contract/blob/main/spring-cloud-contract-tools/spring-cloud-contract-pact/src/main/java/org/springframework/cloud/contract/stubrunner/PactStubDownloaderBuilder.java#L313-L358

You can try passing

naushadamin commented 3 years ago

I've attempted to set the system property -Dpactbroker.auth.token as following:

1./gradlew buiild -Dpactbroker.auth.token="sometoken"

  1. in build.gradle as following:
    test {
    systemProperty "pactbroker.auth.token", "sometoken"
    }

I also attempted to include in contractProperties as following:

contractsProperties(["pactbroker.auth.token":"sometoken"])

However, I am still getting 401 in response back from the broker. This is what I gathered from DEBUG log what is being passed:

2021-09-14T15:47:41.225-0400 [DEBUG] [org.springframework.cloud.contract.stubrunner.AetherStubDownloader] Will be resolving versions for the following options: [StubRunnerOptions{minPortValue=10000, maxPortValue=15000, stubRepositoryRoot='URL [https://namin.pactflow.io/pacts/provider/siteapi/consumer/siteapi-consumer/version/1.0.0.devlocal]', stubsMode='REMOTE', stubsClassifier='stubs', dependencies=[], stubIdsToPortMapping={}, username='****', password='', stubRunnerProxyOptions='null', stubsPerConsumer='false', httpServerStubConfigurer='class org.springframework.cloud.contract.stubrunner.HttpServerStubConfigurer$NoOpHttpServerStubConfigurer'}]

shanman190 commented 2 years ago

This is the same issue as gh-178.