Skip to content
Snippets Groups Projects
Commit 572b4cd7 authored by Filip Piták's avatar Filip Piták
Browse files

Implementation of Process filtering and invalidation stale Processes

parent f9c75433
No related branches found
No related tags found
No related merge requests found
Showing with 206 additions and 16 deletions
......@@ -172,8 +172,7 @@ paths:
content:
application/json:
schema:
type: string
format: date
$ref: '#/components/schemas/ThresholdDto'
/processes/v1/resolve:
get:
......@@ -312,7 +311,7 @@ components:
type: string
format: uuid
status:
$ref: '#/components/schemas/StatusDto'
$ref: '#/components/schemas/StatusDetailDto'
ProcessStatusListDto:
type: object
......@@ -323,4 +322,13 @@ components:
processes:
type: array
items:
$ref: '#/components/schemas/ProcessStatusDto'
\ No newline at end of file
$ref: '#/components/schemas/ProcessStatusDto'
ThresholdDto:
type: object
properties:
message:
type: string
currentThreshold:
type: string
format: date
\ No newline at end of file
package cz.muni.pa165.banking.application.controller;
import cz.muni.pa165.banking.application.facade.ProcessFacade;
import cz.muni.pa165.banking.transaction.processor.ProcessApi;
import cz.muni.pa165.banking.transaction.processor.dto.ProcessStatusDto;
import cz.muni.pa165.banking.transaction.processor.dto.ProcessStatusListDto;
import cz.muni.pa165.banking.transaction.processor.dto.StatusDto;
import cz.muni.pa165.banking.transaction.processor.dto.ThresholdDto;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
......@@ -14,28 +16,34 @@ import java.util.UUID;
@RestController
public class ProcessController implements ProcessApi {
private final ProcessFacade processFacade;
public ProcessController(ProcessFacade processFacade) {
this.processFacade = processFacade;
}
@Override
public ResponseEntity<LocalDate> getDefaultThreshold() {
return null;
public ResponseEntity<ThresholdDto> getDefaultThreshold() {
return ResponseEntity.ok(processFacade.getDefaultThreshold());
}
@Override
public ResponseEntity<ProcessStatusDto> getProcessStatus(UUID uuid) {
return null;
return ResponseEntity.ok(processFacade.getProcessStatus(uuid));
}
@Override
public ResponseEntity<ProcessStatusListDto> getProcessesOfState(StatusDto status) {
return null;
return ResponseEntity.ok(processFacade.getProcessesOfState(status));
}
@Override
public ResponseEntity<ProcessStatusListDto> getUnresolvedProcesses(LocalDate date) {
return null;
return ResponseEntity.ok(processFacade.getUnresolvedProcesses(date));
}
@Override
public ResponseEntity<List<UUID>> resolveProcesses(LocalDate date) {
return null;
return ResponseEntity.ok(processFacade.resolveProcesses(date));
}
}
package cz.muni.pa165.banking.application.facade;
import cz.muni.pa165.banking.application.service.ProcessService;
import cz.muni.pa165.banking.domain.process.Process;
import cz.muni.pa165.banking.domain.process.status.Status;
import cz.muni.pa165.banking.transaction.processor.dto.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.UUID;
@Component
public class ProcessFacade {
@Value("${process.resolution.threshold}")
private int thresholdDays;
private final ProcessService service;
public ProcessFacade(ProcessService service) {
this.service = service;
}
public ThresholdDto getDefaultThreshold() {
return new ThresholdDto()
.message("The default threshold is set to be " + thresholdDays + " days ago.")
.currentThreshold(defaultThreshold());
}
public ProcessStatusDto getProcessStatus(UUID uuid) {
Process process = service.findByUuid(uuid);
return map(process);
}
public ProcessStatusListDto getProcessesOfState(StatusDto statusDto) {
OffsetDateTime now = OffsetDateTime.now();
Status status = Status.valueOf(statusDto.name());
List<Process> processes = service.processesWithStatus(status);
return new ProcessStatusListDto()
.when(now)
.processes(
processes.stream()
.map(this::map)
.toList()
);
}
public ProcessStatusListDto getUnresolvedProcesses(LocalDate threshold) {
OffsetDateTime now = OffsetDateTime.now();
if (threshold == null) {
threshold = defaultThreshold();
}
List<Process> processes = service.unresolvedProcessesToDate(threshold);
return new ProcessStatusListDto()
.when(now)
.processes(
processes.stream()
.map(this::map)
.toList()
);
}
public List<UUID> resolveProcesses(LocalDate threshold) {
if (threshold == null) {
threshold = defaultThreshold();
}
return service.resolveProcesses(threshold);
}
private LocalDate defaultThreshold() {
return LocalDate.now().minusDays(thresholdDays);
}
private ProcessStatusDto map(Process process) {
return new ProcessStatusDto()
.identifier(process.getUuid())
.status(new StatusDetailDto()
.created(process.getWhen().atOffset(ZoneOffset.UTC))
.status(StatusDto.valueOf(process.getStatus().name()))
.information(process.getInformation()));
}
}
package cz.muni.pa165.banking.application.repository;
import cz.muni.pa165.banking.domain.process.Process;
import cz.muni.pa165.banking.domain.process.ProcessOperations;
import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
import cz.muni.pa165.banking.domain.process.status.Status;
import cz.muni.pa165.banking.exception.EntityNotFoundException;
import org.springframework.stereotype.Repository;
import java.time.*;
import java.util.*;
@Repository
......@@ -38,12 +40,14 @@ public class ProcessRepositoryImpl implements ProcessRepository {
@Override
public List<Process> findProcessOfStatus(Status status) {
return null;
return repository.findAllWithStatus(status);
}
@Override
public Integer invalidateStaleProcesses() {
return null;
public List<Process> findProcessesOfStatusUptoDate(Status status, LocalDate localDate) {
LocalDateTime endOfDay = localDate.atTime(LocalTime.MAX);
Instant instant = endOfDay.toInstant(ZoneOffset.UTC);
return repository.findByStatusAndDateBeforeEqual(status, instant);
}
}
package cz.muni.pa165.banking.application.repository;
import cz.muni.pa165.banking.domain.process.Process;
import cz.muni.pa165.banking.domain.process.status.Status;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.time.Instant;
import java.util.List;
public interface ProcessRepositoryJpa extends JpaRepository<Process, String> {
// TODO find podla statusu
@Query("SELECT p FROM Process p WHERE p.currentStatus.status = :status")
List<Process> findAllWithStatus(@Param("status") Status status);
@Query("SELECT p FROM Process p WHERE p.currentStatus.status = :status AND p.currentStatus.when <= :date")
List<Process> findByStatusAndDateBeforeEqual(@Param("status") Status status, @Param("date") Instant date);
// TODO update zaseknute procesy starsie nez e.g. tyzden a zmenit na failed + nastavit message nejaky
}
package cz.muni.pa165.banking.application.service;
import cz.muni.pa165.banking.domain.process.Process;
import cz.muni.pa165.banking.domain.process.ProcessOperations;
import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
import cz.muni.pa165.banking.domain.process.status.Status;
import cz.muni.pa165.banking.domain.process.status.StatusInformation;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Service
public class ProcessService {
private final ProcessRepository processRepository;
public ProcessService(ProcessRepository processRepository) {
this.processRepository = processRepository;
}
public Process findByUuid(UUID uuid) {
return processRepository.findById(uuid);
}
@Transactional(readOnly = true)
public List<Process> processesWithStatus(Status status) {
return processRepository.findProcessOfStatus(status);
}
@Transactional(readOnly = true)
public List<Process> unresolvedProcessesToDate(LocalDate threshold) {
List<Process> result = new ArrayList<>();
result.addAll(processRepository.findProcessesOfStatusUptoDate(Status.CREATED, threshold));
result.addAll(processRepository.findProcessesOfStatusUptoDate(Status.PENDING, threshold));
return result;
}
@Transactional
public List<UUID> resolveProcesses(LocalDate localDate) {
List<Process> staleProcesses = new ArrayList<>();
staleProcesses.addAll(processRepository.findProcessesOfStatusUptoDate(Status.CREATED, localDate));
staleProcesses.addAll(processRepository.findProcessesOfStatusUptoDate(Status.PENDING, localDate));
StatusInformation resolvedInfo = new StatusInformation(Instant.now(), Status.FAILED, "Resolved stale process as FAILED by system");
List<UUID> resolved = new ArrayList<>();
for (Process process : staleProcesses) {
try {
ProcessOperations.changeState(process, resolvedInfo);
processRepository.save(process);
resolved.add(process.getUuid());
} catch (Exception ignored){}
}
return resolved;
}
}
......@@ -3,6 +3,8 @@ package cz.muni.pa165.banking.domain.process.repository;
import cz.muni.pa165.banking.domain.process.Process;
import cz.muni.pa165.banking.domain.process.status.Status;
import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import java.util.UUID;
......@@ -16,5 +18,6 @@ public interface ProcessRepository {
List<Process> findProcessOfStatus(Status status);
Integer invalidateStaleProcesses();
List<Process> findProcessesOfStatusUptoDate(Status status, LocalDate localDate);
}
......@@ -3,7 +3,10 @@ db:
scheduled-payments:
cron:
expression: "00 7 * * *"
process:
resolution:
threshold: 7
banking:
apps:
management:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment