Why does Spring Boot take so long to find method handler - spring-boot

I have a service configured using Spring Boot and Swagger.
My swagger paths config look like this:
paths:
/hello/test:
post:
summary: Hello World Test
description: >-
Hello World
operationId: helloTest
tags:
- Hello
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/HelloRequest'
description: Hello Request
required: true
responses:
'200':
description: >
OK
content:
application/json:
schema:
$ref: '#/components/schemas/HelloResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'500':
$ref: '#/components/responses/InternalServerError'
/confirmations:
post:
summary: Hello World Confirmation
description: >-
Hello World Confirmation
operationId: postConfirmations
tags:
- Confirmation
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ConfirmationRequest'
description: Hello Confirmation Request
required: true
responses:
'204':
description: >
No Content
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'500':
$ref: '#/components/responses/InternalServerError'
My logs keep showing this message several times
Did not find handler method for [/hello/test]
Even after this message is shown:
Returning handler method [public default org.springframework.http.ResponseEntity<com.sample.hello.generated.emvco.model.HelloResponse> com.sample.hello.generated.emvco.api.HelloApi.postTransactionCredentials(com.sample.hello.generated.emvco.model.HelloRequest)]
This takes up to 5 milliseconds of initial resolution which impacts the performance of the service. What causes spring to look repeatedly for one path which is clearly defined?

I think such a problem mainly comes when the structure of the project is not in the right way. I assume your controller class is not found or taking time during scanning cause it is in a package that will not be scanned by default. I guess your application is not in the right way or default structure. please change your controller to com.app.controller and check performance.

Related

How To ignore Endpoints from openapi.yaml in generation with openapi-generator-maven-plugin/

yaml and openapi-generator-maven-plugin is corretly generating Spring Boot Controller Interfaces from it. All is working fine. But now we want to overwrite one of the generated Interfaces with our own interface. How can we exclude a certain endpoint from this generation?
Example:
paths:
/currencies:
get:
tags:
- DomainData
summary: Lists all valid currencies available.
operationId: "getCurrencies"
parameters:
- $ref: '#/components/parameters/AcceptLanguage'
responses:
"200":
description: "OK"
content:
application/json:
schema:
type: string
additionalProperties:
type: string
'401':
$ref: '#/components/responses/Unauthorized'
'5XX':
$ref: '#/components/responses/Unexpected'
/languages:
get:
tags:
- DomainData
summary: Lists all valid languages available.
operationId: "getLanguages"
parameters:
- $ref: '#/components/parameters/AcceptLanguage'
responses:
"200":
description: "OK"
content:
application/json:
schema:
type: string
additionalProperties:
type: string
'401':
$ref: '#/components/responses/Unauthorized'
'5XX':
$ref: '#/components/responses/Unexpected'
This is a part of the openapi.yaml and we would not like to generate for /languages but everything else.
I found a solution we used a .openapi-generator-ignore
and linked it in the pom options of the openapi generator.
In the .openapi-generator-ignore we used the full relative path from position of the ignore file to the file that is not existing and we dont want to get generated.
target/generated-sources/v1/src/main/java/ch/company/dsp/bff/project/generated/api/languageApi.java

Configuring Spring Boot REST API project with yaml file

