Skip to content

Commit bae5e3c

Browse files
author
Shelson Ferrari
committed
pre camel
1 parent 0e38c16 commit bae5e3c

6 files changed

Lines changed: 218 additions & 56 deletions

File tree

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,59 @@
1+
/*
2+
* Copyright (c) 2024, Shelson Ferrari
3+
*
4+
* Licensed under the MIT License and the Apache License, Version 2.0 (the "Licenses"); you may not use this file except in
5+
* compliance with the Licenses. You may obtain a copy of the Licenses at
6+
*
7+
* MIT License:
8+
* https://opensource.org/licenses/MIT
9+
*
10+
* Apache License, Version 2.0:
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software distributed under the Licenses is
14+
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
15+
* the Licenses for the specific language governing permissions and limitations under the Licenses.
16+
*/
117
package com.shelson.application.controller;
218

3-
import org.apache.camel.ProducerTemplate;
419
import org.springframework.beans.factory.annotation.Autowired;
520
import org.springframework.web.bind.annotation.GetMapping;
621
import org.springframework.web.bind.annotation.RequestMapping;
722
import org.springframework.web.bind.annotation.RequestParam;
823
import org.springframework.web.bind.annotation.RestController;
924

1025
import com.shelson.application.dto.CurrencyConversionDTO;
26+
import com.shelson.application.service.CurrencyConversionService;
1127
import com.shelson.domain.model.Currency;
28+
import com.shelson.infrastructure.exception.BusinessException;
1229

1330
import io.swagger.annotations.Api;
1431
import io.swagger.annotations.ApiOperation;
1532
import io.swagger.annotations.ApiParam;
1633
import io.swagger.annotations.ApiResponse;
1734
import io.swagger.annotations.ApiResponses;
1835

