Commit Graph

969 Commits

Author SHA1 Message Date
Johnny Lim ce3be72e7f Polish 2023-02-15 22:22:58 +09:00
Sébastien Deleuze a2a676241c Introduce HttpServiceProxyFactory#createClient Kotlin extension
Closes gh-29942
2023-02-07 15:50:30 +01:00
Sébastien Deleuze 9f061f1eec Refine KotlinWebClientHttpServiceProxyTests
See gh-29527
2023-02-07 11:07:30 +01:00
Donghyeon Kim 1d4bf58e8d Support Coroutines in HttpServiceProxyFactory
See gh-29527
2023-02-07 11:07:29 +01:00
rstoyanchev ce85fdc5c7 Always use application/problem+json with ProblemDetail
See gh-gh-29588
2023-02-07 08:57:24 +00:00
Brian Clozel 5dfa61eb0b Restrict "uri" KeyValue for client observations
Prior to this commit, the "uri" KeyValue for low cardinality metadata
would contain the entire uri template given to the HTTP client when
creating the request. This was a breaking change for existing metrics
dashboards, as previous support was removing the protocol, host and port
parts of the URI.
Indeed, this information is available in the "client.name" and
"http.uri" KayValue.

This commit parses and removes the protocol+host+port information from
the uri template for the "uri" KeyValue.

Fixes gh-29885
2023-01-30 10:09:45 +01:00
Brian Clozel b267547fb4 Contribute "uri" KeyValue for "/" client requests
Prior to this commit, client HTTP requests performed by `WebClient`
could miss the "uri" KeyValue for simple "/" requests.
This can happen when the baseUri is configured for the client with a
host and a root base path like "https://example.org/"; given the nature
of the `WebClient` API, in these cases, one can perform requests like
this:

```
WebClient client = WebClient.builder()
    .observationRegistry(registry)
    .baseUrl("https://example.org/")
    .build();

String response = client.get().retrieve().bodyToMono(String.class).block();
```

Such a call would contribute a `"none"` value for the `"uri"` KeyValue.

While only templates should be allowed for this keyvalue, we can assume
that requests to `"/"` should be recorded anyway and won't cause
cardinality explosion.

Fixes gh-29879
2023-01-30 10:09:41 +01:00
Brian Clozel 7da6e93597 Set WebClient Observation as current in reactor context
Prior to this commit, the `DefaultWebClient` would be instrumented for
client observations and would start/stop a `"http.client.requests"`
observation. This would not set this new observation as the current one
in the Reactor context under `ObservationThreadLocalAccessor.KEY`.
This means that potential child observations would not detect it as
their parent; this can happen if the Reactor Netty `HttpClient`
observation is enabled.

This commit ensures that the reactor context is properly populated for
upstream operators.

Fixes gh-29891
2023-01-27 14:42:08 +01:00
Brian Clozel 767f59a3ae Make client.name low cardinality keyvalue for client observations
Prior to this commit, the `"client.name"` key value for the
`"http.client.requests"` client HTTP observations would be considered as
high cardinality, as the URI host is technically unbounded.
In practice, the number of hosts used by a client in a given application
can be considered as low cardinality. This commit moves this keyvalue to
low cardinality so that it's present for both metrics and traces.

Closes gh-29839
2023-01-25 20:51:15 +01:00
Brian Clozel d37ef61b30 Resolve static resources without wildcard pattern
Prior to this commit, the reactive `ResourceWebHandler` would only look
at the path within the current mapping when resolving static resources
to be served. This means that when registering a handler at
`"/resources/**"` with a `"classpath:/static/"` location, the handler
would process a `"GET /resources/file.txt"` as the `"/static/file.txt"`
classpath location.

When a developer registers a fixed pattern like `"/resources/file.txt"`
with the same location, the path within the handler mapping is empty as
there is no dynamic part in the given pattern. While the typical use
case for this feature is to register multiple resources at once with a
pattern, we should support a single registration like this.

This commit ensures that if the matching `PathPattern` for the current
request does not have a pattern syntax (i.e. no regexp, no wildcard), we
can use it to match the resource directly. Otherwise, we can use the
path within the handler mapping to resolve the resource as before.

