]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7576 WS api/measures/component_tree filter components without measure on the... 939/head
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Mon, 9 May 2016 14:13:08 +0000 (16:13 +0200)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Tue, 10 May 2016 13:06:05 +0000 (15:06 +0200)
server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java
server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java
sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresWsParameters.java
sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java

index 8af4ffe482bc46dafd23f1f3c660a011757b2c47..be23ef35f58d39a78c7254482ebfb3759920d69e 100644 (file)
@@ -58,6 +58,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_DEVELOP
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_KEYS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_PERIOD_SORT;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT_FILTER;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_QUALIFIERS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEGY;
 
@@ -80,16 +81,21 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEG
 public class ComponentTreeAction implements MeasuresWsAction {
   private static final int MAX_SIZE = 500;
   private static final int QUERY_MINIMUM_LENGTH = 3;
+  // tree exploration strategies
   static final String ALL_STRATEGY = "all";
   static final String CHILDREN_STRATEGY = "children";
   static final String LEAVES_STRATEGY = "leaves";
   static final Set<String> STRATEGIES = ImmutableSortedSet.of(ALL_STRATEGY, CHILDREN_STRATEGY, LEAVES_STRATEGY);
+  // sort
   static final String NAME_SORT = "name";
   static final String PATH_SORT = "path";
   static final String QUALIFIER_SORT = "qualifier";
   static final String METRIC_SORT = "metric";
   static final String METRIC_PERIOD_SORT = "metricPeriod";
   static final Set<String> SORTS = ImmutableSortedSet.of(NAME_SORT, PATH_SORT, QUALIFIER_SORT, METRIC_SORT, METRIC_PERIOD_SORT);
+  static final String ALL_METRIC_SORT_FILTER = "all";
+  static final String WITH_MEASURES_ONLY_METRIC_SORT_FILTER = "withMeasuresOnly";
+  static final Set<String> METRIC_SORT_FILTERS = ImmutableSortedSet.of(ALL_METRIC_SORT_FILTER, WITH_MEASURES_ONLY_METRIC_SORT_FILTER);
 
   private final ComponentTreeDataLoader dataLoader;
   private final UserSession userSession;
@@ -152,6 +158,15 @@ public class ComponentTreeAction implements MeasuresWsAction {
       .setSince("5.5")
       .setPossibleValues(1, 2, 3, 4, 5);
 
+    action.createParam(PARAM_METRIC_SORT_FILTER)
+      .setDescription(format("Filter components. Sort must be on a metric. Possible values are: " +
+        "<ul>" +
+        "<li>%s: return all components</li>" +
+        "<li>%s: filter out components that do not have a measure on the sorted metric</li>" +
+        "</ul>", ALL_METRIC_SORT_FILTER, WITH_MEASURES_ONLY_METRIC_SORT_FILTER))
+      .setDefaultValue(ALL_METRIC_SORT_FILTER)
+      .setPossibleValues(METRIC_SORT_FILTERS);
+
     createMetricKeysParameter(action);
     createAdditionalFieldsParameter(action);
     createDeveloperParameters(action);
@@ -253,6 +268,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
       .setSort(request.paramAsStrings(Param.SORT))
       .setAsc(request.paramAsBoolean(Param.ASCENDING))
       .setMetricSort(request.param(PARAM_METRIC_SORT))
+      .setMetricSortFilter(request.mandatoryParam(PARAM_METRIC_SORT_FILTER))
       .setMetricPeriodSort(request.paramAsInt(PARAM_METRIC_PERIOD_SORT))
       .setDeveloperId(request.param(PARAM_DEVELOPER_ID))
       .setDeveloperKey(request.param(PARAM_DEVELOPER_KEY))
@@ -273,6 +289,9 @@ public class ComponentTreeAction implements MeasuresWsAction {
       "To sort by the '%s' metric, it must be in the list of metric keys in the '%s' parameter", metricSortValue, PARAM_METRIC_KEYS);
     checkRequest(componentTreeWsRequest.getMetricPeriodSort() == null ^ componentTreeWsRequest.getSort().contains(METRIC_PERIOD_SORT),
       "To sort by a metric period, the '%s' parameter must contain '%s' and the '%s' must be provided.", Param.SORT, METRIC_PERIOD_SORT, PARAM_METRIC_PERIOD_SORT);
+    checkRequest(ALL_METRIC_SORT_FILTER.equals(componentTreeWsRequest.getMetricSortFilter()) || metricSortValue != null,
+      "To filter components based on the sort metric, the '%s' parameter must contain '%s' or '%s' and the '%s' parameter must be provided",
+      Param.SORT, METRIC_SORT, METRIC_PERIOD_SORT, PARAM_METRIC_SORT);
     return componentTreeWsRequest;
   }
 }
