diff --git a/.gitignore b/.gitignore
index 61f7b68..8c7863e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,367 +1,43 @@
-.idea/.gitignore
-.idea/compiler.xml
-.idea/encodings.xml
-.idea/jarRepositories.xml
-.idea/misc.xml
-.idea/vcs.xml
-target/formatter-maven-cache.properties
-target/impsort-maven-cache.properties
-target/jacoco-quarkus.exec
-target/classes/application.properties
-target/classes/.openapi-generator/announcement-openapi-internal.yaml-internal.sha256
-target/classes/.openapi-generator/announcement-openapi-v1.yaml-v1.sha256
-target/classes/db/migration/V1.0.1__CreateTables.sql
-target/classes/gen/io/github/onecx/announcement/rs/internal/AnnouncementInternalApi.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementPageResultDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementPriorityTypeDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementStatusDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementTypeDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/CreateAnnouncementRequestDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/ProblemDetailInvalidParamDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/ProblemDetailParamDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/ProblemDetailResponseDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/SearchAnnouncementRequestDTO.class
-target/classes/gen/io/github/onecx/announcement/rs/internal/model/UpdateAnnouncementRequestDTO.class
-target/classes/gen/io/github/onecx/announcement/v1/AnnouncementV1Api.class
-target/classes/gen/io/github/onecx/announcement/v1/model/AnnouncementDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/AnnouncementPageResultDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/AnnouncementPriorityTypeDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/AnnouncementStatusDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/AnnouncementTypeDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/DeleteAnnouncementRequestDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/ProblemDetailInvalidParamDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/ProblemDetailParamDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/ProblemDetailResponseDTOV1.class
-target/classes/gen/io/github/onecx/announcement/v1/model/SearchAnnouncementRequestDTOV1.class
-target/classes/META-INF/panache-archive.marker
-target/classes/org/onecx/announcement/domain/dao/AnnouncementDAO.class
-target/classes/org/onecx/announcement/domain/dao/AnnouncementDAO$ErrorKeys.class
-target/classes/org/onecx/announcement/domain/models/Announcement_.class
-target/classes/org/onecx/announcement/domain/models/Announcement.class
-target/classes/org/onecx/announcement/rs/internal/controller/ApplicationControllerInternal.class
-target/classes/org/onecx/announcement/rs/internal/mapper/AnnouncementMapper.class
-target/classes/org/onecx/announcement/rs/internal/mapper/AnnouncementMapperImpl.class
-target/classes/org/onecx/announcement/rs/v1/controller/AnnouncementControllerV1.class
-target/classes/org/onecx/announcement/rs/v1/controller/ErrorKeys.class
-target/classes/org/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1.class
-target/classes/org/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1Impl.class
-target/generated-sources/annotations/org/onecx/announcement/domain/models/Announcement_.java
-target/generated-sources/annotations/org/onecx/announcement/rs/internal/mapper/AnnouncementMapperImpl.java
-target/generated-sources/annotations/org/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1Impl.java
-target/generated-sources/openapi/.openapi-generator/announcement-openapi-internal.yaml-internal.sha256
-target/generated-sources/openapi/.openapi-generator/announcement-openapi-v1.yaml-v1.sha256
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/AnnouncementInternalApi.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementPageResultDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementPriorityTypeDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementStatusDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/AnnouncementTypeDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/CreateAnnouncementRequestDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/ProblemDetailInvalidParamDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/ProblemDetailParamDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/ProblemDetailResponseDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/SearchAnnouncementRequestDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/rs/internal/model/UpdateAnnouncementRequestDTO.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/AnnouncementV1Api.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/AnnouncementDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/AnnouncementPageResultDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/AnnouncementPriorityTypeDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/AnnouncementStatusDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/AnnouncementTypeDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/DeleteAnnouncementRequestDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/ProblemDetailInvalidParamDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/ProblemDetailParamDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/ProblemDetailResponseDTOV1.java
-target/generated-sources/openapi/gen/io/github/onecx/announcement/v1/model/SearchAnnouncementRequestDTOV1.java
-target/jacoco-report/index.html
-target/jacoco-report/jacoco-sessions.html
-target/jacoco-report/jacoco.csv
-target/jacoco-report/jacoco.xml
-target/jacoco-report/jacoco-resources/branchfc.gif
-target/jacoco-report/jacoco-resources/branchnc.gif
-target/jacoco-report/jacoco-resources/branchpc.gif
-target/jacoco-report/jacoco-resources/bundle.gif
-target/jacoco-report/jacoco-resources/class.gif
-target/jacoco-report/jacoco-resources/down.gif
-target/jacoco-report/jacoco-resources/greenbar.gif
-target/jacoco-report/jacoco-resources/group.gif
-target/jacoco-report/jacoco-resources/method.gif
-target/jacoco-report/jacoco-resources/package.gif
-target/jacoco-report/jacoco-resources/prettify.css
-target/jacoco-report/jacoco-resources/prettify.js
-target/jacoco-report/jacoco-resources/redbar.gif
-target/jacoco-report/jacoco-resources/report.css
-target/jacoco-report/jacoco-resources/report.gif
-target/jacoco-report/jacoco-resources/session.gif
-target/jacoco-report/jacoco-resources/sort.gif
-target/jacoco-report/jacoco-resources/sort.js
-target/jacoco-report/jacoco-resources/source.gif
-target/jacoco-report/jacoco-resources/up.gif
-target/jacoco-report/org.onecx.announcement.domain.dao/AnnouncementDAO.html
-target/jacoco-report/org.onecx.announcement.domain.dao/AnnouncementDAO.java.html
-target/jacoco-report/org.onecx.announcement.domain.dao/AnnouncementDAO$ErrorKeys.html
-target/jacoco-report/org.onecx.announcement.domain.dao/index.html
-target/jacoco-report/org.onecx.announcement.domain.dao/index.source.html
-target/jacoco-report/org.onecx.announcement.rs.internal.controller/ApplicationControllerInternal.html
-target/jacoco-report/org.onecx.announcement.rs.internal.controller/ApplicationControllerInternal.java.html
-target/jacoco-report/org.onecx.announcement.rs.internal.controller/index.html
-target/jacoco-report/org.onecx.announcement.rs.internal.controller/index.source.html
-target/jacoco-report/org.onecx.announcement.rs.v1.controller/AnnouncementControllerV1.html
-target/jacoco-report/org.onecx.announcement.rs.v1.controller/AnnouncementControllerV1.java.html
-target/jacoco-report/org.onecx.announcement.rs.v1.controller/ErrorKeys.html
-target/jacoco-report/org.onecx.announcement.rs.v1.controller/ErrorKeys.java.html
-target/jacoco-report/org.onecx.announcement.rs.v1.controller/index.html
-target/jacoco-report/org.onecx.announcement.rs.v1.controller/index.source.html
-target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
-target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
-target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
-target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
-target/quarkus/bootstrap/test-app-model.dat
-target/surefire-reports/org.onecx.announcement.rs.external.v1.AnnouncementExternalControllerTest.txt
-target/surefire-reports/org.onecx.announcement.rs.internal.AnnouncementAPITest.txt
-target/surefire-reports/TEST-org.onecx.announcement.rs.external.v1.AnnouncementExternalControllerTest.xml
-target/surefire-reports/TEST-org.onecx.announcement.rs.internal.AnnouncementAPITest.xml
-target/test-classes/ahm-testdata.xml
-target/test-classes/META-INF/panache-archive.marker
-target/test-classes/META-INF/resources/test_privateKey.pem
-target/test-classes/META-INF/resources/test_publicKey.pem
-target/test-classes/META-INF/resources/test_tokens/admin_token.json
-target/test-classes/META-INF/resources/test_tokens/non_admin_token.json
-target/test-classes/org/onecx/announcement/rs/external/v1/AnnouncementExternalControllerTest.class
-target/test-classes/org/onecx/announcement/rs/external/v1/AnnouncementExternalControllerTestIT.class
-target/test-classes/org/onecx/announcement/rs/internal/AnnouncementAPITest.class
-target/test-classes/org/onecx/announcement/rs/internal/AnnouncementItemAPITestIT.class
-target/test-classes/org/onecx/announcement/rs/test/AbstractTest.class
-.idea/sonarlint/issuestore/index.pb
-.idea/sonarlint/issuestore/0/2/02b0356ea4751bc0b87007849bf76e3e1879fa92
-.idea/sonarlint/issuestore/0/e/0ec43cacf30b15c12fadd38167bf03c824f9409a
-.idea/sonarlint/issuestore/2/d/2d1ba447f7d64cd13f9b3f90edc4193dc656e410
-.idea/sonarlint/issuestore/4/1/4143058a2a87c98bc41c49c23b3265696c2315d3
-.idea/sonarlint/issuestore/4/4/442292b8a7efeabbe4cc176709b833b1792140ec
-.idea/sonarlint/issuestore/8/e/8ea91b85564d1bba5673a8e45f43f94b8be6edae
-.idea/sonarlint/issuestore/8/e/8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d
-.idea/sonarlint/issuestore/9/3/93274201e44a81754526f7033380fffb1581e547
-.idea/sonarlint/issuestore/9/4/949eab112e3e5bd22120ac0e1f06401ff4500c2c
-.idea/sonarlint/issuestore/9/8/9815df64f8f563326bd3133bf3962ff49fb3a9e7
-.idea/sonarlint/issuestore/b/8/b8e28853d4a0fa4fcf35ffceb8d93ddd7cd62ac3
-.idea/sonarlint/issuestore/d/2/d27f8af4262dc89f85141bd5d57b8dcf5fa4a225
-.idea/sonarlint/securityhotspotstore/index.pb
-.idea/sonarlint/securityhotspotstore/0/2/02b0356ea4751bc0b87007849bf76e3e1879fa92
-.idea/sonarlint/securityhotspotstore/0/e/0ec43cacf30b15c12fadd38167bf03c824f9409a
-.idea/sonarlint/securityhotspotstore/2/d/2d1ba447f7d64cd13f9b3f90edc4193dc656e410
-.idea/sonarlint/securityhotspotstore/4/1/4143058a2a87c98bc41c49c23b3265696c2315d3
-.idea/sonarlint/securityhotspotstore/4/4/442292b8a7efeabbe4cc176709b833b1792140ec
-.idea/sonarlint/securityhotspotstore/8/e/8ea91b85564d1bba5673a8e45f43f94b8be6edae
-.idea/sonarlint/securityhotspotstore/8/e/8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d
-.idea/sonarlint/securityhotspotstore/9/3/93274201e44a81754526f7033380fffb1581e547
-.idea/sonarlint/securityhotspotstore/9/4/949eab112e3e5bd22120ac0e1f06401ff4500c2c
-.idea/sonarlint/securityhotspotstore/9/8/9815df64f8f563326bd3133bf3962ff49fb3a9e7
-.idea/sonarlint/securityhotspotstore/b/8/b8e28853d4a0fa4fcf35ffceb8d93ddd7cd62ac3
-.idea/sonarlint/securityhotspotstore/d/2/d27f8af4262dc89f85141bd5d57b8dcf5fa4a225
-target/onecx-announcement-svc-999-SNAPSHOT.jar
-target/quarkus-artifact.properties
-target/maven-archiver/pom.properties
-target/quarkus-app/quarkus-app-dependencies.txt
-target/quarkus-app/quarkus-run.jar
-target/quarkus-app/app/onecx-announcement-svc-999-SNAPSHOT.jar
-target/quarkus-app/lib/boot/io.github.crac.org-crac-0.1.3.jar
-target/quarkus-app/lib/boot/io.quarkus.quarkus-bootstrap-runner-3.5.1.jar
-target/quarkus-app/lib/boot/io.quarkus.quarkus-development-mode-spi-3.5.1.jar
-target/quarkus-app/lib/boot/io.quarkus.quarkus-vertx-latebound-mdc-provider-3.5.1.jar
-target/quarkus-app/lib/boot/io.smallrye.common.smallrye-common-constraint-2.1.2.jar
-target/quarkus-app/lib/boot/io.smallrye.common.smallrye-common-cpu-2.1.2.jar
-target/quarkus-app/lib/boot/io.smallrye.common.smallrye-common-expression-2.1.2.jar
-target/quarkus-app/lib/boot/io.smallrye.common.smallrye-common-function-2.1.2.jar
-target/quarkus-app/lib/boot/io.smallrye.common.smallrye-common-io-2.1.2.jar
-target/quarkus-app/lib/boot/io.smallrye.common.smallrye-common-net-2.1.2.jar
-target/quarkus-app/lib/boot/io.smallrye.common.smallrye-common-os-2.1.2.jar
-target/quarkus-app/lib/boot/io.smallrye.common.smallrye-common-ref-2.1.2.jar
-target/quarkus-app/lib/boot/org.jboss.logging.jboss-logging-3.5.3.Final.jar
-target/quarkus-app/lib/boot/org.jboss.logmanager.jboss-logmanager-3.0.2.Final.jar
-target/quarkus-app/lib/main/com.aayushatharva.brotli4j.brotli4j-1.12.0.jar
-target/quarkus-app/lib/main/com.aayushatharva.brotli4j.native-linux-x86_64-1.12.0.jar
-target/quarkus-app/lib/main/com.aayushatharva.brotli4j.service-1.12.0.jar
-target/quarkus-app/lib/main/com.fasterxml.classmate-1.5.1.jar
-target/quarkus-app/lib/main/com.fasterxml.jackson.core.jackson-annotations-2.15.2.jar
-target/quarkus-app/lib/main/com.fasterxml.jackson.core.jackson-core-2.15.2.jar
-target/quarkus-app/lib/main/com.fasterxml.jackson.core.jackson-databind-2.15.2.jar
-target/quarkus-app/lib/main/com.fasterxml.jackson.dataformat.jackson-dataformat-toml-2.15.2.jar
-target/quarkus-app/lib/main/com.fasterxml.jackson.dataformat.jackson-dataformat-yaml-2.15.2.jar
-target/quarkus-app/lib/main/com.fasterxml.jackson.datatype.jackson-datatype-jdk8-2.15.2.jar
-target/quarkus-app/lib/main/com.fasterxml.jackson.datatype.jackson-datatype-jsr310-2.15.2.jar
-target/quarkus-app/lib/main/com.fasterxml.jackson.module.jackson-module-parameter-names-2.15.2.jar
-target/quarkus-app/lib/main/com.github.ben-manes.caffeine.caffeine-3.1.5.jar
-target/quarkus-app/lib/main/com.google.code.gson.gson-2.10.1.jar
-target/quarkus-app/lib/main/com.google.errorprone.error_prone_annotations-2.22.0.jar
-target/quarkus-app/lib/main/com.sun.istack.istack-commons-runtime-4.1.2.jar
-target/quarkus-app/lib/main/io.agroal.agroal-api-2.1.jar
-target/quarkus-app/lib/main/io.agroal.agroal-narayana-2.1.jar
-target/quarkus-app/lib/main/io.agroal.agroal-pool-2.1.jar
-target/quarkus-app/lib/main/io.netty.netty-buffer-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-codec-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-codec-dns-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-codec-haproxy-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-codec-http-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-codec-http2-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-codec-socks-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-common-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-handler-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-handler-proxy-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-resolver-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-resolver-dns-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-transport-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.netty.netty-transport-native-unix-common-4.1.100.Final.jar
-target/quarkus-app/lib/main/io.quarkus.arc.arc-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-agroal-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-arc-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-caffeine-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-container-image-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-container-image-docker-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-core-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-credentials-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-datasource-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-datasource-common-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-flyway-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-fs-util-0.0.9.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-hibernate-orm-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-hibernate-validator-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-jackson-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-jaxrs-client-reactive-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-jdbc-postgresql-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-jsonp-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-mutiny-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-narayana-jta-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-netty-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-rest-client-config-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-rest-client-reactive-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-resteasy-reactive-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-resteasy-reactive-common-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-resteasy-reactive-jackson-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-resteasy-reactive-jackson-common-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-security-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-security-runtime-spi-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-smallrye-context-propagation-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-smallrye-health-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-smallrye-jwt-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-smallrye-jwt-build-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-smallrye-openapi-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-smallrye-stork-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-swagger-ui-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-transaction-annotations-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-vertx-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-vertx-http-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.quarkus-virtual-threads-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.resteasy.reactive.resteasy-reactive-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.resteasy.reactive.resteasy-reactive-client-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.resteasy.reactive.resteasy-reactive-common-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.resteasy.reactive.resteasy-reactive-common-types-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.resteasy.reactive.resteasy-reactive-jackson-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.resteasy.reactive.resteasy-reactive-vertx-3.5.1.jar
-target/quarkus-app/lib/main/io.quarkus.security.quarkus-security-2.0.2.Final.jar
-target/quarkus-app/lib/main/io.smallrye.common.smallrye-common-annotation-2.1.2.jar
-target/quarkus-app/lib/main/io.smallrye.common.smallrye-common-classloader-2.1.2.jar
-target/quarkus-app/lib/main/io.smallrye.common.smallrye-common-vertx-context-2.1.2.jar
-target/quarkus-app/lib/main/io.smallrye.config.smallrye-config-3.4.1.jar
-target/quarkus-app/lib/main/io.smallrye.config.smallrye-config-common-3.4.1.jar
-target/quarkus-app/lib/main/io.smallrye.config.smallrye-config-core-3.4.1.jar
-target/quarkus-app/lib/main/io.smallrye.config.smallrye-config-validator-3.4.1.jar
-target/quarkus-app/lib/main/io.smallrye.jandex-3.1.5.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.mutiny-2.5.1.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.mutiny-smallrye-context-propagation-2.5.1.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.mutiny-zero-flow-adapters-1.0.0.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-mutiny-vertx-auth-common-3.7.2.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-mutiny-vertx-bridge-common-3.7.2.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-mutiny-vertx-core-3.7.2.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-mutiny-vertx-runtime-3.7.2.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-mutiny-vertx-uri-template-3.7.2.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-mutiny-vertx-web-3.7.2.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-mutiny-vertx-web-common-3.7.2.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-reactive-converter-api-3.0.1.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.smallrye-reactive-converter-mutiny-3.0.1.jar
-target/quarkus-app/lib/main/io.smallrye.reactive.vertx-mutiny-generator-3.7.2.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-context-propagation-2.1.0.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-context-propagation-api-2.1.0.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-context-propagation-jta-2.1.0.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-context-propagation-storage-2.1.0.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-fault-tolerance-vertx-6.2.6.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-health-4.0.4.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-health-api-4.0.4.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-health-provided-checks-4.0.4.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-jwt-4.3.1.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-jwt-build-4.3.1.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-jwt-common-4.3.1.jar
-target/quarkus-app/lib/main/io.smallrye.smallrye-open-api-core-3.7.0.jar
-target/quarkus-app/lib/main/io.smallrye.stork.stork-api-2.3.1.jar
-target/quarkus-app/lib/main/io.smallrye.stork.stork-core-2.3.1.jar
-target/quarkus-app/lib/main/io.vertx.vertx-auth-common-4.4.6.jar
-target/quarkus-app/lib/main/io.vertx.vertx-bridge-common-4.4.6.jar
-target/quarkus-app/lib/main/io.vertx.vertx-codegen-4.4.6.jar
-target/quarkus-app/lib/main/io.vertx.vertx-core-4.4.6.jar
-target/quarkus-app/lib/main/io.vertx.vertx-uri-template-4.4.6.jar
-target/quarkus-app/lib/main/io.vertx.vertx-web-4.4.6.jar
-target/quarkus-app/lib/main/io.vertx.vertx-web-client-4.4.6.jar
-target/quarkus-app/lib/main/io.vertx.vertx-web-common-4.4.6.jar
-target/quarkus-app/lib/main/jakarta.activation.jakarta.activation-api-2.1.2.jar
-target/quarkus-app/lib/main/jakarta.annotation.jakarta.annotation-api-2.1.1.jar
-target/quarkus-app/lib/main/jakarta.ejb.jakarta.ejb-api-4.0.1.jar
-target/quarkus-app/lib/main/jakarta.el.jakarta.el-api-5.0.1.jar
-target/quarkus-app/lib/main/jakarta.enterprise.jakarta.enterprise.cdi-api-4.0.1.jar
-target/quarkus-app/lib/main/jakarta.enterprise.jakarta.enterprise.lang-model-4.0.1.jar
-target/quarkus-app/lib/main/jakarta.inject.jakarta.inject-api-2.0.1.jar
-target/quarkus-app/lib/main/jakarta.interceptor.jakarta.interceptor-api-2.1.0.jar
-target/quarkus-app/lib/main/jakarta.json.jakarta.json-api-2.1.2.jar
-target/quarkus-app/lib/main/jakarta.persistence.jakarta.persistence-api-3.1.0.jar
-target/quarkus-app/lib/main/jakarta.resource.jakarta.resource-api-2.1.0.jar
-target/quarkus-app/lib/main/jakarta.transaction.jakarta.transaction-api-2.0.1.jar
-target/quarkus-app/lib/main/jakarta.validation.jakarta.validation-api-3.0.2.jar
-target/quarkus-app/lib/main/jakarta.ws.rs.jakarta.ws.rs-api-3.1.0.jar
-target/quarkus-app/lib/main/jakarta.xml.bind.jakarta.xml.bind-api-4.0.1.jar
-target/quarkus-app/lib/main/javax.activation.javax.activation-api-1.2.0.jar
-target/quarkus-app/lib/main/javax.xml.bind.jaxb-api-2.3.1.jar
-target/quarkus-app/lib/main/net.bytebuddy.byte-buddy-1.14.7.jar
-target/quarkus-app/lib/main/org.antlr.antlr4-runtime-4.10.1.jar
-target/quarkus-app/lib/main/org.bitbucket.b_c.jose4j-0.9.3.jar
-target/quarkus-app/lib/main/org.eclipse.angus.angus-activation-2.0.1.jar
-target/quarkus-app/lib/main/org.eclipse.microprofile.config.microprofile-config-api-3.0.3.jar
-target/quarkus-app/lib/main/org.eclipse.microprofile.context-propagation.microprofile-context-propagation-api-1.3.jar
-target/quarkus-app/lib/main/org.eclipse.microprofile.health.microprofile-health-api-4.0.1.jar
-target/quarkus-app/lib/main/org.eclipse.microprofile.jwt.microprofile-jwt-auth-api-2.1.jar
-target/quarkus-app/lib/main/org.eclipse.microprofile.openapi.microprofile-openapi-api-3.1.1.jar
-target/quarkus-app/lib/main/org.eclipse.microprofile.reactive-streams-operators.microprofile-reactive-streams-operators-api-3.0.jar
-target/quarkus-app/lib/main/org.eclipse.microprofile.rest.client.microprofile-rest-client-api-3.0.1.jar
-target/quarkus-app/lib/main/org.eclipse.parsson.parsson-1.1.4.jar
-target/quarkus-app/lib/main/org.flywaydb.flyway-core-9.22.2.jar
-target/quarkus-app/lib/main/org.glassfish.expressly.expressly-5.0.0.jar
-target/quarkus-app/lib/main/org.glassfish.jaxb.jaxb-core-4.0.3.jar
-target/quarkus-app/lib/main/org.glassfish.jaxb.jaxb-runtime-4.0.3.jar
-target/quarkus-app/lib/main/org.glassfish.jaxb.txw2-4.0.3.jar
-target/quarkus-app/lib/main/org.hibernate.common.hibernate-commons-annotations-6.0.6.Final.jar
-target/quarkus-app/lib/main/org.hibernate.hibernate-jpamodelgen-5.5.6.jar
-target/quarkus-app/lib/main/org.hibernate.orm.hibernate-core-6.2.13.Final.jar
-target/quarkus-app/lib/main/org.hibernate.orm.hibernate-graalvm-6.2.13.Final.jar
-target/quarkus-app/lib/main/org.hibernate.quarkus-local-cache-0.2.1.jar
-target/quarkus-app/lib/main/org.hibernate.validator.hibernate-validator-8.0.1.Final.jar
-target/quarkus-app/lib/main/org.jboss.invocation.jboss-invocation-2.0.0.Final.jar
-target/quarkus-app/lib/main/org.jboss.jboss-transaction-spi-8.0.0.Final.jar
-target/quarkus-app/lib/main/org.jboss.logging.commons-logging-jboss-logging-1.0.0.Final.jar
-target/quarkus-app/lib/main/org.jboss.logging.jboss-logging-annotations-2.2.1.Final.jar
-target/quarkus-app/lib/main/org.jboss.narayana.jta.narayana-jta-7.0.0.Final.jar
-target/quarkus-app/lib/main/org.jboss.narayana.jts.narayana-jts-integration-7.0.0.Final.jar
-target/quarkus-app/lib/main/org.jboss.slf4j.slf4j-jboss-logmanager-2.0.0.Final.jar
-target/quarkus-app/lib/main/org.jboss.threads.jboss-threads-3.5.0.Final.jar
-target/quarkus-app/lib/main/org.mapstruct.mapstruct-1.5.5.Final.jar
-target/quarkus-app/lib/main/org.postgresql.postgresql-42.6.0.jar
-target/quarkus-app/lib/main/org.reactivestreams.reactive-streams-1.0.4.jar
-target/quarkus-app/lib/main/org.slf4j.slf4j-api-2.0.6.jar
-target/quarkus-app/lib/main/org.tkit.quarkus.lib.tkit-quarkus-context-2.3.0.jar
-target/quarkus-app/lib/main/org.tkit.quarkus.lib.tkit-quarkus-jpa-2.3.0.jar
-target/quarkus-app/lib/main/org.tkit.quarkus.lib.tkit-quarkus-jpa-models-2.3.0.jar
-target/quarkus-app/lib/main/org.tkit.quarkus.lib.tkit-quarkus-log-cdi-2.3.0.jar
-target/quarkus-app/lib/main/org.tkit.quarkus.lib.tkit-quarkus-log-rs-2.3.0.jar
-target/quarkus-app/lib/main/org.tkit.quarkus.lib.tkit-quarkus-rest-2.3.0.jar
-target/quarkus-app/lib/main/org.wildfly.common.wildfly-common-1.5.4.Final-format-001.jar
-target/quarkus-app/lib/main/org.yaml.snakeyaml-2.1.jar
-target/quarkus-app/quarkus/generated-bytecode.jar
-target/quarkus-app/quarkus/quarkus-application.dat
-target/quarkus-app/quarkus/transformed-bytecode.jar
+#Maven
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+release.properties
+.flattened-pom.xml
+
+# Eclipse
+.project
+.classpath
+.settings/
+bin/
+
+# IntelliJ
+.idea
+*.ipr
+*.iml
+*.iws
+
+# NetBeans
+nb-configuration.xml
+
+# Visual Studio Code
+.vscode
+.factorypath
+
+# OSX
+.DS_Store
+
+# Vim
+*.swp
+*.swo
+
+# patch
+*.orig
+*.rej
+
+# Local environment
+.env
+
+# Plugin directory
+/.quarkus/cli/plugins/
diff --git a/onecx-announcement-svc.iml b/onecx-announcement-svc.iml
deleted file mode 100644
index a1585fa..0000000
--- a/onecx-announcement-svc.iml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c8f5ef1..0b54f38 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,141 +1,140 @@
-
-
+
+
+
4.0.0
+
io.github.onecx
onecx-quarkus3-parent
- 0.16.0
+ 0.23.0
- org.onecx
onecx-announcement-svc
999-SNAPSHOT
-
- 3.11.0
- 17
- UTF-8
- UTF-8
- quarkus-bom
- io.quarkus.platform
- 3.5.1
- true
- 3.1.2
-
-
-
-
- ${quarkus.platform.group-id}
- ${quarkus.platform.artifact-id}
- ${quarkus.platform.version}
- pom
- import
-
-
-
+
-
- io.quarkus
- quarkus-jdbc-postgresql
+ io.github.onecx.quarkus
+ onecx-tenant
+
- io.quarkus
- quarkus-resteasy-reactive
+ org.tkit.quarkus.lib
+ tkit-quarkus-rest-context
- io.quarkus
- quarkus-resteasy-reactive-jackson
+ org.tkit.quarkus.lib
+ tkit-quarkus-jpa
- io.quarkus
- quarkus-hibernate-orm
+ org.tkit.quarkus.lib
+ tkit-quarkus-jpa-tenant
- io.quarkus
- quarkus-smallrye-jwt
+ org.tkit.quarkus.lib
+ tkit-quarkus-log-cdi
- io.quarkus
- quarkus-smallrye-openapi
+ org.tkit.quarkus.lib
+ tkit-quarkus-log-rs
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-log-json
+
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-rest
+
+
+
io.quarkus
- quarkus-flyway
+ quarkus-arc
io.quarkus
- quarkus-rest-client-reactive
+ quarkus-liquibase
-
- org.tkit.quarkus.lib
- tkit-quarkus-rest
+ com.github.blagerweij
+ liquibase-sessionlock
- org.tkit.quarkus.lib
- tkit-quarkus-log-cdi
+ io.quarkus
+ quarkus-smallrye-health
- org.tkit.quarkus.lib
- tkit-quarkus-jpa
+ io.quarkus
+ quarkus-micrometer-registry-prometheus
- org.tkit.quarkus.lib
- tkit-quarkus-log-rs
+ io.quarkus
+ quarkus-hibernate-orm
-
- org.hibernate
- hibernate-jpamodelgen
- 5.5.6
+ io.quarkus
+ quarkus-resteasy-reactive
- org.mapstruct
- mapstruct
+ io.quarkus
+ quarkus-resteasy-reactive-jackson
- org.mapstruct
- mapstruct-processor
- 1.5.0.Final
- provided
+ io.quarkus
+ quarkus-jdbc-postgresql
- org.projectlombok
- lombok
+ io.quarkus
+ quarkus-smallrye-context-propagation
io.quarkus
- quarkus-smallrye-health
+ quarkus-smallrye-openapi
io.quarkus
quarkus-hibernate-validator
-
- org.tkit.quarkus.lib
- tkit-quarkus-test-db-import
-
- test
+ io.quarkus
+ quarkus-opentelemetry
+
+
+
+ org.projectlombok
+ lombok
+
+
+ org.mapstruct
+ mapstruct
+
+
+
io.quarkus
quarkus-junit5
test
- org.assertj
- assertj-core
+ io.quarkus
+ quarkus-junit5-mockito
test
-
io.rest-assured
rest-assured
test
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-test-db-import
+ test
+
+
@@ -188,26 +187,13 @@
gen.io.github.onecx.announcement.v1
gen.io.github.onecx.announcement.v1.model
DTOV1
+ V1Api
true
-
- ${quarkus.platform.group-id}
- quarkus-maven-plugin
- ${quarkus.platform.version}
- true
-
-
-
- build
- generate-code
- generate-code-tests
-
-
-
-
+
diff --git a/src/main/helm/Chart.yaml b/src/main/helm/Chart.yaml
index 199e6f2..c166e8d 100644
--- a/src/main/helm/Chart.yaml
+++ b/src/main/helm/Chart.yaml
@@ -1,4 +1,4 @@
-apiVersion: v1
+apiVersion: v2
name: onecx-announcement-svc
version: 0.0.0
appVersion: 0.0.0
diff --git a/src/main/helm/values.yaml b/src/main/helm/values.yaml
index 2b35993..1bc3fee 100644
--- a/src/main/helm/values.yaml
+++ b/src/main/helm/values.yaml
@@ -1,6 +1,5 @@
app:
image:
repository: "onecx/onecx-announcement-svc"
- tag: 999-SNAPSHOT
db:
enabled: true
\ No newline at end of file
diff --git a/src/main/java/io/github/onecx/announcement/domain/criteria/AnnouncementSearchCriteria.java b/src/main/java/io/github/onecx/announcement/domain/criteria/AnnouncementSearchCriteria.java
new file mode 100644
index 0000000..9527d84
--- /dev/null
+++ b/src/main/java/io/github/onecx/announcement/domain/criteria/AnnouncementSearchCriteria.java
@@ -0,0 +1,36 @@
+package io.github.onecx.announcement.domain.criteria;
+
+import java.time.OffsetDateTime;
+
+import jakarta.validation.Valid;
+
+import io.github.onecx.announcement.domain.models.Announcement;
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@RegisterForReflection
+public class AnnouncementSearchCriteria {
+
+ private Announcement.Type type;
+
+ private Announcement.Priority priority;
+
+ private Announcement.Status status;
+
+ private @Valid OffsetDateTime startDateFrom;
+
+ private @Valid OffsetDateTime startDateTo;
+
+ private @Valid OffsetDateTime endDateFrom;
+
+ private @Valid OffsetDateTime endDateTo;
+
+ private @Valid String appId;
+
+ private @Valid Integer pageNumber = 0;
+
+ private @Valid Integer pageSize = 100;
+}
diff --git a/src/main/java/io/github/onecx/announcement/domain/daos/AnnouncementDAO.java b/src/main/java/io/github/onecx/announcement/domain/daos/AnnouncementDAO.java
new file mode 100644
index 0000000..aa35b9f
--- /dev/null
+++ b/src/main/java/io/github/onecx/announcement/domain/daos/AnnouncementDAO.java
@@ -0,0 +1,115 @@
+package io.github.onecx.announcement.domain.daos;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.persistence.NoResultException;
+import jakarta.persistence.Tuple;
+import jakarta.persistence.criteria.*;
+
+import org.tkit.quarkus.jpa.daos.AbstractDAO;
+import org.tkit.quarkus.jpa.daos.Page;
+import org.tkit.quarkus.jpa.daos.PageResult;
+import org.tkit.quarkus.jpa.exceptions.DAOException;
+import org.tkit.quarkus.jpa.models.AbstractTraceableEntity_;
+import org.tkit.quarkus.jpa.models.TraceableEntity_;
+
+import io.github.onecx.announcement.domain.criteria.AnnouncementSearchCriteria;
+import io.github.onecx.announcement.domain.models.Announcement;
+import io.github.onecx.announcement.domain.models.Announcement_;
+import lombok.extern.slf4j.Slf4j;
+
+@ApplicationScoped
+@Slf4j
+public class AnnouncementDAO extends AbstractDAO {
+
+ // https://hibernate.atlassian.net/browse/HHH-16830#icft=HHH-16830
+ @Override
+ public Announcement findById(Object id) throws DAOException {
+ try {
+ var cb = this.getEntityManager().getCriteriaBuilder();
+ var cq = cb.createQuery(Announcement.class);
+ var root = cq.from(Announcement.class);
+ cq.where(cb.equal(root.get(TraceableEntity_.ID), id));
+ return this.getEntityManager().createQuery(cq).getSingleResult();
+ } catch (NoResultException nre) {
+ return null;
+ } catch (Exception e) {
+ throw new DAOException(ErrorKeys.FIND_ENTITY_BY_ID_FAILED, e, entityName, id);
+ }
+ }
+
+ public PageResult loadAnnouncementByCriteria(AnnouncementSearchCriteria criteria) {
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(Announcement.class);
+ Root root = cq.from(Announcement.class);
+ cq.select(root).distinct(true);
+
+ List predicates = new ArrayList<>();
+ if (criteria.getStatus() != null) {
+ predicates.add(root.get(Announcement_.STATUS).in(criteria.getStatus()));
+ }
+ if (criteria.getAppId() != null) {
+ predicates.add(cb.equal(root.get(Announcement_.APP_ID), criteria.getAppId()));
+ }
+ if (criteria.getStartDateFrom() != null) {
+ predicates.add(cb.greaterThanOrEqualTo(root.get(Announcement_.START_DATE),
+ criteria.getStartDateFrom().toLocalDateTime()));
+ }
+ if (criteria.getStartDateTo() != null) {
+ predicates.add(cb.lessThanOrEqualTo(root.get(Announcement_.START_DATE),
+ criteria.getStartDateTo().toLocalDateTime()));
+ }
+ if (criteria.getEndDateFrom() != null) {
+ predicates.add(cb.greaterThanOrEqualTo(root.get(Announcement_.END_DATE),
+ criteria.getEndDateFrom().toLocalDateTime()));
+ }
+ if (criteria.getEndDateTo() != null) {
+ predicates.add(
+ cb.lessThanOrEqualTo(root.get(Announcement_.END_DATE), criteria.getEndDateTo().toLocalDateTime()));
+ }
+ if (criteria.getPriority() != null) {
+ predicates.add(root.get(Announcement_.PRIORITY).in(criteria.getPriority()));
+
+ }
+ if (criteria.getType() != null) {
+ predicates.add(root.get(Announcement_.TYPE).in(criteria.getType()));
+
+ }
+ if (!predicates.isEmpty()) {
+ 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 List findApplicationsWithAnnouncements() {
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createTupleQuery();
+ Root root = cq.from(Announcement.class);
+ cq.multiselect(root.get(Announcement_.APP_ID));
+ cq.distinct(true);
+ List tupleResult = getEntityManager().createQuery(cq).getResultList();
+ return tupleResult.stream().map(t -> (String) t.get(0)).toList();
+ } catch (Exception ex) {
+ throw new DAOException(ErrorKeys.ERROR_FIND_APPLICATIONS_WITH_ANNOUNCEMENTS, ex);
+ }
+ }
+
+ public enum ErrorKeys {
+
+ FIND_ENTITY_BY_ID_FAILED,
+ ERROR_LOAD_ANNOUNCEMENT_BY_CRITERIA,
+ ERROR_FIND_APPLICATIONS_WITH_ANNOUNCEMENTS
+ }
+
+}
diff --git a/src/main/java/org/onecx/announcement/domain/models/Announcement.java b/src/main/java/io/github/onecx/announcement/domain/models/Announcement.java
similarity index 54%
rename from src/main/java/org/onecx/announcement/domain/models/Announcement.java
rename to src/main/java/io/github/onecx/announcement/domain/models/Announcement.java
index 6e11a43..b5889e8 100644
--- a/src/main/java/org/onecx/announcement/domain/models/Announcement.java
+++ b/src/main/java/io/github/onecx/announcement/domain/models/Announcement.java
@@ -1,4 +1,4 @@
-package org.onecx.announcement.domain.models;
+package io.github.onecx.announcement.domain.models;
import java.time.LocalDateTime;
@@ -8,11 +8,9 @@
import jakarta.persistence.Enumerated;
import jakarta.persistence.Table;
+import org.hibernate.annotations.TenantId;
import org.tkit.quarkus.jpa.models.TraceableEntity;
-import gen.io.github.onecx.announcement.rs.internal.model.AnnouncementPriorityTypeDTO;
-import gen.io.github.onecx.announcement.rs.internal.model.AnnouncementStatusDTO;
-import gen.io.github.onecx.announcement.rs.internal.model.AnnouncementTypeDTO;
import lombok.*;
@Getter
@@ -22,18 +20,52 @@
@SuppressWarnings("java:S2160")
public class Announcement extends TraceableEntity {
+ @TenantId
+ @Column(name = "TENANT_ID")
+ private String tenantId;
+
+ @Column(name = "title")
private String title;
+
+ @Column(name = "content")
private String content;
+
+ @Column(name = "type")
@Enumerated(EnumType.STRING)
- private AnnouncementTypeDTO type;
+ private Type type;
+
+ @Column(name = "priority")
@Enumerated(EnumType.STRING)
- private AnnouncementPriorityTypeDTO priority;
+ private Priority priority;
+
+ @Column(name = "status")
@Enumerated(EnumType.STRING)
- private AnnouncementStatusDTO status;
+ private Status status;
+
@Column(name = "startDate")
private LocalDateTime startDate;
+
@Column(name = "endDate")
private LocalDateTime endDate;
+
@Column(name = "appId")
private String appId;
+
+ public enum Type {
+ EVENT,
+ INFO,
+ SYSTEM_MAINTENANCE;
+ }
+
+ public enum Priority {
+ IMPORTANT,
+ NORMAL,
+ LOW;
+ }
+
+ public enum Status {
+ ACTIVE,
+ INACTIVE;
+ }
+
}
diff --git a/src/main/java/io/github/onecx/announcement/rs/internal/controller/AnnouncementControllerInternal.java b/src/main/java/io/github/onecx/announcement/rs/internal/controller/AnnouncementControllerInternal.java
new file mode 100644
index 0000000..dfb2fcc
--- /dev/null
+++ b/src/main/java/io/github/onecx/announcement/rs/internal/controller/AnnouncementControllerInternal.java
@@ -0,0 +1,92 @@
+package io.github.onecx.announcement.rs.internal.controller;
+
+import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.UriInfo;
+
+import org.jboss.resteasy.reactive.RestResponse;
+import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
+import org.tkit.quarkus.log.cdi.LogService;
+
+import gen.io.github.onecx.announcement.rs.internal.AnnouncementInternalApi;
+import gen.io.github.onecx.announcement.rs.internal.model.*;
+import io.github.onecx.announcement.domain.daos.AnnouncementDAO;
+import io.github.onecx.announcement.rs.internal.mapper.AnnouncementMapper;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@LogService
+@ApplicationScoped
+public class AnnouncementControllerInternal implements AnnouncementInternalApi {
+ @Inject
+ AnnouncementMapper mapper;
+ @Inject
+ AnnouncementDAO dao;
+
+ @Context
+ UriInfo uriInfo;
+
+ @Override
+ public Response createAnnouncement(CreateAnnouncementRequestDTO createAnnouncementRequestDTO) {
+ var item = mapper.create(createAnnouncementRequestDTO);
+ item = dao.create(item);
+ return Response
+ .created(uriInfo.getAbsolutePathBuilder().path(item.getId()).build())
+ .entity(mapper.map(item))
+ .build();
+ }
+
+ @Override
+ public Response deleteAnnouncementById(String id) {
+ dao.deleteQueryById(id);
+ return Response.noContent().build();
+ }
+
+ @Override
+
+ public Response getAllAppsWithAnnouncements() {
+ var items = dao.findApplicationsWithAnnouncements();
+ var results = mapper.map(items);
+ return Response.ok(results).build();
+ }
+
+ @Override
+ public Response getAnnouncementById(String id) {
+ var item = dao.findById(id);
+ if (item == null) {
+ return Response.status(NOT_FOUND).build();
+ }
+ return Response.ok(mapper.map(item)).build();
+ }
+
+ @Override
+ public Response getAnnouncements(AnnouncementSearchCriteriaDTO announcementSearchCriteriaDTO) {
+ var criteria = mapper.map(announcementSearchCriteriaDTO);
+ var page = dao.loadAnnouncementByCriteria(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);
+ if (item == null) {
+ return Response.status(NOT_FOUND).build();
+ }
+
+ mapper.update(item, updateAnnouncementRequestDTO);
+ item = dao.update(item);
+ return Response.ok(item).build();
+ }
+
+ @ServerExceptionMapper
+ public RestResponse constraint(ConstraintViolationException ex) {
+ return mapper.constraint(ex);
+ }
+
+}
diff --git a/src/main/java/io/github/onecx/announcement/rs/internal/log/InternalLogParam.java b/src/main/java/io/github/onecx/announcement/rs/internal/log/InternalLogParam.java
new file mode 100644
index 0000000..a4b73a2
--- /dev/null
+++ b/src/main/java/io/github/onecx/announcement/rs/internal/log/InternalLogParam.java
@@ -0,0 +1,34 @@
+package io.github.onecx.announcement.rs.internal.log;
+
+import java.util.List;
+
+import jakarta.enterprise.context.ApplicationScoped;
+
+import org.tkit.quarkus.log.cdi.LogParam;
+
+import gen.io.github.onecx.announcement.rs.internal.model.AnnouncementSearchCriteriaDTO;
+import gen.io.github.onecx.announcement.rs.internal.model.CreateAnnouncementRequestDTO;
+import gen.io.github.onecx.announcement.rs.internal.model.UpdateAnnouncementRequestDTO;
+
+@ApplicationScoped
+public class InternalLogParam implements LogParam {
+
+ @Override
+ public List- getClasses() {
+ return List.of(
+ item(10, CreateAnnouncementRequestDTO.class, x -> {
+ CreateAnnouncementRequestDTO d = (CreateAnnouncementRequestDTO) x;
+ return CreateAnnouncementRequestDTO.class.getSimpleName() + "[ appId:" + d.getAppId() + "]";
+ }),
+ item(10, UpdateAnnouncementRequestDTO.class, x -> {
+ UpdateAnnouncementRequestDTO d = (UpdateAnnouncementRequestDTO) x;
+ return UpdateAnnouncementRequestDTO.class.getSimpleName() + "[ appId:" + d.getAppId() + "]";
+ }),
+ item(10, AnnouncementSearchCriteriaDTO.class, x -> {
+ AnnouncementSearchCriteriaDTO d = (AnnouncementSearchCriteriaDTO) x;
+ return AnnouncementSearchCriteriaDTO.class.getSimpleName() + "[" + d.getPageNumber() + ","
+ + d.getPageSize()
+ + "]";
+ }));
+ }
+}
diff --git a/src/main/java/org/onecx/announcement/rs/internal/mapper/AnnouncementMapper.java b/src/main/java/io/github/onecx/announcement/rs/internal/mapper/AnnouncementMapper.java
similarity index 52%
rename from src/main/java/org/onecx/announcement/rs/internal/mapper/AnnouncementMapper.java
rename to src/main/java/io/github/onecx/announcement/rs/internal/mapper/AnnouncementMapper.java
index c56ed02..4d04a84 100644
--- a/src/main/java/org/onecx/announcement/rs/internal/mapper/AnnouncementMapper.java
+++ b/src/main/java/io/github/onecx/announcement/rs/internal/mapper/AnnouncementMapper.java
@@ -1,4 +1,4 @@
-package org.onecx.announcement.rs.internal.mapper;
+package io.github.onecx.announcement.rs.internal.mapper;
import java.util.List;
import java.util.Map;
@@ -13,17 +13,27 @@
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
-import org.onecx.announcement.domain.models.Announcement;
import org.tkit.quarkus.jpa.daos.PageResult;
-import org.tkit.quarkus.jpa.exceptions.ConstraintException;
import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper;
import gen.io.github.onecx.announcement.rs.internal.model.*;
-import gen.io.github.onecx.announcement.v1.model.AnnouncementDTOV1;
-import gen.io.github.onecx.announcement.v1.model.SearchAnnouncementRequestDTOV1;
+import io.github.onecx.announcement.domain.criteria.AnnouncementSearchCriteria;
+import io.github.onecx.announcement.domain.models.Announcement;
@Mapper(uses = OffsetDateTimeMapper.class)
-public abstract class AnnouncementMapper {
+public interface AnnouncementMapper {
+
+ default AnnouncementAppsDTO map(List appIds) {
+ if (appIds == null) {
+ return null;
+ }
+
+ AnnouncementAppsDTO dto = new AnnouncementAppsDTO();
+ dto.setAppIds(appIds);
+ return dto;
+ }
+
+ AnnouncementSearchCriteria map(AnnouncementSearchCriteriaDTO dto);
@Mapping(target = "id", ignore = true)
@Mapping(target = "controlTraceabilityManual", ignore = true)
@@ -33,22 +43,10 @@ public abstract class AnnouncementMapper {
@Mapping(target = "modificationDate", ignore = true)
@Mapping(target = "creationUser", ignore = true)
@Mapping(target = "modificationUser", ignore = true)
- public abstract Announcement create(CreateAnnouncementRequestDTO dto);
+ @Mapping(target = "tenantId", ignore = true)
+ Announcement create(CreateAnnouncementRequestDTO dto);
- public abstract SearchAnnouncementRequestDTOV1 mapCriteria(SearchAnnouncementRequestDTO searchAnnouncementRequestDTO);
-
- @Mapping(target = "version", ignore = true)
- public abstract AnnouncementDTO map(Announcement announcement);
-
- @Mapping(target = "id", ignore = true)
- @Mapping(target = "creationDate", ignore = true)
- @Mapping(target = "modificationDate", ignore = true)
- @Mapping(target = "creationUser", ignore = true)
- @Mapping(target = "modificationUser", ignore = true)
- @Mapping(target = "controlTraceabilityManual", ignore = true)
- @Mapping(target = "modificationCount", ignore = true)
- @Mapping(target = "persisted", ignore = true)
- public abstract Announcement update(@MappingTarget Announcement announcement, UpdateAnnouncementRequestDTO dto);
+ AnnouncementDTO map(Announcement announcement);
@Mapping(target = "id", ignore = true)
@Mapping(target = "creationDate", ignore = true)
@@ -58,31 +56,25 @@ public abstract class AnnouncementMapper {
@Mapping(target = "controlTraceabilityManual", ignore = true)
@Mapping(target = "modificationCount", ignore = true)
@Mapping(target = "persisted", ignore = true)
- public abstract Announcement map(AnnouncementDTOV1 dto);
+ @Mapping(target = "tenantId", ignore = true)
+ void update(@MappingTarget Announcement announcement, UpdateAnnouncementRequestDTO dto);
@Mapping(target = "removeStreamItem", ignore = true)
- // @Mapping(target = "stream.version", ignore = true)
- public abstract AnnouncementPageResultDTO mapToPageResult(PageResult announcementItemsPageResults);
+ AnnouncementPageResultDTO mapToPageResult(PageResult announcementItemsPageResults);
@Mapping(target = "params", ignore = true)
@Mapping(target = "removeParamsItem", ignore = true)
@Mapping(target = "invalidParams", ignore = true)
@Mapping(target = "removeInvalidParamsItem", ignore = true)
- public abstract ProblemDetailResponseDTO exception(String errorCode, String detail);
+ ProblemDetailResponseDTO exception(String errorCode, String detail);
- public RestResponse constraint(ConstraintViolationException ex) {
- var dto = exception("CONSTRAINT_VIOLATIONS", ex.getMessage());
+ default RestResponse constraint(ConstraintViolationException ex) {
+ var dto = exception(ErrorKeys.CONSTRAINT_VIOLATIONS.name(), ex.getMessage());
dto.setInvalidParams(createErrorValidationResponse(ex.getConstraintViolations()));
return RestResponse.status(Response.Status.BAD_REQUEST, dto);
}
- public RestResponse exception(ConstraintException ex) {
- var dto = exception(ex.getMessageKey().name(), ex.getConstraints());
- dto.setParams(map(ex.namedParameters));
- return RestResponse.status(Response.Status.BAD_REQUEST, dto);
- }
-
- public List map(Map params) {
+ default List map(Map params) {
if (params == null) {
return List.of();
}
@@ -96,14 +88,18 @@ public List map(Map params) {
}).toList();
}
- public abstract List createErrorValidationResponse(
+ List createErrorValidationResponse(
Set> constraintViolation);
@Mapping(target = "name", source = "propertyPath")
@Mapping(target = "message", source = "message")
- public abstract ProblemDetailInvalidParamDTO createError(ConstraintViolation> constraintViolation);
+ ProblemDetailInvalidParamDTO createError(ConstraintViolation> constraintViolation);
- public String mapPath(Path path) {
+ default String mapPath(Path path) {
return path.toString();
}
+
+ enum ErrorKeys {
+ CONSTRAINT_VIOLATIONS
+ }
}
diff --git a/src/main/java/io/github/onecx/announcement/rs/v1/controller/AnnouncementControllerV1.java b/src/main/java/io/github/onecx/announcement/rs/v1/controller/AnnouncementControllerV1.java
new file mode 100644
index 0000000..a3e830d
--- /dev/null
+++ b/src/main/java/io/github/onecx/announcement/rs/v1/controller/AnnouncementControllerV1.java
@@ -0,0 +1,40 @@
+package io.github.onecx.announcement.rs.v1.controller;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.ws.rs.core.Response;
+
+import org.jboss.resteasy.reactive.RestResponse;
+import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
+import org.tkit.quarkus.log.cdi.LogService;
+
+import gen.io.github.onecx.announcement.v1.AnnouncementV1Api;
+import gen.io.github.onecx.announcement.v1.model.AnnouncementSearchCriteriaDTOV1;
+import gen.io.github.onecx.announcement.v1.model.ProblemDetailResponseDTOV1;
+import io.github.onecx.announcement.domain.daos.AnnouncementDAO;
+import io.github.onecx.announcement.rs.v1.mapper.AnnouncementMapperV1;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@LogService
+@ApplicationScoped
+public class AnnouncementControllerV1 implements AnnouncementV1Api {
+
+ @Inject
+ AnnouncementMapperV1 mapper;
+ @Inject
+ AnnouncementDAO dao;
+
+ @Override
+ public Response getAnnouncementsByCriteria(AnnouncementSearchCriteriaDTOV1 announcementSearchCriteriaDTOV1) {
+ var criteria = mapper.map(announcementSearchCriteriaDTOV1);
+ var results = dao.loadAnnouncementByCriteria(criteria);
+ return Response.ok().entity(mapper.mapToPageResult(results)).build();
+ }
+
+ @ServerExceptionMapper
+ public RestResponse constraint(ConstraintViolationException ex) {
+ return mapper.constraint(ex);
+ }
+}
diff --git a/src/main/java/io/github/onecx/announcement/rs/v1/log/ExternalLogParamV1.java b/src/main/java/io/github/onecx/announcement/rs/v1/log/ExternalLogParamV1.java
new file mode 100644
index 0000000..5a7fc9c
--- /dev/null
+++ b/src/main/java/io/github/onecx/announcement/rs/v1/log/ExternalLogParamV1.java
@@ -0,0 +1,24 @@
+package io.github.onecx.announcement.rs.v1.log;
+
+import java.util.List;
+
+import jakarta.enterprise.context.ApplicationScoped;
+
+import org.tkit.quarkus.log.cdi.LogParam;
+
+import gen.io.github.onecx.announcement.v1.model.AnnouncementSearchCriteriaDTOV1;
+
+@ApplicationScoped
+public class ExternalLogParamV1 implements LogParam {
+
+ @Override
+ public List
- getClasses() {
+ return List.of(
+ item(10, AnnouncementSearchCriteriaDTOV1.class, x -> {
+ AnnouncementSearchCriteriaDTOV1 d = (AnnouncementSearchCriteriaDTOV1) x;
+ return AnnouncementSearchCriteriaDTOV1.class.getSimpleName() + "[" + d.getPageNumber() + ","
+ + d.getPageSize()
+ + "]";
+ }));
+ }
+}
diff --git a/src/main/java/io/github/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1.java b/src/main/java/io/github/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1.java
new file mode 100644
index 0000000..90aef56
--- /dev/null
+++ b/src/main/java/io/github/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1.java
@@ -0,0 +1,53 @@
+package io.github.onecx.announcement.rs.v1.mapper;
+
+import java.util.List;
+import java.util.Set;
+
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.validation.Path;
+import jakarta.ws.rs.core.Response;
+
+import org.jboss.resteasy.reactive.RestResponse;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.tkit.quarkus.jpa.daos.PageResult;
+import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper;
+
+import gen.io.github.onecx.announcement.v1.model.*;
+import io.github.onecx.announcement.domain.criteria.AnnouncementSearchCriteria;
+import io.github.onecx.announcement.domain.models.Announcement;
+
+@Mapper(uses = OffsetDateTimeMapper.class)
+public interface AnnouncementMapperV1 {
+
+ AnnouncementSearchCriteria map(AnnouncementSearchCriteriaDTOV1 dto);
+
+ AnnouncementDTOV1 map(Announcement data);
+
+ @Mapping(target = "removeStreamItem", ignore = true)
+ AnnouncementPageResultDTOV1 mapToPageResult(PageResult announcementItemsPageResults);
+
+ default RestResponse constraint(ConstraintViolationException ex) {
+ var dto = exception("CONSTRAINT_VIOLATIONS", ex.getMessage());
+ dto.setInvalidParams(createErrorValidationResponse(ex.getConstraintViolations()));
+ return RestResponse.status(Response.Status.BAD_REQUEST, dto);
+ }
+
+ List createErrorValidationResponse(
+ Set> constraintViolation);
+
+ @Mapping(target = "name", source = "propertyPath")
+ @Mapping(target = "message", source = "message")
+ public abstract ProblemDetailInvalidParamDTOV1 createError(ConstraintViolation> constraintViolation);
+
+ @Mapping(target = "invalidParams", ignore = true)
+ @Mapping(target = "removeInvalidParamsItem", ignore = true)
+ @Mapping(target = "removeParamsItem", ignore = true)
+ @Mapping(target = "params", ignore = true)
+ ProblemDetailResponseDTOV1 exception(String errorCode, String detail);
+
+ default String mapPath(Path path) {
+ return path.toString();
+ }
+}
diff --git a/src/main/java/org/onecx/announcement/domain/dao/AnnouncementDAO.java b/src/main/java/org/onecx/announcement/domain/dao/AnnouncementDAO.java
deleted file mode 100644
index a922065..0000000
--- a/src/main/java/org/onecx/announcement/domain/dao/AnnouncementDAO.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package org.onecx.announcement.domain.dao;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.persistence.Tuple;
-import jakarta.persistence.criteria.*;
-
-import org.onecx.announcement.domain.models.Announcement;
-import org.onecx.announcement.domain.models.Announcement_;
-import org.tkit.quarkus.jpa.daos.AbstractDAO;
-import org.tkit.quarkus.jpa.daos.Page;
-import org.tkit.quarkus.jpa.daos.PageResult;
-import org.tkit.quarkus.jpa.exceptions.DAOException;
-import org.tkit.quarkus.jpa.models.AbstractTraceableEntity_;
-
-import gen.io.github.onecx.announcement.v1.model.SearchAnnouncementRequestDTOV1;
-import lombok.extern.slf4j.Slf4j;
-
-@ApplicationScoped
-@Slf4j
-public class AnnouncementDAO extends AbstractDAO {
-
- public PageResult loadAnnouncementByCriteria(SearchAnnouncementRequestDTOV1 criteria) {
- try {
- CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
- CriteriaQuery cq = cb.createQuery(Announcement.class);
- Root root = cq.from(Announcement.class);
- cq.select(root).distinct(true);
-
- List predicates = new ArrayList<>();
- if (criteria != null) {
- if (criteria.getStatus() != null) {
- predicates.add(root.get(Announcement_.STATUS).in(criteria.getStatus()));
- }
- if (criteria.getAppId() != null) {
- Predicate predicateEqualAppId = cb.equal(root.get(Announcement_.APP_ID), criteria.getAppId());
- Predicate predicateIsNull = cb.isNull(root.get(Announcement_.APP_ID));
- predicates.add(cb.or(predicateEqualAppId, predicateIsNull));
- }
- if (criteria.getStartDateFrom() != null) {
- log.info("criteria.getStartDateFrom() : " + criteria.getStartDateFrom().toLocalDateTime());
- predicates.add(cb.greaterThanOrEqualTo(root.get(Announcement_.START_DATE),
- criteria.getStartDateFrom().toLocalDateTime()));
- }
- if (criteria.getStartDateTo() != null) {
- log.info("criteria.getStartDateTo() : " + criteria.getStartDateTo().toLocalDateTime());
- predicates.add(cb.lessThanOrEqualTo(root.get(Announcement_.START_DATE),
- criteria.getStartDateTo().toLocalDateTime()));
- }
- if (criteria.getEndDateFrom() != null) {
- predicates.add(cb.greaterThanOrEqualTo(root.get(Announcement_.END_DATE),
- criteria.getEndDateFrom().toLocalDateTime()));
- }
- if (criteria.getEndDateTo() != null) {
- predicates.add(
- cb.lessThanOrEqualTo(root.get(Announcement_.END_DATE), criteria.getEndDateTo().toLocalDateTime()));
- }
- if (criteria.getPriority() != null) {
- predicates.add(root.get(Announcement_.PRIORITY).in(criteria.getPriority()));
-
- }
- if (criteria.getType() != null) {
- predicates.add(root.get(Announcement_.TYPE).in(criteria.getType()));
-
- }
- if (criteria.getId() != null) {
- predicates.add(root.get(Announcement_.ID).in(criteria.getId()));
- }
- }
- if (!predicates.isEmpty()) {
- 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 List findApplicationsWithAnnouncements() {
- try {
- CriteriaBuilder cb = em.getCriteriaBuilder();
- CriteriaQuery cq = cb.createTupleQuery();
- Root root = cq.from(Announcement.class);
- cq.multiselect(root.get(Announcement_.APP_ID));
- cq.distinct(true);
- List tupleResult = em.createQuery(cq).getResultList();
- return tupleResult.stream().map(t -> (String) t.get(0)).toList();
- } catch (Exception ex) {
- throw new DAOException(ErrorKeys.ERROR_FIND_APPLICATIONS_WITH_ANNOUNCEMENTS, ex);
- }
- }
-
- public void deleteByAppId(String appId) {
- try {
- CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
- CriteriaDelete criteriaDelete = criteriaBuilder.createCriteriaDelete(Announcement.class);
- Root root = criteriaDelete.from(Announcement.class);
- criteriaDelete.where(criteriaBuilder.equal(root.get(Announcement_.APP_ID), appId));
- int rowsDeleted = em.createQuery(criteriaDelete).executeUpdate();
- log.info("Number of Announcements deleted: " + rowsDeleted);
- } catch (Exception ex) {
- throw new DAOException(ErrorKeys.ERROR_DELETE_BY_CRITERIA, ex);
- }
- }
-
- public enum ErrorKeys {
-
- ERROR_LOAD_ANNOUNCEMENT_BY_CRITERIA,
- ERROR_FIND_APPLICATIONS_WITH_ANNOUNCEMENTS,
- ERROR_DELETE_BY_CRITERIA
- }
-
-}
diff --git a/src/main/java/org/onecx/announcement/rs/internal/controller/ApplicationControllerInternal.java b/src/main/java/org/onecx/announcement/rs/internal/controller/ApplicationControllerInternal.java
deleted file mode 100644
index 2b1970b..0000000
--- a/src/main/java/org/onecx/announcement/rs/internal/controller/ApplicationControllerInternal.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.onecx.announcement.rs.internal.controller;
-
-import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
-import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
-
-import java.util.List;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.validation.ConstraintViolationException;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.UriInfo;
-
-import org.jboss.resteasy.reactive.RestResponse;
-import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
-import org.onecx.announcement.domain.dao.AnnouncementDAO;
-import org.onecx.announcement.domain.models.Announcement;
-import org.onecx.announcement.rs.internal.mapper.AnnouncementMapper;
-import org.onecx.announcement.rs.v1.controller.ErrorKeys;
-import org.tkit.quarkus.jpa.exceptions.ConstraintException;
-import org.tkit.quarkus.jpa.exceptions.DAOException;
-
-import gen.io.github.onecx.announcement.rs.internal.AnnouncementInternalApi;
-import gen.io.github.onecx.announcement.rs.internal.model.*;
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-@ApplicationScoped
-@Path("/internal/announcements")
-public class ApplicationControllerInternal implements AnnouncementInternalApi {
- @Inject
- AnnouncementMapper announcementMapper;
- @Inject
- AnnouncementDAO announcementDAO;
-
- @Context
- UriInfo uriInfo;
-
- @Override
- public Response addAnnouncement(CreateAnnouncementRequestDTO createAnnouncementRequestDTO) {
- Announcement announcementItem = announcementMapper.create(createAnnouncementRequestDTO);
- Announcement responseAnnouncementItem = announcementDAO.create(announcementItem);
- return Response
- .created(uriInfo.getAbsolutePathBuilder().path(responseAnnouncementItem.getId()).build())
- .entity(announcementMapper.map(responseAnnouncementItem))
- .build();
- }
-
- @Override
- public Response deleteAnnouncementById(String id) {
- try {
- Announcement announcement = announcementDAO.findById(id);
- if (announcement != null) {
- announcementDAO.deleteQueryById(id);
- return Response.noContent().build();
- }
- } catch (DAOException e) {
- e.printStackTrace();
- return Response.status(BAD_REQUEST)
- .entity(announcementMapper.exception(ErrorKeys.ERROR_DELETE_ANNOUNCEMENT_BY_CRITERIA.name(),
- "Failed to delete announcements. Error: " + e.getMessage()))
- .build();
- }
- return Response.status(NOT_FOUND).build();
- }
-
- @Override
-
- public Response getAllAppsWithAnnouncements() {
- List resultList = announcementDAO.findApplicationsWithAnnouncements();
- return Response.ok(resultList).build();
- }
-
- @Override
- public Response getAnnouncementById(String id) {
- Announcement fetchedAnnouncement = announcementDAO.findById(id);
- if (fetchedAnnouncement == null) {
- return Response.status(NOT_FOUND).build();
- }
- return Response.ok(announcementMapper.map(fetchedAnnouncement)).build();
- }
-
- @Override
- public Response getAnnouncements(SearchAnnouncementRequestDTO searchAnnouncementRequestDTO) {
- log.info("INSIDE SEARCH SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS");
- var results = announcementDAO.loadAnnouncementByCriteria(announcementMapper.mapCriteria(searchAnnouncementRequestDTO));
- if (results == null) {
- return Response.status(NOT_FOUND).build();
- }
- AnnouncementPageResultDTO announcementPageResultDTO = announcementMapper.mapToPageResult(results);
- return Response.ok().entity(announcementPageResultDTO).build();
- }
-
- @Override
- public Response updateAnnouncementById(String id, UpdateAnnouncementRequestDTO updateAnnouncementRequestDTO) {
- Announcement acItem = announcementDAO.findById(id);
- if (acItem != null) {
- announcementDAO.update(announcementMapper.update(acItem, updateAnnouncementRequestDTO));
- Announcement updatedAnnouncement = announcementDAO.findById(id);
- return Response.ok(updatedAnnouncement).build();
- }
- return Response.status(NOT_FOUND).build();
-
- }
-
- @ServerExceptionMapper
- public RestResponse exception(ConstraintException ex) {
- return announcementMapper.exception(ex);
- }
-
- @ServerExceptionMapper
- public RestResponse constraint(ConstraintViolationException ex) {
- return announcementMapper.constraint(ex);
- }
-}
diff --git a/src/main/java/org/onecx/announcement/rs/v1/controller/AnnouncementControllerV1.java b/src/main/java/org/onecx/announcement/rs/v1/controller/AnnouncementControllerV1.java
deleted file mode 100644
index 51c37d7..0000000
--- a/src/main/java/org/onecx/announcement/rs/v1/controller/AnnouncementControllerV1.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.onecx.announcement.rs.v1.controller;
-
-import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
-import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
-
-import jakarta.inject.Inject;
-import jakarta.transaction.Transactional;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-
-import org.eclipse.microprofile.openapi.annotations.tags.Tag;
-import org.onecx.announcement.domain.dao.AnnouncementDAO;
-import org.onecx.announcement.domain.models.Announcement;
-import org.onecx.announcement.rs.v1.mapper.AnnouncementMapperV1;
-import org.tkit.quarkus.jpa.exceptions.DAOException;
-
-import gen.io.github.onecx.announcement.v1.AnnouncementV1Api;
-import gen.io.github.onecx.announcement.v1.model.AnnouncementDTOV1;
-import gen.io.github.onecx.announcement.v1.model.AnnouncementPageResultDTOV1;
-import gen.io.github.onecx.announcement.v1.model.DeleteAnnouncementRequestDTOV1;
-import gen.io.github.onecx.announcement.v1.model.SearchAnnouncementRequestDTOV1;
-import lombok.extern.slf4j.Slf4j;
-
-@Path("/v1/applications")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-@Slf4j
-@Tag(name = "AnnouncementV1")
-public class AnnouncementControllerV1 implements AnnouncementV1Api {
-
- @Inject
- AnnouncementMapperV1 announcementMapper;
- @Inject
- AnnouncementDAO announcementDAO;
-
- @Override
- public Response getAnnouncementByIdV1(String id) {
- Announcement announcement = announcementDAO.findById(id);
- if (announcement == null) {
- return Response.status(NOT_FOUND).build();
- }
- AnnouncementDTOV1 announcementDto = announcementMapper.map(announcement);
- return Response.ok().entity(announcementDto).build();
- }
-
- @Override
- public Response getAnnouncementsByCriteriaV1(SearchAnnouncementRequestDTOV1 searchAnnouncementRequestDTOV1) {
- var results = announcementDAO.loadAnnouncementByCriteria(searchAnnouncementRequestDTOV1);
- if (results == null) {
- return Response.status(NOT_FOUND).build();
- }
- AnnouncementPageResultDTOV1 announcementPageResultDTOV1 = announcementMapper.mapToPageResult(results);
- return Response.ok().entity(announcementPageResultDTOV1).build();
- }
-
- @Override
- @Transactional
- public Response deleteAnnouncementByCriteriaV1(DeleteAnnouncementRequestDTOV1 deleteAnnouncementRequestDTOV1) {
- try {
- for (String appId : deleteAnnouncementRequestDTOV1.getAppIds()) {
- announcementDAO.deleteByAppId(appId);
- }
- return Response.noContent().build();
- } catch (DAOException e) {
- e.printStackTrace();
- return Response.status(BAD_REQUEST)
- .entity(announcementMapper.exception(ErrorKeys.ERROR_DELETE_ANNOUNCEMENT_BY_CRITERIA.name(),
- "Failed to delete announcements. Error: " + e.getMessage()))
- .build();
- }
- }
-}
diff --git a/src/main/java/org/onecx/announcement/rs/v1/controller/ErrorKeys.java b/src/main/java/org/onecx/announcement/rs/v1/controller/ErrorKeys.java
deleted file mode 100644
index f4932f1..0000000
--- a/src/main/java/org/onecx/announcement/rs/v1/controller/ErrorKeys.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.onecx.announcement.rs.v1.controller;
-
-public enum ErrorKeys {
- ERROR_DELETE_ANNOUNCEMENT_BY_CRITERIA
-}
diff --git a/src/main/java/org/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1.java b/src/main/java/org/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1.java
deleted file mode 100644
index d4d18bd..0000000
--- a/src/main/java/org/onecx/announcement/rs/v1/mapper/AnnouncementMapperV1.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.onecx.announcement.rs.v1.mapper;
-
-import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
-import org.onecx.announcement.domain.models.Announcement;
-import org.tkit.quarkus.jpa.daos.PageResult;
-import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper;
-
-import gen.io.github.onecx.announcement.v1.model.AnnouncementDTOV1;
-import gen.io.github.onecx.announcement.v1.model.AnnouncementPageResultDTOV1;
-import gen.io.github.onecx.announcement.v1.model.ProblemDetailResponseDTOV1;
-
-@Mapper(uses = OffsetDateTimeMapper.class)
-public interface AnnouncementMapperV1 {
-
- @Mapping(target = "id", ignore = true)
- @Mapping(target = "creationDate", ignore = true)
- @Mapping(target = "modificationDate", ignore = true)
- @Mapping(target = "creationUser", ignore = true)
- @Mapping(target = "modificationUser", ignore = true)
- @Mapping(target = "controlTraceabilityManual", ignore = true)
- @Mapping(target = "modificationCount", ignore = true)
- @Mapping(target = "persisted", ignore = true)
- Announcement map(AnnouncementDTOV1 dto);
-
- @Mapping(target = "version", ignore = true)
- AnnouncementDTOV1 map(Announcement data);
-
- @Mapping(target = "removeStreamItem", ignore = true)
- AnnouncementPageResultDTOV1 mapToPageResult(PageResult announcementItemsPageResults);
-
- @Mapping(target = "params", ignore = true)
- @Mapping(target = "removeParamsItem", ignore = true)
- @Mapping(target = "invalidParams", ignore = true)
- @Mapping(target = "removeInvalidParamsItem", ignore = true)
- ProblemDetailResponseDTOV1 exception(String errorCode, String detail);
-
-}
diff --git a/src/main/openapi/announcement-openapi-internal.yaml b/src/main/openapi/announcement-openapi-internal.yaml
index bb20a97..f2f57f3 100644
--- a/src/main/openapi/announcement-openapi-internal.yaml
+++ b/src/main/openapi/announcement-openapi-internal.yaml
@@ -3,7 +3,7 @@ info:
title: onecx-announcement-svc
version: "1.0"
servers:
- - url: https://localhost:8080
+ - url: https://onecx-announcement-svc:8080
tags:
- name: AnnouncementInternal
description: Execute Announcement CRUD operations
@@ -19,7 +19,7 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/SearchAnnouncementRequest'
+ $ref: '#/components/schemas/AnnouncementSearchCriteria'
responses:
"200":
description: OK
@@ -39,8 +39,8 @@ paths:
post:
tags:
- AnnouncementInternal
- summary: Add announcement
- operationId: addAnnouncement
+ summary: Create announcement
+ operationId: createAnnouncement
requestBody:
required: true
content:
@@ -78,8 +78,7 @@ paths:
content:
application/json:
schema:
- type: array
- items: {}
+ $ref: '#/components/schemas/AnnouncementApps'
/internal/announcements/{id}:
get:
tags:
@@ -125,6 +124,7 @@ paths:
schema:
type: string
requestBody:
+ required: true
content:
application/json:
schema:
@@ -144,8 +144,18 @@ paths:
$ref: '#/components/schemas/ProblemDetailResponse'
components:
schemas:
+ AnnouncementApps:
+ type: object
+ properties:
+ appIds:
+ type: array
+ items:
+ type: string
CreateAnnouncementRequest:
type: object
+ required:
+ - title
+ - content
properties:
title:
type: string
@@ -163,23 +173,9 @@ components:
$ref: '#/components/schemas/OffsetDateTime'
appId:
type: string
- SearchAnnouncementRequest:
+ AnnouncementSearchCriteria:
type: object
properties:
- creationDateFrom:
- $ref: '#/components/schemas/OffsetDateTime'
- creationDateTo:
- $ref: '#/components/schemas/OffsetDateTime'
- creationUser:
- type: string
- modificationDateFrom:
- $ref: '#/components/schemas/OffsetDateTime'
- modificationDateTo:
- $ref: '#/components/schemas/OffsetDateTime'
- modificationUser:
- type: string
- id:
- type: string
title:
type: string
content:
@@ -212,6 +208,9 @@ components:
type: integer
UpdateAnnouncementRequest:
type: object
+ required:
+ - title
+ - content
properties:
title:
type: string
@@ -232,7 +231,7 @@ components:
Announcement:
type: object
properties:
- version:
+ modificationCount:
format: int32
type: integer
creationDate:
diff --git a/src/main/openapi/announcement-openapi-v1.yaml b/src/main/openapi/announcement-openapi-v1.yaml
index daaa0f1..14aa91f 100644
--- a/src/main/openapi/announcement-openapi-v1.yaml
+++ b/src/main/openapi/announcement-openapi-v1.yaml
@@ -1,25 +1,25 @@
openapi: "3.0.3"
info:
- title: onecx-announcement-svc-v1
+ title: onecx-announcement
version: "1.0"
servers:
- - url: https://localhost:8080
+ - url: https://onecx-announcement-svc:8080
tags:
- - name: AnnouncementV1
+ - name: Announcement
description: Announcement Management v1 RS API
paths:
/v1/applications/announcements/search:
post:
tags:
- - AnnouncementV1
+ - Announcement
summary: Get announcements
- operationId: getAnnouncementsByCriteriaV1
+ operationId: getAnnouncementsByCriteria
requestBody:
required: true
content:
application/json:
schema:
- $ref: '#/components/schemas/SearchAnnouncementRequest'
+ $ref: '#/components/schemas/AnnouncementSearchCriteria'
responses:
"200":
description: OK
@@ -27,46 +27,6 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/AnnouncementPageResult'
- /v1/applications/announcements/{id}:
- get:
- tags:
- - AnnouncementV1
- summary: Retrieve announcement by Id
- operationId: getAnnouncementByIdV1
- parameters:
- - name: id
- in: path
- required: true
- schema:
- type: string
- responses:
- "200":
- description: OK
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Announcement'
- "404":
- description: Not Found
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ProblemDetailResponse'
- /v1/applications:
- delete:
- tags:
- - AnnouncementV1
- summary: Delete announcement
- operationId: deleteAnnouncementByCriteriaV1
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/DeleteAnnouncementRequest'
- responses:
- "204":
- description: No content
"400":
description: Bad request
content:
@@ -78,43 +38,14 @@ components:
Announcement:
type: object
properties:
- version:
- format: int32
- type: integer
- creationDate:
- format: date-time
- type: string
- example: 2022-03-10T12:15:50-04:00
- creationUser:
- type: string
- modificationDate:
- format: date-time
- type: string
- example: 2022-03-10T12:15:50-04:00
- modificationUser:
- type: string
- id:
- type: string
title:
type: string
- appId:
- type: string
content:
type: string
type:
- $ref: '#/components/schemas/AnnouncementType'
+ $ref: '#/components/schemas/Type'
priority:
- $ref: '#/components/schemas/AnnouncementPriorityType'
- status:
- $ref: '#/components/schemas/AnnouncementStatus'
- startDate:
- format: date-time
- type: string
- example: 2022-03-10T12:15:50-04:00
- endDate:
- format: date-time
- type: string
- example: 2022-03-10T12:15:50-04:00
+ $ref: '#/components/schemas/Priority'
AnnouncementPageResult:
description: PageResult for Announcements
type: object
@@ -135,33 +66,15 @@ components:
type: array
items:
$ref: '#/components/schemas/Announcement'
- SearchAnnouncementRequest:
+ AnnouncementSearchCriteria:
type: object
properties:
- creationDateFrom:
- $ref: '#/components/schemas/OffsetDateTime'
- creationDateTo:
- $ref: '#/components/schemas/OffsetDateTime'
- creationUser:
- type: string
- modificationDateFrom:
- $ref: '#/components/schemas/OffsetDateTime'
- modificationDateTo:
- $ref: '#/components/schemas/OffsetDateTime'
- modificationUser:
- type: string
- id:
- type: string
- title:
- type: string
- content:
- type: string
type:
- $ref: '#/components/schemas/AnnouncementType'
+ $ref: '#/components/schemas/Type'
priority:
- $ref: '#/components/schemas/AnnouncementPriorityType'
+ $ref: '#/components/schemas/Priority'
status:
- $ref: '#/components/schemas/AnnouncementStatus'
+ $ref: '#/components/schemas/Status'
startDateFrom:
$ref: '#/components/schemas/OffsetDateTime'
startDateTo:
@@ -182,25 +95,18 @@ components:
description: The size of page
default: 100
type: integer
- DeleteAnnouncementRequest:
- type: object
- properties:
- appIds:
- type: array
- items:
- type: string
- AnnouncementPriorityType:
+ Priority:
enum:
- IMPORTANT
- NORMAL
- LOW
type: string
- AnnouncementStatus:
+ Status:
enum:
- ACTIVE
- INACTIVE
type: string
- AnnouncementType:
+ Type:
enum:
- EVENT
- INFO
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 0d656ce..2a1bede 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,51 +1,47 @@
-# Configuration file
+# DEFAULT
quarkus.datasource.db-kind=postgresql
-quarkus.datasource.jdbc.max-size=8
-quarkus.datasource.jdbc.min-size=2
+quarkus.datasource.jdbc.max-size=30
+quarkus.datasource.jdbc.min-size=10
-quarkus.flyway.migrate-at-start=true
-quarkus.flyway.validate-on-migrate=true
quarkus.hibernate-orm.database.generation=validate
-quarkus.hibernate-orm.jdbc.timezone=UTC
-smallrye.jwt.path.groups=realm_access/roles
+quarkus.hibernate-orm.multitenant=DISCRIMINATOR
+quarkus.liquibase.migrate-at-start=true
+quarkus.liquibase.validate-on-migrate=true
-mp.jwt.verify.issuer=${RHSSO_HOST:https://secure-keycloak2-test.apps.openshift1.1000kit.net/auth/}admin/realms/${OAUTH_REALM:GigabitHub}
-mp.jwt.verify.publickey.location=${RHSSO_HOST:https://secure-keycloak2-test.apps.openshift1.1000kit.net/auth/}admin/realms/${OAUTH_REALM:GigabitHub}/protocol/openid-connect/certs
-quarkus.swagger-ui.enable=true
-quarkus.swagger-ui.always-include=true
-quarkus.smallrye-openapi.auto-add-server=false
-quarkus.jackson.write-dates-as-timestamps=true
+# enable or disable multi-tenancy support
+tkit.rs.context.tenant-id.enabled=true
# PROD
-%prod.quarkus.datasource.jdbc.url=${DB_URL:jdbc:postgresql://localhost:5432/ahm?sslmode=disable}
-%prod.quarkus.datasource.username=${DB_USER:ahm}
-%prod.quarkus.datasource.password=${DB_PWD:ahm}
+%prod.quarkus.datasource.jdbc.url=${DB_URL:jdbc:postgresql://postgresdb:5432/onecx-announcement?sslmode=disable}
+%prod.quarkus.datasource.username=${DB_USER:onecx-announcement}
+%prod.quarkus.datasource.password=${DB_PWD:onecx-announcement}
+
# DEV
-%dev.quarkus.http.port=9090
-%dev.mp.jwt.verify.issuer=http://keycloak-app/realms/OneCX
-%dev.mp.jwt.verify.publickey.location=http://keycloak-app/realms/OneCX/protocol/openid-connect/certs
-%dev.quarkus.tkit.log.console.json=false
-%dev.tkit.log.mdc=false
-%dev.tkit.log.rs.mdc=false
-%dev.tkit.log.rs.client.mdc=false
-%dev.quarkus.datasource.metrics.enabled=false
-%dev.quarkus.hibernate-orm.metrics.enabled=false
-%dev.quarkus.http.host=0.0.0.0
-%dev.quarkus.datasource.jdbc.url=${DB_URL:jdbc:postgresql://localhost:5432/ahm?sslmode=disable}
-%dev.quarkus.datasource.username=${DB_USER:ahm}
-%dev.quarkus.datasource.password=${DB_PWD:ahm}
-
-
-%test.mp.jwt.verify.publickey.location=META-INF/resources/test_publicKey.pem
-%test.mp.jwt.verify.issuer=https://quarkus.io/using-jwt-rbac
-%test.quarkus.tkit.log.console.json=false
-%test.tkit.log.json=true
-%test.tkit.log.mdc=false
-%test.tkit.log.rs.mdc=false
-%test.tkit.log.rs.client.mdc=false
-%test.quarkus.datasource.metrics.enabled=false
-%test.quarkus.hibernate-orm.metrics.enabled=false
-%test.quarkus.datasource.devservices.image-name=postgres:14.2
-quarkus.test.native-image-profile=test
+%dev.tkit.rs.context.tenant-id.enabled=true
+%dev.tkit.rs.context.tenant-id.mock.enabled=true
+%dev.tkit.rs.context.tenant-id.mock.default-tenant=test
+%dev.tkit.rs.context.tenant-id.mock.data.org1=tenant100
+
+# TEST
+%test.tkit.rs.context.tenant-id.enabled=true
+%test.tkit.rs.context.tenant-id.mock.enabled=true
+%test.tkit.rs.context.tenant-id.mock.default-tenant=default
+%test.tkit.rs.context.tenant-id.mock.claim-org-id=orgId
+%test.tkit.rs.context.tenant-id.mock.token-header-param=apm-principal-token
+%test.tkit.rs.context.tenant-id.mock.data.org1=tenant-100
+%test.tkit.rs.context.tenant-id.mock.data.org2=tenant-200
+
+# TEST-IT
+quarkus.test.integration-test-profile=test-it
+%test-it.tkit.log.json.enabled=false
+%test-it.tkit.rs.context.tenant-id.mock.enabled=true
+%test-it.tkit.rs.context.tenant-id.mock.default-tenant=default
+%test-it.tkit.rs.context.tenant-id.mock.claim-org-id=orgId
+%test-it.tkit.rs.context.tenant-id.mock.token-header-param=apm-principal-token
+%test-it.tkit.rs.context.tenant-id.mock.data.org1=tenant-100
+%test-it.tkit.rs.context.tenant-id.mock.data.org2=tenant-200
+
+# PIPE CONFIG
+
diff --git a/src/main/resources/db/changeLog.xml b/src/main/resources/db/changeLog.xml
new file mode 100644
index 0000000..235cb9c
--- /dev/null
+++ b/src/main/resources/db/changeLog.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V1.0.1__CreateTables.sql b/src/main/resources/db/migration/V1.0.1__CreateTables.sql
deleted file mode 100644
index 8679502..0000000
--- a/src/main/resources/db/migration/V1.0.1__CreateTables.sql
+++ /dev/null
@@ -1,19 +0,0 @@
- create table announcement (
- GUID varchar(255) not null,
- OPTLOCK int4 not null,
- creationDate timestamp,
- creationUser varchar(255),
- modificationDate timestamp,
- modificationUser varchar(255),
- appId varchar(255),
- content varchar(255),
- endDate timestamp,
- name varchar(255),
- priority varchar(255),
- startDate timestamp,
- status varchar(255),
- title varchar(255),
- type varchar(255),
- primary key (GUID)
- );
-
diff --git a/src/main/resources/db/v1/2023-12-11-create-tables.xml b/src/main/resources/db/v1/2023-12-11-create-tables.xml
new file mode 100644
index 0000000..e8be8a0
--- /dev/null
+++ b/src/main/resources/db/v1/2023-12-11-create-tables.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/io/github/onecx/announcement/domain/daos/AnnouncementDAOTest.java b/src/test/java/io/github/onecx/announcement/domain/daos/AnnouncementDAOTest.java
new file mode 100644
index 0000000..72a8f92
--- /dev/null
+++ b/src/test/java/io/github/onecx/announcement/domain/daos/AnnouncementDAOTest.java
@@ -0,0 +1,46 @@
+package io.github.onecx.announcement.domain.daos;
+
+import jakarta.inject.Inject;
+import jakarta.persistence.EntityManager;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.mockito.Mockito;
+import org.tkit.quarkus.jpa.exceptions.DAOException;
+
+import io.github.onecx.announcement.test.AbstractTest;
+import io.quarkus.test.InjectMock;
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+class AnnouncementDAOTest extends AbstractTest {
+
+ @Inject
+ AnnouncementDAO dao;
+
+ @InjectMock
+ EntityManager em;
+
+ @BeforeEach
+ void beforeAll() {
+ Mockito.when(em.getCriteriaBuilder()).thenThrow(new RuntimeException("Test technical error exception"));
+ }
+
+ @Test
+ void methodExceptionTests() {
+ methodExceptionTests(() -> dao.findById(null),
+ AnnouncementDAO.ErrorKeys.FIND_ENTITY_BY_ID_FAILED);
+ methodExceptionTests(() -> dao.findApplicationsWithAnnouncements(),
+ AnnouncementDAO.ErrorKeys.ERROR_FIND_APPLICATIONS_WITH_ANNOUNCEMENTS);
+ methodExceptionTests(() -> dao.loadAnnouncementByCriteria(null),
+ AnnouncementDAO.ErrorKeys.ERROR_LOAD_ANNOUNCEMENT_BY_CRITERIA);
+ }
+
+ void methodExceptionTests(Executable fn, Enum> key) {
+ var exc = Assertions.assertThrows(DAOException.class, fn);
+ Assertions.assertEquals(key, exc.key);
+ }
+
+}
diff --git a/src/test/java/io/github/onecx/announcement/rs/external/v1/AnnouncementControllerV1Test.java b/src/test/java/io/github/onecx/announcement/rs/external/v1/AnnouncementControllerV1Test.java
new file mode 100644
index 0000000..f6cb411
--- /dev/null
+++ b/src/test/java/io/github/onecx/announcement/rs/external/v1/AnnouncementControllerV1Test.java
@@ -0,0 +1,113 @@
+package io.github.onecx.announcement.rs.external.v1;
+
+import static io.restassured.RestAssured.given;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
+import static jakarta.ws.rs.core.Response.Status.OK;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.time.OffsetDateTime;
+
+import org.junit.jupiter.api.Test;
+import org.tkit.quarkus.test.WithDBData;
+
+import gen.io.github.onecx.announcement.v1.model.*;
+import io.github.onecx.announcement.rs.v1.controller.AnnouncementControllerV1;
+import io.github.onecx.announcement.test.AbstractTest;
+import io.quarkus.test.common.http.TestHTTPEndpoint;
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+@TestHTTPEndpoint(AnnouncementControllerV1.class)
+@WithDBData(value = "data/test-v1.xml", deleteBeforeInsert = true, deleteAfterTest = true, rinseAndRepeat = true)
+class AnnouncementControllerV1Test extends AbstractTest {
+
+ @Test
+ void getAnnouncementsByCriteriaAllTest() {
+ AnnouncementSearchCriteriaDTOV1 criteria = new AnnouncementSearchCriteriaDTOV1();
+
+ var data = given()
+ .contentType(APPLICATION_JSON)
+ .body(criteria)
+ .post()
+ .then()
+ .statusCode(OK.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .as(AnnouncementPageResultDTOV1.class);
+
+ assertThat(data).isNotNull();
+ assertThat(data.getTotalElements()).isEqualTo(5);
+ assertThat(data.getStream()).isNotNull().hasSize(5);
+ }
+
+ @Test
+ void getAnnouncementsByCriteriaTest() {
+ AnnouncementSearchCriteriaDTOV1 criteria = new AnnouncementSearchCriteriaDTOV1();
+ criteria.setAppId("app2");
+ criteria.status(StatusDTOV1.ACTIVE);
+ criteria.setPriority(PriorityDTOV1.NORMAL);
+ criteria.setType(TypeDTOV1.EVENT);
+ criteria.setStartDateFrom(OffsetDateTime.parse("2000-03-10T12:15:50-04:00"));
+ criteria.setStartDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
+ criteria.setEndDateFrom(OffsetDateTime.parse("2000-03-10T12:15:50-04:00"));
+ criteria.setEndDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
+
+ var data = given()
+ .contentType(APPLICATION_JSON)
+ .body(criteria)
+ .post()
+ .then()
+ .statusCode(OK.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .as(AnnouncementPageResultDTOV1.class);
+
+ assertThat(data).isNotNull();
+ assertThat(data.getTotalElements()).isEqualTo(2);
+ assertThat(data.getStream()).isNotNull().hasSize(2);
+ }
+
+ @Test
+ void getAnnouncementsByCriteriaNoBodyTest() {
+ var data = given()
+ .contentType(APPLICATION_JSON)
+ .post()
+ .then()
+ .statusCode(BAD_REQUEST.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .as(ProblemDetailResponseDTOV1.class);
+
+ assertThat(data).isNotNull();
+ assertThat(data.getDetail()).isEqualTo("getAnnouncementsByCriteria.announcementSearchCriteriaDTOV1: must not be null");
+ }
+
+ @Test
+ void getAnnouncementsByCriteriaOrg1Test() {
+ AnnouncementSearchCriteriaDTOV1 criteria = new AnnouncementSearchCriteriaDTOV1();
+ criteria.setAppId("app2");
+ criteria.status(StatusDTOV1.ACTIVE);
+ criteria.setPriority(PriorityDTOV1.NORMAL);
+ criteria.setType(TypeDTOV1.EVENT);
+ criteria.setStartDateFrom(OffsetDateTime.parse("2000-03-10T12:15:50-04:00"));
+ criteria.setStartDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
+ criteria.setEndDateFrom(OffsetDateTime.parse("2000-03-10T12:15:50-04:00"));
+ criteria.setEndDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
+
+ var data = given()
+ .header(APM_HEADER_PARAM, createToken("org1"))
+ .contentType(APPLICATION_JSON)
+ .body(criteria)
+ .post()
+ .then()
+ .statusCode(OK.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .as(AnnouncementPageResultDTOV1.class);
+
+ assertThat(data).isNotNull();
+ assertThat(data.getTotalElements()).isEqualTo(2);
+ assertThat(data.getStream()).isNotNull().hasSize(2);
+ }
+}
diff --git a/src/test/java/io/github/onecx/announcement/rs/external/v1/AnnouncementControllerV1TestIT.java b/src/test/java/io/github/onecx/announcement/rs/external/v1/AnnouncementControllerV1TestIT.java
new file mode 100644
index 0000000..696439b
--- /dev/null
+++ b/src/test/java/io/github/onecx/announcement/rs/external/v1/AnnouncementControllerV1TestIT.java
@@ -0,0 +1,7 @@
+package io.github.onecx.announcement.rs.external.v1;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class AnnouncementControllerV1TestIT extends AnnouncementControllerV1Test {
+}
diff --git a/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalExceptionTest.java b/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalExceptionTest.java
new file mode 100644
index 0000000..b1bcbd0
--- /dev/null
+++ b/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalExceptionTest.java
@@ -0,0 +1,49 @@
+package io.github.onecx.announcement.rs.internal;
+
+import static io.restassured.RestAssured.given;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.tkit.quarkus.jpa.exceptions.DAOException;
+
+import io.github.onecx.announcement.domain.daos.AnnouncementDAO;
+import io.github.onecx.announcement.rs.internal.controller.AnnouncementControllerInternal;
+import io.github.onecx.announcement.test.AbstractTest;
+import io.quarkus.test.InjectMock;
+import io.quarkus.test.common.http.TestHTTPEndpoint;
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+@TestHTTPEndpoint(AnnouncementControllerInternal.class)
+class AnnouncementControllerInternalExceptionTest extends AbstractTest {
+
+ @InjectMock
+ AnnouncementDAO dao;
+
+ @BeforeEach
+ void beforeAll() {
+ Mockito.when(dao.findApplicationsWithAnnouncements())
+ .thenThrow(new RuntimeException("Test technical error exception"))
+ .thenThrow(new DAOException(AnnouncementDAO.ErrorKeys.ERROR_FIND_APPLICATIONS_WITH_ANNOUNCEMENTS,
+ new RuntimeException("Test")));
+ }
+
+ @Test
+ void exceptionTest() {
+ given()
+ .contentType(APPLICATION_JSON)
+ .get("appIds")
+ .then()
+ .statusCode(INTERNAL_SERVER_ERROR.getStatusCode());
+
+ given()
+ .contentType(APPLICATION_JSON)
+ .get("appIds")
+ .then()
+ .statusCode(INTERNAL_SERVER_ERROR.getStatusCode());
+
+ }
+}
diff --git a/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalTest.java b/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalTest.java
new file mode 100644
index 0000000..a5dafc3
--- /dev/null
+++ b/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalTest.java
@@ -0,0 +1,262 @@
+package io.github.onecx.announcement.rs.internal;
+
+import static io.restassured.RestAssured.given;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.Response.Status.*;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.jboss.resteasy.reactive.RestResponse.Status.CREATED;
+
+import java.time.OffsetDateTime;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.tkit.quarkus.test.WithDBData;
+
+import gen.io.github.onecx.announcement.rs.internal.model.*;
+import io.github.onecx.announcement.rs.internal.controller.AnnouncementControllerInternal;
+import io.github.onecx.announcement.rs.internal.mapper.AnnouncementMapper;
+import io.github.onecx.announcement.test.AbstractTest;
+import io.quarkus.test.common.http.TestHTTPEndpoint;
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+@TestHTTPEndpoint(AnnouncementControllerInternal.class)
+@WithDBData(value = "data/test-internal.xml", deleteBeforeInsert = true, deleteAfterTest = true, rinseAndRepeat = true)
+class AnnouncementControllerInternalTest extends AbstractTest {
+
+ @Test
+ void getAnnouncementsByCriteriaAllTest() {
+ AnnouncementSearchCriteriaDTO criteria = new AnnouncementSearchCriteriaDTO();
+
+ var data = given()
+ .contentType(APPLICATION_JSON)
+ .body(criteria)
+ .post("search")
+ .then()
+ .statusCode(OK.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .as(AnnouncementPageResultDTO.class);
+
+ Assertions.assertThat(data).isNotNull();
+ Assertions.assertThat(data.getTotalElements()).isEqualTo(5);
+ Assertions.assertThat(data.getStream()).isNotNull().hasSize(5);
+ }
+
+ @Test
+ void getAnnouncementsByCriteriaTest() {
+ AnnouncementSearchCriteriaDTO criteria = new AnnouncementSearchCriteriaDTO();
+ criteria.setAppId("app2");
+ criteria.status(AnnouncementStatusDTO.ACTIVE);
+ criteria.setPriority(AnnouncementPriorityTypeDTO.NORMAL);
+ criteria.setType(AnnouncementTypeDTO.EVENT);
+ criteria.setStartDateFrom(OffsetDateTime.parse("2000-03-10T12:15:50-04:00"));
+ criteria.setStartDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
+ criteria.setEndDateFrom(OffsetDateTime.parse("2000-03-10T12:15:50-04:00"));
+ criteria.setEndDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
+
+ var data = given()
+ .contentType(APPLICATION_JSON)
+ .body(criteria)
+ .post("search")
+ .then()
+ .statusCode(OK.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .as(AnnouncementPageResultDTO.class);
+
+ Assertions.assertThat(data).isNotNull();
+ Assertions.assertThat(data.getTotalElements()).isEqualTo(2);
+ Assertions.assertThat(data.getStream()).isNotNull().hasSize(2);
+ }
+
+ @Test
+ void createAnnouncementTest() {
+
+ // create product
+ var createDto = new CreateAnnouncementRequestDTO();
+
+ createDto.setAppId("app0");
+ createDto.setContent("test01");
+ createDto.setTitle("basePath");
+
+ var dto = given()
+ .when()
+ .contentType(APPLICATION_JSON)
+ .body(createDto)
+ .post()
+ .then()
+ .statusCode(CREATED.getStatusCode())
+ .extract()
+ .body().as(AnnouncementDTO.class);
+
+ assertThat(dto).isNotNull();
+ assertThat(dto.getAppId()).isNotNull().isEqualTo(createDto.getAppId());
+ assertThat(dto.getTitle()).isNotNull().isEqualTo(createDto.getTitle());
+
+ // create theme without body
+ var exception = given()
+ .when()
+ .contentType(APPLICATION_JSON)
+ .post()
+ .then()
+ .statusCode(BAD_REQUEST.getStatusCode())
+ .extract().as(ProblemDetailResponseDTO.class);
+
+ assertThat(exception.getErrorCode()).isEqualTo(AnnouncementMapper.ErrorKeys.CONSTRAINT_VIOLATIONS.name());
+ assertThat(exception.getDetail()).isEqualTo("createAnnouncement.createAnnouncementRequestDTO: must not be null");
+
+ // create theme with existing name
+ dto = given().when()
+ .contentType(APPLICATION_JSON)
+ .body(createDto)
+ .post()
+ .then()
+ .statusCode(CREATED.getStatusCode())
+ .extract().as(AnnouncementDTO.class);
+
+ assertThat(dto).isNotNull();
+ assertThat(dto.getAppId()).isNotNull().isEqualTo(createDto.getAppId());
+ assertThat(dto.getTitle()).isNotNull().isEqualTo(createDto.getTitle());
+ }
+
+ @Test
+ void deleteAnnouncementTest() {
+ // delete
+ given()
+ .contentType(APPLICATION_JSON)
+ .delete("a1")
+ .then().statusCode(NO_CONTENT.getStatusCode());
+
+ // check if exists
+ given()
+ .contentType(APPLICATION_JSON)
+ .get("a1")
+ .then().statusCode(NOT_FOUND.getStatusCode());
+
+ // delete
+ given()
+ .contentType(APPLICATION_JSON)
+ .delete("a1")
+ .then()
+ .statusCode(NO_CONTENT.getStatusCode());
+ }
+
+ @Test
+ void getAnnouncementTest() {
+ var dto = given()
+ .contentType(APPLICATION_JSON)
+ .get("a2")
+ .then()
+ .statusCode(OK.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .body().as(AnnouncementDTO.class);
+
+ assertThat(dto).isNotNull();
+ assertThat(dto.getAppId()).isEqualTo("app2");
+ assertThat(dto.getTitle()).isEqualTo("title2");
+
+ given()
+ .contentType(APPLICATION_JSON)
+ .get("does-not-exists")
+ .then().statusCode(NOT_FOUND.getStatusCode());
+ }
+
+ @Test
+ void updateAnnouncementTest() {
+ var updateDto = new UpdateAnnouncementRequestDTO();
+ updateDto.setTitle("test01");
+ updateDto.setContent("0.0.0");
+
+ given()
+ .contentType(APPLICATION_JSON)
+ .body(updateDto)
+ .when()
+ .put("does-not-exists")
+ .then()
+ .statusCode(NOT_FOUND.getStatusCode());
+
+ given()
+ .contentType(APPLICATION_JSON)
+ .body(updateDto)
+ .when()
+ .put("a1")
+ .then().statusCode(OK.getStatusCode());
+
+ var dto = given().contentType(APPLICATION_JSON)
+ .body(updateDto)
+ .when()
+ .get("a1")
+ .then().statusCode(OK.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .body().as(AnnouncementDTO.class);
+
+ assertThat(dto).isNotNull();
+ assertThat(dto.getTitle()).isEqualTo(updateDto.getTitle());
+ }
+
+ @Test
+ void updateAnnouncementWithoutBodyTest() {
+
+ var exception = given()
+ .contentType(APPLICATION_JSON)
+ .when()
+ .put("update_create_new")
+ .then()
+ .statusCode(BAD_REQUEST.getStatusCode())
+ .extract().as(ProblemDetailResponseDTO.class);
+
+ assertThat(exception).isNotNull();
+ assertThat(exception.getErrorCode()).isEqualTo(AnnouncementMapper.ErrorKeys.CONSTRAINT_VIOLATIONS.name());
+ assertThat(exception.getDetail()).isEqualTo("updateAnnouncementById.updateAnnouncementRequestDTO: must not be null");
+ assertThat(exception.getInvalidParams()).isNotNull().asList().hasSize(1);
+
+ }
+
+ @Test
+ void getAllAnnouncementAppsTest() {
+ var dto = given()
+ .contentType(APPLICATION_JSON)
+ .get("appIds")
+ .then()
+ .statusCode(OK.getStatusCode())
+ .contentType(APPLICATION_JSON)
+ .extract()
+ .body().as(AnnouncementAppsDTO.class);
+
+ assertThat(dto).isNotNull();
+ assertThat(dto.getAppIds()).isNotNull().asList().hasSize(2);
+ }
+
+ @Test
+ void getAnnouncementsByCriteriaOrg200Test() {
+ AnnouncementSearchCriteriaDTO criteria = new AnnouncementSearchCriteriaDTO();
+ criteria.setAppId("app2");
+ criteria.status(AnnouncementStatusDTO.ACTIVE);
+ criteria.setPriority(AnnouncementPriorityTypeDTO.NORMAL);
+ criteria.setType(AnnouncementTypeDTO.EVENT);
+ criteria.setStartDateFrom(OffsetDateTime.parse("2000-03-10T12:15:50-04:00"));
+ criteria.setStartDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
+ criteria.setEndDateFrom(OffsetDateTime.parse("2000-03-10T12:15:50-04:00"));
+ criteria.setEndDateTo(OffsetDateTime.parse("2023-03-10T12:15:50-04:00"));
+
+ var data = given()
+ .contentType(APPLICATION_JSON)
+ .header(APM_HEADER_PARAM, createToken("org2"))
+ .body(criteria)
+ .post("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);
+ Assertions.assertThat(data.getStream().get(0)).isNotNull();
+ Assertions.assertThat(data.getStream().get(0).getId()).isEqualTo("a3-200");
+ }
+}
diff --git a/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalTestIT.java b/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalTestIT.java
new file mode 100644
index 0000000..08bb9e6
--- /dev/null
+++ b/src/test/java/io/github/onecx/announcement/rs/internal/AnnouncementControllerInternalTestIT.java
@@ -0,0 +1,8 @@
+package io.github.onecx.announcement.rs.internal;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class AnnouncementControllerInternalTestIT extends AnnouncementControllerInternalTest {
+
+}
diff --git a/src/test/java/io/github/onecx/announcement/test/AbstractTest.java b/src/test/java/io/github/onecx/announcement/test/AbstractTest.java
new file mode 100644
index 0000000..8aec6c2
--- /dev/null
+++ b/src/test/java/io/github/onecx/announcement/test/AbstractTest.java
@@ -0,0 +1,54 @@
+package io.github.onecx.announcement.test;
+
+import static com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS;
+import static io.restassured.RestAssured.config;
+import static io.restassured.config.ObjectMapperConfig.objectMapperConfig;
+
+import java.security.PrivateKey;
+
+import jakarta.json.Json;
+import jakarta.json.JsonObjectBuilder;
+
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.eclipse.microprofile.jwt.Claims;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import io.restassured.config.RestAssuredConfig;
+import io.smallrye.jwt.build.Jwt;
+import io.smallrye.jwt.util.KeyUtils;
+
+@SuppressWarnings("java:S2187")
+public abstract class AbstractTest {
+
+ protected static final String APM_HEADER_PARAM = ConfigProvider.getConfig()
+ .getValue("%test.tkit.rs.context.tenant-id.mock.token-header-param", String.class);
+ protected static final String CLAIMS_ORG_ID = ConfigProvider.getConfig()
+ .getValue("%test.tkit.rs.context.tenant-id.mock.claim-org-id", String.class);;
+
+ static {
+ config = RestAssuredConfig.config().objectMapperConfig(
+ objectMapperConfig().jackson2ObjectMapperFactory(
+ (cls, charset) -> {
+ var objectMapper = new ObjectMapper();
+ objectMapper.registerModule(new JavaTimeModule());
+ objectMapper.configure(WRITE_DATES_AS_TIMESTAMPS, false);
+ return objectMapper;
+ }));
+ }
+
+ protected static String createToken(String organizationId) {
+ try {
+ String userName = "test-user";
+ JsonObjectBuilder claims = Json.createObjectBuilder();
+ claims.add(Claims.preferred_username.name(), userName);
+ claims.add(Claims.sub.name(), userName);
+ claims.add(CLAIMS_ORG_ID, organizationId);
+ PrivateKey privateKey = KeyUtils.generateKeyPair(2048).getPrivate();
+ return Jwt.claims(claims.build()).sign(privateKey);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/src/test/java/org/onecx/announcement/rs/external/v1/AnnouncementExternalControllerTest.java b/src/test/java/org/onecx/announcement/rs/external/v1/AnnouncementExternalControllerTest.java
deleted file mode 100644
index cf0c425..0000000
--- a/src/test/java/org/onecx/announcement/rs/external/v1/AnnouncementExternalControllerTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package org.onecx.announcement.rs.external.v1;
-
-import static io.restassured.RestAssured.given;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.text.ParseException;
-import java.time.*;
-import java.util.ArrayList;
-import java.util.List;
-
-import jakarta.ws.rs.core.MediaType;
-
-import org.junit.jupiter.api.Test;
-import org.tkit.quarkus.test.WithDBData;
-
-import gen.io.github.onecx.announcement.v1.model.*;
-import io.quarkus.test.junit.QuarkusTest;
-
-@QuarkusTest
-class AnnouncementExternalControllerTest {
- String ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT = "/v1/applications";
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullySearchForOneResultWithId() throws ParseException {
- String fetchedId = "123";
- String creationUser = "Test User";
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .get(ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT + "/announcements/" + fetchedId)
- .prettyPeek();
-
- AnnouncementDTOV1 announcements = response.as(AnnouncementDTOV1.class);
- // then
- response.then().statusCode(200);
- assertThat(announcements.getId()).isEqualTo(fetchedId);
- assertThat(announcements.getCreationUser()).isEqualTo(creationUser);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullySearchForOneResultWithCriteriaV1() throws ParseException {
- String announcementId = "123";
- String creationUser = "Test User";
- OffsetDateTime startDateFrom = OffsetDateTime.parse("2009-12-30T14:55:00+00:00");
- OffsetDateTime startDateTo = OffsetDateTime.parse("2010-01-01T14:55:00+00:00");
-
- SearchAnnouncementRequestDTOV1 searchAnnouncementRequestDTOV1 = new SearchAnnouncementRequestDTOV1();
- searchAnnouncementRequestDTOV1.setStartDateFrom(startDateFrom);
- searchAnnouncementRequestDTOV1.setStartDateTo(startDateTo);
-
- searchAnnouncementRequestDTOV1.setType(AnnouncementTypeDTOV1.EVENT);
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(searchAnnouncementRequestDTOV1)
- .post(ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT + "/announcements/search/")
- .prettyPeek();
-
- AnnouncementPageResultDTOV1 announcements = response.as(AnnouncementPageResultDTOV1.class);
- // then
- response.then().statusCode(200);
- assertThat(announcements.getTotalElements()).isEqualTo(1);
- assertThat(announcements.getStream().get(0).getId()).isEqualTo(announcementId);
- assertThat(announcements.getStream().get(0).getCreationUser()).isEqualTo(creationUser);
- }
-
- @Test
- @WithDBData(value = "ahm-testdata.xml", deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyFetchAllAnnouncementsV1() throws ParseException {
- SearchAnnouncementRequestDTOV1 searchAnnouncementRequestDTOV1 = new SearchAnnouncementRequestDTOV1();
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(searchAnnouncementRequestDTOV1)
- .post(ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT + "/announcements/search")
- .prettyPeek();
-
- AnnouncementPageResultDTOV1 announcements = response.as(AnnouncementPageResultDTOV1.class);
- // then
- response.then().statusCode(200);
- assertThat(announcements.getTotalElements()).isEqualTo(500);
- }
-
- @Test
- @WithDBData(value = "ahm-testdata.xml", deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyFetchAnnouncementsWithPageSize10() throws ParseException {
- int pageSize = 10;
- int pageNumber = 7;
- SearchAnnouncementRequestDTOV1 searchAnnouncementRequestDTOV1 = new SearchAnnouncementRequestDTOV1();
- searchAnnouncementRequestDTOV1.setPageSize(pageSize);
- searchAnnouncementRequestDTOV1.setPageNumber(pageNumber);
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(searchAnnouncementRequestDTOV1)
- .post(ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT + "/announcements/search")
- .prettyPeek();
-
- AnnouncementPageResultDTOV1 announcements = response.as(AnnouncementPageResultDTOV1.class);
- // then
- response.then().statusCode(200);
- assertThat(announcements.getTotalElements()).isEqualTo(500);
- assertThat(announcements.getTotalPages()).isEqualTo(50);
- assertThat(announcements.getSize()).isEqualTo(pageSize);
- assertThat(announcements.getNumber()).isEqualTo(pageNumber);
- }
-
- @Test
- @WithDBData(value = "ahm-testdata.xml", deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyFetchAnnouncementsWithPageSize100() throws ParseException {
- int pageSize = 100;
- int pageNumber = 0;
- SearchAnnouncementRequestDTOV1 searchAnnouncementRequestDTOV1 = new SearchAnnouncementRequestDTOV1();
- searchAnnouncementRequestDTOV1.setPageSize(pageSize);
- searchAnnouncementRequestDTOV1.setPageNumber(pageNumber);
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(searchAnnouncementRequestDTOV1)
- .post(ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT + "/announcements/search")
- .prettyPeek();
-
- AnnouncementPageResultDTOV1 announcements = response.as(AnnouncementPageResultDTOV1.class);
- // then
- response.then().statusCode(200);
- assertThat(announcements.getTotalElements()).isEqualTo(500);
- assertThat(announcements.getTotalPages()).isEqualTo(5);
- assertThat(announcements.getSize()).isEqualTo(pageSize);
- assertThat(announcements.getNumber()).isEqualTo(pageNumber);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyFetchAnnouncementsWithPageSize200() throws ParseException {
- int pageSize = 200;
- int pageNumber = 1;
- SearchAnnouncementRequestDTOV1 searchAnnouncementRequestDTOV1 = new SearchAnnouncementRequestDTOV1();
- searchAnnouncementRequestDTOV1.setPageSize(pageSize);
- searchAnnouncementRequestDTOV1.setPageNumber(pageNumber);
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(searchAnnouncementRequestDTOV1)
- .post(ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT + "/announcements/search")
- .prettyPeek();
-
- AnnouncementPageResultDTOV1 announcements = response.as(AnnouncementPageResultDTOV1.class);
- // then
- response.then().statusCode(200);
- assertThat(announcements.getTotalElements()).isEqualTo(500);
- assertThat(announcements.getTotalPages()).isEqualTo(3);
- assertThat(announcements.getSize()).isEqualTo(pageSize);
- assertThat(announcements.getNumber()).isEqualTo(pageNumber);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyFetchAnnouncementsWithPageSize500() throws ParseException {
- int pageSize = 500;
- int pageNumber = 0;
- SearchAnnouncementRequestDTOV1 searchAnnouncementRequestDTOV1 = new SearchAnnouncementRequestDTOV1();
- searchAnnouncementRequestDTOV1.setPageSize(pageSize);
- searchAnnouncementRequestDTOV1.setPageNumber(pageNumber);
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(searchAnnouncementRequestDTOV1)
- .post(ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT + "/announcements/search")
- .prettyPeek();
-
- AnnouncementPageResultDTOV1 announcements = response.as(AnnouncementPageResultDTOV1.class);
- // then
- response.then().statusCode(200);
- assertThat(announcements.getTotalElements()).isEqualTo(500);
- assertThat(announcements.getTotalPages()).isEqualTo(1);
- assertThat(announcements.getSize()).isEqualTo(pageSize);
- assertThat(announcements.getNumber()).isEqualTo(pageNumber);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyDeleteAnnouncementsWithAppIds() throws ParseException {
- List appIds = new ArrayList<>();
- appIds.add("support-tool-ui");
- DeleteAnnouncementRequestDTOV1 deleteAnnouncementRequestDTOV1 = new DeleteAnnouncementRequestDTOV1();
- deleteAnnouncementRequestDTOV1.setAppIds(appIds);
-
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(deleteAnnouncementRequestDTOV1)
- .delete(ANNOUNCEMENT_CONTROLLER_V1_ENDPOINT)
- .prettyPeek();
-
- response.then().statusCode(204);
- }
-}
diff --git a/src/test/java/org/onecx/announcement/rs/external/v1/AnnouncementExternalControllerTestIT.java b/src/test/java/org/onecx/announcement/rs/external/v1/AnnouncementExternalControllerTestIT.java
deleted file mode 100644
index c534908..0000000
--- a/src/test/java/org/onecx/announcement/rs/external/v1/AnnouncementExternalControllerTestIT.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.onecx.announcement.rs.external.v1;
-
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-
-@QuarkusIntegrationTest
-public class AnnouncementExternalControllerTestIT extends AnnouncementExternalControllerTest {
-}
diff --git a/src/test/java/org/onecx/announcement/rs/internal/AnnouncementAPITest.java b/src/test/java/org/onecx/announcement/rs/internal/AnnouncementAPITest.java
deleted file mode 100644
index 756be07..0000000
--- a/src/test/java/org/onecx/announcement/rs/internal/AnnouncementAPITest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package org.onecx.announcement.rs.internal;
-
-import static io.restassured.RestAssured.given;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.text.ParseException;
-import java.time.*;
-
-import jakarta.ws.rs.core.MediaType;
-
-import org.junit.jupiter.api.Test;
-import org.tkit.quarkus.test.WithDBData;
-
-import gen.io.github.onecx.announcement.rs.internal.model.*;
-import io.quarkus.test.junit.QuarkusTest;
-import lombok.extern.slf4j.Slf4j;
-
-@QuarkusTest
-@Slf4j
-class AnnouncementAPITest {
- String ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT = "/internal/announcements";
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullySearchForOneResultWithCriteria() throws ParseException {
- String fetchedId = "123";
- SearchAnnouncementRequestDTO searchAnnouncementRequestDTO = new SearchAnnouncementRequestDTO();
- OffsetDateTime startDateFrom = OffsetDateTime.parse("2009-12-30T14:55:00+00:00");
- OffsetDateTime startDateTo = OffsetDateTime.parse("2010-01-01T14:55:00+00:00");
-
- searchAnnouncementRequestDTO.setStartDateFrom(startDateFrom);
- searchAnnouncementRequestDTO.setStartDateTo(startDateTo);
- searchAnnouncementRequestDTO.setType(AnnouncementTypeDTO.EVENT);
-
- // when
- var response = given()
- .when()
- .body(searchAnnouncementRequestDTO)
- .contentType(MediaType.APPLICATION_JSON)
- .post(ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT + "/search")
- .prettyPeek();
-
- AnnouncementPageResultDTO announcementPageResultDTO = response.as(AnnouncementPageResultDTO.class);
- // then
- response.then().statusCode(200);
- assertThat(announcementPageResultDTO.getTotalElements()).isEqualTo(1);
- assertThat(announcementPageResultDTO.getStream().get(0).getId()).isEqualTo(fetchedId);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyFetchAllAnnouncements() throws ParseException {
- // when
- SearchAnnouncementRequestDTO searchAnnouncementRequestDTO = new SearchAnnouncementRequestDTO();
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(searchAnnouncementRequestDTO)
- .post(ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT + "/search")
- .prettyPeek();
-
- AnnouncementPageResultDTO announcementPageResultDTO = response.as(AnnouncementPageResultDTO.class);
- // then
- response.then().statusCode(200);
- assertThat(announcementPageResultDTO.getTotalElements()).isEqualTo(500);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyDeleteAnnouncement() {
- String announcementId = "123";
- // when
- var deleteResponse = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .delete(ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT + '/' + announcementId)
- .prettyPeek();
-
- // then
- deleteResponse.then().statusCode(204);
-
- var getResponse = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .get(ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT + '/' + announcementId)
- .prettyPeek();
-
- // then
- getResponse.then().statusCode(404);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyFetchAnnouncementWithId() throws ParseException {
- String announcementId = "123";
- // when
- var response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .get(ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT + "/" + announcementId)
- .prettyPeek();
-
- AnnouncementDTO announcementDTO = response.as(AnnouncementDTO.class);
- // then
- response.then().statusCode(200);
- assertThat(announcementDTO.getId()).isEqualTo(announcementId);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldCorrectlyCreateAnnouncement() {
- CreateAnnouncementRequestDTO announcementCreateDTO = new CreateAnnouncementRequestDTO();
- String appId = "support-tool-ui";
- String content = "Some content of the announcement";
- String title = "Important Announcement";
- AnnouncementTypeDTO type = AnnouncementTypeDTO.INFO;
-
- announcementCreateDTO.setAppId(appId);
- announcementCreateDTO.setContent(content);
- announcementCreateDTO.setTitle(title);
- announcementCreateDTO.setType(type);
- // when
- var createResponse = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(announcementCreateDTO)
- .post(ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT)
- .prettyPeek();
-
- // then
- createResponse.then().statusCode(201);
- AnnouncementDTO announcementDTO = createResponse.as(AnnouncementDTO.class);
- assertThat(announcementDTO.getAppId()).isEqualTo(appId);
- assertThat(announcementDTO.getType()).isEqualTo(type);
- assertThat(announcementDTO.getTitle()).isEqualTo(title);
- }
-
- @Test
- @WithDBData(value = { "ahm-testdata.xml" }, deleteAfterTest = true, deleteBeforeInsert = true)
- void shouldSuccessfullyUpdateAnnouncement() throws ParseException {
- String announcementId = "123";
- UpdateAnnouncementRequestDTO updateAnnouncementRequestDTO = new UpdateAnnouncementRequestDTO();
- String appId = "ahm-ui";
-
- updateAnnouncementRequestDTO.setAppId(appId);
- updateAnnouncementRequestDTO.setPriority(AnnouncementPriorityTypeDTO.LOW);
- updateAnnouncementRequestDTO.setType(AnnouncementTypeDTO.INFO);
- // when
- var patchResponse = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .body(updateAnnouncementRequestDTO)
- .put(ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT + '/' + announcementId)
- .prettyPeek();
-
- // then
- patchResponse.then().statusCode(200);
-
- AnnouncementDTO response = given()
- .when()
- .contentType(MediaType.APPLICATION_JSON)
- .get(ANNOUNCEMENT_ITEM_INTERNAL_ENDPOINT + '/' + announcementId)
- .then()
- .statusCode(200)
- .extract().body().as(AnnouncementDTO.class);
-
- // then
- assertThat(response.getAppId()).isEqualTo(appId);
- assertThat(response.getPriority()).isEqualTo(AnnouncementPriorityTypeDTO.LOW);
- assertThat(response.getType()).isEqualTo(AnnouncementTypeDTO.INFO);
- }
-}
diff --git a/src/test/java/org/onecx/announcement/rs/internal/AnnouncementItemAPITestIT.java b/src/test/java/org/onecx/announcement/rs/internal/AnnouncementItemAPITestIT.java
deleted file mode 100644
index b689044..0000000
--- a/src/test/java/org/onecx/announcement/rs/internal/AnnouncementItemAPITestIT.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.onecx.announcement.rs.internal;
-
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-
-@QuarkusIntegrationTest
-public class AnnouncementItemAPITestIT extends AnnouncementAPITest {
-}
diff --git a/src/test/java/org/onecx/announcement/rs/test/AbstractTest.java b/src/test/java/org/onecx/announcement/rs/test/AbstractTest.java
deleted file mode 100644
index 609ffaa..0000000
--- a/src/test/java/org/onecx/announcement/rs/test/AbstractTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.onecx.announcement.rs.test;
-
-import static com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS;
-import static io.restassured.RestAssured.config;
-import static io.restassured.config.ObjectMapperConfig.objectMapperConfig;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-
-import io.restassured.config.RestAssuredConfig;
-
-@SuppressWarnings("java:S2187")
-public class AbstractTest {
-
- static {
- config = RestAssuredConfig.config().objectMapperConfig(
- objectMapperConfig().jackson2ObjectMapperFactory(
- (cls, charset) -> {
- var objectMapper = new ObjectMapper();
- objectMapper.registerModule(new JavaTimeModule());
- objectMapper.configure(WRITE_DATES_AS_TIMESTAMPS, false);
- return objectMapper;
- }));
- }
-}
diff --git a/src/test/resources/META-INF/resources/test_privateKey.pem b/src/test/resources/META-INF/resources/test_privateKey.pem
deleted file mode 100644
index 82e5e9b..0000000
--- a/src/test/resources/META-INF/resources/test_privateKey.pem
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
-PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H
-OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN
-qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh
-nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM
-uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6
-oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv
-6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY
-URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6
-96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB
-Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3
-zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF
-KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP
-iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B
-m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS
-34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG
-5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2
-tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL
-WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y
-b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09
-nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB
-MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d
-Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe
-Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt
-FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8
-f3cg+fr8aou7pr9SHhJlZCU=
------END PRIVATE KEY-----
\ No newline at end of file
diff --git a/src/test/resources/META-INF/resources/test_publicKey.pem b/src/test/resources/META-INF/resources/test_publicKey.pem
deleted file mode 100644
index 12a18c1..0000000
--- a/src/test/resources/META-INF/resources/test_publicKey.pem
+++ /dev/null
@@ -1,9 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
-Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
-TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
-UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
-AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
-sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
-nQIDAQAB
------END PUBLIC KEY-----
\ No newline at end of file
diff --git a/src/test/resources/META-INF/resources/test_tokens/admin_token.json b/src/test/resources/META-INF/resources/test_tokens/admin_token.json
deleted file mode 100644
index a50871d..0000000
--- a/src/test/resources/META-INF/resources/test_tokens/admin_token.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "jti": "e734f6c2-f1af-4e4d-b373-64d6b7f66655",
- "nbf": 0,
- "iss": "https://quarkus.io/using-jwt-rbac",
- "aud": "portal-launchpad-ui",
- "sub": "f586d429-3da2-40cf-94e2-de21276917f8",
- "typ": "Bearer",
- "azp": "portal-launchpad-ui",
- "auth_time": 0,
- "session_state": "e3307cd4-2f2e-4373-b754-7091dad3d6e8",
- "acr": "1",
- "allowed-origins": [
- "http://localhost:4500"
- ],
- "realm_access": {
- "roles": [
- "tkit-portal-admin"
- ]
- },
- "resource_access": {
- "realm-management": {
- "roles": [
- "view-realm",
- "view-identity-providers",
- "manage-identity-providers",
- "impersonation",
- "realm-admin",
- "create-client",
- "manage-users",
- "query-realms",
- "view-authorization",
- "query-clients",
- "query-users",
- "manage-events",
- "manage-realm",
- "view-events",
- "view-users",
- "view-clients",
- "manage-authorization",
- "manage-clients",
- "query-groups"
- ]
- },
- "account": {
- "roles": [
- "manage-account",
- "manage-account-links",
- "view-profile"
- ]
- }
- },
- "name": "Test Test",
- "preferred_username": "admin",
- "given_name": "TestGivenName",
- "family_name": "TestFamilyName"
-}
\ No newline at end of file
diff --git a/src/test/resources/META-INF/resources/test_tokens/non_admin_token.json b/src/test/resources/META-INF/resources/test_tokens/non_admin_token.json
deleted file mode 100644
index bd92787..0000000
--- a/src/test/resources/META-INF/resources/test_tokens/non_admin_token.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "jti": "e734f6c2-f1af-4e4d-b373-64d6b7f66655",
- "nbf": 0,
- "iss": "https://quarkus.io/using-jwt-rbac",
- "aud": "portal-launchpad-ui",
- "sub": "f586d429-3da2-40cf-94e2-de21276917f8",
- "typ": "Bearer",
- "azp": "portal-launchpad-ui",
- "auth_time": 0,
- "session_state": "e3307cd4-2f2e-4373-b754-7091dad3d6e8",
- "acr": "1",
- "allowed-origins": [
- "http://localhost:4500"
- ],
- "realm_access": {
- "roles": [
- "portal-user"
- ]
- },
- "resource_access": {
- "realm-management": {
- "roles": [
- "view-realm",
- "view-identity-providers",
- "manage-identity-providers",
- "impersonation",
- "realm-admin",
- "create-client",
- "manage-users",
- "query-realms",
- "view-authorization",
- "query-clients",
- "query-users",
- "manage-events",
- "manage-realm",
- "view-events",
- "view-users",
- "view-clients",
- "manage-authorization",
- "manage-clients",
- "query-groups"
- ]
- },
- "account": {
- "roles": [
- "manage-account",
- "manage-account-links",
- "view-profile"
- ]
- }
- },
- "name": "Test Test",
- "preferred_username": "1",
- "given_name": "TestGivenName",
- "family_name": "TestFamilyName"
-}
\ No newline at end of file
diff --git a/src/test/resources/data/test-internal.xml b/src/test/resources/data/test-internal.xml
new file mode 100644
index 0000000..4202405
--- /dev/null
+++ b/src/test/resources/data/test-internal.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/resources/data/test-v1.xml b/src/test/resources/data/test-v1.xml
new file mode 100644
index 0000000..bac8231
--- /dev/null
+++ b/src/test/resources/data/test-v1.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file