Closes gh-29739
2023-01-20 17:15:52 +01:00
Sébastien Deleuze 8f94c4e933 Remove WebClientIntegrationTests#exchangeWithRelativeUrl outdated test
This test can fail when a web server runs on port 80 and
is not relevant anymore due to the removal of related feature
via 6e936a4081.

Closes gh-28902
2023-01-20 13:59:39 +01:00
Sébastien Deleuze fb0aa5abb3 Fix WebClientIntegrationTests flaky Jetty tests
Ensure the port used by the client in malformedResponseChunksOnBodilessEntity
and malformedResponseChunksOnEntityWithBody has correctly been set.

Closes gh-29862
2023-01-20 11:38:22 +01:00
Sam Brannen 1ace42f245 Enable JRubyScriptTemplateTests 2023-01-19 16:20:03 +01:00
Sam Brannen 0502d18e3d Update copyright headers 2023-01-19 16:20:03 +01:00
Sam Brannen c4c786596f Migrate to Mockito.mock(T...) where feasible 2023-01-19 16:20:02 +01:00
Arjen Poutsma 9ebd1e8d64 Fix IllegalStateException in empty ProducesRequestCondition
When comparing empty ProducesRequestCondition, compareTo would throw an
IllegalStateException if the Accept header was invalid. This commit
fixes that behavior.

Closes gh-29794
2023-01-18 10:38:09 +01:00
Sam Brannen 64de6de725 Update copyright headers 2023-01-17 15:49:26 +01:00
Sam Brannen c3e8ff9ce7 Do not use Mockito to mock ReactiveAdapterRegistry 2023-01-17 15:44:57 +01:00
rstoyanchev 312db36849 Combined, empty RequestMapping matches both "" and "/"
Closes gh-29625
2023-01-13 14:58:11 +00:00
Sam Brannen a4956dfe26 Update copyright headers 2023-01-11 13:52:20 +01:00
Sam Brannen 0415975dd1 Polish contribution and related code 2023-01-11 13:52:20 +01:00
Krzysztof Krason afb8a0d1b1 Use new Java features (switch expressions, text blocks, new JDK methods)
Closes gh-29747
2023-01-11 13:51:28 +01:00
Arjen Poutsma c79ae0c842 Align multipart codecs on client and server
This commit ensures that the same multipart codecs are registered on
both client and server. Previously, only the client enabled only sending
 multipart, and the server only receiving.

Closes gh-29630
2022-12-13 10:13:46 +01:00
Sam Brannen 67644a28b6 Use URI#create instead of URI constructor where feasible in spring-webflux 2022-12-09 13:26:30 -05:00
rstoyanchev 39d4d2041a Polishing contribution
Closes gh-29634
2022-12-09 10:24:42 +00:00
koo.taejin 5ac97b16a8 Optimize object creation PartialMatchHelper
See gh-29634
2022-12-09 10:19:54 +00:00
Sam Brannen 348cc01284 Rename MultipartWebClientIntegrationTests classes to avoid duplicate names 2022-12-06 12:50:36 -05:00
Sam Brannen 9f7a510f90 Polishing 2022-12-06 12:29:03 -05:00
divcon f64397d822 Apply "instanceof pattern matching" in spring-webflux
Closes gh-29635
2022-12-06 10:03:26 -05:00
Sam Brannen de07ad47f1 Polishing, suppression of deprecation warnings, copyright headers, etc. 2022-12-05 14:16:22 -05:00
rstoyanchev db53b618c1 Simplify form data handling in HttpRequestValues
Closes gh-29615
2022-12-05 15:37:48 +00:00
rstoyanchev 913163884a Improve invalid Content-Type handling in WebFlux
Closes gh-29565
2022-12-05 15:37:48 +00:00
rstoyanchev a09f93768a Fix URI override for HttpExchange
Closes gh-29624
2022-12-02 17:02:05 +00:00
Sam Brannen ad60164911 Update copyright headers for source code changed since August 2022
The changes in this commit were performed using the newly introduced
update_copyright_headers.sh script.
2022-11-29 19:38:42 +01:00
Sam Brannen 1bb723b9e0 Rename to AbstractReactiveWebSocketIntegrationTests to avoid duplicate class names 2022-11-28 17:43:39 +01:00
Sam Brannen db02c96c55 Avoid deprecation warnings in tests 2022-11-28 17:40:46 +01:00
Juergen Hoeller 9c7b471634 Deprecate JettyWebSocketClient in favor of StandardWebSocketClient
JettyWebSocketClient only supported on Jetty 11, to be phased out.

