From c5ea265e0ff66ba33fc2effa69aafa35e40411ea Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Fri, 14 Nov 2025 14:19:36 +0200 Subject: [PATCH] Extract QL support in a top level module (#2808) Signed-off-by: Avgustin Marinov --- MIGRATION.md | 69 ------------------ .../resource/mapper/MgmtTargetMapper.java | 4 +- .../rest/resource/util/PagingUtility.java | 24 +++---- .../mgmt/rest/resource/util/SortUtility.java | 4 +- .../rest/resource/MgmtTargetResourceTest.java | 2 +- .../README.md | 0 .../pom.xml | 17 ++--- .../eclipse/hawkbit}/ql/EntityMatcher.java | 24 +++---- .../java/org/eclipse/hawkbit}/ql/Node.java | 2 +- .../eclipse/hawkbit/ql/QueryException.java | 44 ++++++++++++ .../org/eclipse/hawkbit/ql}/QueryField.java | 12 ++-- .../eclipse/hawkbit/ql/jpa}/QLSupport.java | 61 ++++++---------- .../hawkbit/ql/jpa}/SpecificationBuilder.java | 70 ++++++++++--------- .../hawkbit/ql/jpa}/utils/HibernateUtils.java | 2 +- .../eclipse/hawkbit/ql/jpa/utils/QlToSql.java | 18 ++--- .../eclipse/hawkbit/ql}/rsql/RsqlParser.java | 69 +++++++++--------- .../org/eclipse/hawkbit/ql/jpa}/Root.java | 2 +- .../hawkbit/ql/jpa}/RootRepository.java | 2 +- .../ql/jpa}/SpecificationBuilderTest.java | 17 ++--- .../java/org/eclipse/hawkbit/ql/jpa}/Sub.java | 2 +- .../hawkbit/ql/jpa}/SubRepository.java | 2 +- .../org/eclipse/hawkbit/ql/jpa}/SubSub.java | 2 +- .../hawkbit/ql/jpa}/SubSubRepository.java | 2 +- .../hawkbit-repository-api/pom.xml | 5 ++ .../repository/exception/QueryException.java | 41 ----------- .../RSQLParameterSyntaxException.java | 2 +- ...SQLParameterUnsupportedFieldException.java | 2 +- .../repository/qfields/ActionFields.java | 21 +++--- .../qfields/ActionStatusFields.java | 7 +- .../qfields/DistributionSetFields.java | 17 ++--- .../qfields/DistributionSetTagFields.java | 17 ++--- .../qfields/DistributionSetTypeFields.java | 7 +- .../repository/qfields/RolloutFields.java | 13 ++-- .../qfields/RolloutGroupFields.java | 7 +- .../qfields/SoftwareModuleFields.java | 15 ++-- .../qfields/SoftwareModuleTypeFields.java | 7 +- .../hawkbit/repository/qfields/TagFields.java | 7 +- .../repository/qfields/TargetFields.java | 27 +++---- .../qfields/TargetFilterQueryFields.java | 15 ++-- .../repository/qfields/TargetTagFields.java | 15 ++-- .../repository/qfields/TargetTypeFields.java | 7 +- .../repository/qfields/QueryFieldsTest.java | 1 + .../repository/jpa/utils/ExceptionMapper.java | 20 +++++- .../jpa/JpaRepositoryConfiguration.java | 23 +++--- .../repository/jpa/acm/AuthorityChecker.java | 10 +-- .../jpa/acm/DefaultAccessController.java | 4 +- .../AbstractJpaRepositoryManagement.java | 4 +- ...ctJpaRepositoryWithMetadataManagement.java | 6 +- .../management/JpaControllerManagement.java | 4 +- .../management/JpaDeploymentManagement.java | 4 +- .../JpaDistributionSetManagement.java | 6 +- .../management/JpaRolloutGroupManagement.java | 6 +- .../jpa/management/JpaRolloutManagement.java | 4 +- .../JpaTargetFilterQueryManagement.java | 11 +-- .../jpa/management/JpaTargetManagement.java | 4 +- .../JpaTenantConfigurationManagement.java | 6 +- .../{repository/jpa => ql}/rsql/NodeTest.java | 4 +- .../jpa => ql}/rsql/RsqlActionFieldsTest.java | 25 +++---- .../jpa => ql}/rsql/RsqlParserTest.java | 4 +- .../jpa => ql}/rsql/RsqlRolloutFieldTest.java | 7 +- .../rsql/RsqlRolloutGroupFieldTest.java | 10 +-- .../rsql/RsqlSoftwareModuleFieldTest.java | 6 +- .../RsqlSoftwareModuleTypeFieldsTest.java | 4 +- .../jpa => ql}/rsql/RsqlTagFieldsTest.java | 4 +- .../jpa => ql}/rsql/RsqlTargetFieldTest.java | 35 ++++++---- .../rsql/RsqlTargetFilterQueryFieldsTest.java | 4 +- .../jpa => ql}/rsql/RsqlToSqlTest.java | 32 +++++---- .../rsql/VirtualPropertyResolverTest.java | 4 +- .../management/DeploymentManagementTest.java | 2 +- hawkbit-repository/pom.xml | 1 - pom.xml | 1 + 71 files changed, 454 insertions(+), 485 deletions(-) delete mode 100644 MIGRATION.md rename {hawkbit-repository/hawkbit-repository-jpa-ql => hawkbit-ql-jpa}/README.md (100%) rename {hawkbit-repository/hawkbit-repository-jpa-ql => hawkbit-ql-jpa}/pom.xml (79%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa => hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit}/ql/EntityMatcher.java (93%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa => hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit}/ql/Node.java (99%) create mode 100644 hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/QueryException.java rename {hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields => hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql}/QueryField.java (90%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa}/QLSupport.java (84%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa}/SpecificationBuilder.java (90%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa}/utils/HibernateUtils.java (99%) rename hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HawkbitQlToSql.java => hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/utils/QlToSql.java (77%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa => hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql}/rsql/RsqlParser.java (77%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa}/Root.java (97%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa}/RootRepository.java (92%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa}/SpecificationBuilderTest.java (98%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa}/Sub.java (94%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa}/SubRepository.java (92%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa}/SubSub.java (94%) rename {hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql => hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa}/SubSubRepository.java (92%) delete mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/QueryException.java rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/NodeTest.java (93%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlActionFieldsTest.java (90%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlParserTest.java (97%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlRolloutFieldTest.java (95%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlRolloutGroupFieldTest.java (95%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlSoftwareModuleFieldTest.java (99%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlSoftwareModuleTypeFieldsTest.java (98%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlTagFieldsTest.java (99%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlTargetFieldTest.java (96%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlTargetFilterQueryFieldsTest.java (99%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/RsqlToSqlTest.java (79%) rename hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/{repository/jpa => ql}/rsql/VirtualPropertyResolverTest.java (98%) diff --git a/MIGRATION.md b/MIGRATION.md deleted file mode 100644 index e24922a61..000000000 --- a/MIGRATION.md +++ /dev/null @@ -1,69 +0,0 @@ -# hawkBit Migration Guides - -## Release 0.2 - -### Configuration Property changes - -- `hawkbit.server.controller._` have changed to `hawkbit.server.ddi._` -- `info.build._` have changed to `hawkbit.server.build._` -- `hawkbit.server.demo._` have changed to `hawkbit.server.ui.demo._` -- `hawkbit.server.email.support` has changed to `hawkbit.server.ui.links.support` -- `hawkbit.server.email.request.account` has changed to `hawkbit.server.ui.links.requestAccount` -- `hawkbit.server.im.login.url` has changed to `hawkbit.server.ui.links.userManagement` - -### REST API model changes for clients - -- ENTITYPagedList classes have been removed; generic `PagedList` used instead (e.g. `PagedList` instead - of `TargetPagedList`). -- ENTITYsrest classes have been removed; `List` used instead (e.g. `List` instead - of `TargetsRest`) - -### Renamed api annotations - -- Annotation `org.eclipse.hawkbit.rest.resource.EnableRestResources` has changed - to `org.eclipse.hawkbit.mgmt.annotation.EnableMgmtApi` -- Annotation `org.eclipse.hawkbit.ddi.resource.EnableDirectDeviceApi` has changed - to `org.eclipse.hawkbit.ddi.annotation.EnableDdiApi` - -### Renamed maven modules - -- Module `hawkbit-mgmt-api-client` has changed to `hawkbit-example-mgmt-simulator` - -## Milestone 0.3.0M6 - -### Configuration Property changes - -- `hawkbit.server.security.dos.maxTargetsPerManualAssignment` has changed - to `hawkbit.server.security.dos.maxTargetDistributionSetAssignmentsPerManualAssignment` - -## Milestone 0.3.0M7 - -### Configuration Property changes - -- Due to Spring Boot version upgrade ( - see [spring boot 2.2 deprecations](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes#deprecations-in-spring-boot-22)) `server.use-forward-headers` - has changed to `server.forward-headers-strategy` - -## Upgrade from Master Branch (after 0.3.0M6) to 0.3.0M7 - -Due to changes in the DB migration scripts within PR [#1017](https://github.com/eclipse-hawkbit/hawkbit/pull/1017) the -Hawkbit will not start up if one of the following cases is true: - -- DB2 database is used -- MSSQL database is used and the `sp_action` table is not empty -- PostgreSql database is used and the `sp_action` table is not empty - -The script was fixed with PR [#1061](https://github.com/eclipse-hawkbit/hawkbit/pull/1061). - -In case you upgrade from 0.3.0M6 to 0.3.0M7 there is no issue. But if you have built the Hawkbit from the master branch -between PR [#1017](https://github.com/eclipse-hawkbit/hawkbit/pull/1017) and -PR [#1061](https://github.com/eclipse-hawkbit/hawkbit/pull/1061), use PostgreSQL or MSSQL and upgrade to 0.3.0M7, it -will fail at startup with the message: `Validate failed: Migration checksum mismatch for migration version 1.12.16` - -This can be fixed by adapting the schema_version table of the database. The checksum field of the entry with the version -1.12.16 has to be changed (mind the minus): - -- -1684307461 for MSSQL -- -596342656 for PostgreSql - -Example for MSSQL: `UPDATE schema_version SET checksum=-1684307461 WHERE version='1.12.16'` diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/mapper/MgmtTargetMapper.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/mapper/MgmtTargetMapper.java index 6900b207a..9ce025de3 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/mapper/MgmtTargetMapper.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/mapper/MgmtTargetMapper.java @@ -88,7 +88,7 @@ public final class MgmtTargetMapper { .withRel(MgmtRestConstants.TARGET_V1_ATTRIBUTES).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionHistory(response.getControllerId(), null, 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, - ActionFields.ID.getJpaEntityFieldName() + ":" + SortDirection.DESC)) + ActionFields.ID.getName() + ":" + SortDirection.DESC)) .withRel(MgmtRestConstants.TARGET_V1_ACTIONS).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getMetadata(response.getControllerId())) .withRel("metadata").expand()); @@ -289,7 +289,7 @@ public final class MgmtTargetMapper { result.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionStatusList(controllerId, action.getId(), 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, - ActionStatusFields.ID.getJpaEntityFieldName() + ":" + SortDirection.DESC)) + ActionStatusFields.ID.getName() + ":" + SortDirection.DESC)) .withRel(MgmtRestConstants.TARGET_V1_ACTION_STATUS).expand()); final Rollout rollout = action.getRollout(); diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/util/PagingUtility.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/util/PagingUtility.java index a68a8f347..a145cd4ce 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/util/PagingUtility.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/util/PagingUtility.java @@ -38,7 +38,7 @@ public final class PagingUtility { public static Sort sanitizeTargetSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, TargetFields.CONTROLLERID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, TargetFields.CONTROLLERID.getName()); } return Sort.by(SortUtility.parse(TargetFields.class, sortParam)); } @@ -46,7 +46,7 @@ public final class PagingUtility { public static Sort sanitizeTargetTypeSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, TargetTypeFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, TargetTypeFields.ID.getName()); } return Sort.by(SortUtility.parse(TargetTypeFields.class, sortParam)); } @@ -54,7 +54,7 @@ public final class PagingUtility { public static Sort sanitizeTagSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, TagFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, TagFields.ID.getName()); } return Sort.by(SortUtility.parse(TagFields.class, sortParam)); } @@ -62,7 +62,7 @@ public final class PagingUtility { public static Sort sanitizeTargetFilterQuerySortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, TargetFilterQueryFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, TargetFilterQueryFields.ID.getName()); } return Sort.by(SortUtility.parse(TargetFilterQueryFields.class, sortParam)); } @@ -70,7 +70,7 @@ public final class PagingUtility { public static Sort sanitizeSoftwareModuleSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, SoftwareModuleFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, SoftwareModuleFields.ID.getName()); } return Sort.by(SortUtility.parse(SoftwareModuleFields.class, sortParam)); } @@ -78,7 +78,7 @@ public final class PagingUtility { public static Sort sanitizeSoftwareModuleTypeSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, SoftwareModuleTypeFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, SoftwareModuleTypeFields.ID.getName()); } return Sort.by(SortUtility.parse(SoftwareModuleTypeFields.class, sortParam)); } @@ -86,7 +86,7 @@ public final class PagingUtility { public static Sort sanitizeDistributionSetSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, DistributionSetFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, DistributionSetFields.ID.getName()); } return Sort.by(SortUtility.parse(DistributionSetFields.class, sortParam)); } @@ -94,7 +94,7 @@ public final class PagingUtility { public static Sort sanitizeDistributionSetTypeSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, DistributionSetTypeFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, DistributionSetTypeFields.ID.getName()); } return Sort.by(SortUtility.parse(DistributionSetTypeFields.class, sortParam)); } @@ -103,7 +103,7 @@ public final class PagingUtility { if (sortParam == null) { // default sort is DESC in case of action to match behavior // of management UI (last entry on top) - return Sort.by(Direction.DESC, ActionFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.DESC, ActionFields.ID.getName()); } return Sort.by(SortUtility.parse(ActionFields.class, sortParam)); } @@ -112,7 +112,7 @@ public final class PagingUtility { if (sortParam == null) { // default sort is DESC in case of action status to match behavior // of management UI (last entry on top) - return Sort.by(Direction.DESC, ActionStatusFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.DESC, ActionStatusFields.ID.getName()); } return Sort.by(SortUtility.parse(ActionStatusFields.class, sortParam)); } @@ -120,7 +120,7 @@ public final class PagingUtility { public static Sort sanitizeRolloutSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, RolloutFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, RolloutFields.ID.getName()); } return Sort.by(SortUtility.parse(RolloutFields.class, sortParam)); } @@ -128,7 +128,7 @@ public final class PagingUtility { public static Sort sanitizeRolloutGroupSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, RolloutGroupFields.ID.getJpaEntityFieldName()); + return Sort.by(Direction.ASC, RolloutGroupFields.ID.getName()); } return Sort.by(SortUtility.parse(RolloutGroupFields.class, sortParam)); } diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/util/SortUtility.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/util/SortUtility.java index 0083b2aaf..3325cc3e4 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/util/SortUtility.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/util/SortUtility.java @@ -18,7 +18,7 @@ import lombok.NoArgsConstructor; import org.eclipse.hawkbit.mgmt.rest.resource.exception.SortParameterSyntaxErrorException; import org.eclipse.hawkbit.mgmt.rest.resource.exception.SortParameterUnsupportedDirectionException; import org.eclipse.hawkbit.mgmt.rest.resource.exception.SortParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.qfields.QueryField; +import org.eclipse.hawkbit.ql.QueryField; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Order; @@ -79,7 +79,7 @@ public final class SortUtility { throw new SortParameterUnsupportedDirectionException(e); } - orders.add(new Order(sortDirection, identifier.getJpaEntityFieldName())); + orders.add(new Order(sortDirection, identifier.getName())); } else { throw new SortParameterSyntaxErrorException(); } diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index c5bf4b732..8f378c9c7 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -384,7 +384,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { assertThat(actions).hasSize(2); updateActionStatus(actions.get(0), Status.FINISHED, null, "test"); - final PageRequest pageRequest = PageRequest.of(0, 1000, Direction.ASC, ActionFields.ID.getJpaEntityFieldName()); + final PageRequest pageRequest = PageRequest.of(0, 1000, Direction.ASC, ActionFields.ID.getName()); final Action action = deploymentManagement.findActionsByTarget(knownTargetId, pageRequest).getContent().get(0); final ActionStatus status = deploymentManagement.findActionStatusByAction(action.getId(), PAGE).getContent() diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/README.md b/hawkbit-ql-jpa/README.md similarity index 100% rename from hawkbit-repository/hawkbit-repository-jpa-ql/README.md rename to hawkbit-ql-jpa/README.md diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/pom.xml b/hawkbit-ql-jpa/pom.xml similarity index 79% rename from hawkbit-repository/hawkbit-repository-jpa-ql/pom.xml rename to hawkbit-ql-jpa/pom.xml index f6dd52fb3..5c3a5a2fe 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/pom.xml +++ b/hawkbit-ql-jpa/pom.xml @@ -14,20 +14,14 @@ 4.0.0 org.eclipse.hawkbit - hawkbit-repository + hawkbit-parent ${revision} - hawkbit-repository-jpa-ql - hawkBit :: Query Language + hawkbit-ql-jpa + hawkBit :: Query Language :: JPA - - org.eclipse.hawkbit - hawkbit-repository-api - ${project.version} - - org.eclipse.persistence org.eclipse.persistence.jpa @@ -63,9 +57,8 @@ - org.eclipse.hawkbit - hawkbit-repository-test - ${project.version} + com.h2database + h2 test diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/EntityMatcher.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/EntityMatcher.java similarity index 93% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/EntityMatcher.java rename to hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/EntityMatcher.java index 369bda236..90b3cb7f3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/EntityMatcher.java +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/EntityMatcher.java @@ -7,18 +7,18 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.EQ; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.GT; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.GTE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.IN; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LIKE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LT; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LTE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NOT_IN; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NOT_LIKE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.EQ; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.GT; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.GTE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.IN; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LIKE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LT; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LTE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NOT_IN; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NOT_LIKE; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -30,7 +30,7 @@ import java.util.Map; import java.util.Objects; import java.util.function.BiPredicate; -import org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator; +import org.eclipse.hawkbit.ql.Node.Comparison.Operator; import org.springframework.core.ResolvableType; /** diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/Node.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/Node.java similarity index 99% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/Node.java rename to hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/Node.java index 673d6a0c3..74598c228 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/Node.java +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/Node.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql; import java.util.ArrayList; import java.util.List; diff --git a/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/QueryException.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/QueryException.java new file mode 100644 index 000000000..236660db5 --- /dev/null +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/QueryException.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.hawkbit.ql; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; + +/** + * Exception used by the REST API in case of RSQL search filter query. + */ +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class QueryException extends RuntimeException { + + public enum ErrorCode { + INVALID_SYNTAX, + UNSUPPORTED_FIELD, + GENERIC // an other + } + + @Getter + private final ErrorCode errorCode; + + public QueryException(final ErrorCode errorCode, final String message) { + this(errorCode, message, null); + } + + public QueryException(final ErrorCode errorCode, final Throwable cause) { + this(errorCode, null, cause); + } + + public QueryException(final ErrorCode errorCode, final String message, final Throwable cause) { + super(message, cause); + this.errorCode = errorCode; + } +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/QueryField.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/QueryField.java similarity index 90% rename from hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/QueryField.java rename to hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/QueryField.java index 482b4a2eb..5d8e8efc1 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/QueryField.java +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/QueryField.java @@ -7,13 +7,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.qfields; +package org.eclipse.hawkbit.ql; import java.util.Collections; import java.util.List; import java.util.Map; -import jakarta.validation.constraints.NotNull; +import lombok.NonNull; /** * A query field interface extended by all the fields that could be used in queries. @@ -27,10 +27,12 @@ public interface QueryField { String SUB_ATTRIBUTE_SPLIT_REGEX = "\\" + SUB_ATTRIBUTE_SEPARATOR; /** - * @return the string representation of the underlying persistence field name e.g. in case of sorting. + * Returns the entity field name, e.g. the JPA entity field name. + * + * @return the string representation of the underlying persistence field name. */ - @NotNull - String getJpaEntityFieldName(); + @NonNull + String getName(); /** * @return all sub entities attributes. diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/QLSupport.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/QLSupport.java similarity index 84% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/QLSupport.java rename to hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/QLSupport.java index b3ad040d2..967ed7a94 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/QLSupport.java +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/QLSupport.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; import java.util.ArrayList; import java.util.List; @@ -22,13 +22,11 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.text.StrLookup; -import org.eclipse.hawkbit.repository.qfields.QueryField; -import org.eclipse.hawkbit.repository.exception.QueryException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver; +import org.eclipse.hawkbit.ql.EntityMatcher; +import org.eclipse.hawkbit.ql.Node; +import org.eclipse.hawkbit.ql.Node.Comparison; +import org.eclipse.hawkbit.ql.QueryException; +import org.eclipse.hawkbit.ql.QueryField; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationListener; @@ -38,17 +36,16 @@ import org.springframework.core.annotation.Order; import org.springframework.data.jpa.domain.Specification; /** - * A utility class which is able to parse RSQL strings into an spring data - * {@link Specification} which then can be enhanced sql queries to filter - * entities. RSQL parser library: https://github.com/jirutka/rsql-parser + * A utility class which is able to parse RSQL strings into an spring data {@link Specification} which then can be enhanced sql queries to + * filter entities. It has out of the box support for the RSQL parser library: https://github.com/jirutka/rsql-parser * *
    - *
  • {@code Equal to : ==}
  • - *
  • {@code Not equal to : !=}
  • - *
  • {@code Less than : =lt= or <}
  • - *
  • {@code Less than or equal to : =le= or <=}
  • - *
  • {@code Greater than operator : =gt= or >}
  • - *
  • {@code Greater than or equal to : =ge= or >=}
  • + *
  • {@code Equal to: ==}
  • + *
  • {@code Not equal to: !=}
  • + *
  • {@code Less than: =lt= or <}
  • + *
  • {@code Less than or equal to: =le= or <=}
  • + *
  • {@code Greater than operator: =gt= or >}
  • + *
  • {@code Greater than or equal to: =ge= or >=}
  • *
*

* Examples of RSQL expressions in both FIQL-like and alternative notation: @@ -60,15 +57,12 @@ import org.springframework.data.jpa.domain.Specification; *

  • {@code name==targetId1 or description==plugAndPlay or updateStatus==UNKNOWN}
  • * *

    - * There is also a mechanism that allows to refer to known macros that can - * resolved by an optional {@link StrLookup} (cp. + * There is also a mechanism that allows to refer to known macros that can resolved by an optional {@link StrLookup} (cp. * {@link VirtualPropertyResolver}).
    - * An example that queries for all overdue targets using the ${OVERDUE_TS} - * placeholder introduced by {@link VirtualPropertyResolver} looks like - * this:
    + * An example that queries for all overdue targets using the ${OVERDUE_TS} placeholder introduced by {@link VirtualPropertyResolver} looks + * like this:
    * lastControllerRequestAt=le=${OVERDUE_TS}
    - * It is possible to escape a macro expression by using a second '$': - * $${OVERDUE_TS} would prevent the ${OVERDUE_TS} token from being expanded. + * It is possible to escape a macro expression by using a second '$': $${OVERDUE_TS} would prevent the ${OVERDUE_TS} token from being expanded. */ @Slf4j @Getter @@ -94,9 +88,8 @@ public class QLSupport implements ApplicationListener { private boolean caseInsensitiveDB; private QueryParser parser; - private List nodeTransformers; + private List nodeTransformers = List.of(); private EntityManager entityManager; - private VirtualPropertyResolver virtualPropertyResolver; /** * @return The holder singleton instance. @@ -106,7 +99,7 @@ public class QLSupport implements ApplicationListener { } @Autowired - void setQueryParser(final QueryParser parser) { + public void setQueryParser(final QueryParser parser) { this.parser = parser; } @@ -124,11 +117,6 @@ public class QLSupport implements ApplicationListener { this.entityManager = entityManager; } - @Autowired(required = false) - void setVirtualPropertyResolver(final VirtualPropertyResolver virtualPropertyResolver) { - this.virtualPropertyResolver = virtualPropertyResolver; - } - public Node parse(final String query) { return parse(query, null); } @@ -144,18 +132,15 @@ public class QLSupport implements ApplicationListener { * @param query the rsql query to be parsed * @param queryFieldType the enum class type which implements the {@link QueryField} * @return a specification which can be used with JPA - * @throws RSQLParameterUnsupportedFieldException if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong + * @throws QueryException if the RSQL syntax is wrong or if a field in the RSQL string is used but not provided by the given {@code queryFieldType} */ public & QueryField, T> Specification buildSpec(final String query, final Class queryFieldType) { return new SpecificationBuilder(ignoreCase && !caseInsensitiveDB) - .specification(transform(parse(query, queryFieldType), queryFieldType)); + .specification(transform(parse(query, queryFieldType), queryFieldType)); } public & QueryField, T> Specification buildSpec(final Node query, final Class queryFieldType) { - return new SpecificationBuilder(ignoreCase && !caseInsensitiveDB) - .specification(transform(query, queryFieldType)); + return new SpecificationBuilder(ignoreCase && !caseInsensitiveDB).specification(transform(query, queryFieldType)); } @SuppressWarnings("java:S1117") // it is again ignoreCase diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilder.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/SpecificationBuilder.java similarity index 90% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilder.java rename to hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/SpecificationBuilder.java index 972b21c87..888807316 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilder.java +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/SpecificationBuilder.java @@ -7,17 +7,19 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.GT; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.GTE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.IN; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LIKE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LT; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LTE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NOT_IN; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NOT_LIKE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.GT; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.GTE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.IN; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LIKE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LT; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LTE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NOT_IN; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NOT_LIKE; +import static org.eclipse.hawkbit.ql.QueryException.ErrorCode.INVALID_SYNTAX; +import static org.eclipse.hawkbit.ql.QueryException.ErrorCode.UNSUPPORTED_FIELD; import java.util.ArrayList; import java.util.Arrays; @@ -49,11 +51,11 @@ import jakarta.persistence.metamodel.SetAttribute; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison; -import org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator; -import org.eclipse.hawkbit.repository.jpa.ql.Node.Logical; +import org.eclipse.hawkbit.ql.Node; +import org.eclipse.hawkbit.ql.Node.Comparison; +import org.eclipse.hawkbit.ql.Node.Comparison.Operator; +import org.eclipse.hawkbit.ql.Node.Logical; +import org.eclipse.hawkbit.ql.QueryException; import org.springframework.data.jpa.domain.Specification; import org.springframework.util.ObjectUtils; @@ -129,14 +131,15 @@ public class SpecificationBuilder { } } - @SuppressWarnings({ "unchecked", "java:S3776" }) // java:S3776 - easier to read at one place + @SuppressWarnings("java:S3776") // java:S3776 - easier to read at one place private Predicate predicate(final Comparison comparison) { final String[] split = comparison.getKey().split("\\.", 2); // { attributeName [, sub attribute / map key] final Attribute attribute = root.getModel().getAttribute(split[0]); final Operator op = comparison.getOp(); if (attribute instanceof MapAttribute) { if (split.length < 2 || ObjectUtils.isEmpty(split[1])) { - throw new RSQLParameterUnsupportedFieldException( + throw new QueryException( + UNSUPPORTED_FIELD, String.format("No key for the map field found. Syntax is: %s.", getPathContext(comparison))); } if (comparison.getValue() == null) { @@ -144,7 +147,8 @@ public class SpecificationBuilder { return switch (op) { case EQ -> cb.isNull(toMapValuePath(pathResolver.getJoinOn(attribute, split[1]))); case NE -> cb.isNotNull(toMapValuePath(pathResolver.getJoinOn(attribute, split[1]))); - default -> throw new RSQLParameterSyntaxException( + default -> throw new QueryException( + INVALID_SYNTAX, String.format("Operator %s is not supported for map fields with value null", op)); }; } else { @@ -155,7 +159,8 @@ public class SpecificationBuilder { } } else if (attribute instanceof SetAttribute setAttribute) { if (split.length < 2 || ObjectUtils.isEmpty(split[1])) { - throw new RSQLParameterUnsupportedFieldException( + throw new QueryException( + UNSUPPORTED_FIELD, String.format("No mapping key for a set field found. Syntax is: %s.", getPathContext(comparison))); } if (isNot(op)) { @@ -243,24 +248,24 @@ public class SpecificationBuilder { : element) .toList(); if (values.isEmpty()) { - throw new RSQLParameterSyntaxException("RSQL values must not be empty", null); + throw new QueryException(INVALID_SYNTAX, "RSQL values must not be empty"); } else if (values.size() == 1) { final Operator op = comparison.getOp(); // enum, boolean or null - doesn't support >, >=, <, <= if (!(values.get(0) instanceof String)) { if (values.get(0) instanceof Number) { if (op == LIKE || op == NOT_LIKE) { - throw new RSQLParameterSyntaxException(op + " operator could not be applied number", null); + throw new QueryException(INVALID_SYNTAX, op + " operator could not be applied number"); } } else if (op == GT || op == GTE || op == LT || op == LTE || op == LIKE || op == NOT_LIKE) { final String errorMsg = values.get(0) == null ? "null value" : "enum or boolean field"; - throw new RSQLParameterSyntaxException(op + " operator could not be applied to " + errorMsg, null); + throw new QueryException(INVALID_SYNTAX, op + " operator could not be applied to " + errorMsg); } } } else { final Operator op = comparison.getOp(); if (op != IN && op != NOT_IN) { - throw new RSQLParameterSyntaxException(op + " operator shall have exactly one value", null); + throw new QueryException(INVALID_SYNTAX, op + " operator shall have exactly one value"); } } return values; @@ -276,9 +281,9 @@ public class SpecificationBuilder { if ("true".equals(value) || "false".equals(value)) { return Boolean.valueOf(value); } else { - throw new RSQLParameterSyntaxException( - String.format( - "The value of %S is not well formed. Only a boolean (true or false) value will be expected", + throw new QueryException( + INVALID_SYNTAX, + String.format("The value of %S is not well formed. Only a boolean (true or false) value will be expected", getPathContext(comparison))); } } @@ -307,14 +312,11 @@ public class SpecificationBuilder { } else { log.debug("Provided value '{}' cannot be transformed into the correct enum type {}", value.toUpperCase(), javaType, e); } - throw new RSQLParameterUnsupportedFieldException( - String.format( - "Value of %s must be one of the following: %s", + throw new QueryException( + UNSUPPORTED_FIELD, + String.format("Value of %s must be one of the following: %s", getPathContext(comparison), - Arrays.stream(tmpEnumType.getEnumConstants()) - .map(Enum::name) - .map(String::toLowerCase) - .toList()), + Arrays.stream(tmpEnumType.getEnumConstants()).map(Enum::name).map(String::toLowerCase).toList()), e); } } @@ -331,7 +333,7 @@ public class SpecificationBuilder { if (path instanceof Join join) { return deepGetPath(join.join(subAttributeName, JoinType.LEFT), subAttributeNameSplit, startIndex); } else { - throw new RSQLParameterSyntaxException("Unexpected sub attribute " + subAttributeName); + throw new QueryException(INVALID_SYNTAX, "Unexpected sub attribute " + subAttributeName); } } } diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HibernateUtils.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/utils/HibernateUtils.java similarity index 99% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HibernateUtils.java rename to hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/utils/HibernateUtils.java index cc3734491..4df2a3151 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HibernateUtils.java +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/utils/HibernateUtils.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql.utils; +package org.eclipse.hawkbit.ql.jpa.utils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HawkbitQlToSql.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/utils/QlToSql.java similarity index 77% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HawkbitQlToSql.java rename to hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/utils/QlToSql.java index 12fa56967..22f9e9566 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HawkbitQlToSql.java +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/jpa/utils/QlToSql.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql.utils; +package org.eclipse.hawkbit.ql.jpa.utils; import java.lang.reflect.InvocationTargetException; @@ -17,15 +17,16 @@ import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; -import org.eclipse.hawkbit.repository.qfields.QueryField; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport; +import org.eclipse.hawkbit.ql.QueryField; +import org.eclipse.hawkbit.ql.jpa.QLSupport; +import org.eclipse.hawkbit.ql.rsql.RsqlParser; -public class HawkbitQlToSql { +public class QlToSql { private final EntityManager entityManager; private final boolean isEclipselink; - public HawkbitQlToSql(final EntityManager entityManager) { + public QlToSql(final EntityManager entityManager) { this.entityManager = entityManager; isEclipselink = entityManager.getProperties().keySet().stream().anyMatch(key -> key.startsWith("eclipselink.")); } @@ -35,7 +36,7 @@ public class HawkbitQlToSql { final TypedQuery typedQuery = entityManager.createQuery(query); if (isEclipselink) { try { - return (String)Class.forName("org.eclipse.hawkbit.repository.jpa.EclipselinkUtils") + return (String) Class.forName("org.eclipse.hawkbit.repository.jpa.EclipselinkUtils") .getMethod("toSql", Query.class) .invoke(null, typedQuery); } catch (final IllegalAccessException | NoSuchMethodException | ClassNotFoundException e) { @@ -56,7 +57,8 @@ public class HawkbitQlToSql { final Class domainClass, final Class fieldsClass, final String rsql) { final CriteriaQuery query = entityManager.getCriteriaBuilder().createQuery(domainClass); final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); - return query.where(QLSupport.getInstance(). buildSpec(rsql, fieldsClass) - .toPredicate(query.from(domainClass), cb.createQuery(domainClass), cb)); + final QLSupport qlSupport = QLSupport.getInstance(); + qlSupport.setQueryParser(RsqlParser::parse); + return query.where(qlSupport. buildSpec(rsql, fieldsClass).toPredicate(query.from(domainClass), cb.createQuery(domainClass), cb)); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlParser.java b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/rsql/RsqlParser.java similarity index 77% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlParser.java rename to hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/rsql/RsqlParser.java index 33181f7ba..b18a0d803 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlParser.java +++ b/hawkbit-ql-jpa/src/main/java/org/eclipse/hawkbit/ql/rsql/RsqlParser.java @@ -7,20 +7,22 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; -import static org.eclipse.hawkbit.repository.qfields.QueryField.SUB_ATTRIBUTE_SEPARATOR; -import static org.eclipse.hawkbit.repository.qfields.QueryField.SUB_ATTRIBUTE_SPLIT_REGEX; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.EQ; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.GT; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.GTE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.IN; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LIKE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LT; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.LTE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NE; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NOT_IN; -import static org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator.NOT_LIKE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.EQ; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.GT; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.GTE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.IN; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LIKE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LT; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.LTE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NE; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NOT_IN; +import static org.eclipse.hawkbit.ql.Node.Comparison.Operator.NOT_LIKE; +import static org.eclipse.hawkbit.ql.QueryException.ErrorCode.INVALID_SYNTAX; +import static org.eclipse.hawkbit.ql.QueryException.ErrorCode.UNSUPPORTED_FIELD; +import static org.eclipse.hawkbit.ql.QueryField.SUB_ATTRIBUTE_SEPARATOR; +import static org.eclipse.hawkbit.ql.QueryField.SUB_ATTRIBUTE_SPLIT_REGEX; import java.util.HashSet; import java.util.List; @@ -39,11 +41,10 @@ import cz.jirutka.rsql.parser.ast.RSQLVisitor; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.repository.qfields.QueryField; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.jpa.ql.Node; -import org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison; +import org.eclipse.hawkbit.ql.Node; +import org.eclipse.hawkbit.ql.Node.Comparison; +import org.eclipse.hawkbit.ql.QueryException; +import org.eclipse.hawkbit.ql.QueryField; /** * {@link RsqlParser} parses RSQL query stings to {@link Node} objects. Doing that it does the following: @@ -85,11 +86,9 @@ public class RsqlParser { private static Node parse(final String rsql, final UnaryOperator keyResolver) { try { - return RSQL_PARSER - .parse(rsql) - .accept(new RsqlVisitor(keyResolver)); + return RSQL_PARSER.parse(rsql).accept(new RsqlVisitor(keyResolver)); } catch (final RSQLParserException e) { - throw new RSQLParameterSyntaxException(e); + throw new QueryException(INVALID_SYNTAX, e); } } @@ -103,27 +102,27 @@ public class RsqlParser { try { enumValue = Enum.valueOf(rsqlQueryFieldType, enumName); } catch (final IllegalArgumentException e) { - throw new RSQLParameterUnsupportedFieldException(e); + throw new QueryException(UNSUPPORTED_FIELD, e); } final String attribute; if (firstSeparatorIndex == -1) { // just field name without sub-attribute if (enumValue.getSubEntityAttributes().isEmpty()) { // no sub-attributes -> simple field - attribute = enumValue.getJpaEntityFieldName(); + attribute = enumValue.getName(); } else { // just enum name for a complex type (with sub-attributes), should have single (default!) sub-attribute if (enumValue.isMap()) { - throw new RSQLParameterUnsupportedFieldException("No key specified for a map type " + enumValue); + throw new QueryException(UNSUPPORTED_FIELD, "No key specified for a map type " + enumValue); } else { final String defaultSubEntityAttribute = enumValue.getDefaultSubEntityAttribute(); if (defaultSubEntityAttribute != null) { // single sub attribute - so, treat it as a default - attribute = enumValue.getJpaEntityFieldName() + SUB_ATTRIBUTE_SEPARATOR + defaultSubEntityAttribute; + attribute = enumValue.getName() + SUB_ATTRIBUTE_SEPARATOR + defaultSubEntityAttribute; } else { - throw new RSQLParameterUnsupportedFieldException( - String.format( - "The given search parameter field {%s} requires one of the following sub-attributes %s", + throw new QueryException( + UNSUPPORTED_FIELD, + String.format("The given search parameter field {%s} requires one of the following sub-attributes %s", key, enumValue.getSubEntityAttributes())); } } @@ -131,19 +130,19 @@ public class RsqlParser { } else { // field name with sub-attribute if (enumValue.isMap()) { // map, the part after the enum name is the key of the map - attribute = enumValue.getJpaEntityFieldName() + SUB_ATTRIBUTE_SEPARATOR + key.substring(firstSeparatorIndex + 1); + attribute = enumValue.getName() + SUB_ATTRIBUTE_SEPARATOR + key.substring(firstSeparatorIndex + 1); } else if (enumValue.getSubEntityAttributes().isEmpty()) { // simple type without sub-attributes, so the sub-attribute is not allowed - throw new RSQLParameterUnsupportedFieldException("Sub-attributes not supported for simple field " + enumValue); + throw new QueryException(UNSUPPORTED_FIELD, "Sub-attributes not supported for simple field " + enumValue); } else { final String[] subAttribute = key.substring(firstSeparatorIndex + 1).split(SUB_ATTRIBUTE_SPLIT_REGEX, 2); - attribute = enumValue.getJpaEntityFieldName() + SUB_ATTRIBUTE_SEPARATOR + enumValue.getSubEntityAttributes().stream() + attribute = enumValue.getName() + SUB_ATTRIBUTE_SEPARATOR + enumValue.getSubEntityAttributes().stream() .filter(attr -> attr.equalsIgnoreCase(subAttribute[0])) // case normalized .findFirst() .map(attr -> subAttribute.length == 1 ? attr : attr + key.substring(firstSeparatorIndex + 1 + attr.length())) - .orElseThrow(() -> new RSQLParameterUnsupportedFieldException( - String.format( - "The given search field {%s} has unsupported sub-attributes. Supported sub-attributes are %s", + .orElseThrow(() -> new QueryException( + UNSUPPORTED_FIELD, + String.format("The given search field {%s} has unsupported sub-attributes. Supported sub-attributes are %s", key, enumValue.getSubEntityAttributes()))); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Root.java b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/Root.java similarity index 97% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Root.java rename to hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/Root.java index 9d0d3f156..655c5cad8 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Root.java +++ b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/Root.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; import java.util.Map; import java.util.Set; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/RootRepository.java b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/RootRepository.java similarity index 92% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/RootRepository.java rename to hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/RootRepository.java index c4f994b59..d0eb17d48 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/RootRepository.java +++ b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/RootRepository.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderTest.java b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SpecificationBuilderTest.java similarity index 98% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderTest.java rename to hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SpecificationBuilderTest.java index 1ddd24e8e..0a02f4187 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderTest.java +++ b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SpecificationBuilderTest.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; import static org.assertj.core.api.Assertions.assertThat; @@ -19,8 +19,9 @@ import java.util.stream.StreamSupport; import jakarta.persistence.EntityManager; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.repository.jpa.ql.utils.HawkbitQlToSql; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParser; +import org.eclipse.hawkbit.ql.EntityMatcher; +import org.eclipse.hawkbit.ql.jpa.utils.QlToSql; +import org.eclipse.hawkbit.ql.rsql.RsqlParser; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; @@ -30,9 +31,7 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.data.jpa.domain.Specification; @SuppressWarnings("java:S5961") // complex check because the matter is very complex -@DataJpaTest(properties = { - "spring.jpa.database=H2" -}, excludeAutoConfiguration = { FlywayAutoConfiguration.class }) +@DataJpaTest(properties = { "spring.jpa.database=H2" }, excludeAutoConfiguration = { FlywayAutoConfiguration.class }) @EnableAutoConfiguration @Slf4j class SpecificationBuilderTest { @@ -494,10 +493,8 @@ class SpecificationBuilderTest { try { assertThat(result).containsExactlyInAnyOrder(refResult.toArray(Root[]::new)); } catch (final AssertionError e) { - log.error( - "Fail to get expected result for RSQL: {} with SQL query: {}", - rsql, new HawkbitQlToSql(entityManager).toSQL(Root.class, null, rsql), - e); + log.error("Fail to get expected result for RSQL: {} with SQL query: {}", + rsql, new QlToSql(entityManager).toSQL(Root.class, null, rsql), e); throw e; } return result; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Sub.java b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/Sub.java similarity index 94% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Sub.java rename to hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/Sub.java index 7bf12e49a..93759777f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Sub.java +++ b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/Sub.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubRepository.java b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubRepository.java similarity index 92% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubRepository.java rename to hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubRepository.java index d77bb2142..ffa8a9c52 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubRepository.java +++ b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubRepository.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSub.java b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubSub.java similarity index 94% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSub.java rename to hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubSub.java index 9eb9c9ef6..8752f3058 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSub.java +++ b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubSub.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSubRepository.java b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubSubRepository.java similarity index 92% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSubRepository.java rename to hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubSubRepository.java index f491b1570..b6e33f194 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSubRepository.java +++ b/hawkbit-ql-jpa/src/test/java/org/eclipse/hawkbit/ql/jpa/SubSubRepository.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.ql; +package org.eclipse.hawkbit.ql.jpa; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; diff --git a/hawkbit-repository/hawkbit-repository-api/pom.xml b/hawkbit-repository/hawkbit-repository-api/pom.xml index b38a9d713..17d66280b 100644 --- a/hawkbit-repository/hawkbit-repository-api/pom.xml +++ b/hawkbit-repository/hawkbit-repository-api/pom.xml @@ -22,6 +22,11 @@ hawkBit :: Repository :: API + + org.eclipse.hawkbit + hawkbit-ql-jpa + ${project.version} + org.eclipse.hawkbit hawkbit-artifact-api diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/QueryException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/QueryException.java deleted file mode 100644 index 0c6a66d53..000000000 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/QueryException.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.exception; - -import java.io.Serial; - -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.eclipse.hawkbit.exception.AbstractServerRtException; -import org.eclipse.hawkbit.exception.SpServerError; - -/** - * Exception used by the REST API in case of RSQL search filter query. - */ -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public abstract class QueryException extends AbstractServerRtException { - - QueryException(final SpServerError error) { - super(error); - } - - QueryException(final SpServerError error, final String message) { - super(error, message); - } - - QueryException(final SpServerError error, final Throwable cause) { - super(error, cause); - } - - QueryException(final SpServerError error, final String message, final Throwable cause) { - super(error, message, cause); - } -} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterSyntaxException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterSyntaxException.java index ae1f5bceb..a1b063b78 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterSyntaxException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterSyntaxException.java @@ -21,7 +21,7 @@ import org.eclipse.hawkbit.exception.SpServerError; */ @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class RSQLParameterSyntaxException extends QueryException { +public class RSQLParameterSyntaxException extends AbstractServerRtException { @Serial private static final long serialVersionUID = 1L; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterUnsupportedFieldException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterUnsupportedFieldException.java index 3bfc00697..020ed7734 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterUnsupportedFieldException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterUnsupportedFieldException.java @@ -21,7 +21,7 @@ import org.eclipse.hawkbit.exception.SpServerError; */ @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class RSQLParameterUnsupportedFieldException extends QueryException { +public class RSQLParameterUnsupportedFieldException extends AbstractServerRtException { @Serial private static final long serialVersionUID = 1L; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/ActionFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/ActionFields.java index 79c5bcb3b..cae8cd20e 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/ActionFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/ActionFields.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.qfields; import java.util.List; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Sort and search fields for actions. @@ -29,21 +30,21 @@ public enum ActionFields implements QueryField { LASTMODIFIEDBY("lastModifiedBy"), WEIGHT("weight"), TARGET("target", - TargetFields.ID.getJpaEntityFieldName(), TargetFields.NAME.getJpaEntityFieldName(), - TargetFields.UPDATESTATUS.getJpaEntityFieldName(), TargetFields.IPADDRESS.getJpaEntityFieldName()), + TargetFields.ID.getName(), TargetFields.NAME.getName(), + TargetFields.UPDATESTATUS.getName(), TargetFields.IPADDRESS.getName()), DISTRIBUTIONSET("distributionSet", - DistributionSetFields.ID.getJpaEntityFieldName(), - DistributionSetFields.NAME.getJpaEntityFieldName(), DistributionSetFields.VERSION.getJpaEntityFieldName(), - DistributionSetFields.TYPE.getJpaEntityFieldName()), - ROLLOUT("rollout", RolloutFields.ID.getJpaEntityFieldName(), RolloutFields.NAME.getJpaEntityFieldName()), - ROLLOUTGROUP("rolloutGroup", RolloutGroupFields.ID.getJpaEntityFieldName(), RolloutGroupFields.NAME.getJpaEntityFieldName()), + DistributionSetFields.ID.getName(), + DistributionSetFields.NAME.getName(), DistributionSetFields.VERSION.getName(), + DistributionSetFields.TYPE.getName()), + ROLLOUT("rollout", RolloutFields.ID.getName(), RolloutFields.NAME.getName()), + ROLLOUTGROUP("rolloutGroup", RolloutGroupFields.ID.getName(), RolloutGroupFields.NAME.getName()), EXTERNALREF("externalRef"); - private final String jpaEntityFieldName; + private final String name; private final List subEntityAttributes; - ActionFields(final String jpaEntityFieldName, final String... subEntityAttributes) { - this.jpaEntityFieldName = jpaEntityFieldName; + ActionFields(final String name, final String... subEntityAttributes) { + this.name = name; this.subEntityAttributes = List.of(subEntityAttributes); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/ActionStatusFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/ActionStatusFields.java index 4eec520b6..a277ebcf6 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/ActionStatusFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/ActionStatusFields.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.qfields; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Sort and search fields for action status. @@ -25,9 +26,9 @@ public enum ActionStatusFields implements QueryField { CREATEDAT("createdAt"), // same as REPORTEDAT CREATEDBY("createdBy"); - private final String jpaEntityFieldName; + private final String name; - ActionStatusFields(final String jpaEntityFieldName) { - this.jpaEntityFieldName = jpaEntityFieldName; + ActionStatusFields(final String name) { + this.name = name; } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetFields.java index 4c343142a..74929f566 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetFields.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.qfields; import java.util.List; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the DistributionSet model which can be used in the @@ -22,9 +23,9 @@ public enum DistributionSetFields implements QueryField { ID("id"), TYPE("type", - DistributionSetTypeFields.ID.getJpaEntityFieldName(), - DistributionSetTypeFields.KEY.getJpaEntityFieldName(), - DistributionSetTypeFields.NAME.getJpaEntityFieldName()), + DistributionSetTypeFields.ID.getName(), + DistributionSetTypeFields.KEY.getName(), + DistributionSetTypeFields.NAME.getName()), NAME("name"), DESCRIPTION("description"), CREATEDAT("createdAt"), @@ -32,22 +33,22 @@ public enum DistributionSetFields implements QueryField { LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"), VERSION("version"), - MODULE("modules", SoftwareModuleFields.ID.getJpaEntityFieldName(), SoftwareModuleFields.NAME.getJpaEntityFieldName()), + MODULE("modules", SoftwareModuleFields.ID.getName(), SoftwareModuleFields.NAME.getName()), TAG("tags", "name"), METADATA("metadata"), VALID("valid"); - private final String jpaEntityFieldName; + private final String name; private final List subEntityAttributes; - DistributionSetFields(final String jpaEntityFieldName, final String... subEntityAttributes) { - this.jpaEntityFieldName = jpaEntityFieldName; + DistributionSetFields(final String name, final String... subEntityAttributes) { + this.name = name; this.subEntityAttributes = List.of(subEntityAttributes); } @Override public String getDefaultSubEntityAttribute() { - return this == TYPE ? DistributionSetTypeFields.KEY.getJpaEntityFieldName() : QueryField.super.getDefaultSubEntityAttribute(); + return this == TYPE ? DistributionSetTypeFields.KEY.getName() : QueryField.super.getDefaultSubEntityAttribute(); } @Override diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetTagFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetTagFields.java index a8cb5003b..2893ccc52 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetTagFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetTagFields.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.qfields; import java.util.List; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the Tag model which can be used in the REST API e.g. @@ -22,23 +23,23 @@ import lombok.Getter; @Getter public enum DistributionSetTagFields implements QueryField { - ID(TagFields.ID.getJpaEntityFieldName()), - NAME(TagFields.NAME.getJpaEntityFieldName()), - DESCRIPTION(TagFields.DESCRIPTION.getJpaEntityFieldName()), - COLOUR(TagFields.COLOUR.getJpaEntityFieldName()), + ID(TagFields.ID.getName()), + NAME(TagFields.NAME.getName()), + DESCRIPTION(TagFields.DESCRIPTION.getName()), + COLOUR(TagFields.COLOUR.getName()), CREATEDAT("createdAt"), CREATEDBY("createdBy"), LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"), DISTRIBUTIONSET( "assignedToDistributionSet", - DistributionSetFields.ID.getJpaEntityFieldName(), DistributionSetFields.NAME.getJpaEntityFieldName()); + DistributionSetFields.ID.getName(), DistributionSetFields.NAME.getName()); - private final String jpaEntityFieldName; + private final String name; private final List subEntityAttributes; - DistributionSetTagFields(final String jpaEntityFieldName, final String... subEntityAttributes) { - this.jpaEntityFieldName = jpaEntityFieldName; + DistributionSetTagFields(final String name, final String... subEntityAttributes) { + this.name = name; this.subEntityAttributes = List.of(subEntityAttributes); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetTypeFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetTypeFields.java index 16b707e17..66fd412e0 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetTypeFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/DistributionSetTypeFields.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.qfields; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the DistributionSetType model which can be used in @@ -27,9 +28,9 @@ public enum DistributionSetTypeFields implements QueryField { LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"); - private final String jpaEntityFieldName; + private final String name; - DistributionSetTypeFields(final String jpaEntityFieldName) { - this.jpaEntityFieldName = jpaEntityFieldName; + DistributionSetTypeFields(final String name) { + this.name = name; } } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/RolloutFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/RolloutFields.java index 5c291ec9f..dbdfc1c48 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/RolloutFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/RolloutFields.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.qfields; import java.util.List; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the Rollout model which can be used in the REST API e.g. for sorting etc. @@ -29,15 +30,15 @@ public enum RolloutFields implements QueryField { LASTMODIFIEDBY("lastModifiedBy"), DISTRIBUTIONSET( "distributionSet", - DistributionSetFields.ID.getJpaEntityFieldName(), - DistributionSetFields.NAME.getJpaEntityFieldName(), DistributionSetFields.VERSION.getJpaEntityFieldName(), - DistributionSetFields.TYPE.getJpaEntityFieldName()); + DistributionSetFields.ID.getName(), + DistributionSetFields.NAME.getName(), DistributionSetFields.VERSION.getName(), + DistributionSetFields.TYPE.getName()); - private final String jpaEntityFieldName; + private final String name; private final List subEntityAttributes; - RolloutFields(final String jpaEntityFieldName, final String... subEntityAttributes) { - this.jpaEntityFieldName = jpaEntityFieldName; + RolloutFields(final String name, final String... subEntityAttributes) { + this.name = name; this.subEntityAttributes = List.of(subEntityAttributes); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/RolloutGroupFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/RolloutGroupFields.java index 66db45828..64a94e8a3 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/RolloutGroupFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/RolloutGroupFields.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.qfields; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the RolloutGroup model which can be used in the REST API e.g. for sorting etc. @@ -25,9 +26,9 @@ public enum RolloutGroupFields implements QueryField { LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"); - private final String jpaEntityFieldName; + private final String name; - RolloutGroupFields(final String jpaEntityFieldName) { - this.jpaEntityFieldName = jpaEntityFieldName; + RolloutGroupFields(final String name) { + this.name = name; } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/SoftwareModuleFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/SoftwareModuleFields.java index a6f402248..a256b5761 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/SoftwareModuleFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/SoftwareModuleFields.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.qfields; import java.util.List; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the SoftwareModule model which can be used in the REST API e.g. for sorting etc. @@ -21,9 +22,9 @@ public enum SoftwareModuleFields implements QueryField { ID("id"), TYPE("type", - SoftwareModuleTypeFields.ID.getJpaEntityFieldName(), - SoftwareModuleTypeFields.KEY.getJpaEntityFieldName(), - SoftwareModuleTypeFields.NAME.getJpaEntityFieldName()), + SoftwareModuleTypeFields.ID.getName(), + SoftwareModuleTypeFields.KEY.getName(), + SoftwareModuleTypeFields.NAME.getName()), NAME("name"), DESCRIPTION("description"), VERSION("version"), @@ -33,18 +34,18 @@ public enum SoftwareModuleFields implements QueryField { LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"); - private final String jpaEntityFieldName; + private final String name; private final List subEntityAttributes; - SoftwareModuleFields(final String jpaEntityFieldName, final String... subEntityAttributes) { - this.jpaEntityFieldName = jpaEntityFieldName; + SoftwareModuleFields(final String name, final String... subEntityAttributes) { + this.name = name; this.subEntityAttributes = List.of(subEntityAttributes); } @Override public String getDefaultSubEntityAttribute() { - return this == TYPE ? SoftwareModuleTypeFields.KEY.getJpaEntityFieldName() : QueryField.super.getDefaultSubEntityAttribute(); + return this == TYPE ? SoftwareModuleTypeFields.KEY.getName() : QueryField.super.getDefaultSubEntityAttribute(); } @Override diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/SoftwareModuleTypeFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/SoftwareModuleTypeFields.java index 909e7ba90..4e8a26979 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/SoftwareModuleTypeFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/SoftwareModuleTypeFields.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.qfields; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the SoftwareModuleType model which can be used in the REST API e.g. for sorting etc. @@ -27,9 +28,9 @@ public enum SoftwareModuleTypeFields implements QueryField { LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"); - private final String jpaEntityFieldName; + private final String name; - SoftwareModuleTypeFields(final String jpaEntityFieldName) { - this.jpaEntityFieldName = jpaEntityFieldName; + SoftwareModuleTypeFields(final String name) { + this.name = name; } } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TagFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TagFields.java index a14bbfdfc..d2baf5a08 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TagFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TagFields.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.qfields; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the Tag model which can be used in the REST API e.g. for sorting etc. @@ -26,9 +27,9 @@ public enum TagFields implements QueryField { LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"); - private final String jpaEntityFieldName; + private final String name; - TagFields(final String jpaEntityFieldName) { - this.jpaEntityFieldName = jpaEntityFieldName; + TagFields(final String name) { + this.name = name; } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetFields.java index 6ebed58b6..f61a1ecec 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetFields.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.qfields; import java.util.List; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the Target model which can be used in the REST API @@ -33,36 +34,36 @@ public enum TargetFields implements QueryField { ATTRIBUTE("controllerAttributes"), GROUP("group"), ASSIGNEDDS("assignedDistributionSet", - DistributionSetFields.NAME.getJpaEntityFieldName(), DistributionSetFields.VERSION.getJpaEntityFieldName()), + DistributionSetFields.NAME.getName(), DistributionSetFields.VERSION.getName()), INSTALLEDDS("installedDistributionSet", - DistributionSetFields.NAME.getJpaEntityFieldName(), DistributionSetFields.VERSION.getJpaEntityFieldName()), - TAG("tags", TagFields.NAME.getJpaEntityFieldName()), + DistributionSetFields.NAME.getName(), DistributionSetFields.VERSION.getName()), + TAG("tags", TagFields.NAME.getName()), LASTCONTROLLERREQUESTAT("lastTargetQuery"), METADATA("metadata"), TYPE("targetType", - TargetTypeFields.ID.getJpaEntityFieldName(), - TargetTypeFields.KEY.getJpaEntityFieldName(), - TargetTypeFields.NAME.getJpaEntityFieldName()), + TargetTypeFields.ID.getName(), + TargetTypeFields.KEY.getName(), + TargetTypeFields.NAME.getName()), // kept just for backward compatibility for backward compatibility // could be removed only if in the systems there are no active auto assignments or rollouts (dynamic or starting) with that condition // to be reconsidered if and when to be removed @Deprecated(forRemoval = true, since = "0.10.0") TARGETTYPE("targetType", - TargetTypeFields.ID.getJpaEntityFieldName(), - TargetTypeFields.KEY.getJpaEntityFieldName(), - TargetTypeFields.NAME.getJpaEntityFieldName()); + TargetTypeFields.ID.getName(), + TargetTypeFields.KEY.getName(), + TargetTypeFields.NAME.getName()); - private final String jpaEntityFieldName; + private final String name; private final List subEntityAttributes; - TargetFields(final String jpaEntityFieldName, final String... subEntityAttributes) { - this.jpaEntityFieldName = jpaEntityFieldName; + TargetFields(final String name, final String... subEntityAttributes) { + this.name = name; this.subEntityAttributes = List.of(subEntityAttributes); } @Override public String getDefaultSubEntityAttribute() { - return this == TYPE ? TargetTypeFields.KEY.getJpaEntityFieldName() : QueryField.super.getDefaultSubEntityAttribute(); + return this == TYPE ? TargetTypeFields.KEY.getName() : QueryField.super.getDefaultSubEntityAttribute(); } @Override diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetFilterQueryFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetFilterQueryFields.java index 11011cbbe..2c4c914c7 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetFilterQueryFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetFilterQueryFields.java @@ -13,6 +13,7 @@ import java.util.Collections; import java.util.List; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the Target model which can be used in the REST API e.g. for sorting etc. @@ -28,19 +29,19 @@ public enum TargetFilterQueryFields implements QueryField { LASTMODIFIEDBY("lastModifiedBy"), AUTOASSIGNDISTRIBUTIONSET("autoAssignDistributionSet", "name", "version"); - private final String jpaEntityFieldName; + private final String name; private final List subEntityAttributes; - TargetFilterQueryFields(final String jpaEntityFieldName) { - this(jpaEntityFieldName, Collections.emptyList()); + TargetFilterQueryFields(final String name) { + this(name, Collections.emptyList()); } - TargetFilterQueryFields(final String jpaEntityFieldName, final String... subEntityAttribues) { - this(jpaEntityFieldName, List.of(subEntityAttribues)); + TargetFilterQueryFields(final String name, final String... subEntityAttribues) { + this(name, List.of(subEntityAttribues)); } - TargetFilterQueryFields(final String jpaEntityFieldName, final List subEntityAttribues) { - this.jpaEntityFieldName = jpaEntityFieldName; + TargetFilterQueryFields(final String name, final List subEntityAttribues) { + this.name = name; this.subEntityAttributes = subEntityAttribues; } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetTagFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetTagFields.java index d25f8ed94..b117d9274 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetTagFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetTagFields.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.qfields; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the Tag model which can be used in the REST API e.g. for sorting etc. @@ -18,18 +19,18 @@ import lombok.Getter; @Getter public enum TargetTagFields implements QueryField { - ID(TagFields.ID.getJpaEntityFieldName()), - NAME(TagFields.NAME.getJpaEntityFieldName()), - DESCRIPTION(TagFields.DESCRIPTION.getJpaEntityFieldName()), - COLOUR(TagFields.COLOUR.getJpaEntityFieldName()), + ID(TagFields.ID.getName()), + NAME(TagFields.NAME.getName()), + DESCRIPTION(TagFields.DESCRIPTION.getName()), + COLOUR(TagFields.COLOUR.getName()), CREATEDAT("createdAt"), CREATEDBY("createdBy"), LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"); - private final String jpaEntityFieldName; + private final String name; - TargetTagFields(final String jpaEntityFieldName) { - this.jpaEntityFieldName = jpaEntityFieldName; + TargetTagFields(final String name) { + this.name = name; } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetTypeFields.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetTypeFields.java index 50414a1b0..69236a9c5 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetTypeFields.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/qfields/TargetTypeFields.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.qfields; import lombok.Getter; +import org.eclipse.hawkbit.ql.QueryField; /** * Describing the fields of the TargetType model which can be used in the REST API @@ -26,9 +27,9 @@ public enum TargetTypeFields implements QueryField { LASTMODIFIEDAT("lastModifiedAt"), LASTMODIFIEDBY("lastModifiedBy"); - private final String jpaEntityFieldName; + private final String name; - TargetTypeFields(final String jpaEntityFieldName) { - this.jpaEntityFieldName = jpaEntityFieldName; + TargetTypeFields(final String name) { + this.name = name; } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/qfields/QueryFieldsTest.java b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/qfields/QueryFieldsTest.java index 6aa950d2f..fbda4c64d 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/qfields/QueryFieldsTest.java +++ b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/qfields/QueryFieldsTest.java @@ -16,6 +16,7 @@ import java.util.List; import io.github.classgraph.ClassGraph; import io.github.classgraph.ClassInfo; import io.github.classgraph.ScanResult; +import org.eclipse.hawkbit.ql.QueryField; import org.junit.jupiter.api.Test; class QueryFieldsTest { diff --git a/hawkbit-repository/hawkbit-repository-jpa-api/src/main/java/org/eclipse/hawkbit/repository/jpa/utils/ExceptionMapper.java b/hawkbit-repository/hawkbit-repository-jpa-api/src/main/java/org/eclipse/hawkbit/repository/jpa/utils/ExceptionMapper.java index 3a3a6946b..3f476fad4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-api/src/main/java/org/eclipse/hawkbit/repository/jpa/utils/ExceptionMapper.java +++ b/hawkbit-repository/hawkbit-repository-jpa-api/src/main/java/org/eclipse/hawkbit/repository/jpa/utils/ExceptionMapper.java @@ -18,8 +18,11 @@ import java.util.Map; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.exception.GenericSpServerException; +import org.eclipse.hawkbit.ql.QueryException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.security.access.AccessDeniedException; @@ -66,6 +69,9 @@ public class ExceptionMapper { * @param e the thrown and catch exception * @return the mapped exception */ + // java:S3776 - complex but flat + // java:S3358 - easy to read + @SuppressWarnings({ "java:S3776", "java:S3358" }) public static Exception map(final Exception e) { if (log.isTraceEnabled()) { log.trace("Handling exception {}", e.getClass().getName(), e); @@ -86,7 +92,8 @@ public class ExceptionMapper { if (EXCEPTION_MAPPING.containsKey(mappedEx.getName())) { try { return (Exception) Class.forName(EXCEPTION_MAPPING.get(mappedEx.getName())).getConstructor(Throwable.class).newInstance(e); - } catch (final ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex) { + } catch (final ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException ex) { log.error(ex.getMessage(), ex); return e; } @@ -101,12 +108,21 @@ public class ExceptionMapper { if (mappingClass != null) { try { return (Exception) Class.forName(mappingClass).getConstructor(Throwable.class).newInstance(e); - } catch (final ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex) { + } catch (final ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException ex) { log.error(ex.getMessage(), ex); return e; } } + if (e instanceof QueryException qe) { + return qe.getErrorCode() == QueryException.ErrorCode.INVALID_SYNTAX + ? new RSQLParameterSyntaxException(qe.getMessage(), qe.getCause()) + : (qe.getErrorCode() == QueryException.ErrorCode.UNSUPPORTED_FIELD + ? new RSQLParameterUnsupportedFieldException(qe.getMessage(), qe.getCause()) + : new GenericSpServerException(qe)); + } + return e; } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java index 91d534ea5..b47d3bc05 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java @@ -22,10 +22,15 @@ import org.aopalliance.intercept.MethodInvocation; import org.eclipse.hawkbit.artifact.encryption.ArtifactEncryption; import org.eclipse.hawkbit.artifact.encryption.ArtifactEncryptionSecretsStorage; import org.eclipse.hawkbit.artifact.encryption.ArtifactEncryptionService; +import org.eclipse.hawkbit.ql.Node.Comparison; +import org.eclipse.hawkbit.ql.QueryField; +import org.eclipse.hawkbit.ql.jpa.QLSupport; +import org.eclipse.hawkbit.ql.jpa.QLSupport.NodeTransformer; +import org.eclipse.hawkbit.ql.jpa.QLSupport.QueryParser; +import org.eclipse.hawkbit.ql.rsql.RsqlParser; import org.eclipse.hawkbit.repository.AutoAssignExecutor; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.PropertiesQuotaManagement; -import org.eclipse.hawkbit.repository.qfields.QueryField; import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.RepositoryConfiguration; import org.eclipse.hawkbit.repository.RepositoryProperties; @@ -41,6 +46,8 @@ import org.eclipse.hawkbit.repository.event.ApplicationEventFilter; import org.eclipse.hawkbit.repository.event.remote.EventEntityManager; import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder; import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent; +import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.helper.TenantConfigurationManagementHolder; import org.eclipse.hawkbit.repository.jpa.acm.AccessController; import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler; import org.eclipse.hawkbit.repository.jpa.autocleanup.AutoActionCleanup; @@ -58,10 +65,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder; -import org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport.NodeTransformer; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport.QueryParser; import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository; import org.eclipse.hawkbit.repository.jpa.repository.ArtifactRepository; import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetRepository; @@ -71,7 +74,6 @@ import org.eclipse.hawkbit.repository.jpa.repository.SoftwareModuleRepository; import org.eclipse.hawkbit.repository.jpa.repository.SoftwareModuleTypeRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetTypeRepository; -import org.eclipse.hawkbit.repository.jpa.scheduler.RolloutScheduler; import org.eclipse.hawkbit.repository.jpa.rollout.condition.PauseRolloutGroupAction; import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupActionEvaluator; import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupConditionEvaluator; @@ -79,15 +81,13 @@ import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupEvaluati import org.eclipse.hawkbit.repository.jpa.rollout.condition.StartNextGroupRolloutGroupSuccessAction; import org.eclipse.hawkbit.repository.jpa.rollout.condition.ThresholdRolloutGroupErrorCondition; import org.eclipse.hawkbit.repository.jpa.rollout.condition.ThresholdRolloutGroupSuccessCondition; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParser; import org.eclipse.hawkbit.repository.jpa.scheduler.AutoAssignScheduler; import org.eclipse.hawkbit.repository.jpa.scheduler.JpaAutoAssignExecutor; import org.eclipse.hawkbit.repository.jpa.scheduler.JpaRolloutHandler; +import org.eclipse.hawkbit.repository.jpa.scheduler.RolloutScheduler; import org.eclipse.hawkbit.repository.jpa.utils.ExceptionMapper; import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.helper.TenantConfigurationManagementHolder; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; import org.eclipse.hawkbit.security.SecurityTokenGenerator; @@ -143,7 +143,7 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess @Import({ RepositoryConfiguration.class, JpaConfiguration.class, LockProperties.class, SystemManagementCacheKeyGenerator.class, - DataSourceAutoConfiguration.class}) + DataSourceAutoConfiguration.class }) @AutoConfigureAfter(DataSourceAutoConfiguration.class) public class JpaRepositoryConfiguration { @@ -413,7 +413,8 @@ public class JpaRepositoryConfiguration { * @return a new {@link AutoActionCleanup} bean */ @Bean - AutoCleanupScheduler.CleanupTask actionCleanup(final DeploymentManagement deploymentManagement, final TenantConfigurationManagement configManagement) { + AutoCleanupScheduler.CleanupTask actionCleanup( + final DeploymentManagement deploymentManagement, final TenantConfigurationManagement configManagement) { return new AutoActionCleanup(deploymentManagement, configManagement); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/AuthorityChecker.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/AuthorityChecker.java index d82280c8d..4efd9c659 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/AuthorityChecker.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/AuthorityChecker.java @@ -14,17 +14,17 @@ import java.util.Set; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.ql.jpa.QLSupport; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.qfields.DistributionSetFields; import org.eclipse.hawkbit.repository.qfields.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.qfields.SoftwareModuleFields; import org.eclipse.hawkbit.repository.qfields.SoftwareModuleTypeFields; import org.eclipse.hawkbit.repository.qfields.TargetFields; import org.eclipse.hawkbit.repository.qfields.TargetTagFields; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; -import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport; // utility class to validate authorities when ACM is enabled @NoArgsConstructor(access = AccessLevel.PRIVATE) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/DefaultAccessController.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/DefaultAccessController.java index 864e06e41..85f2aba05 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/DefaultAccessController.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/DefaultAccessController.java @@ -18,9 +18,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.repository.qfields.QueryField; +import org.eclipse.hawkbit.ql.QueryField; +import org.eclipse.hawkbit.ql.jpa.QLSupport; import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.springframework.data.jpa.domain.Specification; import org.springframework.security.core.GrantedAuthority; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractJpaRepositoryManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractJpaRepositoryManagement.java index 0fce09173..f4e982077 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractJpaRepositoryManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractJpaRepositoryManagement.java @@ -36,9 +36,10 @@ import jakarta.persistence.criteria.Root; import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; +import org.eclipse.hawkbit.ql.QueryField; +import org.eclipse.hawkbit.ql.jpa.QLSupport; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.Identifiable; -import org.eclipse.hawkbit.repository.qfields.QueryField; import org.eclipse.hawkbit.repository.RepositoryManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException; @@ -48,7 +49,6 @@ import org.eclipse.hawkbit.repository.jpa.JpaRepositoryConfiguration; import org.eclipse.hawkbit.repository.jpa.acm.AccessController; import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity; import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity_; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport; import org.eclipse.hawkbit.repository.jpa.repository.BaseEntityRepository; import org.eclipse.hawkbit.utils.ObjectCopyUtil; import org.springframework.cache.Cache; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractJpaRepositoryWithMetadataManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractJpaRepositoryWithMetadataManagement.java index 584f84d92..4fa2c8aaf 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractJpaRepositoryWithMetadataManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractJpaRepositoryWithMetadataManagement.java @@ -24,9 +24,9 @@ import java.util.stream.Collectors; import jakarta.persistence.EntityManager; +import org.eclipse.hawkbit.ql.QueryField; import org.eclipse.hawkbit.repository.Identifiable; import org.eclipse.hawkbit.repository.MetadataSupport; -import org.eclipse.hawkbit.repository.qfields.QueryField; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity; import org.eclipse.hawkbit.repository.jpa.model.WithMetadata; @@ -46,7 +46,7 @@ abstract class AbstractJpaRepositoryWithMetadataManagement - implements TargetFilterQueryManagement{ + implements TargetFilterQueryManagement { private final TargetManagement targetManagement; private final DistributionSetManagement distributionSetManagement; @@ -80,7 +80,8 @@ class JpaTargetFilterQueryManagement protected JpaTargetFilterQueryManagement( final TargetFilterQueryRepository targetFilterQueryRepository, final EntityManager entityManager, - final TargetManagement targetManagement, final DistributionSetManagement distributionSetManagement, + final TargetManagement targetManagement, + final DistributionSetManagement distributionSetManagement, final QuotaManagement quotaManagement, final TenantConfigurationManagement tenantConfigurationManagement, final RepositoryProperties repositoryProperties, final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware auditorAware) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java index 9d8f24416..beaed04f1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java @@ -34,8 +34,8 @@ import jakarta.persistence.criteria.Root; import jakarta.persistence.metamodel.MapAttribute; import jakarta.validation.constraints.NotEmpty; +import org.eclipse.hawkbit.ql.jpa.QLSupport; import org.eclipse.hawkbit.repository.QuotaManagement; -import org.eclipse.hawkbit.repository.qfields.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; @@ -50,7 +50,6 @@ import org.eclipse.hawkbit.repository.jpa.repository.RolloutGroupRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetTagRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetTypeRepository; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport; import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -58,6 +57,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.repository.qfields.TargetFields; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java index 4a3daa669..9a6071257 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java @@ -30,21 +30,21 @@ import java.util.function.Function; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.repository.qfields.TargetFields; +import org.eclipse.hawkbit.ql.jpa.QLSupport; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; import org.eclipse.hawkbit.repository.exception.TenantConfigurationValidatorException; import org.eclipse.hawkbit.repository.exception.TenantConfigurationValueChangeNotAllowedException; +import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport; import org.eclipse.hawkbit.repository.jpa.repository.TenantConfigurationRepository; import org.eclipse.hawkbit.repository.model.PollStatus; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.qfields.TargetFields; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAwareCacheManager; import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/NodeTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/NodeTest.java similarity index 93% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/NodeTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/NodeTest.java index f2fd22a2b..8042bd02c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/NodeTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/NodeTest.java @@ -7,11 +7,11 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; -import org.eclipse.hawkbit.repository.jpa.ql.Node; +import org.eclipse.hawkbit.ql.Node; import org.junit.jupiter.api.Test; class NodeTest { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlActionFieldsTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlActionFieldsTest.java similarity index 90% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlActionFieldsTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlActionFieldsTest.java index 4fda2362c..0aeb1054d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlActionFieldsTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlActionFieldsTest.java @@ -7,14 +7,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import org.eclipse.hawkbit.repository.qfields.ActionFields; import org.eclipse.hawkbit.repository.TargetManagement.Create; -import org.eclipse.hawkbit.repository.exception.QueryException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; @@ -22,9 +22,9 @@ import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.qfields.ActionFields; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; import org.springframework.orm.jpa.vendor.Database; @@ -65,7 +65,9 @@ class RsqlActionFieldsTest extends AbstractJpaIntegrationTest { assertRSQLQuery(ActionFields.ID.name() + "=in=(" + action.getId() + ",10000000)", 1); assertRSQLQuery(ActionFields.ID.name() + "=out=(" + action.getId() + ",10000000)", 10); - }/** + } + + /** * Test action by status */ @Test @@ -73,10 +75,10 @@ class RsqlActionFieldsTest extends AbstractJpaIntegrationTest { assertRSQLQuery(ActionFields.ACTIVE.name() + "==" + true, 5); assertRSQLQuery(ActionFields.ACTIVE.name() + "!=" + true, 6); assertRSQLQuery(ActionFields.ACTIVE.name() + "=in=(" + true + ")", 5); - assertRSQLQuery(ActionFields.ACTIVE.name() + "=out=(" + true +")", 6); + assertRSQLQuery(ActionFields.ACTIVE.name() + "=out=(" + true + ")", 6); final String rsql = ActionFields.ACTIVE.name() + "==true2"; - assertThatExceptionOfType(QueryException.class) + assertThatExceptionOfType(RSQLParameterSyntaxException.class) .as("RSQLParameterUnsupportedFieldException because active cannot be compared with 'true2'") .isThrownBy(() -> assertRSQLQuery(rsql, 5)); } @@ -89,10 +91,10 @@ class RsqlActionFieldsTest extends AbstractJpaIntegrationTest { assertRSQLQuery(ActionFields.STATUS.name() + "==" + Status.RUNNING, 5); assertRSQLQuery(ActionFields.STATUS.name() + "!=" + Status.RUNNING, 6); assertRSQLQuery(ActionFields.STATUS.name() + "=in=(" + Status.RUNNING + ")", 5); - assertRSQLQuery(ActionFields.STATUS.name() + "=out=(" + Status.RUNNING +")", 6); + assertRSQLQuery(ActionFields.STATUS.name() + "=out=(" + Status.RUNNING + ")", 6); final String rsql = ActionFields.STATUS.name() + "==not_a_status"; - assertThatExceptionOfType(QueryException.class) + assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class) .as("RSQLParameterUnsupportedFieldException because status cannot be compared with 'not_a_status'") .isThrownBy(() -> assertRSQLQuery(rsql, 5)); } @@ -127,11 +129,10 @@ class RsqlActionFieldsTest extends AbstractJpaIntegrationTest { } private void assertRSQLQuery(final String rsql, final long expectedEntities) { - final Slice findEntity = deploymentManagement.findActionsByTarget(rsql, target.getControllerId(), - PageRequest.of(0, 100)); + final Slice findEntity = deploymentManagement.findActionsByTarget(rsql, target.getControllerId(), PAGE); final long countAllEntities = deploymentManagement.countActionsByTarget(rsql, target.getControllerId()); assertThat(findEntity).isNotNull(); - assertThat(findEntity.getContent()).hasSize((int)expectedEntities); + assertThat(findEntity.getContent()).hasSize((int) expectedEntities); assertThat(countAllEntities).isEqualTo(expectedEntities); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlParserTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlParserTest.java similarity index 97% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlParserTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlParserTest.java index 9e1a420c4..8b465883f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlParserTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlParserTest.java @@ -7,10 +7,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlParser.parse; +import static org.eclipse.hawkbit.ql.rsql.RsqlParser.parse; import org.eclipse.hawkbit.repository.qfields.TargetFields; import org.junit.jupiter.api.Test; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlRolloutFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlRolloutFieldTest.java similarity index 95% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlRolloutFieldTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlRolloutFieldTest.java index 52f835cfb..f52285a64 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlRolloutFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlRolloutFieldTest.java @@ -7,17 +7,17 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; -import org.eclipse.hawkbit.repository.qfields.RolloutFields; import org.eclipse.hawkbit.repository.RolloutManagement.Create; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition; import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder; +import org.eclipse.hawkbit.repository.qfields.RolloutFields; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Page; @@ -60,7 +60,8 @@ class RsqlRolloutFieldTest extends AbstractJpaIntegrationTest { private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, final String targetFilterQuery) { return rolloutManagement.create( Create.builder() - .distributionSet(distributionSetManagement.find(distributionSetId).get()).name(name).targetFilterQuery(targetFilterQuery) + .distributionSet(distributionSetManagement.find(distributionSetId).get()).name(name) + .targetFilterQuery(targetFilterQuery) .build(), amountGroups, false, diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlRolloutGroupFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlRolloutGroupFieldTest.java similarity index 95% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlRolloutGroupFieldTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlRolloutGroupFieldTest.java index be1d6111c..4c36a1417 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlRolloutGroupFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlRolloutGroupFieldTest.java @@ -7,11 +7,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; -import org.eclipse.hawkbit.repository.qfields.RolloutGroupFields; import org.eclipse.hawkbit.repository.RolloutManagement.Create; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -19,6 +18,7 @@ import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition; import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder; +import org.eclipse.hawkbit.repository.qfields.RolloutGroupFields; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Page; @@ -98,11 +98,11 @@ class RsqlRolloutGroupFieldTest extends AbstractJpaIntegrationTest { assertThat(countTargetsAll).isEqualTo(expectedTargets); } - private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, - final String targetFilterQuery) { + private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, final String targetFilterQuery) { return rolloutManagement.create( Create.builder() - .distributionSet(distributionSetManagement.find(distributionSetId).get()).name(name).targetFilterQuery(targetFilterQuery) + .distributionSet(distributionSetManagement.find(distributionSetId).get()).name(name) + .targetFilterQuery(targetFilterQuery) .build(), amountGroups, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlSoftwareModuleFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlSoftwareModuleFieldTest.java similarity index 99% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlSoftwareModuleFieldTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlSoftwareModuleFieldTest.java index 959dc705e..6e171e178 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlSoftwareModuleFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlSoftwareModuleFieldTest.java @@ -7,16 +7,16 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; -import org.eclipse.hawkbit.repository.qfields.SoftwareModuleFields; import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule.MetadataValueCreate; +import org.eclipse.hawkbit.repository.qfields.SoftwareModuleFields; import org.eclipse.hawkbit.repository.test.util.TestdataFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -96,7 +96,7 @@ class RsqlSoftwareModuleFieldTest extends AbstractJpaIntegrationTest { } /** - * Test filter software module by name which contain mutated vowels + * Test filter software module by name which contain mutated vowels */ @Test void testFilterByParameterNameWithUmlaut() { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlSoftwareModuleTypeFieldsTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlSoftwareModuleTypeFieldsTest.java similarity index 98% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlSoftwareModuleTypeFieldsTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlSoftwareModuleTypeFieldsTest.java index a9068c617..481d94fb9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlSoftwareModuleTypeFieldsTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlSoftwareModuleTypeFieldsTest.java @@ -7,14 +7,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; import org.eclipse.hawkbit.repository.Constants; -import org.eclipse.hawkbit.repository.qfields.SoftwareModuleTypeFields; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.qfields.SoftwareModuleTypeFields; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTagFieldsTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTagFieldsTest.java similarity index 99% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTagFieldsTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTagFieldsTest.java index 0ef388b7a..61784322c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTagFieldsTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTagFieldsTest.java @@ -7,16 +7,16 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; import org.eclipse.hawkbit.repository.DistributionSetTagManagement; -import org.eclipse.hawkbit.repository.qfields.TagFields; import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.repository.qfields.TagFields; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Page; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTargetFieldTest.java similarity index 96% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFieldTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTargetFieldTest.java index 282eb9f17..9fd82e1b7 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTargetFieldTest.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -15,19 +15,22 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import java.util.Arrays; import java.util.Map; -import org.eclipse.hawkbit.repository.qfields.TargetFields; +import org.eclipse.hawkbit.ql.QueryException; +import org.eclipse.hawkbit.ql.QueryField; +import org.eclipse.hawkbit.ql.jpa.QLSupport; import org.eclipse.hawkbit.repository.TargetManagement.Create; import org.eclipse.hawkbit.repository.TargetTagManagement; -import org.eclipse.hawkbit.repository.qfields.TargetTypeFields; import org.eclipse.hawkbit.repository.TargetTypeManagement; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; -import org.eclipse.hawkbit.repository.jpa.ql.QLSupport; +import org.eclipse.hawkbit.repository.jpa.utils.ExceptionMapper; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetType; +import org.eclipse.hawkbit.repository.qfields.TargetFields; +import org.eclipse.hawkbit.repository.qfields.TargetTypeFields; import org.eclipse.hawkbit.repository.test.util.TestdataFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -344,27 +347,26 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { */ @Test void rsqlValidTargetFields() { - final QLSupport qlSupport = QLSupport.getInstance(); - qlSupport.validate( + validate( "ID == '0123' and NAME == abcd and DESCRIPTION == absd and CREATEDAT =lt= 0123 and LASTMODIFIEDAT =gt= 0123" + " and CONTROLLERID == 0123 and UPDATESTATUS == PENDING and IPADDRESS == 0123 and LASTCONTROLLERREQUESTAT == 0123" + " and tag == beta", TargetFields.class, JpaTarget.class); - qlSupport.validate( + validate( "ASSIGNEDDS.name == abcd and ASSIGNEDDS.version == 0123 and INSTALLEDDS.name == abcd and INSTALLEDDS.version == 0123", TargetFields.class, JpaTarget.class); - qlSupport.validate( + validate( "ATTRIBUTE.subkey1 == test and ATTRIBUTE.subkey2 == test and METADATA.metakey1 == abcd and METADATA.metavalue2 == asdfg", TargetFields.class, JpaTarget.class); - qlSupport.validate( + validate( "CREATEDAT =lt= ${NOW_TS} and LASTMODIFIEDAT =ge= ${OVERDUE_TS}", TargetFields.class, JpaTarget.class); - qlSupport.validate( + validate( "ATTRIBUTE.test.dot == test and ATTRIBUTE.subkey2 == test and METADATA.test.dot == abcd and METADATA.metavalue2 == asdfg", TargetFields.class, JpaTarget.class); assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class) - .isThrownBy(() -> qlSupport.validate("wrongfield == abcd", TargetFields.class, JpaTarget.class)); + .isThrownBy(() -> validate("wrongfield == abcd", TargetFields.class, JpaTarget.class)); } /** @@ -418,8 +420,15 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { } private void assertRSQLQueryThrowsException(final String rsql) { - final QLSupport qlSupport = QLSupport.getInstance(); assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class) - .isThrownBy(() -> qlSupport.validate(rsql, TargetFields.class, JpaTarget.class)); + .isThrownBy(() -> validate(rsql, TargetFields.class, JpaTarget.class)); + } + + private & QueryField> void validate(final String query, final Class queryFieldType, final Class jpaType) { + try { + QLSupport.getInstance().validate(query, queryFieldType, jpaType); + } catch (final QueryException e) { + throw ExceptionMapper.mapRe(e); + } } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFilterQueryFieldsTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTargetFilterQueryFieldsTest.java similarity index 99% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFilterQueryFieldsTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTargetFilterQueryFieldsTest.java index b83386674..f4e5e77a4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFilterQueryFieldsTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlTargetFilterQueryFieldsTest.java @@ -7,17 +7,17 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import org.eclipse.hawkbit.repository.qfields.TargetFilterQueryFields; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; +import org.eclipse.hawkbit.repository.qfields.TargetFilterQueryFields; import org.eclipse.hawkbit.repository.test.util.TestdataFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlToSqlTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlToSqlTest.java similarity index 79% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlToSqlTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlToSqlTest.java index 5c77eb40a..34f1877b3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlToSqlTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlToSqlTest.java @@ -7,20 +7,20 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; -import org.eclipse.hawkbit.repository.qfields.QueryField; -import org.eclipse.hawkbit.repository.qfields.SoftwareModuleFields; -import org.eclipse.hawkbit.repository.qfields.TargetFields; +import org.eclipse.hawkbit.ql.QueryField; +import org.eclipse.hawkbit.ql.jpa.utils.QlToSql; import org.eclipse.hawkbit.repository.jpa.JpaRepositoryConfiguration; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; -import org.eclipse.hawkbit.repository.jpa.ql.utils.HawkbitQlToSql; +import org.eclipse.hawkbit.repository.qfields.SoftwareModuleFields; +import org.eclipse.hawkbit.repository.qfields.TargetFields; import org.eclipse.hawkbit.repository.test.TestConfiguration; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -40,7 +40,7 @@ import org.springframework.test.context.ContextConfiguration; class RsqlToSqlTest { private static final boolean FULL = Boolean.getBoolean("full"); - private HawkbitQlToSql rsqlToSQL; + private QlToSql rsqlToSQL; @Test void printPG() { @@ -106,16 +106,22 @@ class RsqlToSqlTest { @Test void printComplex() { print(JpaTarget.class, TargetFields.class, "attribute.key1==00 and (attribute.key2==02 or attribute.key2==01)"); - print(JpaTarget.class, TargetFields.class, "(attribute.key1==00 or attribute.key1==01) and (attribute.key2==02 or attribute.key2==01) and attribute.key3==01"); - print(JpaTarget.class, TargetFields.class, "(attribute.key1==00 or attribute.key1==01) and (attribute.key2==02 or attribute.key2==01) and attribute.key3==01 and updateStatus!=pending"); - print(JpaTarget.class, TargetFields.class, "((attribute.key1==00 or attribute.key1==01) and (attribute.key2==02 or attribute.key2==01) and attribute.key3==03 and updateStatus!=pending)"); - print(JpaTarget.class, TargetFields.class, "((attribute.key1==00 or attribute.key1==01) and (attribute.key2==02 or attribute.key2==01) and attribute.key3==01 and updateStatus!=pending)"); + print(JpaTarget.class, TargetFields.class, + "(attribute.key1==00 or attribute.key1==01) and (attribute.key2==02 or attribute.key2==01) and attribute.key3==01"); + print(JpaTarget.class, TargetFields.class, + "(attribute.key1==00 or attribute.key1==01) and (attribute.key2==02 or attribute.key2==01) and attribute.key3==01 and updateStatus!=pending"); + print(JpaTarget.class, TargetFields.class, + "((attribute.key1==00 or attribute.key1==01) and (attribute.key2==02 or attribute.key2==01) and attribute.key3==03 and updateStatus!=pending)"); + print(JpaTarget.class, TargetFields.class, + "((attribute.key1==00 or attribute.key1==01) and (attribute.key2==02 or attribute.key2==01) and attribute.key3==01 and updateStatus!=pending)"); } @Test void printVeryComplex() { - print(JpaTarget.class, TargetFields.class, "(attribute.key1==00 or attribute.key1==01) and ((attribute.key2==02 or attribute.key2==01) and (attribute.key4==02 or attribute.key5==01)) and attribute.key3==01 and updateStatus!=pending"); - print(JpaTarget.class, TargetFields.class, "(attribute.key1==00 or attribute.key1==01) and ((attribute.key2==02 or attribute.key2==01) or (attribute.key4==02 or attribute.key5==01)) and attribute.key3==01 and updateStatus!=pending"); + print(JpaTarget.class, TargetFields.class, + "(attribute.key1==00 or attribute.key1==01) and ((attribute.key2==02 or attribute.key2==01) and (attribute.key4==02 or attribute.key5==01)) and attribute.key3==01 and updateStatus!=pending"); + print(JpaTarget.class, TargetFields.class, + "(attribute.key1==00 or attribute.key1==01) and ((attribute.key2==02 or attribute.key2==01) or (attribute.key4==02 or attribute.key5==01)) and attribute.key3==01 and updateStatus!=pending"); } private static String from(final String sql) { @@ -124,7 +130,7 @@ class RsqlToSqlTest { @PersistenceContext private void setEntityManager(final EntityManager entityManager) { - rsqlToSQL = new HawkbitQlToSql(entityManager); + rsqlToSQL = new QlToSql(entityManager); } private & QueryField> void print(final Class domainClass, final Class fieldsClass, final String rsql) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/VirtualPropertyResolverTest.java similarity index 98% rename from hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java rename to hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/VirtualPropertyResolverTest.java index 52e4df964..77ac63ed0 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/VirtualPropertyResolverTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/VirtualPropertyResolverTest.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql; +package org.eclipse.hawkbit.ql.rsql; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; @@ -16,9 +16,9 @@ import java.util.concurrent.Callable; import org.apache.commons.text.StringSubstitutor; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.helper.TenantConfigurationManagementHolder; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java index a33c5158d..01b3cfc5b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java @@ -1199,7 +1199,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { */ @Test void assignDistributionSetAndAddFinishedActionStatus() { - final PageRequest pageRequest = PageRequest.of(0, 100, Direction.ASC, ActionStatusFields.ID.getJpaEntityFieldName()); + final PageRequest pageRequest = PageRequest.of(0, 100, Direction.ASC, ActionStatusFields.ID.getName()); final DeploymentResult deployResWithDsA = prepareComplexRepo("undep-A-T", 2, "dep-A-T", 4, 1, "dsA"); final DeploymentResult deployResWithDsB = prepareComplexRepo("undep-B-T", 3, "dep-B-T", 5, 1, "dsB"); diff --git a/hawkbit-repository/pom.xml b/hawkbit-repository/pom.xml index 38c1b264d..e10d83525 100644 --- a/hawkbit-repository/pom.xml +++ b/hawkbit-repository/pom.xml @@ -28,7 +28,6 @@ hawkbit-repository-jpa-api hawkbit-repository-jpa-eclipselink hawkbit-repository-jpa-hibernate - hawkbit-repository-jpa-ql hawkbit-repository-jpa hawkbit-repository-jpa-flyway diff --git a/pom.xml b/pom.xml index 4388a1866..82899818a 100644 --- a/pom.xml +++ b/pom.xml @@ -709,6 +709,7 @@ + hawkbit-ql-jpa hawkbit-core hawkbit-security-core hawkbit-artifact