diff --git a/README.md b/README.md
index d346941..0262513 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,9 @@ This API provides HTTP endpoint's and tools for the following:
* Create a Transaction: `POST/financial/v1/transactions`
* Update a Transaction: `PUT/financial/v1/transactions`
* Delete a Transaction (by id): `DELETE/financial/v1/transactions/1`
-* Get report of all transactions created: `GET/financial/v1/transactions`
+* Get report of transactions in a period of time (sorted and paginated): `GET/financial/v1/transactions?startDate=2020-01-01&endDate=2020-09-18&order=DESC&page=2`
* Find a unique transaction by id: `GET/financial/v1/transactions/1`
+* Find a unique transaction by id, but filtering JSON fields: `GET/financial/v1/transactions/1?fields=id,nsu,transactionDate,amount`
* Find transactions by NSU (Unique sequential number): `GET/financial/v1/transactions/byNsu/{nsuNumber}`
* Get Statistics about the transactions of the API: `GET/financial/v1/statistics`
@@ -101,9 +102,10 @@ the one that was updated.
}
```
-`GET/financial/v1/transactions`
+`GET/financial/v1/transactions?startDate=2020-01-01&endDate=2020-01-18&order=DESC&page=2`
-This end-point returns all transactions created.
+This end-point returns transactions created within the period specified in the request. E.g: in the above query, we are looking for
+all transactions carried out between 01-18 January 2020. Also, the result should return in descending order and only the page 2.
`DELETE/financial/v1/transaction/{id}`
@@ -158,7 +160,7 @@ All `BigDecimal` values always contain exactly two decimal places, e.g: `15.385`
This project was developed with:
* **Java 11 (Java Development Kit - JDK: 11.0.7)**
-* **Spring Boot 2.3.3**
+* **Spring Boot 2.3.4**
* **Spring Admin Client 2.3.0**
* **Maven**
* **JUnit 5**
@@ -170,6 +172,7 @@ This project was developed with:
* **Heroku**
* **EhCache**
* **Bucket4j 4.10.0**
+* **Partialize 20.05**
### Compile and Package
diff --git a/pom.xml b/pom.xml
index f253c5b..bc6602e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,16 +1,17 @@
-
4.0.0
-
+
io.github.mariazevedo88
financial-java-api
3.1.2-SNAPSHOT
jar
-
+
financial-java-api
A financial API for managing transactions
-
+
Mariana Azevedo
@@ -18,22 +19,30 @@
UTC-03:00
-
+
11
3.0.0
2.3.8
4.10.0
2.3.0
+ release~20.05
org.springframework.boot
spring-boot-starter-parent
- 2.3.3.RELEASE
-
+ 2.3.4.RELEASE
+
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+
org.springframework.boot
@@ -45,8 +54,8 @@
test
- org.springframework.boot
- spring-boot-starter-data-jpa
+ org.springframework.boot
+ spring-boot-starter-data-jpa
org.springframework.boot
@@ -57,26 +66,26 @@
spring-boot-starter-hateoas
- org.springframework.boot
- spring-boot-starter-validation
+ org.springframework.boot
+ spring-boot-starter-validation
- org.springframework.boot
- spring-boot-starter-cache
+ org.springframework.boot
+ spring-boot-starter-cache
- org.springframework.boot
- spring-boot-starter-actuator
+ org.springframework.boot
+ spring-boot-starter-actuator
- io.springfox
- springfox-boot-starter
- ${swagger.version}
+ io.springfox
+ springfox-boot-starter
+ ${swagger.version}
- de.codecentric
- spring-boot-admin-starter-client
- ${spring.admin.version}
+ de.codecentric
+ spring-boot-admin-starter-client
+ ${spring.admin.version}
org.projectlombok
@@ -84,36 +93,41 @@
true
- com.h2database
- h2
- runtime
+ com.h2database
+ h2
+ runtime
+
+
+ org.postgresql
+ postgresql
+ runtime
- org.postgresql
- postgresql
- runtime
+ org.flywaydb
+ flyway-core
- org.flywaydb
- flyway-core
+ org.modelmapper
+ modelmapper
+ ${modelmapper.version}
- org.modelmapper
- modelmapper
- ${modelmapper.version}
+ javax.cache
+ cache-api
- javax.cache
- cache-api
+ org.ehcache
+ ehcache
- org.ehcache
- ehcache
+ com.github.vladimir-bukhtoyarov
+ bucket4j-core
+ ${bucket4j.version}
- com.github.vladimir-bukhtoyarov
- bucket4j-core
- ${bucket4j.version}
+ com.github.thibaultmeyer
+ partialize
+ ${partialize.version}
@@ -123,59 +137,59 @@
org.springframework.boot
spring-boot-maven-plugin
-
-
- build-info
-
-
-
+
+
+ build-info
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+ false
+
+
+
+
+ integration-test
+
+
+
- org.apache.maven.plugins
- maven-failsafe-plugin
-
- false
-
-
-
-
- integration-test
-
-
-
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
-
-
- add-integration-test-sources
- generate-test-sources
-
- add-test-source
-
-
-
-
-
-
-
-
- add-integration-test-resources
- generate-test-resources
-
- add-test-resource
-
-
-
-
- src/it/resources
-
-
-
-
-
-
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ add-integration-test-sources
+ generate-test-sources
+
+ add-test-source
+
+
+
+
+
+
+
+
+ add-integration-test-resources
+ generate-test-resources
+
+ add-test-resource
+
+
+
+
+ src/it/resources
+
+
+
+
+
+
diff --git a/src/it/java/io/github/mariazevedo88/financialjavaapi/it/FinancialJavaApiIntegrationTest.java b/src/it/java/io/github/mariazevedo88/financialjavaapi/it/FinancialJavaApiIntegrationTest.java
index a075e3b..338bcc1 100644
--- a/src/it/java/io/github/mariazevedo88/financialjavaapi/it/FinancialJavaApiIntegrationTest.java
+++ b/src/it/java/io/github/mariazevedo88/financialjavaapi/it/FinancialJavaApiIntegrationTest.java
@@ -50,13 +50,8 @@ public class FinancialJavaApiIntegrationTest {
public void testCreateTransactionNSU123456() throws ParseException {
//id=1
- TransactionDTO dtoNsu123456 = new TransactionDTO();
- dtoNsu123456.setNsu("123456");
- dtoNsu123456.setAuthorizationNumber("014785");
- dtoNsu123456.setTransactionDate(FinancialApiUtil.
- getLocalDateTimeFromString("2020-08-21T18:32:04.150Z"));
- dtoNsu123456.setAmount(new BigDecimal(100d));
- dtoNsu123456.setType(TransactionTypeEnum.CARD);
+ TransactionDTO dtoNsu123456 = new TransactionDTO(null, "123456", "014785", FinancialApiUtil.
+ getLocalDateTimeFromString("2020-08-21T18:32:04.150Z"), new BigDecimal(100d), TransactionTypeEnum.CARD);
final HttpHeaders headers = new HttpHeaders();
headers.set("X-api-key", "FX001-ZBSY6YSLP");
@@ -76,12 +71,8 @@ public void testCreateTransactionNSU123456() throws ParseException {
public void testCreateTransactionNSU258963() throws ParseException {
//id=2
- TransactionDTO dtoNsu258963 = new TransactionDTO();
- dtoNsu258963.setNsu("258963");
- dtoNsu258963.setTransactionDate(FinancialApiUtil.
- getLocalDateTimeFromString("2020-08-21T18:32:04.150Z"));
- dtoNsu258963.setAmount(new BigDecimal(2546.93));
- dtoNsu258963.setType(TransactionTypeEnum.MONEY);
+ TransactionDTO dtoNsu258963 = new TransactionDTO(null, "258963", null, FinancialApiUtil.
+ getLocalDateTimeFromString("2020-08-21T18:32:04.150Z"), new BigDecimal(2546.93), TransactionTypeEnum.MONEY);
final HttpHeaders headers = new HttpHeaders();
headers.set("X-api-key", "FX001-ZBSY6YSLP");
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/FinancialJavaApiApplication.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/FinancialJavaApiApplication.java
index 814afc8..8209e5c 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/FinancialJavaApiApplication.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/FinancialJavaApiApplication.java
@@ -1,19 +1,25 @@
package io.github.mariazevedo88.financialjavaapi;
+import java.time.LocalDateTime;
+
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import lombok.extern.log4j.Log4j2;
+
/**
* Class that starts the application
*
* @author Mariana Azevedo
* @since 03/04/2020
*/
+@Log4j2
@SpringBootApplication
public class FinancialJavaApiApplication {
public static void main(String[] args) {
SpringApplication.run(FinancialJavaApiApplication.class, args);
+ log.info("FinancialJavaAPI started successfully at {}", LocalDateTime.now());
}
}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/controller/v1/statistic/StatisticController.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/controller/v1/statistic/StatisticController.java
index 04ace7d..2a32836 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/controller/v1/statistic/StatisticController.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/controller/v1/statistic/StatisticController.java
@@ -4,7 +4,6 @@
import java.math.RoundingMode;
import java.util.List;
-import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
@@ -41,9 +40,7 @@ public class StatisticController {
private TransactionService transactionService;
@Autowired
- public StatisticController(StatisticService statisticService,
- TransactionService transactionService) {
-
+ public StatisticController(StatisticService statisticService, TransactionService transactionService) {
this.statisticService = statisticService;
this.transactionService = transactionService;
}
@@ -77,10 +74,10 @@ public ResponseEntity> create(@RequestHeader(value=Financ
Response response = new Response<>();
Statistic statistics = createStatistics(transactionService.findAll());
- statistics = statisticService.save(statistics);
+ Statistic statisticsToCreate = statisticService.save(statistics);
- StatisticDTO dto = convertEntityToDTO(statistics);
- createSelfLink(statistics, dto);
+ StatisticDTO dto = statisticsToCreate.convertEntityToDTO();
+ createSelfLink(statisticsToCreate, dto);
response.setData(dto);
MultiValueMap headers = new LinkedMultiValueMap<>();
@@ -118,21 +115,6 @@ private Statistic createStatistics(List transactions) {
return new Statistic(sum, avg, min, max, count);
}
- /**
- * Method to convert an Statistic entity to an Statistic DTO.
- *
- * @author Mariana Azevedo
- * @since 03/04/2020
- *
- * @param statistic
- * @return a StatisticDTO
object
- */
- private StatisticDTO convertEntityToDTO(Statistic statistic) {
-
- ModelMapper modelMapper = new ModelMapper();
- return modelMapper.map(statistic, StatisticDTO.class);
- }
-
/**
* Method that creates a self link to statistic object
*
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/controller/v1/transaction/TransactionController.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/controller/v1/transaction/TransactionController.java
index 3743cdb..f925d79 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/controller/v1/transaction/TransactionController.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/controller/v1/transaction/TransactionController.java
@@ -11,7 +11,6 @@
import javax.validation.Valid;
-import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.format.annotation.DateTimeFormat;
@@ -109,10 +108,12 @@ public ResponseEntity> create(@RequestHeader(value=Fina
throw new NotParsableContentException("Date of the transaction is in the future.");
}
- Transaction transaction = transactionService.save(convertDTOToEntity(dto));
- TransactionDTO dtoSaved = convertEntityToDTO(transaction);
- createSelfLink(transaction, dtoSaved);
-
+ Transaction transaction = dto.convertDTOToEntity();
+ Transaction transactionToCreate = transactionService.save(transaction);
+
+ TransactionDTO dtoSaved = transactionToCreate.convertEntityToDTO();
+ createSelfLink(transactionToCreate, dtoSaved);
+
response.setData(dtoSaved);
MultiValueMap headers = new LinkedMultiValueMap<>();
@@ -174,10 +175,11 @@ public ResponseEntity> update(@RequestHeader(value=Fina
throw new TransactionInvalidUpdateException("You don't have permission to change the transaction id=" + dto.getId());
}
- Transaction transaction = transactionService.save(convertDTOToEntity(dto));
- TransactionDTO itemDTO = convertEntityToDTO(transaction);
+ Transaction transaction = dto.convertDTOToEntity();
+ Transaction transactionToUpdate = transactionService.save(transaction);
- createSelfLink(transaction, itemDTO);
+ TransactionDTO itemDTO = transactionToUpdate.convertEntityToDTO();
+ createSelfLink(transactionToUpdate, itemDTO);
response.setData(itemDTO);
MultiValueMap headers = new LinkedMultiValueMap<>();
@@ -231,10 +233,10 @@ public ResponseEntity>> findAllBetweenDates(@Reque
+ " and endDate=" + endDate);
}
- Page itemsDTO = transactions.map(this::convertEntityToDTO);
+ Page itemsDTO = transactions.map(t -> t.convertEntityToDTO());
itemsDTO.stream().forEach(dto -> {
try {
- createSelfLinkInCollections(apiVersion, apiKey, dto);
+ createSelfLinkInCollections(apiVersion, apiKey, dto, null);
} catch (TransactionNotFoundException e) {
log.error("There are no transactions registered between startDate= {} and endDate= {}", startDate, endDate);
}
@@ -286,11 +288,11 @@ public ResponseEntity>> findByNsu(@RequestHeader(v
}
List transactionsDTO = new ArrayList<>();
- transactions.stream().forEach(t -> transactionsDTO.add(convertEntityToDTO(t)));
+ transactions.stream().forEach(t -> transactionsDTO.add(t.convertEntityToDTO()));
transactionsDTO.stream().forEach(dto -> {
try {
- createSelfLinkInCollections(apiVersion, apiKey, dto);
+ createSelfLinkInCollections(apiVersion, apiKey, dto, null);
} catch (TransactionNotFoundException e) {
log.error("There are no transactions registered with the nsu= {}", transactionNSU);
}
@@ -311,6 +313,7 @@ public ResponseEntity>> findByNsu(@RequestHeader(v
* @param apiVersion - API version at the moment
* @param apiKey - API Key to access the routes
* @param transactionId - the id of the transaction
+ * @param fields - Transaction fields that should be returned in JSON as Partial Response
*
* @return ResponseEntity with a Response
object and the HTTP status
*
@@ -320,7 +323,7 @@ public ResponseEntity>> findByNsu(@RequestHeader(v
* 400 - Bad Request: The request was unacceptable, often due to missing a required parameter.
* 404 - Not Found: The requested resource doesn't exist.
* 409 - Conflict: The request conflicts with another request (perhaps due to using the same idempotent key).
- * 429 - Too Many Requests: Too many requests hit the API too quickly. We recommend an exponential backoff of your requests.
+ * 429 - Too Many Requests: Too many requests hit the API too quickly. We recommend an exponential back-off of your requests.
* 500, 502, 503, 504 - Server Errors: something went wrong on API end (These are rare).
*
* @throws TransactionNotFoundException
@@ -328,13 +331,18 @@ public ResponseEntity>> findByNsu(@RequestHeader(v
@GetMapping(value = "/{id}")
@ApiOperation(value = "Route to find a transaction by your id in the API")
public ResponseEntity> findById(@RequestHeader(value=FinancialApiUtil.HEADER_FINANCIAL_API_VERSION, defaultValue="${api.version}")
- String apiVersion, @RequestHeader(value=FinancialApiUtil.HEADER_API_KEY, defaultValue="${api.key}") String apiKey,
- @PathVariable("id") Long transactionId) throws TransactionNotFoundException {
+ String apiVersion, @RequestHeader(value=FinancialApiUtil.HEADER_API_KEY, defaultValue="${api.key}") String apiKey, @PathVariable("id") Long transactionId,
+ @RequestParam(required = false) String fields) throws TransactionNotFoundException {
Response response = new Response<>();
Transaction transaction = transactionService.findById(transactionId);
- TransactionDTO dto = convertEntityToDTO(transaction);
+ TransactionDTO dto = transaction.convertEntityToDTO();
+
+ if(fields != null) {
+ dto = transactionService.getPartialJsonResponse(fields, dto);
+ }
+
createSelfLink(transaction, dto);
response.setData(dto);
@@ -387,36 +395,6 @@ public ResponseEntity> delete(@RequestHeader(value=FinancialApi
return new ResponseEntity<>(response, headers, HttpStatus.NO_CONTENT);
}
- /**
- * Method to convert an Transaction DTO to a Transaction entity.
- *
- * @author Mariana Azevedo
- * @since 03/04/2020
- *
- * @param dto
- * @return a Transaction
object
- */
- private Transaction convertDTOToEntity(TransactionDTO dto) {
-
- ModelMapper modelMapper = new ModelMapper();
- return modelMapper.map(dto, Transaction.class);
- }
-
- /**
- * Method to convert an Transaction entity to a Transaction DTO.
- *
- * @author Mariana Azevedo
- * @since 03/04/2020
- *
- * @param transaction
- * @return a TransactionDTO
object
- */
- private TransactionDTO convertEntityToDTO(Transaction transaction) {
-
- ModelMapper modelMapper = new ModelMapper();
- return modelMapper.map(transaction, TransactionDTO.class);
- }
-
/**
* Method that creates a self link to transaction object
*
@@ -442,10 +420,10 @@ private void createSelfLink(Transaction transaction, TransactionDTO transactionD
* @param transactionDTO
* @throws TransactionNotFoundException
*/
- private void createSelfLinkInCollections(String apiVersion, String apiKey, final TransactionDTO transactionDTO)
+ private void createSelfLinkInCollections(String apiVersion, String apiKey, final TransactionDTO transactionDTO, String fields)
throws TransactionNotFoundException {
Link selfLink = linkTo(methodOn(TransactionController.class).findById(apiVersion, apiKey,
- transactionDTO.getId())).withSelfRel();
+ transactionDTO.getId(), fields)).withSelfRel();
transactionDTO.add(selfLink);
}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/dto/model/transaction/TransactionDTO.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/dto/model/transaction/TransactionDTO.java
index 0769453..73a29d9 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/dto/model/transaction/TransactionDTO.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/dto/model/transaction/TransactionDTO.java
@@ -6,17 +6,23 @@
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
+import org.modelmapper.ModelMapper;
import org.springframework.hateoas.RepresentationModel;
import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.zero_x_baadf00d.partialize.annotation.Partialize;
import io.github.mariazevedo88.financialjavaapi.model.enumeration.TransactionTypeEnum;
+import io.github.mariazevedo88.financialjavaapi.model.transaction.Transaction;
+import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
/**
@@ -28,6 +34,11 @@
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@NoArgsConstructor
+@AllArgsConstructor
+@Partialize(allowedFields = {"id", "nsu", "authorizationNumber", "transactionDate", "amount", "type"},
+ defaultFields = {"nsu", "transactionDate", "amount"})
public class TransactionDTO extends RepresentationModel {
private Long id;
@@ -49,5 +60,18 @@ public class TransactionDTO extends RepresentationModel {
@NotNull(message="Type cannot be null")
private TransactionTypeEnum type;
+
+ /**
+ * Method to convert an Transaction DTO to a Transaction entity.
+ *
+ * @author Mariana Azevedo
+ * @since 03/04/2020
+ *
+ * @param dto
+ * @return a Transaction
object
+ */
+ public Transaction convertDTOToEntity() {
+ return new ModelMapper().map(this, Transaction.class);
+ }
}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/model/statistic/Statistic.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/model/statistic/Statistic.java
index 0207f21..c3f0e66 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/model/statistic/Statistic.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/model/statistic/Statistic.java
@@ -10,6 +10,9 @@
import javax.persistence.Id;
import javax.persistence.Table;
+import org.modelmapper.ModelMapper;
+
+import io.github.mariazevedo88.financialjavaapi.dto.model.statistic.StatisticDTO;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -59,4 +62,17 @@ public Statistic (BigDecimal sum, BigDecimal avg, BigDecimal max, BigDecimal min
this.min = min;
this.count = count;
}
+
+ /**
+ * Method to convert an Statistic entity to an Statistic DTO.
+ *
+ * @author Mariana Azevedo
+ * @since 03/04/2020
+ *
+ * @param statistic
+ * @return a StatisticDTO
object
+ */
+ public StatisticDTO convertEntityToDTO() {
+ return new ModelMapper().map(this, StatisticDTO.class);
+ }
}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/model/transaction/Transaction.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/model/transaction/Transaction.java
index d564591..cddcec7 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/model/transaction/Transaction.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/model/transaction/Transaction.java
@@ -13,6 +13,9 @@
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
+import org.modelmapper.ModelMapper;
+
+import io.github.mariazevedo88.financialjavaapi.dto.model.transaction.TransactionDTO;
import io.github.mariazevedo88.financialjavaapi.model.enumeration.TransactionTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -60,4 +63,17 @@ public Transaction (TransactionTypeEnum type){
this.type = type;
}
+ /**
+ * Method to convert an Transaction entity to a Transaction DTO.
+ *
+ * @author Mariana Azevedo
+ * @since 03/04/2020
+ *
+ * @param transaction
+ * @return a TransactionDTO
object
+ */
+ public TransactionDTO convertEntityToDTO() {
+ return new ModelMapper().map(this, TransactionDTO.class);
+ }
+
}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/service/transaction/TransactionService.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/service/transaction/TransactionService.java
index 4a7a877..33cc074 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/service/transaction/TransactionService.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/service/transaction/TransactionService.java
@@ -5,6 +5,7 @@
import org.springframework.data.domain.Page;
+import io.github.mariazevedo88.financialjavaapi.dto.model.transaction.TransactionDTO;
import io.github.mariazevedo88.financialjavaapi.exception.TransactionNotFoundException;
import io.github.mariazevedo88.financialjavaapi.model.enumeration.PageOrderEnum;
import io.github.mariazevedo88.financialjavaapi.model.transaction.Transaction;
@@ -86,5 +87,16 @@ public interface TransactionService {
*/
Page findBetweenDates(LocalDateTime startDate, LocalDateTime endDate, int page,
PageOrderEnum order);
-
+
+ /**
+ * Method to build a partial response in requests regarding Transaction.
+ *
+ * @author Mariana Azevedo
+ * @since 17/09/2020
+ *
+ * @param fields
+ * @param dto
+ * @return a TransactionDTO
object
+ */
+ TransactionDTO getPartialJsonResponse(String fields, TransactionDTO dto);
}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/service/transaction/impl/TransactionServiceImpl.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/service/transaction/impl/TransactionServiceImpl.java
index eaa1990..09d720d 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/service/transaction/impl/TransactionServiceImpl.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/service/transaction/impl/TransactionServiceImpl.java
@@ -12,6 +12,11 @@
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ContainerNode;
+import com.zero_x_baadf00d.partialize.Partialize;
+
+import io.github.mariazevedo88.financialjavaapi.dto.model.transaction.TransactionDTO;
import io.github.mariazevedo88.financialjavaapi.exception.TransactionNotFoundException;
import io.github.mariazevedo88.financialjavaapi.model.enumeration.PageOrderEnum;
import io.github.mariazevedo88.financialjavaapi.model.transaction.Transaction;
@@ -27,7 +32,7 @@
@Service
public class TransactionServiceImpl implements TransactionService {
- private TransactionRepository transactionRepository;
+ TransactionRepository transactionRepository;
@Value("${pagination.items_per_page}")
private int itemsPerPage;
@@ -95,4 +100,15 @@ public List findAll() {
return transactionRepository.findAll();
}
+ /**
+ * @see TransactionService#getPartialJsonResponse(String, TransactionDTO)
+ */
+ @Override
+ public TransactionDTO getPartialJsonResponse(String fields, TransactionDTO dto) {
+
+ final Partialize partialize = new Partialize();
+ final ContainerNode> node = partialize.buildPartialObject(fields, TransactionDTO.class, dto);
+ return new ObjectMapper().convertValue(node, TransactionDTO.class);
+ }
+
}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/util/BigDecimalConverter.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/util/BigDecimalConverter.java
new file mode 100644
index 0000000..202d9a5
--- /dev/null
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/util/BigDecimalConverter.java
@@ -0,0 +1,41 @@
+package io.github.mariazevedo88.financialjavaapi.util;
+
+import java.math.BigDecimal;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.zero_x_baadf00d.partialize.converter.Converter;
+
+/**
+ * Class that converts a given data in BigDecimal format to a JSON compatible format
+ *
+ * @author Mariana Azevedo
+ * @since 17/09/2020
+ */
+public class BigDecimalConverter implements Converter {
+
+ /**
+ * @see com.zero_x_baadf00d.partialize.converter.Converter#convert(String, Object, ObjectNode)
+ */
+ @Override
+ public void convert(String fieldName, BigDecimal data, ObjectNode node) {
+ node.put(fieldName, data.doubleValue());
+ }
+
+ /**
+ * @see com.zero_x_baadf00d.partialize.converter.Converter#convert(String, Object, ArrayNode)
+ */
+ @Override
+ public void convert(String fieldName, BigDecimal data, ArrayNode node) {
+ node.add(data.doubleValue());
+ }
+
+ /**
+ * @see com.zero_x_baadf00d.partialize.converter.Converter#getManagedObjectClass()
+ */
+ @Override
+ public Class getManagedObjectClass() {
+ return BigDecimal.class;
+ }
+
+}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/util/LocalDateTimeConverter.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/util/LocalDateTimeConverter.java
new file mode 100644
index 0000000..0136ae2
--- /dev/null
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/util/LocalDateTimeConverter.java
@@ -0,0 +1,46 @@
+package io.github.mariazevedo88.financialjavaapi.util;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.zero_x_baadf00d.partialize.converter.Converter;
+
+/**
+ * Class that converts a given data in LocalDateTime format to a JSON compatible format
+ *
+ * @author Mariana Azevedo
+ * @since 17/09/2020
+ */
+public class LocalDateTimeConverter implements Converter {
+
+ private static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
+
+ /**
+ * @see com.zero_x_baadf00d.partialize.converter.Converter#convert(String, Object, ObjectNode)
+ */
+ @Override
+ public void convert(String fieldName, LocalDateTime data, ObjectNode node) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATETIME_FORMAT);
+ node.put(fieldName, data.format(formatter));
+ }
+
+ /**
+ * @see com.zero_x_baadf00d.partialize.converter.Converter#convert(String, Object, ArrayNode)
+ */
+ @Override
+ public void convert(String fieldName, LocalDateTime data, ArrayNode node) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATETIME_FORMAT);
+ node.add(data.format(formatter));
+ }
+
+ /**
+ * @see com.zero_x_baadf00d.partialize.converter.Converter#getManagedObjectClass()
+ */
+ @Override
+ public Class getManagedObjectClass() {
+ return LocalDateTime.class;
+ }
+
+}
diff --git a/src/main/java/io/github/mariazevedo88/financialjavaapi/util/config/FinancialApiConfiguration.java b/src/main/java/io/github/mariazevedo88/financialjavaapi/util/config/FinancialApiConfiguration.java
index 36d5a2d..b588300 100644
--- a/src/main/java/io/github/mariazevedo88/financialjavaapi/util/config/FinancialApiConfiguration.java
+++ b/src/main/java/io/github/mariazevedo88/financialjavaapi/util/config/FinancialApiConfiguration.java
@@ -10,6 +10,11 @@
import org.springframework.hateoas.mediatype.collectionjson.CollectionJsonLinkDiscoverer;
import org.springframework.plugin.core.SimplePluginRegistry;
+import com.zero_x_baadf00d.partialize.PartializeConverterManager;
+
+import io.github.mariazevedo88.financialjavaapi.util.BigDecimalConverter;
+import io.github.mariazevedo88.financialjavaapi.util.LocalDateTimeConverter;
+
/**
* Class that implements the necessary settings for the API to works.
*
@@ -33,4 +38,16 @@ public LinkDiscoverers discoverers() {
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.of(plugins));
}
+
+ /**
+ * Method that allow the initialization of Partialize converters.
+ *
+ * @author Mariana Azevedo
+ * @since 17/09/2020
+ */
+ @Bean
+ public void initPartialize(){
+ PartializeConverterManager.getInstance().registerConverter(new LocalDateTimeConverter());
+ PartializeConverterManager.getInstance().registerConverter(new BigDecimalConverter());
+ }
}
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index 5dc2157..9514fa2 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -23,7 +23,7 @@ spring.mvc.resources.add-mappings=false
spring.mvc.date-format=yyyy-MM-dd
#configuring API pagination
-pagination.items_per_page=5
+pagination.items_per_page=10
#configuring jwt secret
jwt.secret=oioqowepjsjdasd!$%mknfskdnf090192019
@@ -31,7 +31,7 @@ jwt.expiration=6000
#configuring API version
release.version=3.1.2
-api.version=2020-09-05
+api.version=2020-09-18
api.key="FX001-FREE"
#enable response compression
@@ -58,4 +58,8 @@ spring.boot.admin.client.instance.metadata.user.password={SPRING_ADMIN_PASSWORD}
management.endpoints.web.base-path=/manage
management.endpoints.web.exposure.include=*
-management.endpoint.health.show-details=always
\ No newline at end of file
+management.endpoint.health.show-details=always
+
+#Log path
+logging.file.name=/var/log/apis/financial-java-api/financial-java-api.log
+management.endpoint.logfile.external-file=/var/log/apis/financial-java-api/financial-java-api.log
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 3bc9e79..f37f719 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -24,7 +24,7 @@ spring.mvc.resources.add-mappings=false
#configuring API version
release.version=3.1.2
-api.version=2020-09-05
+api.version=2020-09-18
api.key="FX001-FREE"
#enable response compression
@@ -34,4 +34,8 @@ server.compression.enabled=true
server.compression.min-response-size=2048
#mime types that should be compressed
-server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
\ No newline at end of file
+server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
+
+#Log path
+logging.file.name=/var/log/apis/financial-java-api/financial-java-api.log
+management.endpoint.logfile.external-file=/var/log/apis/financial-java-api/financial-java-api.log
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 90e8fdd..c474317 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -24,7 +24,7 @@ spring.mvc.throw-exception-if-no-handler-found=true
spring.mvc.resources.add-mappings=false
#configuring API pagination
-pagination.items_per_page=5
+pagination.items_per_page=10
#configuring jwt secret
jwt.secret=qweernadnamdn19820918209!#ajhad
@@ -32,7 +32,7 @@ jwt.expiration=3600
#configuring API version
release.version=3.1.2
-api.version=2020-09-05
+api.version=2020-09-18
api.key="FX001-FREE"
#enable response compression
@@ -60,4 +60,8 @@ spring.boot.admin.client.instance.metadata.user.password=${spring.boot.admin.cli
management.endpoints.web.base-path=/manage
management.endpoints.web.exposure.include=*
-management.endpoint.health.show-details=always
\ No newline at end of file
+management.endpoint.health.show-details=always
+
+#Log path
+logging.file.name=/var/log/apis/financial-java-api/financial-java-api.log
+management.endpoint.logfile.external-file=/var/log/apis/financial-java-api/financial-java-api.log
\ No newline at end of file
diff --git a/src/main/resources/log4j2-spring.xml b/src/main/resources/log4j2-spring.xml
new file mode 100644
index 0000000..fc86da2
--- /dev/null
+++ b/src/main/resources/log4j2-spring.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/io/github/mariazevedo88/financialjavaapi/test/controller/statistic/StatisticControllerTest.java b/src/test/java/io/github/mariazevedo88/financialjavaapi/test/controller/statistic/StatisticControllerTest.java
index 63f7f1c..6f5b5dc 100644
--- a/src/test/java/io/github/mariazevedo88/financialjavaapi/test/controller/statistic/StatisticControllerTest.java
+++ b/src/test/java/io/github/mariazevedo88/financialjavaapi/test/controller/statistic/StatisticControllerTest.java
@@ -35,10 +35,10 @@
* @since 05/04/2020
*/
@SpringBootTest
-@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, MockitoTestExecutionListener.class })
@AutoConfigureMockMvc
@ActiveProfiles("test")
@TestInstance(Lifecycle.PER_CLASS)
+@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, MockitoTestExecutionListener.class })
public class StatisticControllerTest {
private static final Long ID = 1L;
diff --git a/src/test/java/io/github/mariazevedo88/financialjavaapi/test/controller/transaction/TransactionControllerTest.java b/src/test/java/io/github/mariazevedo88/financialjavaapi/test/controller/transaction/TransactionControllerTest.java
index 5341a16..0080115 100644
--- a/src/test/java/io/github/mariazevedo88/financialjavaapi/test/controller/transaction/TransactionControllerTest.java
+++ b/src/test/java/io/github/mariazevedo88/financialjavaapi/test/controller/transaction/TransactionControllerTest.java
@@ -44,10 +44,10 @@
* @since 05/04/2020
*/
@SpringBootTest
-@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, MockitoTestExecutionListener.class })
@AutoConfigureMockMvc
@ActiveProfiles("test")
@TestInstance(Lifecycle.PER_CLASS)
+@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, MockitoTestExecutionListener.class })
public class TransactionControllerTest {
private static final Long ID = 1L;
@@ -61,17 +61,16 @@ public class TransactionControllerTest {
private HttpHeaders headers;
@Autowired
- private MockMvc mockMvc;
-
+ MockMvc mockMvc;
+
@MockBean
- private TransactionService service;
+ TransactionService transactionService;
@BeforeAll
private void setUp() {
headers = new HttpHeaders();
headers.set("X-api-key", "FX001-ZBSY6YSLP");
- }
-
+ }
/**
* Method that tests to save an Transaction in the API
*
@@ -83,13 +82,11 @@ private void setUp() {
@Test
public void testSave() throws Exception {
- BDDMockito.given(service.save(Mockito.any(Transaction.class))).willReturn(getMockTransaction());
+ BDDMockito.given(transactionService.save(Mockito.any(Transaction.class))).willReturn(getMockTransaction());
- mockMvc.perform(MockMvcRequestBuilders.post(URL)
- .content(getJsonPayload(ID, NSU, AUTH, FinancialApiUtil.
- getLocalDateTimeFromString(TRANSACTION_DATE.concat("Z")), VALUE, TYPE))
- .contentType(MediaType.APPLICATION_JSON)
- .accept(MediaType.APPLICATION_JSON)
+ mockMvc.perform(MockMvcRequestBuilders.post(URL).content(getJsonPayload(ID, NSU, AUTH,
+ FinancialApiUtil.getLocalDateTimeFromString(TRANSACTION_DATE.concat("Z")), VALUE, TYPE))
+ .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.headers(headers))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isCreated())
@@ -112,13 +109,11 @@ public void testSave() throws Exception {
@Test
public void testSaveInvalidTransaction() throws Exception {
- BDDMockito.given(service.save(Mockito.any(Transaction.class))).willReturn(getMockTransaction());
+ BDDMockito.given(transactionService.save(Mockito.any(Transaction.class))).willReturn(getMockTransaction());
- mockMvc.perform(MockMvcRequestBuilders.post(URL)
- .content(getJsonPayload(ID, null, AUTH, FinancialApiUtil.
+ mockMvc.perform(MockMvcRequestBuilders.post(URL).content(getJsonPayload(ID, null, AUTH, FinancialApiUtil.
getLocalDateTimeFromString(TRANSACTION_DATE.concat("Z")), VALUE, TYPE))
- .contentType(MediaType.APPLICATION_JSON)
- .accept(MediaType.APPLICATION_JSON)
+ .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.headers(headers))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errors.details").value("Nsu cannot be null"));
@@ -135,10 +130,8 @@ public void testSaveInvalidTransaction() throws Exception {
*/
private Transaction getMockTransaction() throws ParseException {
- Transaction transaction = new Transaction(ID, NSU, AUTH,
- FinancialApiUtil.getLocalDateTimeFromString(TRANSACTION_DATE.concat("Z")),
- VALUE, TYPE);
-
+ Transaction transaction = new Transaction(ID, NSU, AUTH, FinancialApiUtil.getLocalDateTimeFromString
+ (TRANSACTION_DATE.concat("Z")), VALUE, TYPE);
return transaction;
}
@@ -161,13 +154,7 @@ private Transaction getMockTransaction() throws ParseException {
private String getJsonPayload(Long id, String nsu, String authorization, LocalDateTime transactionDate,
BigDecimal amount, TransactionTypeEnum type) throws JsonProcessingException {
- TransactionDTO dto = new TransactionDTO();
- dto.setId(id);
- dto.setNsu(nsu);
- dto.setAuthorizationNumber(authorization);
- dto.setTransactionDate(transactionDate);
- dto.setAmount(amount);
- dto.setType(type);
+ TransactionDTO dto = new TransactionDTO(id, nsu, authorization, transactionDate, amount, type);
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
diff --git a/src/test/java/io/github/mariazevedo88/financialjavaapi/test/repository/statistic/StatisticRepositoryTest.java b/src/test/java/io/github/mariazevedo88/financialjavaapi/test/repository/statistic/StatisticRepositoryTest.java
index 545b670..2b8f0ba 100644
--- a/src/test/java/io/github/mariazevedo88/financialjavaapi/test/repository/statistic/StatisticRepositoryTest.java
+++ b/src/test/java/io/github/mariazevedo88/financialjavaapi/test/repository/statistic/StatisticRepositoryTest.java
@@ -42,12 +42,8 @@ public class StatisticRepositoryTest {
@Test
public void testSave() {
- Statistic statistic = new Statistic();
- statistic.setSum(new BigDecimal(200d));
- statistic.setMin(new BigDecimal(100d));
- statistic.setMax(new BigDecimal(100d));
- statistic.setAvg(new BigDecimal(100d));
- statistic.setCount(2);
+ Statistic statistic = new Statistic(null, new BigDecimal(200d), new BigDecimal(100d),
+ new BigDecimal(100d), new BigDecimal(100d), 2);
Statistic response = repository.save(statistic);
diff --git a/src/test/java/io/github/mariazevedo88/financialjavaapi/test/repository/transaction/TransactionRepositoryTest.java b/src/test/java/io/github/mariazevedo88/financialjavaapi/test/repository/transaction/TransactionRepositoryTest.java
index d320547..ebdd234 100644
--- a/src/test/java/io/github/mariazevedo88/financialjavaapi/test/repository/transaction/TransactionRepositoryTest.java
+++ b/src/test/java/io/github/mariazevedo88/financialjavaapi/test/repository/transaction/TransactionRepositoryTest.java
@@ -46,12 +46,8 @@ public class TransactionRepositoryTest {
@BeforeAll
private void setUp() {
- Transaction transaction = new Transaction();
- transaction.setNsu("220788");
- transaction.setAuthorizationNumber("000123");
- transaction.setTransactionDate(LocalDateTime.now());
- transaction.setAmount(new BigDecimal(100d));
- transaction.setType(TransactionTypeEnum.CARD);
+ Transaction transaction = new Transaction(null, "220788", "000123",
+ LocalDateTime.now(), new BigDecimal(100d), TransactionTypeEnum.CARD);
repository.save(transaction);
}
@@ -65,12 +61,8 @@ private void setUp() {
@Test
public void testSave() {
- Transaction transaction = new Transaction();
- transaction.setNsu("270257");
- transaction.setAuthorizationNumber("000123");
- transaction.setTransactionDate(LocalDateTime.now());
- transaction.setAmount(new BigDecimal(100d));
- transaction.setType(TransactionTypeEnum.CARD);
+ Transaction transaction = new Transaction(null, "270257", "000123", LocalDateTime.now(),
+ new BigDecimal(100d), TransactionTypeEnum.CARD);
Transaction response = repository.save(transaction);