Closes gh-29576
2022-11-25 17:06:15 +01:00
Juergen Hoeller 459e8a1ea5 Deprecate LocalVariableTableParameterNameDiscoverer completely
LocalVariableTableParameterNameDiscoverer is not registered by default anymore now.
Java sources should be compiled with `-parameters` instead (available since Java 8).
Also retaining standard Java parameter names for all of Spring's Kotlin sources now.

Closes gh-29531
2022-11-22 19:26:15 +01:00
Sam Brannen 7fcd1de8e3 Use AssertJ's isEmpty() instead of hasSize(0)
Achieved via global search-and-replace.
2022-11-22 17:11:50 +01:00
Sam Brannen d5b0b2b1a1 User AssertJ's hasSize() for arrays
Achieved via global search-and-replace.
2022-11-22 17:03:45 +01:00
Sam Brannen 36f7597f25 Use AssertJ's hasSize() for collections and maps
Achieved via a global search-and-replace.
2022-11-22 16:50:10 +01:00
Stephane Nicoll 09a58a55bf Polish 2022-11-15 20:10:03 +01:00
Brian Clozel 1ad7cc3702 Reorganize server observability packages
Prior to this commit, the server observability support would create a
cycle in Java packages.

This commit refactors the current arrangement to solve this by:

* "flattening" the reactive HTTP instrumentation; this removes the
  dependency to the `ServerWebExchange` and `PathPattern` types
* moving the `observation` package under
  `org.springframework.http.server` and
  `org.springframework.http.server.reactive`

See gh-29477
2022-11-14 12:59:45 +01:00
Sébastien Deleuze 7a9bd3fed9 Merge branch '5.3.x' 2022-11-13 19:08:28 +01:00
Sébastien Deleuze b766a49a4d Support suspending functions returning Unit in WebFlux
Closes gh-27629
2022-11-13 19:05:29 +01:00
rstoyanchev 2878ade980 WebFlux support for handling of early exceptions
This change enables a WebFlux HandlerAdapter to handle not only the
success scenario when a handler is selected, but also any potential
error signal that may occur instead. This makes it possible to
extend ControllerAdvice support to exceptions from handler mapping
such as a 404, 406, 415, and/or even earlier exceptions from the
WebFilter chain.

Closes gh-22991
2022-11-08 15:13:18 +00:00
Sam Brannen a281d8c3fd Polishing 2022-11-04 16:24:59 +01:00
Brian Clozel db79d1d2b9 Set matching pattern in reactive server observation context
This commit fixes the observation instrumentation for the reactive HTTP
server by setting the best matching pattern determined by the web
framework into the `ServerRequestObservationContext`.

This information is required by the observation convention for creating
the expected `KeyValue` for the matching pattern. Prior to this commit,
the information was missing and resulted in an UNKNOWN key value.

Fixes gh-29422
2022-11-02 19:02:31 +01:00
Brian Clozel 3c049a2bd0 Polish
See gh-29388
2022-11-02 16:26:01 +01:00
Marcin Grzejszczak c03ccb2e6c Propagate context in reactive HTTP server and client
Prior to this commit, the ServerHttpObservationFilter would not add
the current observation as a key in the Reactor context, preventing
from being used or propagated during the HTTP exchange handling.

Also, the client instrumentation in `DefaultWebClient` would start
the observation once the request is fully formed and immutable,
preventing the context from being propagated through HTTP request
headers.

This commit fixes both uses cases now by:

* adding the current observation as a key in the reactor context
  on the server side
* using the `ClientRequest.Builder` as a Carrier on the client side

Closes gh-29388
2022-11-02 16:25:50 +01:00
Arjen Poutsma 2042cb68a5 Merge two DispatcherHandlerIntegrationTests 2022-11-02 14:48:58 +01:00
Arjen Poutsma 9e306151c7 Use case-insensitive check for request conditions
This commit ensures that the ConsumesRequestCondition and
ProducesRequestCondition use a case insensitive check when comparing
parameters.

