Copyright (C) Viorel Contu 2020.
This application source code can only be used for educational purposes.
This application serves as a road map to learning many technologies necessary to build and run a web service. It is build on spring boot. The app provides an example of using the following instruments:
- Java 11
- Spring Boot
- Spring Web; Jackson, MapStruct; RestTemplate; Swagger
- Spring Data; Hibernate; H2; Oracle
- JUnit Jupiter; AssertJ; Mockito; RestAssured
- Lombok
- Logback
The application connects to CoinMarketCap Api to retrieve cryptocurrency price quotes and share this information through a selection of REST endpoints. Please, see how to configure application to access CoinMarketCap here.
Project requires:
- Java 11
- Apache Maven
- Docker (optional)
Docker will allow to run containers for both application and Oracle database.
- Configure maven properties in pom.xml
<properties>
<oracle.cdb>cdb</oracle.cdb>
<oracle.pdb>pdb</oracle.pdb>
<oracle.sys.password>orclpass</oracle.sys.password>
<oracle.host>oracle-rd</oracle.host>
<oracle.roadmap.username>roadmap</oracle.roadmap.username>
<oracle.roadmap.password>roadpass</oracle.roadmap.password>
<oracle.url>jdbc:oracle:thin:@//${oracle.host}:1521/${oracle.pdb}</oracle.url>
<coinmarket.host>https://sandbox-api.coinmarketcap.com</coinmarket.host>
<!-- you must supply this argument during maven builds-->
<coinmarket.token/>
</properties>
These properties will be used for application property files and oracle credentials. You can live the defaults. 2. Obtain a free API key from Coin Market Cap from https://sandbox.coinmarketcap.com/ Write it in
<coinmarket.token>YOUR-API-HERE</coinmarket.token>>
- Build your application and Docker files
While in project root directory:
mvn clean package -P docker
- Start both roadmap and oracle inside container
While in project root directory:
docker-compose up -d
Wait for oracle database to start and load. - Open src/test/http and try any http request inside
The application will migrate the src/main/resources/db/migration sql script files automatically upon starting.
The Flyway is also accessible as a maven plugin. To manually trigger flyway migration: mvn flyway:migrate
mvn clean test
to run unit tests
mvn clean verify
to run integration tests
First of all, go to CoinMarketCap Sandbox create free sandbox account and obtain an API key. The key should be inserted into config file:
- src/main/resources/roadmap.properties
crypto.portal.token=<Insert API Key here>
crypto.portal.host=https://sandbox-api.coinmarketcap.com
crypto.listing.limit=20
The application connects to Coin Market Sandbox. To connect to Coin Market production servers, you need a different production account. Change the property crypto.portal.host
to point to the URL of the production server.
With a valid account on Coin Market either Sandbox or production, and valid API key for that account you can now use the /quotes endpoint and make HTTP REST calls to obtain market values for different crypto-currencies.
To start the application, while inside the code repository, you can use maven:
mvn spring-boot:run
To execute the deployable jar:
java -jar roadmap-2.0.jar
The Spring profiles define how the application actually runs.
- no-security profile: Disables authentication and authorization for most of endpoints.
The application now includes all sort of properties configured for debugging and learning:
- hibernate SQL queries
- transaction management messages
- swagger ui endpoint
You need to create a user in your Oracle DB in order to be able to migrate the data. Connect to sys user and issue the following commands:
CREATE USER ROADMAP IDENTIFIED BY PASSWORD
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE SEQUENCE TO ROADMAP
GRANT UNLIMITED TABLESPACE TO ROADMAP
Consult Oracle reference manual for extra configuration.
- InteliJ IDEA:
- CTRL+SHIFT+A
- Type
edit configurations
- Select in right column Spring Boot -> RoadmapApplication
- Configuration Tab -> Section Spring Boot
- Edit Active Profiles field with prod profile
- Run Roadmap Application from InteliJ IDEA
- From command line:
java -jar roadmap-2.0.jar -Dspring.profiles.active=dev
- From command line with maven:
mvn spring-boot:run -Drun.arguments="--spring.profiles.active=dev"
Application will only serve authenticated and authorized users. The required data is pulled from database.
To make calls you need, to include in request Header your api key. Consult the migration scripts located in
src/main/resources/db/migration
for the user tokens to identify yourself as that specific user.
example: X-API-KEY: 12345678-1234-1234-1234-111111122211
Different api calls require different user roles. Please consult the migration scripts to select a user authorized to make a specific call.
/users
performs different CRUD operations on users/map
maps the ids and symbols for crypto-currencies and normal currencies used by app/quotes
retrieves market quotes for selected crypto-currencies
You can inspect REST endpoints with Swagger UI: http://localhost:8080/api/swagger/
Following api specifications are available (select through combobox upper right):
- open-api - custom specification written manually (more detailed, with examples)
- default - automatically generated by swagger based on class definitions
The custom api file location is defined in application.yml:
swagger.custom-api: /api/roadmap-api.yml
- src/test/resources/http/
contains http template files:
- users.http
- map.http
- quotes.http
You can invoke the HTTP requests in these files directly from InteliJ IDEA.
No other configuration is necessary.
For testing purposes, a different sql file is loaded, located in
- src/test/resources/db/test-data.sql
- Add exception handler for RestTemplate
- Generate custom API schema for Swagger
- Upgrade to a Oracle DB instead of H2 and wire Flyway
- Adjust API endpoints to require authentication tokens active for users
- Implement authorization for different user roles (with Spring AOP)
- Add caching mechanism for CoinMarketCap requests
- Migrate to Java 11
- Containerize application with Docker
- Add audit feature integrated with RabbitMQ
- Add DB Unit for integration tests
- Add Zipkin for log tracing
- Add credits for users which will be used when they consume API
- Add wiremock to enable integration tests for /quotes endpoints
- Complete test coverage
- Add Swagger Validator for endpoints that require message body
- Add a sandbox profile that substitutes CoinMarketCap functionality with WireMock
- Add a connection retry mechanism
- Migrate to Spring Security
- Migrate to PostgreSQL
Also, you need to install the InteliJ plugin for lombok, which will make the IDE understand the annotations and allow you to use getters and setters in code completion
- https://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration
- https://www.baeldung.com/spring-request-response-body
- http://tutorials.jenkov.com/java-json/index.html
- https://www.baeldung.com/jackson-annotations
- https://www.baeldung.com/jackson-ignore-properties-on-serialization
- https://www.baeldung.com/jackson-ignore-null-fields
- https://www.baeldung.com/jackson-map
- https://editor.swagger.io/
- https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api
- https://swagger.io/specification/
- https://idratherbewriting.com/learnapidoc/docapis_introtoapis.html
- http://json-schema.org/understanding-json-schema/index.html
- https://github.com/rest-assured/rest-assured/wiki/Usage
- https://www.testingexcellence.com/parse-json-response-rest-assured/
- https://joel-costigliola.github.io/assertj/assertj-core-quick-start.html
- https://www.vogella.com/tutorials/AssertJ/article.html