Refactor RSQL serach fields related classes (#1834)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-09-09 17:39:45 +03:00
committed by GitHub
parent a31028ee19
commit 072809be6c
34 changed files with 291 additions and 285 deletions

View File

@@ -18,7 +18,7 @@ import java.util.List;
* Sort and search fields for actions.
*/
@Getter
public enum ActionFields implements FieldNameProvider, FieldValueConverter<ActionFields> {
public enum ActionFields implements RsqlQueryField, FieldValueConverter<ActionFields> {
ID("id"),
STATUS("active"),
@@ -26,29 +26,29 @@ public enum ActionFields implements FieldNameProvider, FieldValueConverter<Actio
LASTSTATUSCODE("lastActionStatusCode"),
WEIGHT("weight"),
TARGET("target",
TargetFields.ID.getFieldName(), TargetFields.NAME.getFieldName(),
TargetFields.UPDATESTATUS.getFieldName(), TargetFields.IPADDRESS.getFieldName()),
TargetFields.ID.getJpaEntityFieldName(), TargetFields.NAME.getJpaEntityFieldName(),
TargetFields.UPDATESTATUS.getJpaEntityFieldName(), TargetFields.IPADDRESS.getJpaEntityFieldName()),
DISTRIBUTIONSET("distributionSet",
DistributionSetFields.ID.getFieldName(),
DistributionSetFields.NAME.getFieldName(), DistributionSetFields.VERSION.getFieldName(),
DistributionSetFields.TYPE.getFieldName()),
ROLLOUT("rollout", RolloutFields.ID.getFieldName(), RolloutFields.NAME.getFieldName()),
ROLLOUTGROUP("rolloutGroup", RolloutGroupFields.ID.getFieldName(), RolloutGroupFields.NAME.getFieldName()),
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()),
EXTERNALREF("externalRef");
private static final String ACTIVE = "pending";
private static final String INACTIVE = "finished";
private final String fieldName;
private final String jpaEntityFieldName;
private final List<String> subEntityAttributes;
ActionFields(final String fieldName) {
this.fieldName = fieldName;
ActionFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityAttributes = Collections.emptyList();
}
ActionFields(final String fieldName, final String... subEntityAttributes) {
this.fieldName = fieldName;
ActionFields(final String jpaEntityFieldName, final String... subEntityAttributes) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityAttributes = List.of(subEntityAttributes);
}

View File

@@ -15,14 +15,14 @@ import lombok.Getter;
* Sort and search fields for action status.
*/
@Getter
public enum ActionStatusFields implements FieldNameProvider {
public enum ActionStatusFields implements RsqlQueryField {
ID("id"),
REPORTEDAT("createdAt");
private final String fieldName;
private final String jpaEntityFieldName;
ActionStatusFields(final String fieldName) {
this.fieldName = fieldName;
ActionStatusFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
}

View File

@@ -22,7 +22,7 @@ import java.util.Optional;
* REST API e.g. for sorting etc.
*/
@Getter
public enum DistributionSetFields implements FieldNameProvider {
public enum DistributionSetFields implements RsqlQueryField {
ID("id"),
TYPE("type.key"),
@@ -32,29 +32,29 @@ public enum DistributionSetFields implements FieldNameProvider {
LASTMODIFIEDAT("lastModifiedAt"),
VERSION("version"),
COMPLETE("complete"),
MODULE("modules", SoftwareModuleFields.ID.getFieldName(), SoftwareModuleFields.NAME.getFieldName()),
MODULE("modules", SoftwareModuleFields.ID.getJpaEntityFieldName(), SoftwareModuleFields.NAME.getJpaEntityFieldName()),
TAG("tags.name"),
METADATA("metadata", new SimpleImmutableEntry<>("key", "value")),
VALID("valid");
private final String fieldName;
private final String jpaEntityFieldName;
private final Entry<String, String> subEntityMapTuple;
private final List<String> subEntityAttributes;
DistributionSetFields(final String fieldName) {
this(fieldName, null, Collections.emptyList());
DistributionSetFields(final String jpaEntityFieldName) {
this(jpaEntityFieldName, null, Collections.emptyList());
}
DistributionSetFields(final String fieldName, final String... subEntityAttributes) {
this(fieldName, null, List.of(subEntityAttributes));
DistributionSetFields(final String jpaEntityFieldName, final String... subEntityAttributes) {
this(jpaEntityFieldName, null, List.of(subEntityAttributes));
}
DistributionSetFields(final String fieldName, final Entry<String, String> subEntityMapTuple) {
this(fieldName, subEntityMapTuple, Collections.emptyList());
DistributionSetFields(final String jpaEntityFieldName, final Entry<String, String> subEntityMapTuple) {
this(jpaEntityFieldName, subEntityMapTuple, Collections.emptyList());
}
DistributionSetFields(final String fieldName, final Entry<String, String> subEntityMapTuple, List<String> subEntityAttributes) {
this.fieldName = fieldName;
DistributionSetFields(final String jpaEntityFieldName, final Entry<String, String> subEntityMapTuple, List<String> subEntityAttributes) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityMapTuple = subEntityMapTuple;
this.subEntityAttributes = subEntityAttributes;
}

View File

@@ -15,19 +15,19 @@ import lombok.Getter;
* Sort fields for DistributionSetMetadata.
*/
@Getter
public enum DistributionSetMetadataFields implements FieldNameProvider {
public enum DistributionSetMetadataFields implements RsqlQueryField {
KEY("key"),
VALUE("value");
private final String fieldName;
private final String jpaEntityFieldName;
DistributionSetMetadataFields(final String fieldName) {
this.fieldName = fieldName;
DistributionSetMetadataFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
@Override
public String identifierFieldName() {
return KEY.getFieldName();
return KEY.getJpaEntityFieldName();
}
}

View File

@@ -21,25 +21,25 @@ import java.util.List;
* filtering over distribution set fields also.
*/
@Getter
public enum DistributionSetTagFields implements FieldNameProvider {
public enum DistributionSetTagFields implements RsqlQueryField {
ID(TagFields.ID.getFieldName()),
NAME(TagFields.NAME.getFieldName()),
DESCRIPTION(TagFields.DESCRIPTION.getFieldName()),
COLOUR(TagFields.COLOUR.getFieldName()),
ID(TagFields.ID.getJpaEntityFieldName()),
NAME(TagFields.NAME.getJpaEntityFieldName()),
DESCRIPTION(TagFields.DESCRIPTION.getJpaEntityFieldName()),
COLOUR(TagFields.COLOUR.getJpaEntityFieldName()),
DISTRIBUTIONSET("assignedToDistributionSet",
DistributionSetFields.ID.getFieldName(), DistributionSetFields.NAME.getFieldName());
DistributionSetFields.ID.getJpaEntityFieldName(), DistributionSetFields.NAME.getJpaEntityFieldName());
private final String fieldName;
private final String jpaEntityFieldName;
private final List<String> subEntityAttributes;
DistributionSetTagFields(final String fieldName) {
this.fieldName = fieldName;
DistributionSetTagFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityAttributes = Collections.emptyList();
}
DistributionSetTagFields(final String fieldName, final String... subEntityAttributes) {
this.fieldName = fieldName;
DistributionSetTagFields(final String jpaEntityFieldName, final String... subEntityAttributes) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityAttributes = List.of(subEntityAttributes);
}
}

View File

@@ -16,16 +16,16 @@ import lombok.Getter;
* the REST API e.g. for sorting etc.
*/
@Getter
public enum DistributionSetTypeFields implements FieldNameProvider {
public enum DistributionSetTypeFields implements RsqlQueryField {
ID("id"),
KEY("key"),
NAME("name"),
DESCRIPTION("description");
private final String fieldName;
private final String jpaEntityFieldName;
DistributionSetTypeFields(final String fieldName) {
this.fieldName = fieldName;
DistributionSetTypeFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
}

View File

@@ -18,26 +18,26 @@ import java.util.List;
* Describing the fields of the Rollout model which can be used in the REST API e.g. for sorting etc.
*/
@Getter
public enum RolloutFields implements FieldNameProvider {
public enum RolloutFields implements RsqlQueryField {
ID("id"),
NAME("name"),
DESCRIPTION("description"),
STATUS("status"),
DISTRIBUTIONSET("distributionSet", DistributionSetFields.ID.getFieldName(),
DistributionSetFields.NAME.getFieldName(), DistributionSetFields.VERSION.getFieldName(),
DistributionSetFields.TYPE.getFieldName());
DISTRIBUTIONSET("distributionSet", DistributionSetFields.ID.getJpaEntityFieldName(),
DistributionSetFields.NAME.getJpaEntityFieldName(), DistributionSetFields.VERSION.getJpaEntityFieldName(),
DistributionSetFields.TYPE.getJpaEntityFieldName());
private final String fieldName;
private final String jpaEntityFieldName;
private final List<String> subEntityAttributes;
RolloutFields(final String fieldName) {
this.fieldName = fieldName;
RolloutFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityAttributes = Collections.emptyList();
}
RolloutFields(final String fieldName, final String... subEntityAttributes) {
this.fieldName = fieldName;
RolloutFields(final String jpaEntityFieldName, final String... subEntityAttributes) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityAttributes = List.of(subEntityAttributes);
}
}

View File

@@ -15,15 +15,15 @@ import lombok.Getter;
* Describing the fields of the RolloutGroup model which can be used in the REST API e.g. for sorting etc.
*/
@Getter
public enum RolloutGroupFields implements FieldNameProvider {
public enum RolloutGroupFields implements RsqlQueryField {
ID("id"),
NAME("name"),
DESCRIPTION("description");
private final String fieldName;
private final String jpaEntityFieldName;
RolloutGroupFields(final String fieldName) {
this.fieldName = fieldName;
RolloutGroupFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
}

View File

@@ -15,15 +15,13 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import jakarta.validation.constraints.NotNull;
import org.springframework.util.ObjectUtils;
/**
* An interface for declaring the name of the field described in the database
* which is used as string representation of the field, e.g. for sorting the
* fields over REST.
* An RSQL query field interface extended by all the fields that could be used in RSQL queries.
*/
@FunctionalInterface
public interface FieldNameProvider {
public interface RsqlQueryField {
/**
* Separator for the sub attributes
@@ -32,10 +30,10 @@ public interface FieldNameProvider {
String SUB_ATTRIBUTE_SPLIT_REGEX = "\\" + SUB_ATTRIBUTE_SEPARATOR;
/**
* @return the string representation of the underlying persistence field
* name e.g. in case of sorting. Never {@code null}.
* @return the string representation of the underlying persistence field name e.g. in case of sorting.
*/
String getFieldName();
@NotNull
String getJpaEntityFieldName();
/**
* Returns the sub attributes
@@ -48,7 +46,7 @@ public interface FieldNameProvider {
final String[] subAttributes = propertyFieldName.split(SUB_ATTRIBUTE_SPLIT_REGEX, 2);
// [0] field name | [1] key name (could miss, e.g. for target attributes)
final String mapKeyName = subAttributes.length == 2 ? subAttributes[1] : null;
return ObjectUtils.isEmpty(mapKeyName) ? new String[] { getFieldName() } : new String[] { getFieldName(), mapKeyName };
return ObjectUtils.isEmpty(mapKeyName) ? new String[] { getJpaEntityFieldName() } : new String[] { getJpaEntityFieldName(), mapKeyName };
} else {
return propertyFieldName.split(SUB_ATTRIBUTE_SPLIT_REGEX);
}

View File

@@ -19,7 +19,7 @@ import java.util.Optional;
* Describing the fields of the SoftwareModule model which can be used in the REST API e.g. for sorting etc.
*/
@Getter
public enum SoftwareModuleFields implements FieldNameProvider {
public enum SoftwareModuleFields implements RsqlQueryField {
ID("id"),
TYPE("type.key"),
@@ -28,15 +28,15 @@ public enum SoftwareModuleFields implements FieldNameProvider {
VERSION("version"),
METADATA("metadata", new SimpleImmutableEntry<>("key", "value"));
private final String fieldName;
private final String jpaEntityFieldName;
private Entry<String, String> subEntityMapTuple;
SoftwareModuleFields(final String fieldName) {
this(fieldName, null);
SoftwareModuleFields(final String jpaEntityFieldName) {
this(jpaEntityFieldName, null);
}
SoftwareModuleFields(final String fieldName, final Entry<String, String> subEntityMapTuple) {
this.fieldName = fieldName;
SoftwareModuleFields(final String jpaEntityFieldName, final Entry<String, String> subEntityMapTuple) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityMapTuple = subEntityMapTuple;
}

View File

@@ -15,20 +15,20 @@ import lombok.Getter;
* Sort fields for SoftwareModuleMetadata.
*/
@Getter
public enum SoftwareModuleMetadataFields implements FieldNameProvider {
public enum SoftwareModuleMetadataFields implements RsqlQueryField {
KEY("key"),
VALUE("value"),
TARGETVISIBLE("targetVisible");
private final String fieldName;
private final String jpaEntityFieldName;
SoftwareModuleMetadataFields(final String fieldName) {
this.fieldName = fieldName;
SoftwareModuleMetadataFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
@Override
public String identifierFieldName() {
return KEY.getFieldName();
return KEY.getJpaEntityFieldName();
}
}

View File

@@ -15,7 +15,7 @@ import lombok.Getter;
* Describing the fields of the SoftwareModuleType model which can be used in the REST API e.g. for sorting etc.
*/
@Getter
public enum SoftwareModuleTypeFields implements FieldNameProvider {
public enum SoftwareModuleTypeFields implements RsqlQueryField {
ID("id"),
KEY("key"),
@@ -23,9 +23,9 @@ public enum SoftwareModuleTypeFields implements FieldNameProvider {
DESCRIPTION("description"),
MAXASSIGNMENTS("maxAssignments");
private final String fieldName;
private final String jpaEntityFieldName;
SoftwareModuleTypeFields(final String fieldName) {
this.fieldName = fieldName;
SoftwareModuleTypeFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
}

View File

@@ -15,16 +15,16 @@ import lombok.Getter;
* Describing the fields of the Tag model which can be used in the REST API e.g. for sorting etc.
*/
@Getter
public enum TagFields implements FieldNameProvider {
public enum TagFields implements RsqlQueryField {
ID("id"),
NAME("name"),
DESCRIPTION("description"),
COLOUR("colour");
private final String fieldName;
private final String jpaEntityFieldName;
TagFields(final String fieldName) {
this.fieldName = fieldName;
TagFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
}

View File

@@ -22,7 +22,7 @@ import java.util.Optional;
* e.g. for sorting etc.
*/
@Getter
public enum TargetFields implements FieldNameProvider {
public enum TargetFields implements RsqlQueryField {
ID("controllerId"),
NAME("name"),
@@ -38,26 +38,26 @@ public enum TargetFields implements FieldNameProvider {
TAG("tags.name"),
LASTCONTROLLERREQUESTAT("lastTargetQuery"),
METADATA("metadata", new SimpleImmutableEntry<>("key", "value")),
TARGETTYPE("targetType", TargetTypeFields.KEY.getFieldName(), TargetTypeFields.NAME.getFieldName());
TARGETTYPE("targetType", TargetTypeFields.KEY.getJpaEntityFieldName(), TargetTypeFields.NAME.getJpaEntityFieldName());
private final String fieldName;
private final String jpaEntityFieldName;
private final List<String> subEntityAttributes;
private final Entry<String, String> subEntityMapTuple;
TargetFields(final String fieldName) {
this(fieldName, Collections.emptyList(), null);
TargetFields(final String jpaEntityFieldName) {
this(jpaEntityFieldName, Collections.emptyList(), null);
}
TargetFields(final String fieldName, final String... subEntityAttributes) {
this(fieldName, List.of(subEntityAttributes), null);
TargetFields(final String jpaEntityFieldName, final String... subEntityAttributes) {
this(jpaEntityFieldName, List.of(subEntityAttributes), null);
}
TargetFields(final String fieldName, final Entry<String, String> subEntityMapTuple) {
this(fieldName, Collections.emptyList(), subEntityMapTuple);
TargetFields(final String jpaEntityFieldName, final Entry<String, String> subEntityMapTuple) {
this(jpaEntityFieldName, Collections.emptyList(), subEntityMapTuple);
}
TargetFields(final String fieldName, final List<String> subEntityAttributes, final Entry<String, String> subEntityMapTuple) {
this.fieldName = fieldName;
TargetFields(final String jpaEntityFieldName, final List<String> subEntityAttributes, final Entry<String, String> subEntityMapTuple) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityAttributes = subEntityAttributes;
this.subEntityMapTuple = subEntityMapTuple;
}

View File

@@ -18,25 +18,25 @@ import java.util.List;
* Describing the fields of the Target model which can be used in the REST API e.g. for sorting etc.
*/
@Getter
public enum TargetFilterQueryFields implements FieldNameProvider {
public enum TargetFilterQueryFields implements RsqlQueryField {
ID("id"),
NAME("name"),
AUTOASSIGNDISTRIBUTIONSET("autoAssignDistributionSet", "name", "version");
private final String fieldName;
private final String jpaEntityFieldName;
private List<String> subEntityAttributes;
TargetFilterQueryFields(final String fieldName) {
this(fieldName, Collections.emptyList());
TargetFilterQueryFields(final String jpaEntityFieldName) {
this(jpaEntityFieldName, Collections.emptyList());
}
TargetFilterQueryFields(final String fieldName, final String... subEntityAttribues) {
this(fieldName, List.of(subEntityAttribues));
TargetFilterQueryFields(final String jpaEntityFieldName, final String... subEntityAttribues) {
this(jpaEntityFieldName, List.of(subEntityAttribues));
}
TargetFilterQueryFields(final String fieldName, final List<String> subEntityAttribues) {
this.fieldName = fieldName;
TargetFilterQueryFields(final String jpaEntityFieldName, final List<String> subEntityAttribues) {
this.jpaEntityFieldName = jpaEntityFieldName;
this.subEntityAttributes = subEntityAttribues;
}
}

View File

@@ -15,19 +15,19 @@ import lombok.Getter;
* Sort fields for TargetMetadata.
*/
@Getter
public enum TargetMetadataFields implements FieldNameProvider {
public enum TargetMetadataFields implements RsqlQueryField {
KEY("key"),
VALUE("value");
private final String fieldName;
private final String jpaEntityFieldName;
TargetMetadataFields(final String fieldName) {
this.fieldName = fieldName;
TargetMetadataFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
@Override
public String identifierFieldName() {
return KEY.getFieldName();
return KEY.getJpaEntityFieldName();
}
}

View File

@@ -16,16 +16,16 @@ import lombok.Getter;
* Additionally, here were added fields for Target in order filtering over target fields also.
*/
@Getter
public enum TargetTagFields implements FieldNameProvider {
public enum TargetTagFields implements RsqlQueryField {
ID(TagFields.ID.getFieldName()),
NAME(TagFields.NAME.getFieldName()),
DESCRIPTION(TagFields.DESCRIPTION.getFieldName()),
COLOUR(TagFields.COLOUR.getFieldName());
ID(TagFields.ID.getJpaEntityFieldName()),
NAME(TagFields.NAME.getJpaEntityFieldName()),
DESCRIPTION(TagFields.DESCRIPTION.getJpaEntityFieldName()),
COLOUR(TagFields.COLOUR.getJpaEntityFieldName());
private final String fieldName;
private final String jpaEntityFieldName;
TargetTagFields(final String fieldName) {
this.fieldName = fieldName;
TargetTagFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
}

View File

@@ -15,16 +15,16 @@ import lombok.Getter;
* Describing the fields of the TargetType model which can be used in the REST API
*/
@Getter
public enum TargetTypeFields implements FieldNameProvider {
public enum TargetTypeFields implements RsqlQueryField {
ID("id"),
KEY("key"),
NAME("name"),
DESCRIPTION("description");
private final String fieldName;
private final String jpaEntityFieldName;
TargetTypeFields(final String fieldName) {
this.fieldName = fieldName;
TargetTypeFields(final String jpaEntityFieldName) {
this.jpaEntityFieldName = jpaEntityFieldName;
}
}

View File

@@ -27,16 +27,16 @@ public class FileNameFieldsTest {
public void repositoryManagementMethodsArePreAuthorizedAnnotated() {
final String packageName = getClass().getPackage().getName();
try (final ScanResult scanResult = new ClassGraph().acceptPackages(packageName).scan()) {
final List<? extends Class<? extends FieldNameProvider>> matchingClasses = scanResult.getAllClasses()
final List<? extends Class<? extends RsqlQueryField>> matchingClasses = scanResult.getAllClasses()
.stream()
.filter(classInPackage -> classInPackage.implementsInterface(FieldNameProvider.class))
.filter(classInPackage -> classInPackage.implementsInterface(RsqlQueryField.class))
.map(ClassInfo::loadClass)
.map(clazz -> (Class<? extends FieldNameProvider>) clazz)
.map(clazz -> (Class<? extends RsqlQueryField>) clazz)
.toList();
assertThat(matchingClasses).isNotEmpty();
matchingClasses.forEach(providerClass -> {
assertThat(providerClass.getEnumConstants()).isNotEmpty();
for (final FieldNameProvider provider : providerClass.getEnumConstants()) {
for (final RsqlQueryField provider : providerClass.getEnumConstants()) {
if (provider.isMap() && !provider.getSubEntityAttributes().isEmpty()) {
throw new UnsupportedOperationException(
"Currently sub-entity attributes for maps are not supported, alternatively you could use the key/value tuple, defined by SimpleImmutableEntry class");