Closes gh-29416
2022-11-02 14:29:50 +01:00
rstoyanchev 921eeadff4 Minor refactoring after recent commits
See gh-29384
2022-11-01 13:56:40 +00:00
rstoyanchev e71057dca9 Support i8n of ProblemDetail "title" field
Closes gh-29407
2022-11-01 12:42:34 +00:00
rstoyanchev 506fbe5243 Improve mapping any Exception to ErrorResponse
Add protected, convenience method in ResponseEntityExceptionHandler
to create a ProblemDetail for any exception, along with a
MessageSource lookup for the "detail" field.

Closes gh-29384
2022-11-01 12:42:34 +00:00
rstoyanchev bd59c7a691 Polishing contribution
Closes gh-29310
2022-10-19 13:22:38 +01:00
Violeta Georgieva 997d1b3d7e Enable leak detection in Netty 5 tests
See gh-29310
2022-10-19 12:07:40 +01:00
Brian Clozel 001b2636d6 Reorganize HTTP Observation types
Closes gh-29334
2022-10-17 21:54:53 +02:00
rstoyanchev 5cb3af708c Add Builder to HttpServiceProxyFactory
HttpServiceProxyFactory now support programmatic initialization through
a builder, while bean-style initialization is deprecated.

See gh-29296
2022-10-17 12:23:58 +01:00
Arjen Poutsma ce03980fb4 Mark HttpRequest::getMethodValue and ClientHttpResponse::getRawStatusCode for removal 2022-10-12 16:29:14 +02:00
Iain Henderson b8243e6f84 Support CBOR and Protobuf with Kotlin Serialization
This commit introduces support for CBOR and Protobuf using Kotlin
serialization. Support comes in the form of Encoder/Decoder as well
as HttpMessageConverters. Seperate abstract base classes supply support
for binary and string (de)serialization.

The exising JSON codecs and message converters have been migrated to
use the new base classes.

Closes gh-27628
2022-10-06 13:51:50 +02:00
rstoyanchev a4210854fb MessageSource support for Spring MVC and WebFlux exceptions
See gh-28814
2022-10-05 14:02:42 +01:00
Brian Clozel 7dd6afc263 Temporarily disable kotlin scripts tests with Java 19
See gh-29249
2022-10-05 10:04:24 +02:00
Brian Clozel 486a1b6024 Change keyvalue name to http.url in server observations
This commit changes the new high cardinality key value from
"uri.expanded" to "http.url" in order to align with the OTel
specification, since there is no need for backwards compatibility on
this new metadata.

Closes gh-29254
2022-10-05 09:55:42 +02:00
Brian Clozel 5613922fba Polish test
This test should not rely on a particular content-type as none is
defined on the producing end, not on the requesting end.
2022-10-04 10:09:07 +02:00
Violeta Georgieva b5adae2086 Switch to Reactor Netty 2 snapshots
Update to Reactor BOM 2022.0.0-SNAPSHOT.
Process package changes.
Adapt to new `HttpHeaders` API.
Adapt to new cookies API.

See gh-29247
2022-10-03 18:20:52 +01:00
Johnny Lim 380795e5b8 Polish observability changes
Closes gh-29235
2022-09-30 23:12:26 +02:00
Brian Clozel 8c24e8c034 Add HttpOutcome for HTTP observations
Prior to this commit, the HTTP Observations would use
`HttpStatus.Series` as a value source for the "outcome" key value in
recorded observations. This would work for most cases, but would not
align in the 2xx HTTP status cases: the series would provide a
"SUCESSFUL" value whereas the heritage metrics support in Spring Boot
would give "SUCESS".

This commit introduces a dedicated `HttpOutcome` concept for this and
applies it to all HTTP observations.

Fixes gh-29232
2022-09-30 18:17:23 +02:00
Brian Clozel b9070ae752 Add contextualName to HTTP Observations
This commit ensures that all HTTP `ObservationConvention`
implementations provide a consistent contextual name for observations.
This name should be like "http get" where only the HTTP verb changes
depending on the request.

Fixes gh-29231
2022-09-30 18:17:23 +02:00
Arjen Poutsma 0293e22910 Trying to fix flaky CoroutinesIntegrationTests 2022-09-30 15:54:01 +02:00
Adam Ostrožlík 0ccb64fe10 Replace Collectors.toList with Stream.toList
Closes gh-29203
2022-09-26 18:32:01 +02:00
ijonathanc 9d263668d5 Pass current request to filter in RouterFunction extensions
This commit ensures that the proper request is passed in the
Kotlin RouterFunction extension DSL.

