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

include wiremock jsr310 in starter

Open xenoterracide opened this issue 3 years ago • 14 comments

I got an error saying to serialize instant it was required and some things like OAuth2AccessTokenResponse in spring security use it. Harder to do yourself with gradle while keeping versions lockstepped. I wonder if they have a bom you can pull in like jackson itself does.

wiremock.com.fasterxml.jackson.datatype:jackson-datatype-jsr310:.

xenoterracide avatar Sep 23 '22 19:09 xenoterracide

I don't understand the problem. We're using Wiremock's standalone JAR so it should have all the dependencies shaded. IF you're missing one maybe you should file an issue in the WireMock repo?

marcingrzejszczak avatar Sep 26 '22 06:09 marcingrzejszczak

It's not a dependency of wiremock. It's an additional possible dependency for the jsr 310 (time) library. I want you to add it so it's version managed.

xenoterracide avatar Sep 26 '22 11:09 xenoterracide

Why should we manage it? Also, wiremock.com.fasterxml.jackson.datatype:jackson-datatype-jsr310:. looks like a shaded WireMock dependency

marcingrzejszczak avatar Sep 26 '22 11:09 marcingrzejszczak

It is shaded. You should manage it so that the upstream versions are consistent with each other. It's a lot harder to micromanage that downstream. Also because jsr 310 is probably pretty commonly needed these days. Honestly who doesn't use the Java time API at this point. I'm sure someone but that's kind of besides the point.

xenoterracide avatar Sep 26 '22 13:09 xenoterracide

So you're saying that the standalone WireMock jar doesn't include wiremock.com.fasterxml.jackson.datatype:jackson-datatype-jsr310 and there's a separate wiremock.com.fasterxml.jackson.datatype:jackson-datatype-jsr310 artifact with shaded stuff released by WireMock ?

marcingrzejszczak avatar Sep 26 '22 13:09 marcingrzejszczak

Yes. That is exactly what I'm saying.

xenoterracide avatar Sep 26 '22 13:09 xenoterracide

I don't see such an artifact in maven central - https://search.maven.org/search?q=g:wiremock.com.fasterxml.jackson.datatype%20AND%20a:jackson-datatype-jsr310

marcingrzejszczak avatar Sep 26 '22 13:09 marcingrzejszczak

hmm... did I typo something somewhere.... doesn't look like it

Java 8 date/time type `java.time.Instant` not supported by default: add Module "wiremock.com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse["accessToken"]->org.springframework.security.oauth2.core.OAuth2AccessToken["issuedAt"])
wiremock.com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default: add Module "wiremock.com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse["accessToken"]->org.springframework.security.oauth2.core.OAuth2AccessToken["issuedAt"])
	at app//wiremock.com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
	at app//wiremock.com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1300)
	```

xenoterracide avatar Sep 26 '22 14:09 xenoterracide

Can you provide a minimal reproducer for this issue? Are you using the latest versions of Spring Cloud Contract?

marcingrzejszczak avatar Sep 26 '22 14:09 marcingrzejszczak

I believe so, using the latest version of the BOM

❯ fd gradle.lockfile -x grep contract {} | awk -F'=' '{ print $1 }' | sort -u
org.springframework.cloud:spring-cloud-contract-converters:3.1.4
org.springframework.cloud:spring-cloud-contract-shade:3.1.4
org.springframework.cloud:spring-cloud-contract-spec-groovy:3.1.4
org.springframework.cloud:spring-cloud-contract-spec-java:3.1.4
org.springframework.cloud:spring-cloud-contract-spec:3.1.4
org.springframework.cloud:spring-cloud-contract-stub-runner:3.1.4
org.springframework.cloud:spring-cloud-contract-verifier:3.1.4
org.springframework.cloud:spring-cloud-contract-wiremock:3.1.4
org.springframework.cloud:spring-cloud-starter-contract-stub-runner:3.1.4
com.github.tomakehurst:wiremock-jre8-standalone:2.33.0
org.springframework.cloud:spring-cloud-contract-wiremock:3.1.4
com.nimbusds:oauth2-oidc-sdk:9.35
org.springframework.boot:spring-boot-starter-oauth2-client:2.7.4
org.springframework.security:spring-security-oauth2-client:5.7.3
org.springframework.security:spring-security-oauth2-core:5.7.3
org.springframework.security:spring-security-oauth2-jose:5.7.3

This is my test, which I believe is sufficient (test actually isn't for me but that's another issue)

package e1.configuration.feign

import com.github.tomakehurst.wiremock.client.WireMock.get
import com.github.tomakehurst.wiremock.client.WireMock.ok
import com.github.tomakehurst.wiremock.client.WireMock.post
import com.github.tomakehurst.wiremock.client.WireMock.stubFor
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock
import org.springframework.cloud.openfeign.FeignClient
import org.springframework.security.oauth2.core.OAuth2AccessToken
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse
import org.springframework.web.bind.annotation.GetMapping
import wiremock.com.fasterxml.jackson.databind.node.JsonNodeFactory
import java.time.Duration
import java.util.UUID

@SpringBootTest
@AutoConfigureWireMock(port = 0)
internal class DevExchangeOauth2FeignRequestInterceptorTest {

  @Test
  fun oauth( @Autowired fooRepo: FooRepo) {
    val token = OAuth2AccessTokenResponse.withToken(UUID.randomUUID().toString())
      .tokenType(OAuth2AccessToken.TokenType.BEARER)
      .expiresIn(Duration.ofMillis(10).toMillis())
      .build()

    stubFor(post("/oauth/token").willReturn(ok().withJsonBody(JsonNodeFactory.instance.pojoNode(token))))
    stubFor(get("/foo").willReturn(ok().withJsonBody(JsonNodeFactory.instance.arrayNode())))

    val list = fooRepo.findAll()
    assertThat(list).isEmpty()
  }

  @FeignClient(name = "exchange-v1", url = "\${exchange.url}/foo")
  interface FooRepo {
    @GetMapping
    fun findAll(): List<Any>
  }
}

xenoterracide avatar Sep 26 '22 14:09 xenoterracide

maybe this, I trusted the error message... https://github.com/wiremock/wiremock/issues/1127

xenoterracide avatar Sep 26 '22 14:09 xenoterracide

com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.4

xenoterracide avatar Sep 26 '22 14:09 xenoterracide

https://stackoverflow.com/a/66831427/206466 looks like the answer might be in the comments, but it's not being registered for me...

xenoterracide avatar Sep 26 '22 14:09 xenoterracide

No wonder, because you want to setup the shaded version. I guess we need to wait for the #1127 to get somehow addressed in WireMock first before we do anything here. The question is how to configure Jackson for shaded WireMock.

marcingrzejszczak avatar Sep 26 '22 14:09 marcingrzejszczak