index 789a2171d007bffa154d8f550dde2dd1e20b7fcd..aa82944b8b64191dd9d185e3cd48f5975e863b69 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.measure.ws;
 
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.collect.HashBasedTable;
@@ -61,6 +62,7 @@ import org.sonarqube.ws.WsMeasures;
 import org.sonarqube.ws.client.measure.ComponentTreeWsRequest;
 
 import static com.google.common.base.Objects.firstNonNull;
+import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.FluentIterable.from;
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Sets.newHashSet;
@@ -76,6 +78,7 @@ import static org.sonar.server.measure.ws.ComponentTreeAction.LEAVES_STRATEGY;
 import static org.sonar.server.measure.ws.ComponentTreeAction.METRIC_PERIOD_SORT;
 import static org.sonar.server.measure.ws.ComponentTreeAction.METRIC_SORT;
 import static org.sonar.server.measure.ws.ComponentTreeAction.NAME_SORT;
+import static org.sonar.server.measure.ws.ComponentTreeAction.WITH_MEASURES_ONLY_METRIC_SORT_FILTER;
 import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriods.snapshotToWsPeriods;
 import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
 
@@ -116,6 +119,7 @@ public class ComponentTreeDataLoader {
       Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric = searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, baseSnapshot, components, metrics,
         periods, developerId);
 
+      components = filterComponents(components, measuresByComponentUuidAndMetric, metrics, wsRequest);
       components = sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric);
       components = paginateComponents(components, componentCount, wsRequest);
       Map<Long, ComponentDto> referenceComponentsById = searchReferenceComponentsById(dbSession, components);
