Skip to content

Commit 587cc96

Browse files
committed
Task 27 : Define README.md
1 parent 38a0420 commit 587cc96

File tree

1 file changed

+355
-0
lines changed

1 file changed

+355
-0
lines changed

README.md

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
# Case Study - Crypto Exchange Api
2+
3+
<p align="center">
4+
<img src="screenshots/main-image.png" alt="Main Information" width="800" height="550">
5+
</p>
6+
7+
### 📖 Information
8+
9+
<h3>Project Definition (CryptoExchange API)</h3>
10+
<p>
11+
A Spring Boot service that converts an amount from one cryptocurrency to another using CoinMarketCap (CMC),
12+
persists each conversion as a history record, and exposes pageable search &amp; discovery endpoints.
13+
All responses are wrapped in <code>CustomResponse&lt;T&gt;</code>; paged payloads use
14+
<code>CustomPagingResponse&lt;T&gt;</code>.
15+
</p>
16+
17+
<h4>End-to-end flow (convert API):</h4>
18+
<ul>
19+
<li>
20+
Client sends <code>POST /api/convert</code> with <code>ConvertRequest</code>:
21+
<code>{ from, to, amount }</code> (e.g., <code>BTC</code> → <code>ARB</code>, <code>amount=100</code>).
22+
</li>
23+
<li>
24+
Service fetches the conversion rate from CMC, computes <code>convertedAmount</code>, and persists a record:
25+
<ul>
26+
<li><code>transactionId</code> (UUID)</li>
27+
<li><code>createdAt</code> (ISO-8601)</li>
28+
<li><code>from</code>, <code>to</code>, <code>amount</code>, <code>convertedAmount</code></li>
29+
</ul>
30+
</li>
31+
<li>
32+
Returns <code>201 Created</code> with <code>CustomResponse&lt;CryptoConvert&gt;</code> containing the saved record.
33+
</li>
34+
</ul>
35+
36+
<h4>History search:</h4>
37+
<p>
38+
<code>POST /api/convert/history</code> accepts <code>FilterServicePagingRequest</code> and returns
39+
<code>CustomPagingResponse&lt;CryptoConvertResponse&gt;</code>. Filtering supports:
40+
</p>
41+
<ul>
42+
<li><code>from</code>, <code>to</code> (symbols)</li>
43+
<li>amount range: <code>minAmount</code> .. <code>maxAmount</code></li>
44+
<li>convertedAmount range: <code>minConvertedAmount</code> .. <code>maxConvertedAmount</code></li>
45+
<li>createdAt range: <code>createdAtFrom</code> .. <code>createdAtTo</code></li>
46+
<li><code>transactionIdContains</code> (substring)</li>
47+
</ul>
48+
<p>
49+
Pagination &amp; sorting are provided in the request (e.g., <code>pageNumber</code>, <code>pageSize</code>,
50+
<code>sortBy</code>, <code>sortDirection</code>).
51+
</p>
52+
53+
<h4>Crypto map (name + symbol):</h4>
54+
<ul>
55+
<li>
56+
<code>GET /api/convert/map</code> returns a paged list of cryptocurrencies (name &amp; symbol) via CMC
57+
<code>/v1/cryptocurrency/map</code>.
58+
</li>
59+
<li>
60+
Query params:
61+
<ul>
62+
<li><code>page</code> (1-based, default <code>1</code>, min <code>1</code>)</li>
63+
<li><code>size</code> (default <code>20</code>, range <code>1..5000</code>)</li>
64+
</ul>
65+
</li>
66+
<li>
67+
Response: <code>CustomPagingResponse&lt;CryptoNameSymbolResponse&gt;</code> with standard paging metadata.
68+
</li>
69+
</ul>
70+
71+
<h4>Error semantics:</h4>
72+
<ul>
73+
<li><code>201 Created</code> — Successful conversion persisted (<code>/api/convert</code>)</li>
74+
<li><code>200 OK</code> — Successful paged responses (<code>/history</code>, <code>/map</code>)</li>
75+
<li><code>400 Bad Request</code> — Validation errors (invalid symbols, amounts, or paging inputs)</li>
76+
<li><code>502 Bad Gateway</code> — Upstream CMC call failed or unavailable (convert/map)</li>
77+
</ul>
78+
79+
<h4>Caching &amp; invalidation:</h4>
80+
<p>
81+
CMC results are cached to reduce latency and request volume. Cache eviction runs on a fixed schedule configured via
82+
<code>cmc.cache-ttl</code> and a lifecycle hook (<code>@PostConstruct</code>) to ensure fresh state on startup.
83+
</p>
84+
85+
<h4>OpenAPI (Swagger):</h4>
86+
<p>
87+
The controller is annotated with detailed <code>@Operation</code> and <code>@ApiResponse</code> metadata. Explore at:
88+
<code>http://localhost:1927/swagger-ui/index.html</code> (port configurable).
89+
</p>
90+
91+
92+
### Explore Rest APIs
93+
94+
### Explore Rest APIs
95+
96+
Endpoints Summary
97+
<table style="width:100%; border-collapse: collapse;">
98+
<thead>
99+
<tr style="background-color:#f2f2f2;">
100+
<th style="border:1px solid #ddd; padding:8px; text-align:left;">Method</th>
101+
<th style="border:1px solid #ddd; padding:8px; text-align:left;">URL</th>
102+
<th style="border:1px solid #ddd; padding:8px; text-align:left;">Description</th>
103+
<th style="border:1px solid #ddd; padding:8px; text-align:left;">Request Body</th>
104+
<th style="border:1px solid #ddd; padding:8px; text-align:left;">Headers/Path</th>
105+
<th style="border:1px solid #ddd; padding:8px; text-align:left;">Response</th>
106+
<th style="border:1px solid #ddd; padding:8px; text-align:left;">Status Codes</th>
107+
</tr>
108+
</thead>
109+
<tbody>
110+
<tr>
111+
<td style="border:1px solid #ddd; padding:8px;">POST</td>
112+
<td style="border:1px solid #ddd; padding:8px;"><code>/api/convert</code></td>
113+
<td style="border:1px solid #ddd; padding:8px;">Convert an amount from one crypto to another and persist the result</td>
114+
<td style="border:1px solid #ddd; padding:8px;"><code>ConvertRequest</code></td>
115+
<td style="border:1px solid #ddd; padding:8px;">—</td>
116+
<td style="border:1px solid #ddd; padding:8px;">CustomResponse&lt;CryptoConvert&gt;</td>
117+
<td style="border:1px solid #ddd; padding:8px;">201, 400, 502</td>
118+
</tr>
119+
<tr>
120+
<td style="border:1px solid #ddd; padding:8px;">POST</td>
121+
<td style="border:1px solid #ddd; padding:8px;"><code>/api/convert/history</code></td>
122+
<td style="border:1px solid #ddd; padding:8px;">Paged search of conversion history with filters, pagination and sorting</td>
123+
<td style="border:1px solid #ddd; padding:8px;"><code>FilterServicePagingRequest</code></td>
124+
<td style="border:1px solid #ddd; padding:8px;">—</td>
125+
<td style="border:1px solid #ddd; padding:8px;">CustomResponse&lt;CustomPagingResponse&lt;CryptoConvertResponse&gt;&gt;</td>
126+
<td style="border:1px solid #ddd; padding:8px;">200, 400</td>
127+
</tr>
128+
<tr>
129+
<td style="border:1px solid #ddd; padding:8px;">GET</td>
130+
<td style="border:1px solid #ddd; padding:8px;"><code>/api/convert/map</code></td>
131+
<td style="border:1px solid #ddd; padding:8px;">List cryptocurrencies (name + symbol) with pagination</td>
132+
<td style="border:1px solid #ddd; padding:8px;">—</td>
133+
<td style="border:1px solid #ddd; padding:8px;">Query: <code>page</code> (default 1), <code>size</code> (default 20, max 5000)</td>
134+
<td style="border:1px solid #ddd; padding:8px;">CustomResponse&lt;CustomPagingResponse&lt;CryptoNameSymbolResponse&gt;&gt;</td>
135+
<td style="border:1px solid #ddd; padding:8px;">200, 502</td>
136+
</tr>
137+
</tbody>
138+
</table>
139+
140+
### Technologies
141+
142+
---
143+
- Java 25
144+
- Spring Boot 3.0
145+
- Restful API
146+
- Open Api (Swagger)
147+
- Maven
148+
- Junit5
149+
- Mockito
150+
- Integration Tests
151+
- Docker
152+
- Docker Compose
153+
- CI/CD (Github Actions)
154+
- Postman
155+
- Prometheus
156+
- Grafana
157+
- Kubernetes
158+
- JaCoCo (Test Report)
159+
- AOP
160+
- Jenkins
161+
162+
### Postman
163+
164+
```
165+
Import postman collection under postman_collection folder
166+
```
167+
168+
169+
### Prerequisites
170+
171+
#### Define Variable in .env file
172+
173+
```
174+
MONGO_DB_HOST=localhost
175+
MONGO_DB_PORT=27017
176+
MONGO_DB_NAME=cryptoexchangedatabase
177+
COIN_MARKET_CAP_API_KEY={YOUR_COIN_MARKET_CAP_API_KEY}
178+
```
179+
180+
### Open Api (Swagger)
181+
182+
```
183+
http://localhost:1927/swagger-ui/index.html
184+
```
185+
186+
---
187+
188+
### JaCoCo (Test Report)
189+
190+
After the command named `mvn clean install` completes, the JaCoCo report will be available at:
191+
```
192+
target/site/jacoco/index.html
193+
```
194+
Navigate to the `target/site/jacoco/` directory.
195+
196+
Open the `index.html` file in your browser to view the detailed coverage report.
197+
198+
---
199+
200+
### Maven, Docker and Kubernetes Running Process
201+
202+
203+
### Maven Run
204+
To build and run the application with `Maven`, please follow the directions shown below;
205+
206+
```sh
207+
$ cd git clone https://github.com/Rapter1990/cryptoexchangeapi.git
208+
$ cd cryptoexchangeapi
209+
$ mvn clean install
210+
$ mvn spring-boot:run
211+
```
212+
213+
---
214+
215+
### Docker Run
216+
The application can be built and run by the `Docker` engine. The `Dockerfile` has multistage build, so you do not need to build and run separately.
217+
218+
Please follow directions shown below in order to build and run the application with Docker Compose file;
219+
220+
```sh
221+
$ cd cryptoexchangeapi
222+
$ docker-compose up -d
223+
```
224+
225+
If you change anything in the project and run it on Docker, you can also use this command shown below
226+
227+
```sh
228+
$ cd cryptoexchangeapi
229+
$ docker-compose up --build
230+
```
231+
232+
To monitor the application, you can use the following tools:
233+
234+
- **Prometheus**:
235+
Open in your browser at [http://localhost:9090](http://localhost:9090)
236+
Prometheus collects and stores application metrics.
237+
238+
- **Grafana**:
239+
Open in your browser at [http://localhost:3000](http://localhost:3000)
240+
Grafana provides a dashboard for visualizing the metrics.
241+
**Default credentials**:
242+
- Username: `admin`
243+
- Password: `admin`
244+
245+
Define prometheus data source url, use this link shown below
246+
247+
```
248+
http://prometheus:9090
249+
```
250+
251+
---
252+
253+
### Kubernetes Run
254+
To run the application, please follow the directions shown below;
255+
256+
- Start Minikube
257+
258+
```sh
259+
$ minikube start
260+
```
261+
262+
- Open Minikube Dashboard
263+
264+
```sh
265+
$ minikube dashboard
266+
```
267+
268+
- Revise `CMC_API_KEY` in `cryptoexchangeapi-secrets.yml` according to your usage
269+
270+
271+
- To deploy the application on Kubernetes, apply the Kubernetes configuration file underneath k8s folder
272+
273+
```sh
274+
$ kubectl apply -f k8s
275+
```
276+
277+
- To open Prometheus, click tunnel url link provided by the command shown below to reach out Prometheus
278+
279+
```sh
280+
minikube service prometheus-service
281+
```
282+
283+
- To open Grafana, click tunnel url link provided by the command shown below to reach out Prometheus
284+
285+
```sh
286+
minikube service grafana-service
287+
```
288+
289+
- Define prometheus data source url, use this link shown below
290+
291+
```
292+
http://prometheus-service.default.svc.cluster.local:9090
293+
```
294+
295+
---
296+
### Docker Image Location
297+
298+
```
299+
https://hub.docker.com/repository/docker/noyandocker/githubscreenshotmailer/general
300+
```
301+
302+
### Jenkins
303+
304+
- Go to `jenkins` folder
305+
- Run `docker-compose up -d`
306+
- Open Jenkins in the browser via `localhost:8080`
307+
- Define `credentials` for `Github General token` used by `GIT_REPO_ID` and `docker-hub-credentials` for `Docker` `Username` and `Password`
308+
- Go to pipeline named `cryptoexchangeapi`
309+
- Run Pipeline
310+
- Show `Pipeline Step` to verify if it succeeded or failed
311+
312+
### 📸 Screenshots
313+
314+
<details>
315+
<summary>Click here to show the screenshots of project</summary>
316+
<p> Figure 1 </p>
317+
<img src ="screenshots/1.PNG">
318+
<p> Figure 2 </p>
319+
<img src ="screenshots/2.PNG">
320+
<p> Figure 3 </p>
321+
<img src ="screenshots/3.PNG">
322+
<p> Figure 4 </p>
323+
<img src ="screenshots/4.PNG">
324+
<p> Figure 5 </p>
325+
<img src ="screenshots/5.PNG">
326+
<p> Figure 6 </p>
327+
<img src ="screenshots/6.PNG">
328+
<p> Figure 7 </p>
329+
<img src ="screenshots/7.PNG">
330+
<p> Figure 8 </p>
331+
<img src ="screenshots/8.PNG">
332+
<p> Figure 9 </p>
333+
<img src ="screenshots/9.PNG">
334+
<p> Figure 10 </p>
335+
<img src ="screenshots/10.PNG">
336+
<p> Figure 11 </p>
337+
<img src ="screenshots/11.PNG">
338+
<p> Figure 12 </p>
339+
<img src ="screenshots/12.PNG">
340+
<p> Figure 13 </p>
341+
<img src ="screenshots/13.PNG">
342+
<p> Figure 14 </p>
343+
<img src ="screenshots/14.PNG">
344+
<p> Figure 15 </p>
345+
<img src ="screenshots/15.PNG">
346+
<p> Figure 16 </p>
347+
<img src ="screenshots/16.PNG">
348+
<p> Figure 17 </p>
349+
<img src ="screenshots/17.PNG">
350+
</details>
351+
352+
353+
### Contributors
354+
355+
- [Sercan Noyan Germiyanoğlu](https://github.com/Rapter1990)

0 commit comments

Comments
 (0)