It is my first time working with Spring Boot REST API. I would like to build a Spring Boot Project with 2 microservices: UserManagement and Messaging.
I have the following yaml file for my UserManagement API endpoint:
swagger: '2.0'
info:
description: UMS Service
version: 1.0.0
title: UMS API
host: ums
basePath: /api/v1
tags:
- name: role
description: Operations about roles
- name: user
description: Operations about users
- name: login/logout
description: Operations about sessions
schemes:
- https
- http
paths:
/role:
post:
tags:
- role
summary: Create role
description: This can only be done by the logged in user.
operationId: createRole
produces:
- application/json
parameters:
- in: body
name: body
description: Created role object
required: true
schema:
$ref: '#/definitions/Role'
responses:
default:
description: successful operation
get:
tags:
- role
summary: Get role by name
description: ''
operationId: getRoleByName
produces:
- application/json
parameters:
- name: rolename
in: query
description: The name that needs to be fetched.
required: true
type: string
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/Role'
'400':
description: Invalid rolename supplied
'401':
description: Not authenticated
'404':
description: Role not found
put:
tags:
- role
summary: Updated role name
operationId: updateRole
produces:
- application/json
parameters:
- name: rolename
in: query
description: name that need to be updated
required: true
type: string
- in: body
name: body
description: Updated role object
required: true
schema:
$ref: '#/definitions/Role'
responses:
'400':
description: Invalid role supplied
'401':
description: Not authenticated
'404':
description: Role not found
delete:
tags:
- role
summary: Delete role
description: This can only be done by the logged in user.
operationId: deleteRole
produces:
- application/json
parameters:
- name: rolename
in: query
description: The role that needs to be deleted
required: true
type: string
responses:
'400':
description: Invalid role supplied
'401':
description: Not authenticated
'404':
description: Role not found
/user:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
produces:
- application/json
parameters:
- in: body
name: body
description: Created user object
required: true
schema:
$ref: '#/definitions/User'
responses:
default:
description: successful operation
get:
tags:
- user
summary: Get user by user name
description: ''
operationId: getUserByName
produces:
- application/json
parameters:
- name: username
in: query
description: The name that needs to be fetched
required: true
type: string
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/User'
'400':
description: Invalid username supplied
'401':
description: Not authenticated
'404':
description: User not found
put:
tags:
- user
summary: Updated user
description: This can only be done by the logged in user.
operationId: updateUser
produces:
- application/xml
- application/json
parameters:
- in: body
name: body
description: Updated user object
required: true
schema:
$ref: '#/definitions/User'
responses:
'400':
description: Invalid user supplied
'401':
description: Not authenticated
'404':
description: User not found
delete:
tags:
- user
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
produces:
- application/json
parameters:
- name: username
in: query
description: The name that needs to be deleted
required: true
type: string
responses:
'400':
description: Invalid username supplied
'401':
description: Not authenticated
'404':
description: User not found
/user/role:
post:
tags:
- user
summary: Assign role to user
description: This can only be done by the logged in user.
operationId: createUserRole
produces:
- application/json
parameters:
- in: body
name: body
description: Created user object
required: true
schema:
$ref: '#/definitions/UserRole'
responses:
default:
description: successful operation
get:
tags:
- user
summary: Get role by user name
description: ''
operationId: getRoleByUserName
produces:
- application/json
parameters:
- name: username
in: query
description: The name that needs to be fetched
required: true
type: string
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/UserRole'
'400':
description: Invalid username supplied
'401':
description: Not authenticated
'404':
description: User not found
put:
tags:
- user
summary: Updated user's role
description: This can only be done by the logged in user.
operationId: updateUserRole
produces:
- application/json
parameters:
- in: body
name: body
description: Updated user object with new role
required: true
schema:
$ref: '#/definitions/UserRole'
responses:
'400':
description: Invalid username supplied
'401':
description: Not authenticated
'404':
description: User not found
/session/login:
get:
tags:
- login/logout
summary: Get last login for user
description: This can only be done by the logged in user.
operationId: getLastSessionStart
produces:
- application/json
parameters:
- name: username
in: query
required: true
type: string
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/Session'
'401':
description: Not authenticated
/session/logout:
get:
tags:
- login/logout
summary: Get last logout for user
description: This can only be done by the logged in user.
operationId: getLastSessionEnd
produces:
- application/json
parameters:
- name: username
in: query
required: true
type: string
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/Session'
'401':
description: Not authenticated
post:
tags:
- login/logout
summary: Set logout for user
description: This can only be done by the logged in user.
operationId: setLastSessionEnd
produces:
- application/json
parameters:
- in: body
name: body
description: Set Log out data for user
required: true
schema:
$ref: '#/definitions/Session'
responses:
default:
description: successful operation
securityDefinitions:
ums_auth:
type: oauth2
authorizationUrl: 'http://ums/oauth/user'
flow: implicit
scopes:
'write:users': modify users in your account
'read:users': read user data
api_key:
type: apiKey
name: api_key
in: header
definitions:
UserRole:
type: object
properties:
username:
type: string
rolename:
type: string
Role:
type: object
properties:
rolename:
type: string
User:
type: object
properties:
username:
type: string
email:
type: string
password:
type: string
role:
type: string
Session:
type: object
properties:
username:
type: string
login:
type: number
logout:
type: number
My question is: how do I configure my UserManagement Service to communicate with this yaml file and generate its contents in a web browser? I am using Eclipse with STS3 plugin.
Thank you for any suggestions. Also, I'd be grateful to sample links to Spring Boot REST API projects with application.yml files which could help me build a simple Spring Boot REST API with 2 services.
You may need a openapi-generator-maven-plugin to read your YML file and generate an OAS (Open API specification) out of it.
Not completely tried from scratch, but check if below helps
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>4.3.1</version>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/oas/openapi.yaml</inputSpec>
<generatorName>spring</generatorName>
<modelPackage>com.xyz....</modelPackage>
<apiPackage>com.xyz...</apiPackage>
<output>./../api</output>
<generateSupportingFiles>false</generateSupportingFiles>
<configOptions>
<sourceFolder>src/main/java</sourceFolder>
<interfaceOnly>true</interfaceOnly>
<skipDefaultInterface>true</skipDefaultInterface>
<hideGenerationTimestamp>true</hideGenerationTimestamp>
</configOptions>
</configuration>
</plugin>
You may reach out to the one who asked a similar question on this article, he might have tried from scratch Openapi operationid is repeated