@@ -227,8 +231,8 @@ public class ComponentTreeDataLoader {
   /**
    * Conditions for best value measure:
    * <ul>
-   *   <li>component is a production file or test file</li>
-   *   <li>metric is optimized for best value</li>
+   * <li>component is a production file or test file</li>
+   * <li>metric is optimized for best value</li>
    * </ul>
    */
   private static void addBestValuesToMeasures(Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric, List<ComponentDtoWithSnapshotId> components,
@@ -251,6 +255,22 @@ public class ComponentTreeDataLoader {
     }
   }
 
+  private static List<ComponentDtoWithSnapshotId> filterComponents(List<ComponentDtoWithSnapshotId> components,
+    Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric,
+    List<MetricDto> metrics, ComponentTreeWsRequest wsRequest) {
+    if (!WITH_MEASURES_ONLY_METRIC_SORT_FILTER.equals(wsRequest.getMetricSortFilter())) {
+      return components;
+    }
+
+    final String metricKeyToSort = wsRequest.getMetricSort();
+    Optional<MetricDto> metricToSort = from(metrics).firstMatch(new MatchMetricKey(metricKeyToSort));
+    checkState(metricToSort.isPresent(), "Metric '%s' not found", metricKeyToSort, wsRequest.getMetricKeys());
+
+    return from(components)
+      .filter(new HasMeasure(measuresByComponentUuidAndMetric, metricToSort.get()))
+      .toList();
+  }
+
   private static List<ComponentDtoWithSnapshotId> sortComponents(List<ComponentDtoWithSnapshotId> components, ComponentTreeWsRequest wsRequest, List<MetricDto> metrics,
     Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric) {
     if (!isSortByMetric(wsRequest)) {
@@ -276,6 +296,7 @@ public class ComponentTreeDataLoader {
   }
 
   private static boolean isSortByMetric(ComponentTreeWsRequest wsRequest) {
+    requireNonNull(wsRequest.getSort());
     return wsRequest.getSort().contains(METRIC_SORT) || wsRequest.getSort().contains(METRIC_PERIOD_SORT);
   }
 
@@ -389,9 +410,38 @@ public class ComponentTreeDataLoader {
 
   private enum ComponentDtoWithSnapshotIdToCopyResourceIdFunction implements Function<ComponentDtoWithSnapshotId, Long> {
     INSTANCE;
+
     @Override
     public Long apply(@Nonnull ComponentDtoWithSnapshotId input) {
       return input.getCopyResourceId();
     }
   }
+
+  private static class HasMeasure implements Predicate<ComponentDtoWithSnapshotId> {
+    private final Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric;
+    private final MetricDto metric;
+
+    private HasMeasure(Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric, MetricDto metric) {
+      this.measuresByComponentUuidAndMetric = measuresByComponentUuidAndMetric;
+      this.metric = metric;
+    }
+
+    @Override
+    public boolean apply(@Nonnull ComponentDtoWithSnapshotId input) {
+      return measuresByComponentUuidAndMetric.contains(input.uuid(), metric);
+    }
+  }
+
+  private static class MatchMetricKey implements Predicate<MetricDto> {
+    private final String metricKeyToSort;
+
+    private MatchMetricKey(String metricKeyToSort) {
+      this.metricKeyToSort = metricKeyToSort;
+    }
+
+    @Override
+    public boolean apply(@Nonnull MetricDto input) {
+      return input.getKey().equals(metricKeyToSort);
+    }
+  }
 }
index cc932d405b9b48599c06c7e2a456979a187c268c..f523642673ffa8644fdfa0d79ebf15a9997f41c7 100644 (file)
@@ -70,6 +70,7 @@ import static org.sonar.server.measure.ws.ComponentTreeAction.LEAVES_STRATEGY;
 import static org.sonar.server.measure.ws.ComponentTreeAction.METRIC_PERIOD_SORT;
 import static org.sonar.server.measure.ws.ComponentTreeAction.METRIC_SORT;
 import static org.sonar.server.measure.ws.ComponentTreeAction.NAME_SORT;
+import static org.sonar.server.measure.ws.ComponentTreeAction.WITH_MEASURES_ONLY_METRIC_SORT_FILTER;
 import static org.sonar.test.JsonAssert.assertJson;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ADDITIONAL_PERIODS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS;
@@ -79,6 +80,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_DEVELOP
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_KEYS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_PERIOD_SORT;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT_FILTER;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_QUALIFIERS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEGY;
 
@@ -256,6 +258,7 @@ public class ComponentTreeActionTest {
   public void sort_by_metric_value() {
     ComponentDto projectDto = newProjectDto("project-uuid");
     SnapshotDto projectSnapshot = componentDb.insertProjectAndSnapshot(projectDto);
+    componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-4"), projectSnapshot);
     SnapshotDto fileSnapshot3 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-3"), projectSnapshot);
     SnapshotDto fileSnapshot1 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-1"), projectSnapshot);
     SnapshotDto fileSnapshot2 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-2"), projectSnapshot);
@@ -273,7 +276,35 @@ public class ComponentTreeActionTest {
       .setParam(PARAM_METRIC_SORT, "ncloc")
       .setParam(PARAM_METRIC_KEYS, "ncloc"));
 
-    assertThat(response.getComponentsList()).extracting("id").containsExactly("file-uuid-1", "file-uuid-2", "file-uuid-3");
+    assertThat(response.getComponentsList()).extracting("id").containsExactly("file-uuid-1", "file-uuid-2", "file-uuid-3", "file-uuid-4");
+  }
+
+  @Test
+  public void remove_components_without_measure_on_the_metric_sort() {
+    ComponentDto projectDto = newProjectDto("project-uuid");
+    SnapshotDto projectSnapshot = componentDb.insertProjectAndSnapshot(projectDto);
+    componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-4"), projectSnapshot);
+    SnapshotDto fileSnapshot3 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-3"), projectSnapshot);
+    SnapshotDto fileSnapshot1 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-1"), projectSnapshot);
+    SnapshotDto fileSnapshot2 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-2"), projectSnapshot);
+    MetricDto ncloc = newMetricDtoWithoutOptimization().setKey("ncloc").setValueType(ValueType.INT.name()).setDirection(1);
+    dbClient.metricDao().insert(dbSession, ncloc);
+    dbClient.measureDao().insert(dbSession,
+      newMeasureDto(ncloc, fileSnapshot1.getId()).setValue(1.0d),
+      newMeasureDto(ncloc, fileSnapshot2.getId()).setValue(2.0d),
+      newMeasureDto(ncloc, fileSnapshot3.getId()).setValue(3.0d));
+    db.commit();
+
+    ComponentTreeWsResponse response = call(ws.newRequest()
+      .setParam(PARAM_BASE_COMPONENT_ID, "project-uuid")
+      .setParam(Param.SORT, METRIC_SORT)
+      .setParam(PARAM_METRIC_SORT, "ncloc")
+      .setParam(PARAM_METRIC_KEYS, "ncloc")
+      .setParam(PARAM_METRIC_SORT_FILTER, WITH_MEASURES_ONLY_METRIC_SORT_FILTER));
+
+    assertThat(response.getComponentsList()).extracting("id")
+      .containsExactly("file-uuid-1", "file-uuid-2", "file-uuid-3")
+      .doesNotContain("file-uuid-4");
   }
 
   @Test
@@ -393,8 +424,7 @@ public class ComponentTreeActionTest {
     ComponentTreeWsResponse result = call(ws.newRequest()
       .setParam(PARAM_BASE_COMPONENT_ID, projectUuid)
       .setParam(PARAM_STRATEGY, LEAVES_STRATEGY)
-      .setParam(PARAM_METRIC_KEYS, "ncloc")
-    );
+      .setParam(PARAM_METRIC_KEYS, "ncloc"));
 
     assertThat(result.getBaseComponent().getId()).isEqualTo(projectUuid);
     assertThat(result.getComponentsCount()).isEqualTo(0);
@@ -527,6 +557,20 @@ public class ComponentTreeActionTest {
       .setParam(Param.PAGE_SIZE, "2540"));
   }
 
+  @Test
+  public void fail_when_with_measures_only_and_no_metric_sort() {
+    componentDb.insertProjectAndSnapshot(newProjectDto("project-uuid"));
+    insertNclocMetric();
+    expectedException.expect(BadRequestException.class);
+    expectedException
+      .expectMessage("To filter components based on the sort metric, the 's' parameter must contain 'metric' or 'metricPeriod' and the 'metricSort' parameter must be provided");
+
+    call(ws.newRequest()
+      .setParam(PARAM_BASE_COMPONENT_ID, "project-uuid")
+      .setParam(PARAM_METRIC_KEYS, "ncloc")
+      .setParam(PARAM_METRIC_SORT_FILTER, WITH_MEASURES_ONLY_METRIC_SORT_FILTER));
+  }
+
   private static ComponentTreeWsResponse call(TestRequest request) {
     TestResponse testResponse = request
       .setMediaType(MediaTypes.PROTOBUF)
index 86727a6c5c3a2bf971ffe94b5807d4ffe4a66a57..1d7322a486b20aae6f5ac5f6574ce52d00f22dc3 100644 (file)
@@ -35,6 +35,7 @@ public class ComponentTreeWsRequest {
   private Boolean asc;
   private String metricSort;
   private Integer metricPeriodSort;
+  private String metricSortFilter;
   private List<String> metricKeys;
   private Integer page;
   private Integer pageSize;
@@ -121,6 +122,16 @@ public class ComponentTreeWsRequest {
     return this;
   }
 
+  @CheckForNull
+  public String getMetricSortFilter() {
+    return metricSortFilter;
+  }
+
+  public ComponentTreeWsRequest setMetricSortFilter(@Nullable String metricSortFilter) {
+    this.metricSortFilter = metricSortFilter;
+    return this;
+  }
+
   @CheckForNull
   public List<String> getMetricKeys() {
     return metricKeys;
index 6eab2608301b6284f353b485897f337e9ceb684f..c6c39285761430c062243639400957d03d0801c2 100644 (file)
@@ -37,6 +37,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_DEVELOP
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_DEVELOPER_KEY;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_KEYS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT_FILTER;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_QUALIFIERS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEGY;
 
@@ -60,7 +61,8 @@ public class MeasuresService extends BaseService {
       .setParam("ps", request.getPageSize())
       .setParam("s", inlineMultipleParamValue(request.getSort()))
       .setParam("asc", request.getAsc())
-      .setParam(PARAM_METRIC_SORT, request.getMetricSort());
+      .setParam(PARAM_METRIC_SORT, request.getMetricSort())
+      .setParam(PARAM_METRIC_SORT_FILTER, request.getMetricSortFilter());
 
     return call(getRequest, ComponentTreeWsResponse.parser());
   }
index b06b762c8e8058e033f932ee79f68adb853880ea..d884f76cbd1b328d7800dada289cc199ead2c35b 100644 (file)
@@ -39,6 +39,7 @@ public class MeasuresWsParameters {
   public static final String PARAM_METRIC_KEYS = "metricKeys";
   public static final String PARAM_METRIC_SORT = "metricSort";
   public static final String PARAM_METRIC_PERIOD_SORT = "metricPeriodSort";
+  public static final String PARAM_METRIC_SORT_FILTER = "metricSortFilter";
   public static final String PARAM_ADDITIONAL_FIELDS = "additionalFields";
   public static final String PARAM_COMPONENT_ID = "componentId";
   public static final String PARAM_COMPONENT_KEY = "componentKey";
index 869dd6fcd2191e2e1a101aff8a11095f6f657309..d5087a971c1319a2da815bfbf83b52a7b2051a2e 100644 (file)
@@ -38,6 +38,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_DEVELOP
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_DEVELOPER_KEY;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_KEYS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_SORT_FILTER;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_QUALIFIERS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEGY;
 
@@ -51,6 +52,7 @@ public class MeasuresServiceTest {
   private static final List<String> VALUE_SORT = newArrayList("qualifier", "metric");
   private static final boolean VALUE_ASC = false;
   private static final String VALUE_METRIC_SORT = "ncloc";
+  private static final String VALUE_METRIC_SORT_FILTER = "all";
   private static final int VALUE_PAGE = 42;
   private static final int VALUE_PAGE_SIZE = 1984;
   private static final String VALUE_QUERY = "query-sq";
@@ -78,7 +80,8 @@ public class MeasuresServiceTest {
       .setPageSize(VALUE_PAGE_SIZE)
       .setQuery(VALUE_QUERY)
       .setDeveloperId(VALUE_DEVELOPER_ID)
-      .setDeveloperKey(VALUE_DEVELOPER_KEY);
+      .setDeveloperKey(VALUE_DEVELOPER_KEY)
+      .setMetricSortFilter(VALUE_METRIC_SORT_FILTER);
 
     underTest.componentTree(componentTreeRequest);
     GetRequest getRequest = serviceTester.getGetRequest();
@@ -99,6 +102,7 @@ public class MeasuresServiceTest {
       .hasParam("q", VALUE_QUERY)
       .hasParam(PARAM_DEVELOPER_ID, VALUE_DEVELOPER_ID)
       .hasParam(PARAM_DEVELOPER_KEY, VALUE_DEVELOPER_KEY)
+      .hasParam(PARAM_METRIC_SORT_FILTER, VALUE_METRIC_SORT_FILTER)
       .andNoOtherParam();
   }
 }