[BAEL-7524] API Code
This commit is contained in:
parent
de7b62ea36
commit
c5ced2f936
|
@ -111,6 +111,7 @@
|
||||||
<module>spring-boot-3-url-matching</module>
|
<module>spring-boot-3-url-matching</module>
|
||||||
<module>spring-boot-graalvm-docker</module>
|
<module>spring-boot-graalvm-docker</module>
|
||||||
<module>spring-boot-validations</module>
|
<module>spring-boot-validations</module>
|
||||||
|
<module>spring-boot-openapi</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>spring-boot-openapi</artifactId>
|
||||||
|
<name>spring-boot-openapi</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>OpenAPI Generator module</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung.spring-boot-modules</groupId>
|
||||||
|
<artifactId>spring-boot-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger.core.v3</groupId>
|
||||||
|
<artifactId>swagger-annotations</artifactId>
|
||||||
|
<version>${swagger-annotations.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.openapitools</groupId>
|
||||||
|
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||||
|
<version>${openapi-generator.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>generate</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<skipValidateSpec>true</skipValidateSpec>
|
||||||
|
<inputSpec>${project.basedir}/src/main/resources/api/quotes.yaml</inputSpec>
|
||||||
|
<generatorName>spring</generatorName>
|
||||||
|
<supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
|
||||||
|
<configOptions>
|
||||||
|
<dateLibrary>custom</dateLibrary>
|
||||||
|
<openApiNullable>false</openApiNullable>
|
||||||
|
<delegatePattern>true</delegatePattern>
|
||||||
|
<apiPackage>com.baeldung.tutorials.openapi.quotes.api</apiPackage>
|
||||||
|
<modelPackage>com.baeldung.tutorials.openapi.quotes.api.model</modelPackage>
|
||||||
|
<documentationProvider>source</documentationProvider>
|
||||||
|
</configOptions>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<openapi-generator.version>7.3.0</openapi-generator.version>
|
||||||
|
<swagger-annotations.version>2.2.20</swagger-annotations.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.tutorials.openapi.quotes;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
import com.baeldung.tutorials.openapi.quotes.service.BrokerService;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class QuotesApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(QuotesApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.tutorials.openapi.quotes.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.baeldung.tutorials.openapi.quotes.api.OrdersApiDelegate;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class OrdersApiImpl implements OrdersApiDelegate {
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.tutorials.openapi.quotes.controller;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.baeldung.tutorials.openapi.quotes.api.QuotesApiDelegate;
|
||||||
|
import com.baeldung.tutorials.openapi.quotes.api.model.QuoteResponse;
|
||||||
|
import com.baeldung.tutorials.openapi.quotes.service.BrokerService;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class QuotesApiImpl implements QuotesApiDelegate {
|
||||||
|
private final BrokerService broker;
|
||||||
|
|
||||||
|
public QuotesApiImpl(BrokerService broker) {
|
||||||
|
this.broker = broker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /quotes/{symbol} : Get current quote for a security
|
||||||
|
*
|
||||||
|
* @param symbol Security's symbol (required)
|
||||||
|
* @return OK (status code 200)
|
||||||
|
* @see QuotesApi#getQuote
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<QuoteResponse> getQuote(String symbol) {
|
||||||
|
|
||||||
|
var price = broker.getSecurityPrice(symbol);
|
||||||
|
|
||||||
|
if ( price.isPresent()) {
|
||||||
|
var quote = new QuoteResponse();
|
||||||
|
quote.setSymbol(symbol);
|
||||||
|
quote.setPrice(price.get());
|
||||||
|
return ResponseEntity.ok(quote);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.tutorials.openapi.quotes.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class BrokerService {
|
||||||
|
|
||||||
|
private Map<String,BigDecimal> securities = new HashMap<>();
|
||||||
|
|
||||||
|
public BrokerService() {
|
||||||
|
Random rnd = new Random();
|
||||||
|
securities.put("GOOG", BigDecimal.valueOf(rnd.nextDouble() * 1000.00).setScale(4, RoundingMode.DOWN));
|
||||||
|
securities.put("AA", BigDecimal.valueOf(rnd.nextDouble() * 1000.00).setScale(4, RoundingMode.DOWN));
|
||||||
|
securities.put("BAEL", BigDecimal.valueOf(rnd.nextDouble() * 1000.00).setScale(4, RoundingMode.DOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Optional<BigDecimal> getSecurityPrice(@NonNull String symbol) {
|
||||||
|
return Optional.ofNullable(securities.get(symbol));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
openapi: 3.0.0
|
||||||
|
info:
|
||||||
|
title: Quotes API
|
||||||
|
version: 1.0.0
|
||||||
|
servers:
|
||||||
|
- description: Test server
|
||||||
|
url: http://localhost:8080
|
||||||
|
paths:
|
||||||
|
/quotes/{symbol}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- quotes
|
||||||
|
summary: Get current quote for a security
|
||||||
|
operationId: getQuote
|
||||||
|
security:
|
||||||
|
- ApiKey:
|
||||||
|
- Quotes.Read
|
||||||
|
parameters:
|
||||||
|
- name: symbol
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Security's symbol
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
pattern: '[A-Z0-9]+'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/QuoteResponse'
|
||||||
|
/orders/{symbol}:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- orders
|
||||||
|
operationId: createOrder
|
||||||
|
security:
|
||||||
|
- ApiKey:
|
||||||
|
- Orders.Write
|
||||||
|
summary: Places a new order to buy a security
|
||||||
|
parameters:
|
||||||
|
- name: symbol
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Security's symbol
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
pattern: '[A-Z0-9]'
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
description: Order info
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
$ref: '#'#/components/schemas/OrderRequest'
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: Order accepted
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/OrderResponse'
|
||||||
|
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
ApiKey:
|
||||||
|
type: apiKey
|
||||||
|
in: header
|
||||||
|
name: X-API-KEY
|
||||||
|
|
||||||
|
schemas:
|
||||||
|
OrderType:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- BUY
|
||||||
|
- SELL
|
||||||
|
OrderStatus:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- PENDING
|
||||||
|
- REJECTED
|
||||||
|
- FULFILLED
|
||||||
|
QuoteResponse:
|
||||||
|
description: Quote response
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
symbol:
|
||||||
|
type: string
|
||||||
|
description: security's symbol
|
||||||
|
price:
|
||||||
|
type: number
|
||||||
|
description: Quote value
|
||||||
|
OrderRequest:
|
||||||
|
description: Buy/Sell order details
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
clientRef:
|
||||||
|
type: string
|
||||||
|
orderType:
|
||||||
|
$ref: '#/components/schemas/OrderType'
|
||||||
|
symbol:
|
||||||
|
type: string
|
||||||
|
description: security's symbol
|
||||||
|
quantity:
|
||||||
|
type: number
|
||||||
|
price:
|
||||||
|
type: number
|
||||||
|
OrderResponse:
|
||||||
|
description: Buy/Sell order response
|
||||||
|
properties:
|
||||||
|
clientRef:
|
||||||
|
type: string
|
||||||
|
orderType:
|
||||||
|
$ref: '#/components/schemas/OrderType'
|
||||||
|
symbol:
|
||||||
|
type: string
|
||||||
|
description: security's symbol
|
||||||
|
quantity:
|
||||||
|
type: number
|
||||||
|
price:
|
||||||
|
type: number
|
||||||
|
orderStatus:
|
||||||
|
$ref: '#/components/schemas/OrderStatus'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
root: INFO
|
||||||
|
org.springframework: DEBUG
|
Loading…
Reference in New Issue