Skip to content

Commit

Permalink
Restentpoints with same name get mix up. Fixes #2876
Browse files Browse the repository at this point in the history
  • Loading branch information
bnasslahsen committed Feb 15, 2025
1 parent cce8e8b commit 0775180
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.async.DeferredResult;

import static org.springdoc.core.utils.Constants.GLOBAL_OPEN_API_CUSTOMIZER;
import static org.springdoc.core.utils.Constants.SPRINGDOC_DEPRECATING_CONVERTER_ENABLED;
import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLED;
import static org.springdoc.core.utils.Constants.SPRINGDOC_POLYMORPHIC_CONVERTER_ENABLED;
Expand Down Expand Up @@ -654,7 +655,7 @@ ParameterObjectNamingStrategyCustomizer parameterObjectNamingStrategyCustomizer(
* @return the global open api customizer
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnMissingBean(name = GLOBAL_OPEN_API_CUSTOMIZER)
@Lazy(false)
GlobalOpenApiCustomizer globalOpenApiCustomizer() {
return new OperationIdCustomizer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ CollectionModelContentConverter collectionModelContentConverter(HateoasHalProvid
* @return the open api customizer
* @see org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider) org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)
*/
@Bean(Constants.LINKS_SCHEMA_CUSTOMISER)
@ConditionalOnMissingBean(name = Constants.LINKS_SCHEMA_CUSTOMISER)
@Bean(Constants.LINKS_SCHEMA_CUSTOMIZER)
@ConditionalOnMissingBean(name = Constants.LINKS_SCHEMA_CUSTOMIZER)
@Lazy(false)
GlobalOpenApiCustomizer linksSchemaCustomizer(HateoasHalProvider halProvider, SpringDocConfigProperties springDocConfigProperties) {
if (!halProvider.isHalEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.CollectionUtils;

import static org.springdoc.core.utils.Constants.LINKS_SCHEMA_CUSTOMISER;
import static org.springdoc.core.utils.Constants.LINKS_SCHEMA_CUSTOMIZER;

/**
* The type Spring doc customizers.
Expand Down Expand Up @@ -223,7 +223,7 @@ public Optional<Set<GlobalOpenApiMethodFilter>> getGlobalOpenApiMethodFilters()
public void afterPropertiesSet() {
//add the default customizers
Map<String, OpenApiCustomizer> existingOpenApiCustomizers = context.getBeansOfType(OpenApiCustomizer.class);
if (!CollectionUtils.isEmpty(existingOpenApiCustomizers) && existingOpenApiCustomizers.containsKey(LINKS_SCHEMA_CUSTOMISER))
this.openApiCustomizers.ifPresent(openApiCustomizersList -> openApiCustomizersList.add(existingOpenApiCustomizers.get(LINKS_SCHEMA_CUSTOMISER)));
if (!CollectionUtils.isEmpty(existingOpenApiCustomizers) && existingOpenApiCustomizers.containsKey(LINKS_SCHEMA_CUSTOMIZER))
this.openApiCustomizers.ifPresent(openApiCustomizersList -> openApiCustomizersList.add(existingOpenApiCustomizers.get(LINKS_SCHEMA_CUSTOMIZER)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,12 @@ public final class Constants {
/**
* The constant LINKS_SCHEMA_CUSTOMISER.
*/
public static final String LINKS_SCHEMA_CUSTOMISER = "linksSchemaCustomizer";
public static final String LINKS_SCHEMA_CUSTOMIZER = "linksSchemaCustomizer";

/**
* The constant GLOBAL_OPEN_API_CUSTOMIZER.
*/
public static final String GLOBAL_OPEN_API_CUSTOMIZER = "globalOpenApiCustomizer";

/**
* The constant SPRINGDOC_SORT_CONVERTER_ENABLED.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.springdoc.core.utils.Constants.LINKS_SCHEMA_CUSTOMISER;
import static org.springdoc.core.utils.Constants.LINKS_SCHEMA_CUSTOMIZER;

class SpringDocHateoasConfigurationTest {

Expand All @@ -33,8 +33,8 @@ void linksSchemaCustomizerShouldBeRegistered() {
.run(context -> {
assertThat(context).getBeanNames(GlobalOpenApiCustomizer.class)
.hasSize(2)
.contains(LINKS_SCHEMA_CUSTOMISER);
assertThat(context.getBean(LINKS_SCHEMA_CUSTOMISER)).isExactlyInstanceOf(OpenApiHateoasLinksCustomizer.class);
.contains(LINKS_SCHEMA_CUSTOMIZER);
assertThat(context.getBean(LINKS_SCHEMA_CUSTOMIZER)).isExactlyInstanceOf(OpenApiHateoasLinksCustomizer.class);
});
}

Expand All @@ -56,7 +56,7 @@ void linksSchemaCustomizerShouldBeRegisteredWithMultipleGlobalOpenApiCustomizer(
.run(context -> {
assertThat(context).getBeanNames(GlobalOpenApiCustomizer.class)
.hasSize(2)
.containsExactlyInAnyOrder(LINKS_SCHEMA_CUSTOMISER, "globalOpenApiCustomizer");
.containsExactlyInAnyOrder(LINKS_SCHEMA_CUSTOMIZER, "globalOpenApiCustomizer");
});
}

Expand All @@ -74,12 +74,12 @@ void linksSchemaCustomizerShouldNotBeRegisteredIfBeanWithSameNameAlreadyExists()
SpringDocConfigProperties.class,
SpringDocHateoasConfiguration.class
))
.withBean(LINKS_SCHEMA_CUSTOMISER, GlobalOpenApiCustomizer.class, () -> mock(GlobalOpenApiCustomizer.class))
.withBean(LINKS_SCHEMA_CUSTOMIZER, GlobalOpenApiCustomizer.class, () -> mock(GlobalOpenApiCustomizer.class))
.run(context -> {
assertThat(context).getBeanNames(GlobalOpenApiCustomizer.class)
.hasSize(1)
.containsExactly(LINKS_SCHEMA_CUSTOMISER);
assertThat(context.getBean(LINKS_SCHEMA_CUSTOMISER)).isNotExactlyInstanceOf(OpenApiHateoasLinksCustomizer.class);
.hasSize(2)
.contains(LINKS_SCHEMA_CUSTOMIZER);
assertThat(context.getBean(LINKS_SCHEMA_CUSTOMIZER)).isNotExactlyInstanceOf(OpenApiHateoasLinksCustomizer.class);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package test.org.springdoc.api.v31.app240;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import io.swagger.v3.oas.annotations.Parameter;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/demo")
public class DemoRestController {

@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public Set<String> getDemo(
@Parameter(required = false, description = "Very important description.")
@RequestParam(name = "darstellung", required = false) final Optional<String> darstellung) {
return new HashSet<>();
}

@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> setDemo(@RequestBody final String str) {
return ResponseEntity.noContent().build();
}

@GetMapping(value = "/{vvpId}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getDemo(@PathVariable("vvpId") final Long vvpId) {
return "Test";
}

@PatchMapping("/{vvpId}")
public ResponseEntity<?> patchDemo(@PathVariable("vvpId") final Long idVerfahren,
@RequestBody() final String jsonPatch,
final Optional<Boolean> statusKinderAendern) {
return ResponseEntity.noContent().build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package test.org.springdoc.api.v31.app240;

import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpRequest;

@Configuration
public class OpenApiConfig {

@Bean
public OpenApiCustomizer openApiCustomiser() {
return openApi -> {

};
}

@Bean
ServerBaseUrlCustomizer serverBaseUrlCustomizer() {
return new ServerBaseUrlCustomizer() {

@Override
public String customize(final String serverBaseUrl,
final HttpRequest request) {
// TODO Auto-generated method stub
return null;
}

};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
*
* *
* * *
* * * *
* * * * *
* * * * * * Copyright 2019-2025 the original author or authors.
* * * * * *
* * * * * * Licensed under the Apache License, Version 2.0 (the "License");
* * * * * * you may not use this file except in compliance with the License.
* * * * * * You may obtain a copy of the License at
* * * * * *
* * * * * * https://www.apache.org/licenses/LICENSE-2.0
* * * * * *
* * * * * * Unless required by applicable law or agreed to in writing, software
* * * * * * distributed under the License is distributed on an "AS IS" BASIS,
* * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * * * * * See the License for the specific language governing permissions and
* * * * * * limitations under the License.
* * * * *
* * * *
* * *
* *
*
*/

package test.org.springdoc.api.v31.app240;

import test.org.springdoc.api.v31.AbstractSpringDocTest;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.test.context.TestPropertySource;

@TestPropertySource(properties = "springdoc.api-docs.resolve-schema-properties=true" )
public class SpringDocApp240Test extends AbstractSpringDocTest {

@SpringBootApplication
static class SpringDocTestApp {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
{
"openapi": "3.1.0",
"info": {
"title": "OpenAPI definition",
"version": "v0"
},
"paths": {
"/demo": {
"get": {
"tags": [
"demo-rest-controller"
],
"operationId": "getDemo",
"parameters": [
{
"name": "darstellung",
"in": "query",
"description": "Very important description.",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
}
}
}
}
},
"post": {
"tags": [
"demo-rest-controller"
],
"operationId": "setDemo",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
}
}
}
},
"/demo/{vvpId}": {
"get": {
"tags": [
"demo-rest-controller"
],
"operationId": "getDemo_1",
"parameters": [
{
"name": "vvpId",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
},
"patch": {
"tags": [
"demo-rest-controller"
],
"operationId": "patchDemo",
"parameters": [
{
"name": "vvpId",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "statusKinderAendern",
"in": "query",
"required": false,
"schema": {
"type": "boolean"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"type": "object"
}
}
}
}
}
}
}
},
"components": {}
}

0 comments on commit 0775180

Please # to comment.