Closes gh-27086
2022-09-26 14:55:14 +02:00
Arjen Poutsma fa5998ebd4 Trying to fix flaky CoroutinesIntegrationTests 2022-09-19 12:22:18 +02:00
Sam Brannen 911d1f2dea Suppress warnings 2022-09-14 15:27:11 +02:00
Arjen Poutsma 71f9a84d22 Fix releasing bug in StringDecoder
This commit fixes an issue in StringDecoder, where, if the buffer did
not contain any delimiters, it was released before it was relayed to
any subscribers.

Closes gh-29119
2022-09-13 15:46:24 +02:00
Brian Clozel ac9360b624 Instrument WebClient for Observability
This commit introduces Micrometer as an API dependency to the
spring-webflux module. Micrometer is used here to instrument `WebClient`
and record `Observation` for HTTP client exchanges.

This replaces Spring Boot's `MetricsWebClientFilterFunction` which
instruments `WebClient` via an `ExchangeFilterFunction`. Here, a direct
instrumentation is more efficient and less prone to metrics errors.

See gh-28341
2022-09-12 11:37:47 +02:00
Brian Clozel 2b5ca63339 Fix serialization compiler warnings with Java 18
As of Java 18, the serial lint warning in javac has been expanded to
check for class fields that are not marked as `Serializable`.
See https://www.oracle.com/java/technologies/javase/18all-relnotes.html#JDK-8202056

In the Spring Framework codebase, this can happen with `Map`, `Set` or
`List` attributes which are often assigned with an unmodifiable
implementation variant. Such implementations are `Serializable` but
cannot be used as field types.

This commit ensures that the following changes are applied:
* fields are marked as transient if they can't be serialized
* classes are marked as `Serializable` if this was missing
* `@SuppressWarnings("serial")` is applied where relevant
2022-09-09 20:24:26 +02:00
rstoyanchev d373435856 Support for WebFlux on Reactor Netty 2 with Netty 5
See gh-28847
2022-09-08 21:54:46 +01:00
Sam Brannen 0395fb4f5f Polish tests 2022-09-07 15:12:15 +02:00
Sam Brannen 1688becd73 Avoid questionable use of ClassPathResource#getPath() in tests
Prior to this commit, several tests used ClassPathResource#getPath()
based on the knowledge that the ClassPathResource had been created
using the ClassPathResource(String,Class) constructor. However, making
such an assumption seems ill advised in light of the abstraction that
ClassPathResource provides.

In light of that, this commit avoids questionable use of
ClassPathResource#getPath() in tests by refactoring those tests to use
the proper abstractions provided by ClassPathResource.
2022-09-07 14:59:05 +02:00
Arjen Poutsma 4b18cc94ea Merge branch '5.3.x' 2022-08-30 15:15:57 +02:00
Arjen Poutsma f91943977c RenderingResponse must set status code on RedirectView
This commit makes sure that WebFlux's RenderingResponse sets the HTTP
status code when rendering a RedirectView.

Closes: gh-28839
2022-08-30 15:14:03 +02:00
Sam Brannen b50415062b Clean up warnings and polish tests
This commit also modifies ResourceWebHandlerTests.getResourceFromFileSystem()
so that it passes in the IDE.
2022-08-26 15:20:16 +02:00
Arjen Poutsma 9c33d2707a Introduce support for Netty 5 Buffer
This commit introduces support for Netty 5's Buffer, in the form of
Netty5DataBuffer. Because of the new API offered by Buffer, several
changes have been made to the DataBuffer API:

- CloseableDataBuffer is a simpler alternative to PooledDataBuffer, and
  implemented by Netty5DataBuffer. DataBufferUtils::release can now
  handle CloseableDataBuffer as well as PooledDataBuffer.
- PooledDataBuffer::touch has been moved into a separate interface:
  TouchableDataBuffer, which is implemented by Netty5DataBuffer.
- The capacity of DataBuffers can no longer be reduced, they can only
  grow larger. As a consequence, DataBuffer::capacity(int) has been
  deprecated, but ensureWritable (formally ensureCapacity) still exists.
