Skip to content

Commit

Permalink
feat: added new endpoint for banner search (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
JordenReuter authored Jul 30, 2024
1 parent 917c369 commit 24b4712
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.tkit.onecx.announcement.domain.criteria;

import java.time.OffsetDateTime;

import jakarta.validation.Valid;

import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@RegisterForReflection
public class AnnouncementBannerSearchCriteria {

private @Valid OffsetDateTime currentDate;

private @Valid String productName;

private @Valid String workspaceName;

private @Valid Integer pageNumber = 0;

private @Valid Integer pageSize = 100;

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.persistence.NoResultException;
import jakarta.persistence.criteria.*;

import org.tkit.onecx.announcement.domain.criteria.AnnouncementBannerSearchCriteria;
import org.tkit.onecx.announcement.domain.criteria.AnnouncementSearchCriteria;
import org.tkit.onecx.announcement.domain.models.Announcement;
import org.tkit.onecx.announcement.domain.models.Announcement_;
Expand Down Expand Up @@ -65,15 +66,8 @@ public PageResult<Announcement> loadAnnouncementByCriteria(AnnouncementSearchCri
criteria.getStartDateTo().toLocalDateTime()));
}
if (criteria.getEndDateFrom() != null) {

Predicate endDatePredicate = cb.greaterThanOrEqualTo(root.get(Announcement_.END_DATE),
criteria.getEndDateFrom().toLocalDateTime());
// Also include cases where END_DATE is null
Predicate endDateIsNullPredicate = cb.isNull(root.get(Announcement_.END_DATE));

// Combine the predicates using OR
predicates.add(cb.or(endDatePredicate, endDateIsNullPredicate));

predicates.add(cb.greaterThanOrEqualTo(root.get(Announcement_.END_DATE),
criteria.getEndDateFrom().toLocalDateTime()));
}
if (criteria.getEndDateTo() != null) {
predicates.add(
Expand Down Expand Up @@ -129,6 +123,39 @@ public List<String> findWorkspacesWithAnnouncements() {
}
}

public PageResult<Announcement> loadAnnouncementBannersByCriteria(AnnouncementBannerSearchCriteria criteria) {

try {
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Announcement> cq = cb.createQuery(Announcement.class);
Root<Announcement> root = cq.from(Announcement.class);
cq.select(root).distinct(true);

List<Predicate> predicates = new ArrayList<>();
if (criteria.getProductName() != null) {
predicates.add(cb.or(cb.equal(root.get(Announcement_.PRODUCT_NAME), criteria.getProductName()),
cb.isNull(root.get(Announcement_.PRODUCT_NAME))));
}
if (criteria.getWorkspaceName() != null) {
predicates.add(cb.or(cb.equal(root.get(Announcement_.WORKSPACE_NAME), criteria.getWorkspaceName()),
cb.isNull(root.get(Announcement_.WORKSPACE_NAME))));
}
predicates.add(cb.lessThanOrEqualTo(root.get(Announcement_.START_DATE),
criteria.getCurrentDate().toLocalDateTime()));
predicates.add(cb.or(cb.greaterThanOrEqualTo(root.get(Announcement_.END_DATE),
criteria.getCurrentDate().toLocalDateTime()),
cb.isNull(root.get(Announcement_.END_DATE))));

cq.where(cb.and(predicates.toArray(new Predicate[0])));

//do query and sort resultList by Priority and creation-date
cq.orderBy(cb.desc(root.get(AbstractTraceableEntity_.CREATION_DATE)));
return createPageQuery(cq, Page.of(criteria.getPageNumber(), criteria.getPageSize())).getPageResult();
} catch (Exception ex) {
throw new DAOException(ErrorKeys.ERROR_LOAD_ANNOUNCEMENT_BY_CRITERIA, ex);
}
}

public enum ErrorKeys {

FIND_ENTITY_BY_ID_FAILED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ public Response getAnnouncements(AnnouncementSearchCriteriaDTO announcementSearc
return Response.ok().entity(results).build();
}

@Override
public Response searchAnnouncementBanners(AnnouncementBannerSearchCriteriaDTO announcementBannerSearchCriteriaDTO) {
var criteria = mapper.map(announcementBannerSearchCriteriaDTO);
var page = dao.loadAnnouncementBannersByCriteria(criteria);
var results = mapper.mapToPageResult(page);
return Response.ok().entity(results).build();
}

@Override
public Response updateAnnouncementById(String id, UpdateAnnouncementRequestDTO updateAnnouncementRequestDTO) {
var item = dao.findById(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.tkit.onecx.announcement.domain.criteria.AnnouncementBannerSearchCriteria;
import org.tkit.onecx.announcement.domain.criteria.AnnouncementSearchCriteria;
import org.tkit.onecx.announcement.domain.models.Announcement;
import org.tkit.quarkus.jpa.daos.PageResult;
Expand Down Expand Up @@ -111,6 +112,8 @@ default String mapPath(Path path) {
return path.toString();
}

AnnouncementBannerSearchCriteria map(AnnouncementBannerSearchCriteriaDTO announcementBannerSearchCriteriaDTO);

enum ErrorKeys {
CONSTRAINT_VIOLATIONS,
OPTIMISTIC_LOCK
Expand Down
51 changes: 51 additions & 0 deletions src/main/openapi/announcement-openapi-internal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,35 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ProblemDetailResponse'
/internal/announcements/banner/search:
post:
security:
- oauth2: [ ocx-an:all, ocx-an:read ]
tags:
- AnnouncementInternal
summary: Find announcements by criteria
operationId: searchAnnouncementBanners
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AnnouncementBannerSearchCriteria'
responses:
"200":
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/AnnouncementPageResult'
"400":
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ProblemDetailResponse'
/internal/announcements:
post:
security:
Expand Down Expand Up @@ -238,6 +267,28 @@ components:
default: 100
maximum: 1000
type: integer
AnnouncementBannerSearchCriteria:
type: object
required:
- currentDate
properties:
currentDate:
$ref: '#/components/schemas/OffsetDateTime'
productName:
type: string
workspaceName:
type: string
pageNumber:
format: int32
description: The number of page.
default: 0
type: integer
pageSize:
format: int32
description: The size of page
default: 100
maximum: 1000
type: integer
UpdateAnnouncementRequest:
type: object
required:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ void methodExceptionTests() {
AnnouncementDAO.ErrorKeys.ERROR_FIND_PRODUCTS_WITH_ANNOUNCEMENTS);
methodExceptionTests(() -> dao.loadAnnouncementByCriteria(null),
AnnouncementDAO.ErrorKeys.ERROR_LOAD_ANNOUNCEMENT_BY_CRITERIA);
methodExceptionTests(() -> dao.loadAnnouncementBannersByCriteria(null),
AnnouncementDAO.ErrorKeys.ERROR_LOAD_ANNOUNCEMENT_BY_CRITERIA);
methodExceptionTests(() -> dao.findWorkspacesWithAnnouncements(),
AnnouncementDAO.ErrorKeys.ERROR_FIND_WORKSPACES_WITH_ANNOUNCEMENTS);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,51 @@ void getAnnouncementsByCriteriaAllTest() {
}

@Test
void getActiveAnnouncementsByCriteriaAllTest() {
AnnouncementSearchCriteriaDTO criteria = new AnnouncementSearchCriteriaDTO();

criteria.status(AnnouncementStatusDTO.ACTIVE);
criteria.workspaceName("workspace6");
criteria.setStartDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
criteria.setEndDateFrom(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
void searchAnnouncementBannersByCriteriaTest() {
AnnouncementBannerSearchCriteriaDTO criteriaDTO = new AnnouncementBannerSearchCriteriaDTO();
criteriaDTO.setCurrentDate(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));

var data = given()
.auth().oauth2(getKeycloakClientToken("testClient"))
.contentType(APPLICATION_JSON)
.body(criteria)
.post("search")
.body(criteriaDTO)
.post("banner/search")
.then()
.statusCode(OK.getStatusCode())
.contentType(APPLICATION_JSON)
.extract()
.as(AnnouncementPageResultDTO.class);

Assertions.assertThat(data).isNotNull();
Assertions.assertThat(data.getTotalElements()).isEqualTo(1);
Assertions.assertThat(data.getStream()).isNotNull().hasSize(1);

criteriaDTO.setWorkspaceName("workspace6");

data = given()
.auth().oauth2(getKeycloakClientToken("testClient"))
.contentType(APPLICATION_JSON)
.body(criteriaDTO)
.post("banner/search")
.then()
.statusCode(OK.getStatusCode())
.contentType(APPLICATION_JSON)
.extract()
.as(AnnouncementPageResultDTO.class);

Assertions.assertThat(data).isNotNull();
Assertions.assertThat(data.getTotalElements()).isEqualTo(1);
Assertions.assertThat(data.getStream()).isNotNull().hasSize(1);

criteriaDTO.setWorkspaceName(null);
criteriaDTO.setProductName("product1");
criteriaDTO.setCurrentDate(OffsetDateTime.parse("2020-03-10T12:15:50-04:00"));

data = given()
.auth().oauth2(getKeycloakClientToken("testClient"))
.contentType(APPLICATION_JSON)
.body(criteriaDTO)
.post("banner/search")
.then()
.statusCode(OK.getStatusCode())
.contentType(APPLICATION_JSON)
Expand All @@ -71,7 +103,6 @@ void getActiveAnnouncementsByCriteriaAllTest() {
Assertions.assertThat(data).isNotNull();
Assertions.assertThat(data.getTotalElements()).isEqualTo(1);
Assertions.assertThat(data.getStream()).isNotNull().hasSize(1);
Assertions.assertThat(data.getStream().get(0).getWorkspaceName()).isEqualTo("workspace6");
}

@Test
Expand Down

0 comments on commit 24b4712

Please sign in to comment.