Yaml - Swagger, Duplicate mapping key

I've created a simple API, however I am having problems documenting it with Swagger as I get error: Duplicate mapping key on line 200. It is the line which says: "INVALID TOKEN" on route to update a switch: api/switches/update/{id}
I've tried creating also definition specific for update, but it was the same as Create so I think its okay to use Create definition for update as well. Not sure, if this could be a part of the problem.
swagger: "2.0"
info:
version: "1.0.0"
title: Mechanical Switches API
host: localhost:4000
basePath: /
schemes:
- http
- https
consumes:
- application/json
produces:
- application/json
- application/xml
- text/xml
- text/html
paths:
/api/welcome:
get:
description: Sharing the love with welcome message
summary: Welcome message
operationId: getWelcomeMessage
tags:
- user
responses:
'200':
description: "OK"
/api/user/register:
post:
description: Register a new user
summary: Create new user
operationId: postNewUser
tags:
- user
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
parameters:
- in: body
name: User registration
description: The user to create
schema:
$ref: "#/definitions/userCreate"
/api/user/login:
post:
description: Login as user
summary: Login user
operationId: loginExistingUser
tags:
- user
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
parameters:
- in: body
name: User login
description: The user to login
schema:
$ref: "#/definitions/userLogin"
/api/switches/create:
post:
description: Create a new switch
summary: New Switch
operationId: postNewSwitch
tags:
- switches
responses:
'200':
description: "OK"
'400':
description: "ACCESS DENIED"
'401':
description: "INVALID TOKEN"
parameters:
- in: body
name: Create switch
description: Create a new switch
schema:
$ref: "#/definitions/switchCreate"
/api/switches:
get:
description: Get all the switches
summary: All Switches
operationId: getAllSwitches
tags:
- switches
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
/api/switches/{id}:
get:
parameters:
- name: id
in: path
required: true
type: integer
format: int64
description: Get a specific switch
summary: Specific switch
operationId: getSingleSwitch
tags:
- switches
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
/api/switches/type/linear:
get:
description: Get all linear switches
summary: Linear switches
operationId: getLinearSwitches
tags:
- switches
- type linear
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
/api/switches/type/tactile:
get:
description: Get all tactile switches
summary: Tactile switches
operationId: getTactileSwitches
tags:
- switches
- type tactile
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
/api/switches/type/clicky:
get:
description: Get all clicky switches
summary: Clicky switches
operationId: getClickySwitches
tags:
- switches
- type clicky
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
/api/switches/mount/5pin:
get:
description: Get all switches with 5-pin mount
summary: All 5-pin
operationId: getAll5pin
tags:
- switches
- 5pin
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
/api/switches/mount/3pin:
get:
description: Get all switches with 3-pin mount
summary: All 3-pin
operationId: getAll3pin
tags:
- switches
- 3pin
responses:
'200':
description: "OK"
'400':
description: "NOT OK"
/api/switches/update/{id}:
put:
parameters:
- name: id
in: path
required: true
type: integer
format: int64
description: Update a specific switch
summary: Update switch
operationId: updateSwitch
tags:
- switches
- update
responses:
'200':
description: "OK"
'400':
description: "ACCESS DENIED"
'401':
description: "INVALID TOKEN"
parameters:
- in: body
name: Update existing switch
description: Update a switch
schema:
$ref: "#/definitions/switchCreate"
/api/switches/delete/{id}:
delete:
parameters:
- name: id
in: path
required: true
type: integer
format: int64
description: Delete a specific switch
summary: Delete switch
operationId: deleteSwitch
tags:
- switches
- delete
responses:
'200':
description: "OK"
'400':
description: "ACCESS DENIED"
'401':
description: "INVALID TOKEN"
definitions:
userCreate:
properties:
userName:
type: string
email:
type: string
password:
type: string
required:
- userName
- email
- password
userLogin:
properties:
email:
type: string
password:
type: string
required:
- email
- password
switchCreate:
properties:
model:
type: string
brand:
type: string
switchCollection:
type: string
switchType:
type: string
actuationForce:
type: string
preTravel:
type: string
totalTravel:
type: string
stemStructure:
type: string
mount:
type: string
lifespan:
type: string
colors:
type: string
manufacturer:
type: string
required:
- model
- brand
- switchCollection
- switchType
- actuationForce
- preTravel
- totalTravel
- stemStructure
- mount
- lifespan
- colors
- manufacturer
The "duplicate mapping key" error occurs because the /api/switches/update/{id} definition contains two parameters sections:
/api/switches/update/{id}:
put:
parameters: # <------
- name: id
in: path
required: true
type: integer
format: int64
description: Update a specific switch
...
responses:
...
parameters: # <------
- in: body
name: Update existing switch
description: Update a switch
schema:
$ref: "#/definitions/switchCreate"
You need to merge the parameters into a single list:
/api/switches/update/{id}:
put:
parameters:
- name: id
in: path
required: true
type: integer
format: int64
- in: body
name: Update existing switch
description: Update a switch
schema:
$ref: "#/definitions/switchCreate"