- DataBuffer::slice and retainedSlice have been deprecated in favor of
  split, a new method that ensures that memory regions do not overlap.
- DataBuffer::asByteBuffer has been deprecated in favor of toByteBuffer,
  a new method that returns a copy, instead of shared data.
- DataBufferFactory::allocateBuffer has been deprecated in favor of
  allocateBuffer(int).

Closes gh-28874
2022-08-25 11:00:22 +02:00
Arjen Poutsma f145b53fc8 Use existing context path in DefaultServerRequestBuilder
Closes gh-28820
2022-07-14 15:24:44 +02:00
Arjen Poutsma 1e03b30d33 Use existing context path in DefaultServerRequestBuilder
Closes gh-28820
2022-07-14 15:10:31 +02:00
Sam Brannen 0fb9de5d0e Merge branch '5.3.x' 2022-07-13 16:36:01 +02:00
Marc Wrobel bd3499671c Fix typos in test code
This commit fixes typos in test class names, test method names, and
test variable names.

Closes gh-28807
2022-07-13 16:24:11 +02:00
rstoyanchev 263811ecfa Add WebFlux equivalent of ResponseEntityExceptionHandler
Closes gh-28665
2022-07-13 10:58:48 +01:00
rstoyanchev 380aedb12a Add ProblemDetailJacksonMixin
Closes gh-28665
2022-07-12 13:04:58 +01:00
Sam Brannen 983c6e233f Merge branch '5.3.x'
# Conflicts:
#	spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java
2022-07-12 12:01:27 +02:00
Marc Wrobel 31c6965c7f Fix and improve Javadoc in spring-webflux
Closes gh-28790
2022-07-12 11:48:58 +02:00
Sam Brannen b61ac6315a Merge branch '5.3.x'
# Conflicts:
#	spring-webmvc/src/test/java/org/springframework/web/servlet/view/freemarker/FreeMarkerMacroTests.java
2022-07-05 13:27:09 +02:00
Sam Brannen 0621a8eff1 Fix concurrency issues in FreeMarkerMacroTests
Prior to this commit, tests in these two classes intermittently failed
with errors similar to the following, due to concurrent modification
of shared files.

expected:
  "<input type="text" id="name" name="name" value="Darren"     >"
 but was:
  "<input type="text" id="name" name="name" value="Darren"     >

  "hidden"/>"

This commit fixes this by creating a new temporary folder for each test
method invocation.
2022-07-05 13:17:50 +02:00
rstoyanchev b312eca391 Deprecate and set trailingSlash option to false
Closes gh-28552
2022-06-29 16:09:10 +01:00
rstoyanchev a04e805d27 Expose status handler at WebClient.Builder level
See gh-28533
2022-06-24 13:58:57 +01:00
rstoyanchev 4ed581cdd7 Fix build failures 2022-06-24 13:58:57 +01:00
rstoyanchev b72ee5f034 Add static factory methods to WebClientAdapter
Ideally one would pass WebClient directly to HttpServiceProxyFactory,
but two need to remain decoupled. This commit adds static, shortcut
methods to WebClientAdapter to create an HttpServiceProxyFactory, thus
eliminating the step to wrap the WebClient.
2022-06-24 09:55:21 +01:00
Brian Clozel 0783f0762d Improve conditional requests support
Prior to this commit, Spring MVC and Spring WebFlux would not support
conditional requests with `If-Match` preconditions. As underlined in the
RFC9110 Section 13.1, those are related to the `If-None-Match`
conditions, but this time only performing requests if the resource
matches the given ETag.

This feature, and in general the `"*"` request Etag, are generally
useful to prevent "lost updates" when performing a POST/PUT request: we
want to ensure that we're updating a version with a known version or
create a new resource only if it doesn't exist already.

This commit adds `If-Match` conditional requests support and ensures
that both `If-Match` and `If-None-Match` work well with `"*"` request
ETags.

We can't rely on `checkNotModified(null)`, as the compiler can't decide
between method variants accepting an ETag `String` or a Last Modified
`long`. Instead, developers should use empty ETags `""` to signal that
no resource is known on the server side.

Closes gh-24881
2022-06-21 19:29:20 +02:00
Sam Brannen 04dde03451 Merge branch '5.3.x' 2022-06-20 16:03:09 +02:00