Feature target metadata filter (#767)

* implemented RSQL query filter for target metadata

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>

* refactored rsql fields providers code for targets, distribution sets and software modules for consistency, fixed predicate grouping for map fields in rsql utility

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>

* extended tests for target management rsql queries with target metadata

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>

* extended target management test for RSQL not equal case of target metadata, added a suggestion of comparator operators when map key ends with = or ! symbol in Target Filter View

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>

* Fixed peer review findings

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>

* small test fixes: seconds are respected while scheduling the maintenance window, redundant ds-target assignment statement removed

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>
This commit is contained in:
Bondar Bogdan
2018-11-28 14:09:52 +01:00
committed by Dominic Schabel
parent a460f61e13
commit b2dfd4a99e
16 changed files with 272 additions and 153 deletions

View File

@@ -8,6 +8,10 @@
*/
package org.eclipse.hawkbit.repository;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Map.Entry;
import java.util.Optional;
/**
* Describing the fields of the DistributionSet model which can be used in the
* REST API e.g. for sorting etc.
@@ -59,35 +63,39 @@ public enum DistributionSetFields implements FieldNameProvider {
/**
* The metadata.
*/
METADATA("metadata", "key", "value");
METADATA("metadata", new SimpleImmutableEntry<>("key", "value"));
private final String fieldName;
private String keyFieldName;
private String valueFieldName;
private boolean mapField;
private Entry<String, String> subEntityMapTuple;
private DistributionSetFields(final String fieldName) {
this(fieldName, null, null);
this(fieldName, false, null);
}
private DistributionSetFields(final String fieldName, final String keyFieldName, final String valueFieldName) {
private DistributionSetFields(final String fieldName, final Entry<String, String> subEntityMapTuple) {
this(fieldName, true, subEntityMapTuple);
}
private DistributionSetFields(final String fieldName, final boolean mapField,
final Entry<String, String> subEntityMapTuple) {
this.fieldName = fieldName;
this.keyFieldName = keyFieldName;
this.valueFieldName = valueFieldName;
this.mapField = mapField;
this.subEntityMapTuple = subEntityMapTuple;
}
@Override
public String getValueFieldName() {
return valueFieldName;
public Optional<Entry<String, String>> getSubEntityMapTuple() {
return Optional.ofNullable(subEntityMapTuple);
}
@Override
public String getKeyFieldName() {
return keyFieldName;
public boolean isMap() {
return mapField;
}
@Override
public String getFieldName() {
return fieldName;
}
}

View File

@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.repository;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
/**
* An interface for declaring the name of the field described in the database
@@ -65,21 +67,10 @@ public interface FieldNameProvider {
}
/**
* The database column for the key
*
* @return key fieldname
* @return a key/value tuple of a sub entity.
*/
default String getKeyFieldName() {
return null;
}
/**
* The database column for the value
*
* @return key fieldname
*/
default String getValueFieldName() {
return null;
default Optional<Entry<String, String>> getSubEntityMapTuple() {
return Optional.empty();
}
/**
@@ -88,6 +79,6 @@ public interface FieldNameProvider {
* @return <true> is a map <false> is not a map
*/
default boolean isMap() {
return getKeyFieldName() != null;
return false;
}
}

View File

@@ -8,6 +8,10 @@
*/
package org.eclipse.hawkbit.repository;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Map.Entry;
import java.util.Optional;
/**
* Describing the fields of the SoftwareModule model which can be used in the
* REST API e.g. for sorting etc.
@@ -40,34 +44,39 @@ public enum SoftwareModuleFields implements FieldNameProvider {
/**
* The metadata.
*/
METADATA("metadata", "key", "value");
METADATA("metadata", new SimpleImmutableEntry<>("key", "value"));
private final String fieldName;
private String keyFieldName;
private String valueFieldName;
private boolean mapField;
private Entry<String, String> subEntityMapTuple;
private SoftwareModuleFields(final String fieldName) {
this(fieldName, null, null);
this(fieldName, false, null);
}
private SoftwareModuleFields(final String fieldName, final String keyFieldName, final String valueFieldName) {
private SoftwareModuleFields(final String fieldName, final Entry<String, String> subEntityMapTuple) {
this(fieldName, true, subEntityMapTuple);
}
private SoftwareModuleFields(final String fieldName, final boolean mapField,
final Entry<String, String> subEntityMapTuple) {
this.fieldName = fieldName;
this.keyFieldName = keyFieldName;
this.valueFieldName = valueFieldName;
this.mapField = mapField;
this.subEntityMapTuple = subEntityMapTuple;
}
@Override
public Optional<Entry<String, String>> getSubEntityMapTuple() {
return Optional.ofNullable(subEntityMapTuple);
}
@Override
public boolean isMap() {
return mapField;
}
@Override
public String getFieldName() {
return fieldName;
}
@Override
public String getKeyFieldName() {
return keyFieldName;
}
@Override
public String getValueFieldName() {
return valueFieldName;
}
}

View File

@@ -8,9 +8,12 @@
*/
package org.eclipse.hawkbit.repository;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
/**
* Describing the fields of the Target model which can be used in the REST API
@@ -77,28 +80,40 @@ public enum TargetFields implements FieldNameProvider {
/**
* Last time the DDI or DMF client polled.
*/
LASTCONTROLLERREQUESTAT("lastTargetQuery");
LASTCONTROLLERREQUESTAT("lastTargetQuery"),
/**
* The metadata.
*/
METADATA("metadata", new SimpleImmutableEntry<>("key", "value"));
private final String fieldName;
private List<String> subEntityAttribues;
private boolean mapField;
private Entry<String, String> subEntityMapTuple;
TargetFields(final String fieldName) {
this(fieldName, false, Collections.emptyList());
private TargetFields(final String fieldName) {
this(fieldName, false, Collections.emptyList(), null);
}
TargetFields(final String fieldName, final boolean isMapField) {
this(fieldName, isMapField, Collections.emptyList());
private TargetFields(final String fieldName, final boolean isMapField) {
this(fieldName, isMapField, Collections.emptyList(), null);
}
TargetFields(final String fieldName, final String... subEntityAttribues) {
this(fieldName, false, Arrays.asList(subEntityAttribues));
private TargetFields(final String fieldName, final String... subEntityAttribues) {
this(fieldName, false, Arrays.asList(subEntityAttribues), null);
}
TargetFields(final String fieldName, final boolean mapField, final List<String> subEntityAttribues) {
private TargetFields(final String fieldName, final Entry<String, String> subEntityMapTuple) {
this(fieldName, true, Collections.emptyList(), subEntityMapTuple);
}
private TargetFields(final String fieldName, final boolean mapField, final List<String> subEntityAttribues,
final Entry<String, String> subEntityMapTuple) {
this.fieldName = fieldName;
this.mapField = mapField;
this.subEntityAttribues = subEntityAttribues;
this.subEntityMapTuple = subEntityMapTuple;
}
@Override
@@ -106,6 +121,11 @@ public enum TargetFields implements FieldNameProvider {
return subEntityAttribues;
}
@Override
public Optional<Entry<String, String>> getSubEntityMapTuple() {
return Optional.ofNullable(subEntityMapTuple);
}
@Override
public boolean isMap() {
return mapField;

View File

@@ -36,34 +36,27 @@ public enum TargetFilterQueryFields implements FieldNameProvider {
private final String fieldName;
private List<String> subEntityAttributes;
private boolean mapField;
TargetFilterQueryFields(final String fieldName) {
this(fieldName, false, Collections.emptyList());
private TargetFilterQueryFields(final String fieldName) {
this(fieldName, Collections.emptyList());
}
TargetFilterQueryFields(final String fieldName, final String... subEntityAttribues) {
this(fieldName, false, Arrays.asList(subEntityAttribues));
private TargetFilterQueryFields(final String fieldName, final String... subEntityAttribues) {
this(fieldName, Arrays.asList(subEntityAttribues));
}
TargetFilterQueryFields(final String fieldName, final boolean mapField, final List<String> subEntityAttribues) {
private TargetFilterQueryFields(final String fieldName, final List<String> subEntityAttribues) {
this.fieldName = fieldName;
this.mapField = mapField;
this.subEntityAttributes = subEntityAttribues;
}
@Override
public List<String> getSubEntityAttributes() {
return subEntityAttributes;
}
@Override
public boolean isMap() {
return mapField;
}
@Override
public String getFieldName() {
return fieldName;
}
@Override
public List<String> getSubEntityAttributes() {
return subEntityAttributes;
}
}

View File

@@ -25,7 +25,7 @@ public enum TargetMetadataFields implements FieldNameProvider {
private final String fieldName;
TargetMetadataFields(final String fieldName) {
private TargetMetadataFields(final String fieldName) {
this.fieldName = fieldName;
}