-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
396eb1a
commit 890d51c
Showing
17 changed files
with
737 additions
and
19 deletions.
There are no files selected for viewing
118 changes: 118 additions & 0 deletions
118
api/src/main/java/ca/bc/gov/educ/api/institute/controller/v1/SchoolAPIController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package ca.bc.gov.educ.api.institute.controller.v1; | ||
|
||
import ca.bc.gov.educ.api.institute.endpoint.v1.SchoolAPIEndpoint; | ||
import ca.bc.gov.educ.api.institute.exception.EntityNotFoundException; | ||
import ca.bc.gov.educ.api.institute.exception.InvalidPayloadException; | ||
import ca.bc.gov.educ.api.institute.exception.errors.ApiError; | ||
import ca.bc.gov.educ.api.institute.mapper.v1.SchoolMapper; | ||
import ca.bc.gov.educ.api.institute.service.v1.SchoolHistoryService; | ||
import ca.bc.gov.educ.api.institute.service.v1.SchoolService; | ||
import ca.bc.gov.educ.api.institute.struct.v1.School; | ||
import ca.bc.gov.educ.api.institute.struct.v1.SchoolHistory; | ||
import ca.bc.gov.educ.api.institute.util.RequestUtil; | ||
import ca.bc.gov.educ.api.institute.validator.SchoolPayloadValidator; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.extern.slf4j.Slf4j; | ||
import lombok.val; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.validation.FieldError; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.UUID; | ||
import java.util.function.Supplier; | ||
import java.util.stream.Collectors; | ||
|
||
import static org.springframework.http.HttpStatus.BAD_REQUEST; | ||
|
||
@RestController | ||
@Slf4j | ||
public class SchoolAPIController implements SchoolAPIEndpoint { | ||
|
||
private static final SchoolMapper mapper = SchoolMapper.mapper; | ||
@Getter(AccessLevel.PRIVATE) | ||
private final SchoolService schoolService; | ||
@Getter(AccessLevel.PRIVATE) | ||
private final SchoolHistoryService schoolHistoryService; | ||
|
||
@Getter(AccessLevel.PRIVATE) | ||
private final SchoolPayloadValidator payloadValidator; | ||
|
||
@Autowired | ||
public SchoolAPIController(final SchoolService schoolService, final SchoolHistoryService schoolHistoryService, final SchoolPayloadValidator payloadValidator) { | ||
this.schoolService = schoolService; | ||
this.schoolHistoryService = schoolHistoryService; | ||
this.payloadValidator = payloadValidator; | ||
} | ||
|
||
@Override | ||
public School getSchool(String schoolId) { | ||
UUID schoolUUID; | ||
try{ | ||
schoolUUID = UUID.fromString(schoolId); | ||
}catch(Exception e){ | ||
final ApiError error = ApiError.builder().timestamp(LocalDateTime.now()).message("Invalid school ID").status(BAD_REQUEST).build(); | ||
throw new InvalidPayloadException(error); | ||
} | ||
|
||
var school = getSchoolService().getSchool(schoolUUID); | ||
|
||
if(school.isPresent()){ | ||
return mapper.toStructure(school.get()); | ||
}else{ | ||
throw new EntityNotFoundException(); | ||
} | ||
} | ||
|
||
@Override | ||
public List<SchoolHistory> getSchoolHistory(String schoolId) { | ||
UUID schoolUUID; | ||
try{ | ||
schoolUUID = UUID.fromString(schoolId); | ||
}catch(Exception e){ | ||
final ApiError error = ApiError.builder().timestamp(LocalDateTime.now()).message("Invalid school history ID").status(BAD_REQUEST).build(); | ||
throw new InvalidPayloadException(error); | ||
} | ||
|
||
return getSchoolHistoryService().getAllSchoolHistoryList(schoolUUID).stream().map(mapper::toStructure).collect(Collectors.toList()); | ||
} | ||
|
||
@Override | ||
public School createSchool(School school) { | ||
validatePayload(() -> getPayloadValidator().validateCreatePayload(school)); | ||
RequestUtil.setAuditColumnsForCreate(school); | ||
return mapper.toStructure(schoolService.createSchool(school)); | ||
} | ||
|
||
@Override | ||
public School updateSchool(UUID id, School school) { | ||
validatePayload(() -> getPayloadValidator().validateUpdatePayload(school)); | ||
RequestUtil.setAuditColumnsForUpdate(school); | ||
return mapper.toStructure(schoolService.updateSchool(school, id)); | ||
} | ||
|
||
@Override | ||
@Transactional | ||
public ResponseEntity<Void> deleteSchool(UUID id) { | ||
getSchoolService().deleteSchool(id); | ||
return ResponseEntity.noContent().build(); | ||
} | ||
|
||
private void validatePayload(Supplier<List<FieldError>> validator) { | ||
val validationResult = validator.get(); | ||
if (!validationResult.isEmpty()) { | ||
ApiError error = ApiError.builder().timestamp(LocalDateTime.now()).message("Payload contains invalid data.").status(BAD_REQUEST).build(); | ||
error.addValidationErrors(validationResult); | ||
throw new InvalidPayloadException(error); | ||
} | ||
} | ||
|
||
@Override | ||
public List<School> getAllSchools() { | ||
return getSchoolService().getAllSchoolsList().stream().map(mapper::toStructure).collect(Collectors.toList()); | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
api/src/main/java/ca/bc/gov/educ/api/institute/endpoint/v1/SchoolAPIEndpoint.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package ca.bc.gov.educ.api.institute.endpoint.v1; | ||
|
||
import ca.bc.gov.educ.api.institute.constants.v1.URL; | ||
import ca.bc.gov.educ.api.institute.struct.v1.School; | ||
import ca.bc.gov.educ.api.institute.struct.v1.SchoolHistory; | ||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import io.swagger.v3.oas.annotations.OpenAPIDefinition; | ||
import io.swagger.v3.oas.annotations.info.Info; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import io.swagger.v3.oas.annotations.security.SecurityRequirement; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.access.prepost.PreAuthorize; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
import static org.springframework.http.HttpStatus.CREATED; | ||
|
||
@RequestMapping(URL.BASE_URL_SCHOOL) | ||
@OpenAPIDefinition(info = @Info(title = "API to School CRUD.", description = "This API is related to school data.", version = "1"), | ||
security = {@SecurityRequirement(name = "OAUTH2", scopes = {"READ_SCHOOL", "WRITE_SCHOOL", "DELETE_SCHOOL"})}) | ||
public interface SchoolAPIEndpoint { | ||
|
||
@GetMapping("/{schoolId}") | ||
@PreAuthorize("hasAuthority('SCOPE_READ_SCHOOL')") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "NOT FOUND")}) | ||
@Transactional(readOnly = true) | ||
@Tag(name = "Endpoint to get school entity.", description = "Endpoint to get school entity by ID.") | ||
@Schema(name = "School", implementation = School.class) | ||
School getSchool(@PathVariable("schoolId") String schoolId); | ||
|
||
@GetMapping("/{schoolId}/history") | ||
@PreAuthorize("hasAuthority('SCOPE_READ_SCHOOL')") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "NOT FOUND")}) | ||
@Transactional(readOnly = true) | ||
@Tag(name = "Endpoint to get school history entity list by school ID.", description = "Endpoint to get school history entity list by school ID.") | ||
@Schema(name = "SchoolHistory", implementation = SchoolHistory.class) | ||
List<SchoolHistory> getSchoolHistory(@PathVariable("schoolId") String schoolId); | ||
|
||
@PostMapping | ||
@PreAuthorize("hasAuthority('SCOPE_WRITE_SCHOOL')") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "201", description = "CREATED"), @ApiResponse(responseCode = "400", description = "BAD REQUEST")}) | ||
@Tag(name = "Endpoint to create school entity.", description = "Endpoint to create school entity.") | ||
@Schema(name = "School", implementation = School.class) | ||
@ResponseStatus(CREATED) | ||
School createSchool(@Validated @RequestBody School school) throws JsonProcessingException; | ||
|
||
@PutMapping("/{id}") | ||
@PreAuthorize("hasAuthority('SCOPE_WRITE_SCHOOL')") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "BAD REQUEST"), @ApiResponse(responseCode = "404", description = "NOT FOUND")}) | ||
@Tag(name = "Endpoint to update school entity.", description = "Endpoint to update school entity.") | ||
@Schema(name = "School", implementation = School.class) | ||
School updateSchool(@PathVariable UUID id, @Validated @RequestBody School school) throws JsonProcessingException; | ||
|
||
@DeleteMapping("/{id}") | ||
@PreAuthorize("hasAuthority('SCOPE_DELETE_SCHOOL')") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "NO CONTENT"), @ApiResponse(responseCode = "404", description = "NOT FOUND."), @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR.")}) | ||
@Tag(name = "Endpoint to delete school entity.", description = "Endpoint to delete school entity.") | ||
ResponseEntity<Void> deleteSchool(@PathVariable UUID id); | ||
|
||
@GetMapping | ||
@PreAuthorize("hasAuthority('SCOPE_READ_SCHOOL')") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) | ||
@Transactional(readOnly = true) | ||
@Tag(name = "Endpoint to get all school entities.", description = "Endpoint to get all school entities.") | ||
@Schema(name = "School", implementation = School.class) | ||
List<School> getAllSchools(); | ||
|
||
} |
35 changes: 35 additions & 0 deletions
35
api/src/main/java/ca/bc/gov/educ/api/institute/mapper/v1/SchoolMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package ca.bc.gov.educ.api.institute.mapper.v1; | ||
|
||
import ca.bc.gov.educ.api.institute.mapper.LocalDateTimeMapper; | ||
import ca.bc.gov.educ.api.institute.mapper.StringMapper; | ||
import ca.bc.gov.educ.api.institute.mapper.UUIDMapper; | ||
import ca.bc.gov.educ.api.institute.model.v1.SchoolEntity; | ||
import ca.bc.gov.educ.api.institute.model.v1.SchoolHistoryEntity; | ||
import ca.bc.gov.educ.api.institute.struct.v1.School; | ||
import ca.bc.gov.educ.api.institute.struct.v1.SchoolHistory; | ||
import org.mapstruct.Mapper; | ||
import org.mapstruct.Mapping; | ||
import org.mapstruct.factory.Mappers; | ||
|
||
@Mapper(uses = {UUIDMapper.class, LocalDateTimeMapper.class, StringMapper.class}) | ||
@SuppressWarnings("squid:S1214") | ||
public interface SchoolMapper { | ||
|
||
SchoolMapper mapper = Mappers.getMapper(SchoolMapper.class); | ||
|
||
@Mapping(target = "updateUser", ignore = true) | ||
@Mapping(target = "updateDate", ignore = true) | ||
@Mapping(target = "createUser", ignore = true) | ||
@Mapping(target = "createDate", ignore = true) | ||
SchoolEntity toModel(School structure); | ||
|
||
School toStructure(SchoolEntity entity); | ||
|
||
@Mapping(target = "updateUser", ignore = true) | ||
@Mapping(target = "updateDate", ignore = true) | ||
@Mapping(target = "createUser", ignore = true) | ||
@Mapping(target = "createDate", ignore = true) | ||
SchoolHistoryEntity toModel(SchoolHistory structure); | ||
|
||
SchoolHistory toStructure(SchoolHistoryEntity entity); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 9 additions & 2 deletions
11
api/src/main/java/ca/bc/gov/educ/api/institute/repository/v1/SchoolHistoryRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,19 @@ | ||
package ca.bc.gov.educ.api.institute.repository.v1; | ||
|
||
import ca.bc.gov.educ.api.institute.model.v1.DistrictHistoryEntity; | ||
import ca.bc.gov.educ.api.institute.model.v1.SchoolHistoryEntity; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
@Repository | ||
public interface SchoolHistoryRepository extends JpaRepository<SchoolHistoryEntity, UUID> { | ||
public interface SchoolHistoryRepository extends JpaRepository<SchoolHistoryEntity, UUID>, JpaSpecificationExecutor<DistrictHistoryEntity> { | ||
|
||
} | ||
List<SchoolHistoryEntity> findBySchoolId(UUID districtId); | ||
|
||
void deleteBySchoolId(UUID schoolId); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.