Commit Graph

372 Commits

Author SHA1 Message Date
Greg Turnquist
a084686156 #786 - Deprecate VndErrors and VndError. 2019-12-10 10:07:28 -06:00
Greg Turnquist
20bff3e26f #786 - Implement vendor neutral error handling with RFC-7807. 2019-12-10 10:00:23 -06:00
Greg Turnquist
4f3be119c0 #775 - Clean up VndError implementation to match spec.
* Handle single, multiple, and nested errors.
* Retain backward compatibility with existing constructors.
2019-12-10 09:56:11 -06:00
Oliver Drotbohm
6bb2310682 #1155 - Fixed thread-safety issues in AnnotationLinkRelationProvider.
We now use a ConcurrentReferenceHashMap to cache annotation lookups in AnnotationLinkRelationProvider to avoid thread-safety issues.
2019-12-10 15:23:06 +01:00
Oliver Drotbohm
a2290c692a #1132 - HAL link relation rendering now applies Jackson's PropertyNamingStrategy.
The rendering of HAL's link relations now applies Jackson's PropertyNamingStrategy if one is configured except it's a IANA link relation. This behavior can be opt out from by setting HalConfiguration.withApplyPropertyNamingStrategy(false).

LinkRelation now has a ….map(…) method allowing the post-processing of it given a Function<String, String>. By default, that's applied to all relations that are not IANA ones. HalLinkRelation applies this transformation to only the local part of the relation. Tweaked IanaLinkRelations.isIanaLinkRelation(…) to do a simple ….contains(…) check first before we stream over all values to apply a case insensitive check.
2019-12-10 11:29:21 +01:00
Oliver Drotbohm
8f1f355c9f #1154 - WebFlux Link creation starts with clean query parameters.
We now explicitly remove all query parameters from the base URI we use when creating links from method names.
2019-12-09 16:02:07 +01:00
Oliver Drotbohm
26c44dcc98 #1152 - Allow adding path segments to links created via WebFluxLinkBuilder.
WebFluxLinkBuilder now allows to call ….slash(…) in symmetry to other LinkBuilder implementations.
2019-12-09 12:10:10 +01:00
Oliver Drotbohm
8e96eafb37 #1150 - WebFluxLinkBuilder now considers the requests context path.
The base URI we create now consists of the requests root URI plus the context path concatenated. On actual UriComponentsBuilder creation we then simply append the path discovered from the method mapping.
2019-12-09 12:10:07 +01:00
Oliver Drotbohm
7744bda4b1 #1147 - Make sure we explicitly expose all media type model properties.
Jackson can be configured to not auto-detect properties on objects to be rendered, requiring them to be explicitly annotated with @JsonProperty to be exposed. In such a configuration setup, some of our model types do not work properly as so far we have expected public properties to be included automatically.

This commit changes that to explicitly include @JsonProperty on all of the getter methods exposed.
2019-12-09 09:38:19 +01:00
Oliver Drotbohm
452189edd8 #1148 - Further performance improvements in link creation.
The implementation details of WebHandler have been significantly refactored to rather work with structures that allow better cacheability by clearly separating abstractions over the statically available information from the per-invocation aspects. This results in a new HandlerMethodParameter(s) abstraction within WebHandler. BoundMethodParameter has been removed entirely. HandlerMethodParameters are create once then cached for every controller method being linked to.

DummyInvocationUtils now creates a ThreadLocal cache of the proxies created for calls to methodOn(…) as they essentially only act as basis for subsequent calls to the methods on the proxy created which in turn are expected to be handed into a linkTo(…) call which obtains the invocation right away. This avoids overhead in cases methodOn(…) is called multiple times for the same controller from a single controller.

The lookup of the LastInvocationAware was previously routed through the proxy, handled by InvocationRecordingMethodInterceptor. This resulted in a second, reflective call for every link creation. DummyInvocationUtils now provides a dedicated lookup method as it knows about the structure of the proxy it created and thus can unfold the recorded invocation more effectively.

The LinkBuilder type hierarchy now works with UriComponents and only creates a UriComponentsBuilder if it needs to modify the backing link in the first place. This avoids superfluous back and forth between UriComponents and UriComponentsBuilders that involved quite a bit of String parsing and creation.

EncodingUtils now starts from a StandardCharsets.UTF_8 to avoid repeated Charset creation.

The changes result in a ~3x performance compared to 1.0.2.RELEASE:

1.0.2.RELEASE

