OrganizationsController.java
package se.jobtechdev.personaldatagateway.api.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.context.request.NativeWebRequest;
import se.jobtechdev.personaldatagateway.api.generated.api.OrganizationsApi;
import se.jobtechdev.personaldatagateway.api.generated.model.Organization;
import se.jobtechdev.personaldatagateway.api.generated.model.OrganizationFaq;
import se.jobtechdev.personaldatagateway.api.generated.model.OrganizationFaqPatch;
import se.jobtechdev.personaldatagateway.api.generated.model.OrganizationPatch;
import se.jobtechdev.personaldatagateway.api.service.FaqService;
import se.jobtechdev.personaldatagateway.api.service.OrganizationService;
import se.jobtechdev.personaldatagateway.api.util.ControllerUtil;
import se.jobtechdev.personaldatagateway.api.util.LinkHeaderUtil;
import se.jobtechdev.personaldatagateway.api.util.OffsetBasedPageRequest;
import se.jobtechdev.personaldatagateway.api.util.ResponseFactory;
import java.util.List;
import java.util.UUID;
import static se.jobtechdev.personaldatagateway.api.util.ControllerUtil.*;
import static se.jobtechdev.personaldatagateway.api.util.ResponseFactory.createOrganization;
@Controller
public class OrganizationsController implements OrganizationsApi {
public static final String DELETED = "deleted";
private final OrganizationService organizationService;
private final FaqService faqService;
private final NativeWebRequest request;
private final String baseUrl;
@Autowired
public OrganizationsController(
@Value("${pdg-api.base-url}") String baseUrl,
NativeWebRequest request,
OrganizationService organizationService,
FaqService faqService) {
this.baseUrl = baseUrl;
this.request = request;
this.organizationService = organizationService;
this.faqService = faqService;
}
@Override
public ResponseEntity<Organization> postOrganization(Organization organization) {
final var createdOrganization =
throwApiExceptionOnAbsentValue(
organizationService.createOrganization(
organization.getOrgNr(), organization.getName()),
HttpStatus.BAD_REQUEST,
"Failed to handle POST organization request - Attempt to create organization"
+ " resulted in an empty result");
final var response = createOrganization(createdOrganization);
final var headers =
LinkHeaderUtil.createHeadersWithLocation(
createdOrganization.getId().toString(),
new Class<?>[]{Organization.class},
organization);
return ResponseEntity.status(HttpStatus.CREATED)
.contentType(MediaType.APPLICATION_JSON)
.headers(headers)
.body(response);
}
@Override
@CrossOrigin(origins = "*")
public ResponseEntity<List<Organization>> getOrganizations(Integer offset, Integer limit) {
final var pageable = OffsetBasedPageRequest.of(offset, limit);
final var organizations = organizationService.getOrganizations(pageable);
final var response =
organizations.stream()
.map(
ResponseFactory::createOrganization)
.toList();
final var headers =
LinkHeaderUtil.createHeadersWithPagination(
organizations,
new Class<?>[]{Integer.class, Integer.class},
(int) pageable.getOffset(),
pageable.getPageSize());
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.headers(headers)
.body(response);
}
@Override
@CrossOrigin(origins = "*")
public ResponseEntity<Organization> getOrganization(UUID organizationId) {
final var organization =
throwApiExceptionOnAbsentValue(
organizationService.getOrganizationById(organizationId),
HttpStatus.NOT_FOUND,
String.format(
"Failed to handle GET organization request - Could not find organization with"
+ " id: %s",
organizationId));
final var response = createOrganization(organization);
final var headers = LinkHeaderUtil.createHeaders(new Class<?>[]{UUID.class}, organizationId);
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.headers(headers)
.body(response);
}
@Override
public ResponseEntity<Organization> patchOrganization(
UUID organizationId, OrganizationPatch organizationPatch) {
final var organization =
throwApiExceptionOnAbsentValue(
organizationService.getOrganizationById(organizationId),
HttpStatus.NOT_FOUND,
String.format(
"Failed to handle PATCH organization request - Could not find organization with"
+ " id: %s",
organizationId));
final var assigned =
ControllerUtil.assignNonNull(
organizationPatch, organization, List.of("name", DELETED), List.of(DELETED));
final var updated = organizationService.update(assigned);
final var response = ResponseFactory.createOrganization(updated);
final var headers =
LinkHeaderUtil.createHeaders(
new Class<?>[]{UUID.class, OrganizationPatch.class},
organizationId,
organizationPatch);
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.headers(headers)
.body(response);
}
@Override
public ResponseEntity<OrganizationFaq> postOrganizationFaq(
UUID organizationId, OrganizationFaq organizationFaq) {
final var organization =
throwApiExceptionOnAbsentValue(
organizationService.getOrganizationById(organizationId),
HttpStatus.NOT_FOUND,
String.format(
"Failed to handle POST organization faq request - Could not find organization"
+ " with id: %s",
organizationId));
final var faqs = organization.getFaqEntities();
final var faq =
faqService.createFaq(
organizationFaq.getLang(),
organizationFaq.getTitle(),
organizationFaq.getContent());
faqs.add(faq);
organizationService.save(organization);
final var response =
ResponseFactory.createOrganizationFaq(organizationId, faq);
final var headers =
LinkHeaderUtil.createHeadersWithLocation(
faq.getId().toString(),
new Class<?>[]{UUID.class, OrganizationFaq.class},
organizationId,
organizationFaq);
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.headers(headers)
.body(response);
}
@Override
@CrossOrigin(origins = "*")
public ResponseEntity<List<OrganizationFaq>> getOrganizationFaqs(
UUID organizationId, String acceptLanguage, Integer offset, Integer limit) {
throwApiExceptionOnAbsentValue(
organizationService.getOrganizationById(organizationId),
HttpStatus.NOT_FOUND,
String.format(
"Failed to handle GET organization faqs request - Could not find organization"
+ " with id: %s",
organizationId));
final var pageable = OffsetBasedPageRequest.of(offset, limit);
final var faqs = faqService.getOrganizationFaqs(organizationId, acceptLanguage, pageable);
final var response =
faqs.stream()
.map(
faq ->
ResponseFactory.createOrganizationFaq(organizationId, faq))
.toList();
final var headers =
LinkHeaderUtil.createHeadersWithPagination(
faqs,
new Class<?>[]{UUID.class, String.class, Integer.class, Integer.class},
organizationId,
acceptLanguage,
(int) pageable.getOffset(),
pageable.getPageSize());
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.headers(headers)
.body(response);
}
@Override
@CrossOrigin(origins = "*")
public ResponseEntity<OrganizationFaq> getOrganizationFaq(
UUID organizationId, UUID faqId) {
final var faq =
throwApiExceptionOnAbsentValue(
faqService.getFaqById(faqId),
HttpStatus.NOT_FOUND,
String.format(
"Failed to handle GET organization faq request - Could not find faq with id:"
+ " %s",
faqId));
final var organization =
throwApiExceptionOnAbsentValue(
organizationService.getOrganizationById(organizationId),
HttpStatus.NOT_FOUND,
String.format(
"Failed to handle GET organization faq request - Could not find organization with id:"
+ " %s",
organizationId));
earlyExit(
organization,
notAmong(faq.getOrganizationEntities()),
HttpStatus.NOT_FOUND,
String.format(
"Failed to handle GET organization faq request - Could not find faq with id: %s for organization with id: %s",
faqId, organizationId));
final var response =
ResponseFactory.createOrganizationFaq(organizationId, faq);
final var headers =
LinkHeaderUtil.createHeaders(
new Class<?>[]{UUID.class, UUID.class}, organizationId, faqId);
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.headers(headers)
.body(response);
}
@Override
public ResponseEntity<OrganizationFaq> patchOrganizationFaq(
UUID organizationId, UUID faqId, OrganizationFaqPatch organizationFaqPatch) {
final var faq =
throwApiExceptionOnAbsentValue(
faqService.getFaqById(faqId),
HttpStatus.NOT_FOUND,
String.format(
"Failed to handle PATCH organization faq request - Could not find faq with id:"
+ " %s",
faqId));
final var patchedFaq = assignNonNull(organizationFaqPatch, faq, List.of(DELETED));
final var updated = faqService.update(patchedFaq);
final var response = ResponseFactory.createOrganizationFaq(organizationId, updated);
final var headers =
LinkHeaderUtil.createHeaders(
new Class<?>[]{UUID.class, UUID.class, OrganizationFaqPatch.class},
organizationId,
faqId,
organizationFaqPatch);
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.headers(headers)
.body(response);
}
}