Skip to content

Commit

Permalink
Adding Partial Response.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mariana Azevedo committed Sep 17, 2020
1 parent ab393d1 commit 5f3121b
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 77 deletions.
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<modelmapper.version>2.3.8</modelmapper.version>
<bucket4j.version>4.10.0</bucket4j.version>
<spring.admin.version>2.3.0</spring.admin.version>
<partialize.version>release~20.05</partialize.version>
</properties>

<parent>
Expand All @@ -33,6 +34,13 @@
<version>2.3.3.RELEASE</version>
<relativePath/>
</parent>

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<dependencies>
<dependency>
Expand Down Expand Up @@ -115,6 +123,11 @@
<artifactId>bucket4j-core</artifactId>
<version>${bucket4j.version}</version>
</dependency>
<dependency>
<groupId>com.github.thibaultmeyer</groupId>
<artifactId>partialize</artifactId>
<version>${partialize.version}</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ public ResponseEntity<Response<StatisticDTO>> create(@RequestHeader(value=Financ
Response<StatisticDTO> 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 = convertEntityToDTO(statisticsToCreate);
createSelfLink(statisticsToCreate, dto);
response.setData(dto);

MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
Expand Down Expand Up @@ -119,32 +119,32 @@ private Statistic createStatistics(List<Transaction> transactions) {
}

/**
* Method to convert an Statistic entity to an Statistic DTO.
* Method that creates a self link to statistic object
*
* @author Mariana Azevedo
* @since 03/04/2020
*
* @param statistic
* @return a <code>StatisticDTO</code> object
* @param statistics
* @param statisticDTO
*/
private StatisticDTO convertEntityToDTO(Statistic statistic) {

ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(statistic, StatisticDTO.class);
private void createSelfLink(Statistic statistics, StatisticDTO statisticDTO) {
Link selfLink = WebMvcLinkBuilder.linkTo(StatisticController.class).slash(statistics.getId()).withSelfRel();
statisticDTO.add(selfLink);
}

/**
* Method that creates a self link to statistic object
* Method to convert an Statistic entity to an Statistic DTO.
*
* @author Mariana Azevedo
* @since 03/04/2020
*
* @param statistics
* @param statisticDTO
* @param statistic
* @return a <code>StatisticDTO</code> object
*/
private void createSelfLink(Statistic statistics, StatisticDTO statisticDTO) {
Link selfLink = WebMvcLinkBuilder.linkTo(StatisticController.class).slash(statistics.getId()).withSelfRel();
statisticDTO.add(selfLink);
public StatisticDTO convertEntityToDTO(Statistic statistic) {

ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(statistic, StatisticDTO.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,12 @@ public ResponseEntity<Response<TransactionDTO>> 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 = convertDTOToEntity(dto);
Transaction transactionToCreate = transactionService.save(transaction);

TransactionDTO dtoSaved = convertEntityToDTO(transactionToCreate);
createSelfLink(transactionToCreate, dtoSaved);

response.setData(dtoSaved);

MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
Expand Down Expand Up @@ -174,10 +176,11 @@ public ResponseEntity<Response<TransactionDTO>> 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 = convertDTOToEntity(dto);
Transaction transactionToUpdate = transactionService.save(transaction);

createSelfLink(transaction, itemDTO);
TransactionDTO itemDTO = convertEntityToDTO(transactionToUpdate);
createSelfLink(transactionToUpdate, itemDTO);
response.setData(itemDTO);

MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
Expand Down Expand Up @@ -234,7 +237,7 @@ public ResponseEntity<Response<Page<TransactionDTO>>> findAllBetweenDates(@Reque
Page<TransactionDTO> itemsDTO = transactions.map(this::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);
}
Expand Down Expand Up @@ -290,7 +293,7 @@ public ResponseEntity<Response<List<TransactionDTO>>> findByNsu(@RequestHeader(v

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);
}
Expand All @@ -311,6 +314,7 @@ public ResponseEntity<Response<List<TransactionDTO>>> 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 <code>Response<TransactionDTO></code> object and the HTTP status
*
Expand All @@ -320,21 +324,26 @@ public ResponseEntity<Response<List<TransactionDTO>>> 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
*/
@GetMapping(value = "/{id}")
@ApiOperation(value = "Route to find a transaction by your id in the API")
public ResponseEntity<Response<TransactionDTO>> 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<TransactionDTO> response = new Response<>();
Transaction transaction = transactionService.findById(transactionId);

TransactionDTO dto = convertEntityToDTO(transaction);

if(fields != null) {
dto = transactionService.getPartialJsonResponse(fields, dto);
}

createSelfLink(transaction, dto);
response.setData(dto);

Expand Down Expand Up @@ -387,36 +396,6 @@ public ResponseEntity<Response<String>> 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 <code>Transaction</code> 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 <code>TransactionDTO</code> 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
*
Expand All @@ -442,11 +421,41 @@ 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);
}

/**
* Method to convert an Transaction DTO to a Transaction entity.
*
* @author Mariana Azevedo
* @since 03/04/2020
*
* @param dto
* @return a <code>Transaction</code> object
*/
public 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 <code>TransactionDTO</code> object
*/
public TransactionDTO convertEntityToDTO(Transaction transaction) {

ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(transaction, TransactionDTO.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
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 lombok.EqualsAndHashCode;
Expand All @@ -28,6 +30,11 @@
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Partialize(
allowedFields = {"id", "nsu", "authorizationNumber", "transactionDate", "amount", "type"},
defaultFields = {"nsu", "transactionDate", "amount"}
)
public class TransactionDTO extends RepresentationModel<TransactionDTO> {

private Long id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -86,5 +87,16 @@ public interface TransactionService {
*/
Page<Transaction> 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 <code>TransactionDTO</code> object
*/
TransactionDTO getPartialJsonResponse(String fields, TransactionDTO dto);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -95,4 +100,15 @@ public List<Transaction> 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);
}

}
Original file line number Diff line number Diff line change
@@ -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<BigDecimal> {

/**
* @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<BigDecimal> getManagedObjectClass() {
return BigDecimal.class;
}

}
Loading

0 comments on commit 5f3121b

Please sign in to comment.