Skip to content

Commit

Permalink
Merge pull request #240 from Health-Education-England/feat-endpoint-f…
Browse files Browse the repository at this point in the history
…or-exceptions

Feat endpoint for exceptions
  • Loading branch information
CaiWillis authored Oct 19, 2023
2 parents a82f484 + b132d97 commit dddee61
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import uk.nhs.hee.tis.revalidation.connection.service.DisconnectedElasticSearchService;
import uk.nhs.hee.tis.revalidation.connection.service.DiscrepanciesElasticSearchService;
import uk.nhs.hee.tis.revalidation.connection.service.ElasticsearchQueryHelper;
import uk.nhs.hee.tis.revalidation.connection.service.ExceptionService;

@Slf4j
@RestController
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package uk.nhs.hee.tis.revalidation.connection.controller;

import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import uk.nhs.hee.tis.revalidation.connection.dto.ExceptionLogDto;
import uk.nhs.hee.tis.revalidation.connection.service.ExceptionService;

@Slf4j
@RestController
@RequestMapping("/api/exceptionLog")
public class ExceptionLogController {
private ExceptionService exceptionService;

public ExceptionLogController(ExceptionService exceptionService) {
this.exceptionService = exceptionService;
}

private static final String ADMIN = "admin";

/**
* GET /exceptions/today : get list of exceptions from today for an admin.
*
* @return the list of ExceptionLogDto
*/
@GetMapping("/today")
public ResponseEntity<List<ExceptionLogDto>> getListOfConnectionExceptionsFromToday(
@RequestParam(name = ADMIN) final String admin) {

log.info("Received request to fetch exceptions for admin: {}", admin);
final var exceptions = exceptionService.getConnectionExceptionLogsFromToday(admin);
return ResponseEntity.ok().body(exceptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,21 @@

package uk.nhs.hee.tis.revalidation.connection.dto;

import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@Builder
public class ExceptionRecordDto {
@AllArgsConstructor
@NoArgsConstructor
public class ExceptionLogDto {

private String gmcId;
private String exceptionMessage;
private String errorMessage;
private LocalDateTime timestamp;
private String admin;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ public class ExceptionResponseDto {
private long countTotal;
private long totalPages;
private long totalResults;
private List<ExceptionRecordDto> exceptionRecord;
private List<ExceptionLogDto> exceptionRecord;
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
@Builder
@Document(collection = "exceptionLogs")
public class ExceptionLog {

@Id
private String id;
private String gmcId;
private String errorMessage;
private LocalDateTime timestamp;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package uk.nhs.hee.tis.revalidation.connection.mapper;

import java.util.List;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import uk.nhs.hee.tis.revalidation.connection.dto.ExceptionLogDto;
import uk.nhs.hee.tis.revalidation.connection.entity.ExceptionLog;

@Mapper(componentModel = "spring")
public interface ExceptionLogMapper {

@Mapping(target = "id", ignore = true)
List<ExceptionLogDto> exceptionLogsToExceptionLogDtos(List<ExceptionLog> exceptionLog);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@

package uk.nhs.hee.tis.revalidation.connection.repository;

import java.time.LocalDateTime;
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import uk.nhs.hee.tis.revalidation.connection.entity.ExceptionLog;

@Repository
public interface ExceptionRepository extends MongoRepository<ExceptionLog, String> {

List<ExceptionLog> findByAdminAndTimestampBetween(final String admin, final LocalDateTime start,
final LocalDateTime end);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import static uk.nhs.hee.tis.revalidation.connection.entity.GmcResponseCode.fromCode;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,17 @@
package uk.nhs.hee.tis.revalidation.connection.service;

import static java.time.LocalDateTime.now;
import static java.util.stream.Collectors.toList;
import static org.springframework.data.domain.PageRequest.of;
import static org.springframework.data.domain.Sort.Direction.ASC;
import static org.springframework.data.domain.Sort.Direction.DESC;
import static org.springframework.data.domain.Sort.by;

import java.util.HashMap;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import uk.nhs.hee.tis.revalidation.connection.dto.ExceptionRecordDto;
import uk.nhs.hee.tis.revalidation.connection.dto.ExceptionRequestDto;
import uk.nhs.hee.tis.revalidation.connection.dto.ExceptionResponseDto;
import uk.nhs.hee.tis.revalidation.connection.dto.ExceptionLogDto;
import uk.nhs.hee.tis.revalidation.connection.entity.ExceptionLog;
import uk.nhs.hee.tis.revalidation.connection.mapper.ExceptionLogMapper;
import uk.nhs.hee.tis.revalidation.connection.repository.ExceptionRepository;

@Slf4j
Expand All @@ -49,14 +43,19 @@ public class ExceptionService {
@Autowired
private ExceptionRepository repository;

@Autowired
private ExceptionLogMapper exceptionLogMapper;

/**
* Create exception log.
*
* @param gmcId gmcId of trainees where there are some issue when updating connection
* @param exceptionMessage response code that response from gmc
* @param errorMessage response code that response from gmc
* @param admin the admin that generated the exception log
*/
public void createExceptionLog(final String gmcId, final String exceptionMessage, String admin) {
final var exceptionLog = ExceptionLog.builder().gmcId(gmcId).errorMessage(exceptionMessage)
public void createExceptionLog(final String gmcId, final String errorMessage, String admin) {

final var exceptionLog = ExceptionLog.builder().gmcId(gmcId).errorMessage(errorMessage)
.timestamp(now()).admin(admin).build();

repository.save(exceptionLog);
Expand All @@ -72,42 +71,16 @@ public void removeExceptionLog(final String gmcId) {
}

/**
* Get exception log.
* Get today's exception logs for a specific admin.
*
* @param requestDto request for getting exception log
* @param admin the admin that generated the exception log
*/
public ExceptionResponseDto getExceptionLog(final ExceptionRequestDto requestDto) {
final var direction = "asc".equalsIgnoreCase(requestDto.getSortOrder()) ? ASC : DESC;
final var pageableAndSortable = of(requestDto.getPageNumber(), 20,
by(direction, requestDto.getSortColumn()));

final var exceptionLogPage = repository.findAll(pageableAndSortable);
final var exceptionLogs = exceptionLogPage.get().collect(toList());
return ExceptionResponseDto.builder()
.totalPages(exceptionLogPage.getTotalPages())
.totalResults(exceptionLogPage.getTotalElements())
.exceptionRecord(buildExceptionRecords(exceptionLogs))
.build();
}
public List<ExceptionLogDto> getConnectionExceptionLogsFromToday(String admin) {
LocalDateTime today = LocalDate.now().atStartOfDay();
LocalDateTime tomorrow = today.plusDays(1);

/**
* Get exception log hashmap.
*/
public Map<String, String> getExceptionsMap() {
Map<String,String> exceptionsMap = new HashMap<>();
List<ExceptionLog> exceptionLogList = repository.findAll();
for (ExceptionLog exceptionLog: exceptionLogList) {
exceptionsMap.put(exceptionLog.getGmcId(), exceptionLog.getErrorMessage());
}
return exceptionsMap;
final var todaysExceptions = repository.findByAdminAndTimestampBetween(admin, today, tomorrow);
return exceptionLogMapper.exceptionLogsToExceptionLogDtos(todaysExceptions);
}

private List<ExceptionRecordDto> buildExceptionRecords(final List<ExceptionLog> exceptionLogs) {
return exceptionLogs.stream().map(exception -> {
return ExceptionRecordDto.builder()
.gmcId(exception.getGmcId())
.exceptionMessage(exception.getErrorMessage())
.build();
}).collect(toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import uk.nhs.hee.tis.revalidation.connection.service.DisconnectedElasticSearchService;
import uk.nhs.hee.tis.revalidation.connection.service.DiscrepanciesElasticSearchService;


@WebMvcTest(ConnectionController.class)
class ConnectionControllerTest {

Expand All @@ -86,6 +87,7 @@ class ConnectionControllerTest {
private ConnectedElasticSearchService connectedElasticSearchService;
@MockBean
private DisconnectedElasticSearchService disconnectedElasticSearchService;

private String changeReason;
private String designatedBodyCode;
private String gmcId;
Expand Down Expand Up @@ -117,6 +119,7 @@ class ConnectionControllerTest {
private String exceptionReason1;
private String exceptionReason2;


@BeforeEach
public void setup() {
changeReason = faker.lorem().sentence();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package uk.nhs.hee.tis.revalidation.connection.controller;

import static java.util.List.of;
import static org.hamcrest.Matchers.hasItem;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.github.javafaker.Faker;
import java.time.LocalDateTime;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import uk.nhs.hee.tis.revalidation.connection.dto.ExceptionLogDto;
import uk.nhs.hee.tis.revalidation.connection.service.ExceptionService;

@WebMvcTest(ExceptionLogController.class)
class ExceptionLogControllerTest {

private final Faker faker = new Faker();
private String admin;
private LocalDateTime today;
private String gmcId1;
private String gmcId2;
private String exceptionReason1;
private String exceptionReason2;
@Autowired
private MockMvc mockMvc;
@MockBean
private ExceptionService exceptionService;
@InjectMocks
private ExceptionLogController exceptionLogController;

@BeforeEach
public void setup() {

admin = faker.internet().emailAddress();
today = LocalDateTime.now();
gmcId1 = faker.number().digits(8);
gmcId2 = faker.number().digits(8);
exceptionReason1 = faker.lorem().characters(20);
exceptionReason2 = faker.lorem().characters(20);
}

@Test
void shouldReturnAllExceptionsFromTodayForAnAdmin() throws Exception {
final var exceptionRecordDtoList = buildExceptionRecordDtoList();

when(exceptionService.getConnectionExceptionLogsFromToday(admin)).thenReturn(
exceptionRecordDtoList);

mockMvc.perform(get("/api/exceptionLog/today")
.param("admin", admin))
.andExpect(status().isOk())
.andExpect(jsonPath("$.[*].gmcId").value(hasItem(gmcId1)))
.andExpect(jsonPath("$.[*].errorMessage").value(hasItem(exceptionReason1)))
.andExpect(jsonPath("$.[*].admin").value(hasItem(admin)))
.andExpect(jsonPath("$.[*].gmcId").value(hasItem(gmcId2)))
.andExpect(jsonPath("$.[*].errorMessage").value(hasItem(exceptionReason2)))
.andExpect(jsonPath("$.[*].admin").value(hasItem(admin)));

}

private List<ExceptionLogDto> buildExceptionRecordDtoList() {
final var record1 = ExceptionLogDto.builder()
.gmcId(gmcId1).errorMessage(exceptionReason1)
.timestamp(today).admin(admin)
.build();
final var record2 = ExceptionLogDto.builder()
.gmcId(gmcId2).errorMessage(exceptionReason2)
.timestamp(today).admin(admin)
.build();
return of(record1, record2);
}
}
Loading

0 comments on commit dddee61

Please sign in to comment.