Benchmark                                         Mode  Cnt         Score        Error  Units
ControllerLinkBuilderBenchmark.noLinkCreation    thrpt   10  39004583,189 ± 751668,181  ops/s
ControllerLinkBuilderBenchmark.pureLinkCreation  thrpt   10     43443,133 ±    783,120  ops/s
ControllerLinkBuilderBenchmark.withLinkCreation  thrpt   10     60201,629 ±   1292,179  ops/s

1.1 / 1.0.3 SNAPSHOT

Benchmark                                         Mode  Cnt         Score        Error  Units
ControllerLinkBuilderBenchmark.noLinkCreation    thrpt   10  39618560,950 ± 612794,310  ops/s
ControllerLinkBuilderBenchmark.pureLinkCreation  thrpt   10    121700,634 ±   1510,415  ops/s
ControllerLinkBuilderBenchmark.withLinkCreation  thrpt   10    121982,085 ±   3344,206  ops/s

noLinkCreation - creates a single RepresentationModel instance but adds no links
pureLinkCreation - creates a single link pointing to a controller method
withLinkCreation - creates a single RepresentationModel instance adding a single link
2019-12-06 14:27:27 +01:00
Oliver Drotbohm
8befce38e4 #1134 - Forward global codec settings to decoders in WebClientConfigurer.
We now use new API introduced in Spring Framework 5.2.2 to forward the global configuration settings into the hypermedia decoders we register.
2019-12-03 14:33:51 +01:00
Oliver Drotbohm
3127c97ba9 #1134 - Make sure we don't accidentally drop customizations made to WebClient.
We now use the API introduced in Spring Framework 5.2.2 to customize a WebClient to add hypermedia related en- and decoders without dropping customizations potentially made to the WebClient instance.
2019-12-02 16:52:47 +01:00
Oliver Drotbohm
a630a43c28 #1119 - Moved WebConverters bean declaration into common HateoasConfiguration.
RestTemplateHateoasConfiguration depends on a shared bean WebConverters (previously WebMvcConverters). As it can safely be used in both WebFlux and WebMVC scenarios (as it only depends on types from spring-web), we now include a declaration in the shared HateoasConfiguration. This also allows us to remove the just introduced explicit declaration of a WebConverter bean in WebFluxHateoasConfiguration.
2019-12-01 22:58:02 +01:00
Greg Turnquist
17543fc4fa #1119 - Include WebMvcConverters in WebFluxHateoasConfiguration. 2019-12-01 22:57:55 +01:00
Oliver Drotbohm
d98e678c59 #593 - Make UriTemplate smarter to avoid reencoding of given URI strings.
UriTemplate now uses UriBuilderFactory (DefaultUriBuilderFactory in particular) to expand templates. We inspect the given source URI string, try to decode it and configure the factory to only encode values if the decoded String is shorter than the source one as that indicates it already contains encoded characters.

The UriBuilderFactory is held as transient value as its implementations are usually not serializable in the first place. Added the necessary logic to recreate the factory instance on deserialization.

Added all expansion tests given in the original ticket as unit tests.
2019-11-28 15:00:37 +01:00
Oliver Drotbohm
d3ece765bc #1127 - Avoid double encoding in UriTemplate.
We now directly use UriComponentsBuilder in UriTemplate.expand(…) to avoid potential double encoding in the base URI.
2019-11-28 11:14:57 +01:00
Oliver Drotbohm
5f016d6c9e #1119 - Avoid reference to spring-webmvc in configuration for RestTemplate.
RestTemplateHateoasConfiguration previously referred to HypermediaWebMvcConfigurer which is turn depending on WebMvcConfigurer, a type living in spring-webmvc. The very former would still get active in WebFlux as the web stack is selected based on the presence of either DispatcherServlet or DispatcherHandler. This is now resolved by using a WebMvcConverter indrection to handle the configuration tweaks avoiding the reference to interfaces from spring-webmvc.

Introduced an ArchUnit based test that Spring HATEOAS code only depends on Spring types containing references to reactive types from either the ….reactive package or classes starting with WebFlux.
2019-11-28 10:53:12 +01:00
Oliver Drotbohm
5444e14017 #1122 - Polishing. 2019-11-22 12:00:15 +01:00
Oliver Drotbohm
3d9fe3893f #1122 - Fixed generics declaration in RepresentationModelAssemblerSupport.
We constrained the RepresentationModel type parameter in a way that non of the RepresentationModel subclasses we provide aren't usable with it. That's now fixed by loosing that restriction to an arbitrary type.
2019-11-22 12:00:04 +01:00
Oliver Drotbohm
aa9e449841 #1121 - Shortcut ignored property lookups to prevent NullPointerExceptions. 2019-11-18 20:53:20 +01:00
Oliver Drotbohm
d0198d5ff5 #1118 - Switch to ConcurrentReferenceHashMap to cache UriTemplate instances.
We now use Spring's ConcurrentReferenceHashMap to keep instances of UriTemplate cached but at the same time allow the cache entries to be garbage collected if necessary.
2019-11-18 20:27:54 +01:00
Greg Turnquist
cf0c606ef4 #1098 - Institute checks for client-only setups.
Gather client- and server-side settings into one "stack". Move all logic of checking this into the enum itself.
2019-10-24 14:11:17 -05:00
Greg Turnquist
b048c272e6 #1045 - Reduce visiblity of UriTemplate constructors.
Related issues: #1044
2019-10-10 14:17:08 -05:00
Oliver Drotbohm
507f7de0c3 #1075 - Explicitly use classpath protocol for base names of MessageResolver resource bundles.
We now explicitly equip the resource bundle base name with a "classpath:" prefix so that the resource lookup also works in Boot web applications in which the ResourceLoader setup is tweaked to prefer ServletContext resources.
2019-09-26 16:54:19 +02:00
Greg Turnquist
f15740fb25 #1038 - Update documentation and testing for ALPS.
Also make the ALPS types support deserialization using @JsonCreator-based private constructor calls.
2019-09-26 09:28:45 -05:00
Oliver Drotbohm
30ddf1873c #1080 - Improved configuration setup and documentation on EntityLinks.
We now explicitly only enable EntityLinks in WebMVC environments. This is also now reflected properly in the reference documentation.
2019-09-26 15:21:35 +02:00
Oliver Drotbohm
1a2ddfaa2a #1075 - Improvements in I18N configuration setup.
We now avoid a double-lookup of the default messages in the resource bundle setup. Tightened the test case to make sure the sample resource bundle is properly used, even if no default messages bundle is present.
2019-09-20 22:40:33 +02:00
Greg Turnquist
9ddfdc8639 #1061 - Polishing. 2019-09-16 09:21:26 -05:00
Oliver Drotbohm
91a34f2517 #1072 - Moved null value inclusion configuration to the getter of HalFormsTemplate.title. 2019-09-05 17:13:03 +02:00
Greg Turnquist
fd70fd90d2 #1061 - Reenable default codecs for WebFlux configuration.
With Spring WebFlux properly handling custom codecs, no need to disable the default handlers.

This commit verifies WebFlux configuration in test cases, and also adds an equivalent set of test cases verifying Web MVC configuration as well.

Supercedes: #1047
2019-09-05 09:38:49 -05:00
Greg Turnquist
85fe81e3a2 #1067 - Remove @EnableEntityLinks. 2019-09-05 06:56:22 -05:00
Greg Turnquist
e5669eefa0 #1059 - Polishing. 2019-08-31 08:15:38 -05:00
Greg Turnquist
fff5396a1c #1059 - Cleanup the core codebase.
Clean up code containing various patterns:

* Remove redundant `final`, `public`, and `static` declarations in interfaces and enums.
* Replace redundant `? extends Object` generic parameters with `?`.
* Convert collections to arrays using empty array instead of pre-sized one (modern JVM recommendation).
* Initialize collections using constructor call over `addAll`.
* Favor `addAll` over iterating and adding one-by-one.
* Take advantage of `Map.forEach` that was introduced with Java 8.
2019-08-30 17:43:07 -05:00
Greg Turnquist
ecbcdef870 #1044 - Restore visibility of UriTemplate constructors.
Visibility must only be removed after publishing a deprecated API.

See #1045 to track reducing the visibility of these constructor calls.
2019-08-06 10:30:25 -05:00
Greg Turnquist
b6accb16ea #1039 - Don't render null ALPS attributes. 2019-08-05 06:19:34 -05:00
Greg Turnquist
6d17d7e949 #857 - Use List instead of Collection in configuration classes. 2019-08-01 16:27:39 -05:00
Greg Turnquist
feaa56a68c #987 - Drop UTF8 HAL media type. 2019-07-31 11:53:53 -05:00
Oliver Drotbohm
400a6bb703 #1019 - Improvements to I18N optimizations.
We now properly look for resource bundles by scanning for a resource bundle *pattern* instead of a plain file named rest-messages. Added integration tests to make sure that resource bundles are not skipped even if they existed.