19-
import java.util.HashMap;
20-
import java.util.Map;
21-
36+
/**
37+
* Controller responsible for currency conversion operations.
38+
* Provides endpoints for converting values between different currencies.
39+
*/
2240
@RestController
2341
@RequestMapping("/api/v1/conversions")
2442
@Api(value = "Currency Conversion Controller", description = "Currency conversion operations")
2543
public class CurrencyConversionController {
2644

2745
@Autowired
28-
private ProducerTemplate producerTemplate;
46+
private CurrencyConversionService currencyConversionService;
2947

48+
/**
49+
* Converts the source currency to the target currency.
50+
*
51+
* @param source The source currency. Example: USD.
52+
* @param target The target currency. Example: BRL.
53+
* @param amount The amount to be converted. Example: 100.0.
54+
* @return A {@link CurrencyConversionDTO} containing the conversion details.
55+
* @throws BusinessException
56+
*/
3057
@GetMapping("/convert")
3158
@ApiOperation(value = "Converts the source currency to the target currency", notes = "Returns the currency conversion details")
3259
@ApiResponses(value = {
@@ -36,12 +63,7 @@ public class CurrencyConversionController {
3663
public CurrencyConversionDTO convertCurrency(
3764
@RequestParam @ApiParam(value = "Source currency", example = "USD") Currency source,
3865
@RequestParam @ApiParam(value = "Target currency", example = "BRL") Currency target,
39-
@RequestParam @ApiParam(value = "Amount to be converted", example = "100.0") double amount) {
40-
41-
Map<String, Object> headers = new HashMap<>();
42-
headers.put("sourceCurrency", source);
43-
headers.put("targetCurrency", target);
44-
45-
return producerTemplate.requestBodyAndHeaders("direct:convertCurrency", amount, headers, CurrencyConversionDTO.class);
66+
@RequestParam @ApiParam(value = "Amount to be converted", example = "100.0") double amount) throws BusinessException {
67+
return currencyConversionService.convertCurrency(source, target, amount);
4668
}
4769
}

src/main/java/com/shelson/application/dto/CurrencyConversionDTO.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
package com.shelson.application.dto;
22

33
import java.time.LocalDateTime;
4-
5-
import com.shelson.domain.model.Currency;
6-
74
import jakarta.validation.constraints.NotNull;
85
import jakarta.validation.constraints.PastOrPresent;
96
import jakarta.validation.constraints.Positive;
107

8+
import com.shelson.domain.model.Currency;
9+
1110
import io.swagger.annotations.ApiModel;
1211
import io.swagger.annotations.ApiModelProperty;
1312

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,63 @@
1+
/*
2+
* Copyright (c) 2024, Shelson Ferrari
3+
*
4+
* Licensed under the MIT License and the Apache License, Version 2.0 (the "Licenses"); you may not use this file except in
5+
* compliance with the Licenses. You may obtain a copy of the Licenses at
6+
*
7+
* MIT License:
8+
* https://opensource.org/licenses/MIT
9+
*
10+
* Apache License, Version 2.0:
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software distributed under the Licenses is
14+
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
15+
* the Licenses for the specific language governing permissions and limitations under the Licenses.
16+
*/
117
package com.shelson.application.service;
218

3-
import org.apache.camel.ProducerTemplate;
4-
import org.springframework.beans.factory.annotation.Autowired;
5-
import org.springframework.stereotype.Service;
6-
719
import java.time.LocalDateTime;
820
import java.util.Map;
921

22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.stereotype.Service;
26+
import org.springframework.web.client.HttpClientErrorException;
27+
import org.springframework.web.client.HttpServerErrorException;
28+
import org.springframework.web.client.RestTemplate;
29+
1030
import com.shelson.application.dto.CurrencyConversionDTO;
1131
import com.shelson.domain.model.Currency;
1232
import com.shelson.domain.model.CurrencyConversion;
1333
import com.shelson.domain.repository.CurrencyConversionRepository;
1434
import com.shelson.infrastructure.exception.BusinessException;
1535
import com.shelson.infrastructure.exception.ResourceNotFoundException;
1636

37+
/**
38+
* Service responsible for currency conversion operations.
39+
*/
1740
@Service
1841
public class CurrencyConversionService {
1942

2043
@Autowired
21-
private ProducerTemplate producerTemplate;
44+
private RestTemplate restTemplate;
2245

2346
@Autowired
2447
private CurrencyConversionRepository repository;
48+
49+
private static final Logger logger = LoggerFactory.getLogger(CurrencyConversionService.class);
2550

51+
/**
52+
* Converts an amount from a source currency to a target currency.
53+
*
54+
* @param sourceCurrency The source currency.
55+
* @param targetCurrency The target currency.
56+
* @param amount The amount to be converted.
57+
* @return A {@link CurrencyConversionDTO} containing the conversion details.
58+
* @throws BusinessException if the source or target currency is null, or if the amount is less than or equal to zero.
59+
* @throws ResourceNotFoundException if an error occurs when fetching exchange rates from the API, or if the target currency is invalid.
60+
*/
2661
public CurrencyConversionDTO convertCurrency(Currency sourceCurrency, Currency targetCurrency, double amount) throws BusinessException {
2762
if (sourceCurrency == null || targetCurrency == null) {
2863
throw new BusinessException("Source and target currencies must not be null");
@@ -32,23 +67,21 @@ public CurrencyConversionDTO convertCurrency(Currency sourceCurrency, Currency t
3267
throw new BusinessException("Amount must be greater than zero");
3368
}
3469

35-
Map<String, Object> headers = Map.of(
36-
"sourceCurrency", sourceCurrency.getCode(),
37-
"targetCurrency", targetCurrency.getCode()
38-
);
70+
logger.info("Starting currency conversion from {} to {}", sourceCurrency, targetCurrency);
3971

40-
Map<String, Double> rates;
72+
String apiUrl = "https://api.exchangerate-api.com/v4/latest/" + sourceCurrency.getCode();
73+
ApiResponse response;
4174
try {
42-
rates = producerTemplate.requestBodyAndHeaders("direct:fetchRate", null, headers, Map.class);
43-
} catch (Exception e) {
44-
throw new ResourceNotFoundException("Unable to fetch exchange rates from API");
75+
response = restTemplate.getForObject(apiUrl, ApiResponse.class);
76+
} catch (HttpClientErrorException | HttpServerErrorException ex) {
77+
throw new ResourceNotFoundException("Error fetching exchange rates from API: " + ex.getMessage());
4578
}
4679

47-
if (rates == null || rates.isEmpty()) {
80+
if (response == null || response.getRates() == null) {
4881
throw new ResourceNotFoundException("Unable to fetch exchange rates from API");
4982
}
5083

51-
Double rate = rates.get(targetCurrency.getCode());
84+
Double rate = response.getRates().get(targetCurrency.getCode());
5285

5386
if (rate == null) {
5487
throw new ResourceNotFoundException("Invalid target currency");
@@ -58,6 +91,33 @@ public CurrencyConversionDTO convertCurrency(Currency sourceCurrency, Currency t
5891
CurrencyConversion conversion = new CurrencyConversion(sourceCurrency, targetCurrency, rate, LocalDateTime.now());
5992
repository.save(conversion);
6093

94+
logger.info("Conversion completed successfully");
95+
6196
return new CurrencyConversionDTO(sourceCurrency, targetCurrency, rate, LocalDateTime.now(), amount, convertedAmount);
6297
}
98+
99+
/**
100+
* Inner class representing the exchange rates API response.
101+
*/
102+
public static class ApiResponse {
103+
private Map<String, Double> rates;
104+
105+
/**
106+
* Gets the exchange rates.
107+
*
108+
* @return A map where the keys are currency codes and the values are exchange rates.
109+
*/
110+
public Map<String, Double> getRates() {
111+
return rates;
112+
}
113+
114+
/**
115+
* Sets the exchange rates.
116+
*
117+
* @param rates A map where the keys are currency codes and the values are exchange rates.
118+
*/
119+
public void setRates(Map<String, Double> rates) {
120+
this.rates = rates;
121+
}
122+
}
63123
}

src/main/java/com/shelson/domain/model/CurrencyConversion.java

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ public class CurrencyConversion {
3030
@GeneratedValue(strategy = GenerationType.IDENTITY)
3131
private Long id;
3232

33+
@Enumerated(EnumType.STRING)
3334
@Column(name = "source_currency")
3435
private Currency sourceCurrency;
3536

37+
@Enumerated(EnumType.STRING)
3638
@Column(name = "target_currency")
3739
private Currency targetCurrency;
3840

@@ -63,50 +65,118 @@ public CurrencyConversion(Currency sourceCurrency, Currency targetCurrency, doub
6365
this.queryDate = queryDate;
6466
}
6567

66-
// Getters and setters
67-
68+
/**
69+
* Gets the conversion ID.
70+
*
71+
* @return The conversion ID.
72+
*/
6873
public Long getId() {
6974
return id;
7075
}
7176

77+
/**
78+
* Sets the conversion ID.
79+
*
80+
* @param id The conversion ID.
81+
*/
7282
public void setId(Long id) {
7383
this.id = id;
7484
}
7585

86+
/**
87+
* Gets the source currency.
88+
*
89+
* @return The source currency.
90+
*/
7691
public Currency getSourceCurrency() {
7792
return sourceCurrency;
7893
}
7994

95+
/**
96+
* Sets the source currency.
97+
*
98+
* @param sourceCurrency The source currency.
99+
*/
80100
public void setSourceCurrency(Currency sourceCurrency) {
81101
this.sourceCurrency = sourceCurrency;
82102
}
83103

104+
/**
105+
* Gets the target currency.
106+
*
107+
* @return The target currency.
108+
*/
84109
public Currency getTargetCurrency() {
85110
return targetCurrency;
86111
}
87112

113+
/**
114+
* Sets the target currency.
115+
*
116+
* @param targetCurrency The target currency.
117+
*/
88118
public void setTargetCurrency(Currency targetCurrency) {
89119
this.targetCurrency = targetCurrency;
90120
}
91121

122+
/**
123+
* Gets the conversion rate.
124+
*
125+
* @return The conversion rate.
126+
*/
92127
public double getConversionRate() {
93128
return conversionRate;
94129
}
95130

131+
/**
132+
* Sets the conversion rate.
133+
*
134+
* @param conversionRate The conversion rate.
135+
*/
96136
public void setConversionRate(double conversionRate) {
97137
this.conversionRate = conversionRate;
98138
}
99139

140+
/**
141+
* Gets the query date and time.
142+
*
143+
* @return The query date and time.
144+
*/
100145
public LocalDateTime getQueryDate() {
101146
return queryDate;
102147
}
103148

149+
/**
150+
* Sets the query date and time.
151+
*
152+
* @param queryDate The query date and time.
153+
*/
104154
public void setQueryDate(LocalDateTime queryDate) {
105155
this.queryDate = queryDate;
106156
}
107157

108-
// Override equals and hashCode methods
158+
/**
159+
* Returns a string representation of the currency conversion.
160+
*
161+
* @return A string representing the currency conversion.
162+
*/
163+
@Override
164+
public String toString() {
165+
return "CurrencyConversion{" +
166+
"id=" + id +
167+
", sourceCurrency=" + sourceCurrency +
168+
", targetCurrency=" + targetCurrency +
169+
", conversionRate=" + conversionRate +
170+
", queryDate=" + queryDate +
171+
'}';
172+
}
109173

174+
/**
175+
* Checks if two instances of CurrencyConversion are equal.
176+
*
177+
* @param o The object to be compared.
178+
* @return {@code true} if the objects are equal; {@code false} otherwise.
179+
*/
110180
@Override
111181
public boolean equals(Object o) {
112182
if (this == o) return true;
@@ -121,6 +191,11 @@ public boolean equals(Object o) {
121191
return queryDate.equals(that.queryDate);
122192
}
123193

194+
/**
195+
* Computes the hash code of the instance.
196+
*
197+
* @return The hash code of the instance.
198+
*/
124199
@Override
125200
public int hashCode() {
126201
int result;
@@ -133,17 +208,4 @@ public int hashCode() {
133208
result = 31 * result + queryDate.hashCode();
134209
return result;
135210
}
136-
137-
// Override toString method
138-
139-
@Override
140-
public String toString() {
141-
return "CurrencyConversion{" +
142-
"id=" + id +
143-
", sourceCurrency=" + sourceCurrency +
144-
", targetCurrency=" + targetCurrency +
145-
", conversionRate=" + conversionRate +
146-
", queryDate=" + queryDate +
147-
'}';
148-
}
149211
}

0 commit comments

Comments
 (0)