spring-cloud-contract-samples icon indicating copy to clipboard operation
spring-cloud-contract-samples copied to clipboard

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

Open naushadamin opened this issue 3 years ago • 12 comments

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?

naushadamin avatar Jun 23 '21 11:06 naushadamin

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

marcingrzejszczak avatar Jun 23 '21 11:06 marcingrzejszczak

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 avatar Jun 24 '21 12:06 naushadamin

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!

naushadamin avatar Jul 17 '21 15:07 naushadamin

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

marcingrzejszczak avatar Jul 21 '21 08:07 marcingrzejszczak

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?

naushadamin avatar Jul 21 '21 13:07 naushadamin

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

marcingrzejszczak avatar Jul 21 '21 13:07 marcingrzejszczak

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

marcingrzejszczak avatar Jul 21 '21 13:07 marcingrzejszczak

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 avatar Jul 21 '21 14:07 naushadamin

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

naushadamin avatar Sep 11 '21 22:09 naushadamin

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

  • a system property -Dpactbroker.auth.token
  • a system property -Dstubrunner.properties.pactbroker.auth.token
  • For Stub runner and Maven / Gradle plugins
    • an env var STUBRUNNER_PROPERTIES_PACTBROKER_AUTH_TOKEN
    • pass those via the properties annotation method oif the @AutoConfigureStubRunner annotation (https://github.com/spring-cloud/spring-cloud-contract/blob/dc9b19be6dbbb6d9654fa582e8ef14877ee29a16/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java#L132)
  • For Stub runner only
    • use JUnit extension in the same fashion
  • For the Gradle plugin only
    • set the contractProperties extension value - https://github.com/spring-cloud/spring-cloud-contract/blob/main/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/java/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.java#L221

marcingrzejszczak avatar Sep 13 '21 08:09 marcingrzejszczak

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

1. /gradlew buiild -Dpactbroker.auth.token="sometoken" 2. 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'}]

naushadamin avatar Sep 14 '21 19:09 naushadamin

This is the same issue as gh-178.

shanman190 avatar Feb 23 '22 14:02 shanman190