Added the ability to define common messages in a rest-default-messages.properties, as Spring Data REST requires that and it would be too cumbersome for Spring Data REST to additionally deploy them in its own configuration.
2019-07-31 18:21:50 +02:00
Oliver Drotbohm
b1af903de0 #1021 - Removed explicit depends on to avoid Spring MVC reference in EntityLinksConfiguration. 2019-07-31 10:38:22 +02:00
Oliver Drotbohm
a71aeeb4d1 #1019 - Further optimizations in case not I18N is enabled.
Introduced MessageResolver interface and moved all components previously referring to MessageSourceResolvable to it. This allows us to directly shortcut message resolution by providing a no-op instance in case our default resource bundle rest-messages does not exist and thus avoid the overhead of attempted message resolutions in that case.
2019-07-18 14:49:32 +02:00
Oliver Drotbohm
fc1b4a8b51 #1018 - HAL Forms properties customizable via annotations on representation model classes.
We now consider additional Jackson and JSR-303 annotations on representation models to enrich the HAL Forms template properties with additional information:

- @NotNull on a property flips its `required` flag to `true`.
- The "regexp" attribute of @Pattern on a property is forwarded into the "regex" field.
- @JsonProperty(Access.READ_ONLY) on a property is translated into the "readOnly" flag.

The default for the "required" flag have been changed to false even for PUT and POST as whether they're required or not is completely determined by the model, not the HTTP method.

All of this is backed by significant refactoring in the way that Affordance instances are build internally. The new API is centered around the Affordances type in the mediatype package. The methods on Link to create the Affordance` from its details have been removed and replaced by builder style APIs on Affordance. AffordanceModelFactory has been moved to the mediatype as well.

PropertyUtils has been significantly revamped to expose a PayloadMetadata/PropertyMetadata model to abstract the individual traits of a property. This allows to optionally plug in the support for JSR-303 annotations. AffordanceModelFactory has been refactored to rather work with those instead of ResolvableType.
2019-07-18 13:07:58 +02:00
Oliver Drotbohm
ec8fba1dd5 #1020 - Re-introduce BasicLinkBuilder.
Reintroduced type apparently lost in the package restructuring. Adapted migration script to include the package rename in the migration.
2019-07-17 14:44:06 +02:00
Oliver Drotbohm
9e9221c325 #1022 - Deprecate @EnableEntityLinks. 2019-07-17 14:22:23 +02:00
Oliver Drotbohm
b21c362111 #1021 - Tweak setup of @EnableEntityLinks to make sure it only runs on Spring WebMVC.
We now clearly separate the beans registered by configuration backing @EnableEntityLinks into the ones that depend on Spring MVC being used and commonly shared ones. Tweaked the setup of @EnableHypermediaSupport to rather include the individual configuration classes instead of using @EnableEntityLinks directly as that would always pull WebMVC specific components.
2019-07-17 14:22:23 +02:00
Oliver Drotbohm
ff6380063c #1019 - Avoid exceptions on HAL link title rendering.
HalLinkRelation now implements MessageSourceResolvable.getDefaultMessage() returning an empty String to avoid NoSuchMessageExceptions for every resolution not backed by an actual translation. Tweaked serialization configuration for HalLink to not render empty title strings.
2019-07-15 22:39:10 +02:00
Oliver Drotbohm
81b685d196 #1014 - Polishing.
Javadoc.
2019-07-02 20:06:48 +02:00
Oliver Drotbohm
d1a06bbcc8 #1014 - Added API to conditionally add links to RepresentationModel.
This allows more fluent usage of the API.
2019-07-02 20:05:07 +02:00
Greg Turnquist
a0469e0371 #445 - Make RepresentationModelAssemblerSupport extensible.
Original pull-request: #590
2019-06-28 06:19:23 -05:00
Greg Turnquist
0a5e8b98e5 #729 - Fix serialization of RepresentationModel for HAL-FORMS.
Original pull request: #824.
2019-06-27 17:00:14 +02:00
Oliver Drotbohm
70586c9f22 #832 - Tweaked setup of HalFormsConfiguration and HalConfiguration.
HalFormsConfiguration now delegates to a HalConfiguration and the configuration will favor a user registered instance of the former over an instance of the latter or even fall back to default instances in case none of that is defined in the ApplicationContext.

This allows seamless pickup of HalConfiguration for HAL FORMS but also explicit opt-out if not desired.
2019-06-27 15:46:50 +02:00