Schema error at paths should NOT have additional properties in SWAGGER

Please help me to solve this issue
paths: 'sepa/sct/{OriginatorAccount}':
post:
tags:
- SCT Initiation
summary: SCT Initiation
description: ''
operationId: doSEPASCTInit
parameters:
- name: OriginatorAccount
in: path
description: Originator Account
required: true
type: string
- in: body
description: Input Content
name: body
required: false
schema:
$ref: '#/definitions/MandateInfo'
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/MandateInfo'
'400':
description: Operation failed
default:
description: Alert details added successfully.
Error:
Schema error at paths should NOT have additional properties
additionalProperty: sepa/sct/{OriginatorAccount}
Endpoint paths must begin with a forward slash /:
/sepa/sct/{OriginatorAccount}

openapi generator maven plugin : Polymorphism support

I have written YAML files with polymorphism syntax but i get a nullpointer error whenever maven plugin parses a definition with polymorphism schema.
Does "openapi-generator-maven-plugin" supports polymorphic YAML files to generate java stubs?
An example of polymorphis definition :
IRFloatSwapLegDO:
title: IRFloatSwapLegDO
allOf:
- $ref: '#/definitions/IRSwapLegDO'
- type: object
properties:
amortizationSchedule:
$ref: '#/definitions/AmortizationScheduleDO'
compoundingSchedule:
$ref: '#/definitions/CompoundingScheduleDO'
couponSchedule:
$ref: '#/definitions/CouponScheduleDO'
currency:
$ref: '#/definitions/CurrencyDO'
dayCountConvention:
type: string
fixInArrears:
type: boolean
fixingMultiplier:
type: number
format: double
fixingSchedule:
$ref: '#/definitions/CompoundingScheduleDO'
irSwapLegType:
type: string
enum:
- IRFixedSwapLeg
- IRFloatSwapLeg
irUnderlying:
$ref: '#/definitions/IRUnderlyingDO'
legID:
type: string
notional:
type: number
format: double
notionalExchange:
$ref: '#/definitions/NotionalExchangeDO'
overriddenFixings:
$ref: '#/definitions/CouponScheduleDO'
payAtStart:
type: boolean
schedule:
$ref: '#/definitions/ScheduleDO'
title: IRFloatSwapLegDO
Below is the exception which i get:
java.lang.NullPointerException
at io.swagger.v3.parser.util.OpenAPIDeserializer.getObject(OpenAPIDeserializer.java:730)
at io.swagger.v3.parser.util.OpenAPIDeserializer.getSchema(OpenAPIDeserializer.java:1957)
at io.swagger.v3.parser.ResolverCache.loadRef(ResolverCache.java:147)
at io.swagger.v3.parser.processors.ExternalRefProcessor.processRefToExternalSchema(ExternalRefProcessor.java:48)
at io.swagger.v3.parser.processors.ExternalRefProcessor.processRefSchema(ExternalRefProcessor.java:644)
at io.swagger.v3.parser.processors.ExternalRefProcessor.processRefToExternalSchema(ExternalRefProcessor.java:115)

Resources