aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-02-21 11:38:19 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-02-22 15:33:57 +0100
commitc7c06d7ae381d87a37fb4d9eaeb7fe38ce29de8a (patch)
tree369248ca1cd658401fbabc4c701dbc81f71300ec
parent86d4eb4c0372975e98b942945efe75fbf94c9fe3 (diff)
downloadsonarqube-c7c06d7ae381d87a37fb4d9eaeb7fe38ce29de8a.tar.gz
sonarqube-c7c06d7ae381d87a37fb4d9eaeb7fe38ce29de8a.zip
SONAR-8795 Extract text search feature in a dedicated class
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndex.java30
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/es/textsearch/ComponentTextSearchFeature.java (renamed from server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndexSearchFeature.java)54
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/es/textsearch/ComponentTextSearchQueryFactory.java114
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/es/textsearch/package-info.java24
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureKeyTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePartialTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePrefixTest.java7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexMultipleWordsTest.java5
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexScoreTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/es/textsearch/ComponentTextSearchFeatureRule.java (renamed from server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexSearchFeatureRule.java)12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/es/textsearch/ComponentTextSearchQueryFactoryTest.java89
12 files changed, 289 insertions, 58 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndex.java b/server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndex.java
index 6c891e0554c..65ceb1af541 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndex.java
@@ -38,10 +38,15 @@ import org.elasticsearch.search.aggregations.metrics.tophits.InternalTopHits;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHitsBuilder;
import org.sonar.core.util.stream.Collectors;
import org.sonar.server.es.EsClient;
+import org.sonar.server.es.textsearch.ComponentTextSearchFeature;
+import org.sonar.server.es.textsearch.ComponentTextSearchQueryFactory;
+import org.sonar.server.es.textsearch.ComponentTextSearchQueryFactory.ComponentTextSearchQuery;
import org.sonar.server.permission.index.AuthorizationTypeSupport;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_KEY;
+import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_NAME;
import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_QUALIFIER;
import static org.sonar.server.component.index.ComponentIndexDefinition.INDEX_COMPONENTS;
import static org.sonar.server.component.index.ComponentIndexDefinition.TYPE_COMPONENT;
@@ -60,11 +65,11 @@ public class ComponentIndex {
}
public List<ComponentsPerQualifier> search(ComponentIndexQuery query) {
- return search(query, ComponentIndexSearchFeature.values());
+ return search(query, ComponentTextSearchFeature.values());
}
@VisibleForTesting
- List<ComponentsPerQualifier> search(ComponentIndexQuery query, ComponentIndexSearchFeature... features) {
+ List<ComponentsPerQualifier> search(ComponentIndexQuery query, ComponentTextSearchFeature... features) {
Collection<String> qualifiers = query.getQualifiers();
if (qualifiers.isEmpty()) {
return Collections.emptyList();
@@ -87,10 +92,7 @@ public class ComponentIndex {
private static FiltersAggregationBuilder createAggregation(ComponentIndexQuery query) {
FiltersAggregationBuilder filtersAggregation = AggregationBuilders.filters(FILTERS_AGGREGATION_NAME)
.subAggregation(createSubAggregation(query));
-
- query.getQualifiers().stream()
- .forEach(q -> filtersAggregation.filter(q, termQuery(FIELD_QUALIFIER, q)));
-
+ query.getQualifiers().forEach(q -> filtersAggregation.filter(q, termQuery(FIELD_QUALIFIER, q)));
return filtersAggregation;
}
@@ -100,17 +102,15 @@ public class ComponentIndex {
return sub.setFetchSource(false);
}
- private QueryBuilder createQuery(ComponentIndexQuery query, ComponentIndexSearchFeature... features) {
+ private QueryBuilder createQuery(ComponentIndexQuery query, ComponentTextSearchFeature... features) {
BoolQueryBuilder esQuery = boolQuery();
esQuery.filter(authorizationTypeSupport.createQueryFilter());
-
- BoolQueryBuilder featureQuery = boolQuery();
-
- Arrays.stream(features)
- .map(f -> f.getQuery(query.getQuery()))
- .forEach(featureQuery::should);
-
- return esQuery.must(featureQuery);
+ ComponentTextSearchQuery componentTextSearchQuery = ComponentTextSearchQuery.builder()
+ .setQueryText(query.getQuery())
+ .setFieldKey(FIELD_KEY)
+ .setFieldName(FIELD_NAME)
+ .build();
+ return esQuery.must(ComponentTextSearchQueryFactory.createQuery(componentTextSearchQuery, features));
}
private static List<ComponentsPerQualifier> aggregationsToQualifiers(SearchResponse response) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndexSearchFeature.java b/server/sonar-server/src/main/java/org/sonar/server/es/textsearch/ComponentTextSearchFeature.java
index 603224b04cd..5410a7a4eea 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndexSearchFeature.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/es/textsearch/ComponentTextSearchFeature.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.server.component.index;
+package org.sonar.server.es.textsearch;
import java.util.Arrays;
import java.util.Locale;
@@ -28,59 +28,58 @@ import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.sonar.server.es.DefaultIndexSettings;
+import org.sonar.server.es.textsearch.ComponentTextSearchQueryFactory.ComponentTextSearchQuery;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.prefixQuery;
-import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_KEY;
-import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_NAME;
import static org.sonar.server.es.DefaultIndexSettingsElement.SEARCH_GRAMS_ANALYZER;
import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
-public enum ComponentIndexSearchFeature {
+public enum ComponentTextSearchFeature {
EXACT_IGNORE_CASE {
@Override
- public QueryBuilder getQuery(String queryText) {
- return matchQuery(SORTABLE_ANALYZER.subField(FIELD_NAME), queryText)
+ public QueryBuilder getQuery(ComponentTextSearchQuery query) {
+ return matchQuery(SORTABLE_ANALYZER.subField(query.getFieldName()), query.getQueryText())
.boost(2.5f);
}
},
PREFIX {
@Override
- public QueryBuilder getQuery(String queryText) {
- return prefixAndPartialQuery(queryText, FIELD_NAME)
+ public QueryBuilder getQuery(ComponentTextSearchQuery query) {
+ return prefixAndPartialQuery(query.getQueryText(), query.getFieldName(), query.getFieldName())
.boost(2f);
}
},
PREFIX_IGNORE_CASE {
@Override
- public QueryBuilder getQuery(String queryText) {
- String lowerCaseQueryText = queryText.toLowerCase(Locale.getDefault());
- return prefixAndPartialQuery(lowerCaseQueryText, SORTABLE_ANALYZER.subField(FIELD_NAME))
+ public QueryBuilder getQuery(ComponentTextSearchQuery query) {
+ String lowerCaseQueryText = query.getQueryText().toLowerCase(Locale.getDefault());
+ return prefixAndPartialQuery(lowerCaseQueryText, SORTABLE_ANALYZER.subField(query.getFieldName()), query.getFieldName())
.boost(3f);
}
},
PARTIAL {
@Override
- public QueryBuilder getQuery(String queryText) {
- BoolQueryBuilder query = boolQuery();
- split(queryText)
- .map(this::partialTermQuery)
- .forEach(query::must);
- return query
+ public QueryBuilder getQuery(ComponentTextSearchQuery query) {
+ BoolQueryBuilder queryBuilder = boolQuery();
+ split(query.getQueryText())
+ .map(text -> partialTermQuery(text, query.getFieldName()))
+ .forEach(queryBuilder::must);
+ return queryBuilder
.boost(0.5f);
}
},
KEY {
@Override
- public QueryBuilder getQuery(String queryText) {
- return matchQuery(SORTABLE_ANALYZER.subField(FIELD_KEY), queryText)
+ public QueryBuilder getQuery(ComponentTextSearchQuery query) {
+ return matchQuery(SORTABLE_ANALYZER.subField(query.getFieldKey()), query.getQueryText())
.boost(50f);
}
};
- public abstract QueryBuilder getQuery(String queryText);
+ public abstract QueryBuilder getQuery(ComponentTextSearchQuery query);
protected Stream<String> split(String queryText) {
return Arrays.stream(
@@ -88,8 +87,8 @@ public enum ComponentIndexSearchFeature {
.filter(StringUtils::isNotEmpty);
}
- protected BoolQueryBuilder prefixAndPartialQuery(String queryText, String fieldName) {
- BoolQueryBuilder query = boolQuery();
+ protected BoolQueryBuilder prefixAndPartialQuery(String queryText, String fieldName, String originalFieldName) {
+ BoolQueryBuilder queryBuilder = boolQuery();
AtomicBoolean first = new AtomicBoolean(true);
split(queryText)
@@ -99,17 +98,16 @@ public enum ComponentIndexSearchFeature {
return prefixQuery(fieldName, queryTerm);
}
- return partialTermQuery(queryTerm);
+ return partialTermQuery(queryTerm, originalFieldName);
})
- .forEach(query::must);
- return query;
+ .forEach(queryBuilder::must);
+ return queryBuilder;
}
- protected MatchQueryBuilder partialTermQuery(String queryTerm) {
+ protected MatchQueryBuilder partialTermQuery(String queryTerm, String fieldName) {
// We will truncate the search to the maximum length of nGrams in the index.
// Otherwise the search would for sure not find any results.
String truncatedQuery = StringUtils.left(queryTerm, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH);
-
- return matchQuery(SEARCH_GRAMS_ANALYZER.subField(FIELD_NAME), truncatedQuery);
+ return matchQuery(SEARCH_GRAMS_ANALYZER.subField(fieldName), truncatedQuery);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/textsearch/ComponentTextSearchQueryFactory.java b/server/sonar-server/src/main/java/org/sonar/server/es/textsearch/ComponentTextSearchQueryFactory.java
new file mode 100644
index 00000000000..81e85881041
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/es/textsearch/ComponentTextSearchQueryFactory.java
@@ -0,0 +1,114 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.es.textsearch;
+
+import java.util.Arrays;
+import org.elasticsearch.index.query.BoolQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
+
+/**
+ * This class is used in order to do some advanced full text search in an index on component key and component name
+ *
+ * The index must contains at least one field for the component key and one field for the component name
+ */
+public class ComponentTextSearchQueryFactory {
+
+ private ComponentTextSearchQueryFactory() {
+ // Only static methods
+ }
+
+ public static QueryBuilder createQuery(ComponentTextSearchQuery query, ComponentTextSearchFeature... features) {
+ checkArgument(features.length > 0, "features cannot be empty");
+ BoolQueryBuilder featureQuery = boolQuery();
+ Arrays.stream(features)
+ .map(f -> f.getQuery(query))
+ .forEach(featureQuery::should);
+ return featureQuery;
+ }
+
+ public static class ComponentTextSearchQuery {
+ private final String queryText;
+ private final String fieldKey;
+ private final String fieldName;
+
+ private ComponentTextSearchQuery(Builder builder) {
+ this.queryText = builder.queryText;
+ this.fieldKey = builder.fieldKey;
+ this.fieldName = builder.fieldName;
+ }
+
+ public String getQueryText() {
+ return queryText;
+ }
+
+ public String getFieldKey() {
+ return fieldKey;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String queryText;
+ private String fieldKey;
+ private String fieldName;
+
+ /**
+ * The text search query
+ */
+ public Builder setQueryText(String queryText) {
+ this.queryText = queryText;
+ return this;
+ }
+
+ /**
+ * The index field that contains the component key
+ */
+ public Builder setFieldKey(String fieldKey) {
+ this.fieldKey = fieldKey;
+ return this;
+ }
+
+ /**
+ * The index field that contains the component name
+ */
+ public Builder setFieldName(String fieldName) {
+ this.fieldName = fieldName;
+ return this;
+ }
+
+ public ComponentTextSearchQuery build() {
+ this.queryText = requireNonNull(queryText, "query text cannot be null");
+ this.fieldKey = requireNonNull(fieldKey, "field key cannot be null");
+ this.fieldName = requireNonNull(fieldName, "field name cannot be null");
+ return new ComponentTextSearchQuery(this);
+ }
+ }
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/textsearch/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/es/textsearch/package-info.java
new file mode 100644
index 00000000000..9439c3b6d07
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/es/textsearch/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.es.textsearch;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureKeyTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureKeyTest.java
index 51912fc6c35..cd8e6fc557f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureKeyTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureKeyTest.java
@@ -22,12 +22,13 @@ package org.sonar.server.component.index;
import org.junit.Before;
import org.junit.Test;
import org.sonar.db.component.ComponentDto;
+import org.sonar.server.es.textsearch.ComponentTextSearchFeature;
public class ComponentIndexFeatureKeyTest extends ComponentIndexTest {
@Before
public void before() {
- features.set(ComponentIndexSearchFeature.KEY);
+ features.set(ComponentTextSearchFeature.KEY);
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePartialTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePartialTest.java
index 471db3b6ebe..5cdeff81d81 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePartialTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePartialTest.java
@@ -22,12 +22,13 @@ package org.sonar.server.component.index;
import org.junit.Before;
import org.junit.Test;
import org.sonar.db.component.ComponentDto;
+import org.sonar.server.es.textsearch.ComponentTextSearchFeature;
public class ComponentIndexFeaturePartialTest extends ComponentIndexTest {
@Before
public void before() {
- features.set(ComponentIndexSearchFeature.PARTIAL);
+ features.set(ComponentTextSearchFeature.PARTIAL);
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePrefixTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePrefixTest.java
index bb2c4f735b4..55b8fe0d235 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePrefixTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePrefixTest.java
@@ -21,12 +21,13 @@ package org.sonar.server.component.index;
import org.junit.Before;
import org.junit.Test;
+import org.sonar.server.es.textsearch.ComponentTextSearchFeature;
public class ComponentIndexFeaturePrefixTest extends ComponentIndexTest {
@Before
public void before() {
- features.set(ComponentIndexSearchFeature.PREFIX, ComponentIndexSearchFeature.PREFIX_IGNORE_CASE);
+ features.set(ComponentTextSearchFeature.PREFIX, ComponentTextSearchFeature.PREFIX_IGNORE_CASE);
}
@Test
@@ -41,13 +42,13 @@ public class ComponentIndexFeaturePrefixTest extends ComponentIndexTest {
@Test
public void should_be_able_to_ignore_case() {
- features.set(ComponentIndexSearchFeature.PREFIX_IGNORE_CASE);
+ features.set(ComponentTextSearchFeature.PREFIX_IGNORE_CASE);
assertResultOrder("cOmPoNeNt.Js", "CoMpOnEnT.jS");
}
@Test
public void should_be_able_to_match_case() {
- features.set(ComponentIndexSearchFeature.PREFIX);
+ features.set(ComponentTextSearchFeature.PREFIX);
assertNoFileMatches("cOmPoNeNt.Js", "CoMpOnEnT.jS");
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexMultipleWordsTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexMultipleWordsTest.java
index f621db542d8..76f49b40309 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexMultipleWordsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexMultipleWordsTest.java
@@ -20,6 +20,7 @@
package org.sonar.server.component.index;
import org.junit.Test;
+import org.sonar.server.es.textsearch.ComponentTextSearchFeature;
public class ComponentIndexMultipleWordsTest extends ComponentIndexTest {
@@ -31,7 +32,7 @@ public class ComponentIndexMultipleWordsTest extends ComponentIndexTest {
@Test
public void should_find_partial_match() {
- features.set(ComponentIndexSearchFeature.PARTIAL);
+ features.set(ComponentTextSearchFeature.PARTIAL);
assertResultOrder("struts java",
"Xstrutsx.Xjavax");
}
@@ -86,7 +87,7 @@ public class ComponentIndexMultipleWordsTest extends ComponentIndexTest {
@Test
public void should_require_all_words_to_match_for_partial() {
- features.set(ComponentIndexSearchFeature.PARTIAL);
+ features.set(ComponentTextSearchFeature.PARTIAL);
assertNoFileMatches("struts java",
"Struts");
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexScoreTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexScoreTest.java
index 13ebac31f0c..2851892cc03 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexScoreTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexScoreTest.java
@@ -22,6 +22,7 @@ package org.sonar.server.component.index;
import org.junit.Test;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
+import org.sonar.server.es.textsearch.ComponentTextSearchFeature;
public class ComponentIndexScoreTest extends ComponentIndexTest {
@@ -103,7 +104,7 @@ public class ComponentIndexScoreTest extends ComponentIndexTest {
@Test
public void scoring_test_DbTester() {
- features.set(ComponentIndexSearchFeature.PARTIAL);
+ features.set(ComponentTextSearchFeature.PARTIAL);
ComponentDto project = indexProject("key-1", "Quality Product");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexTest.java
index 0f2b8628d04..40508ff39a3 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexTest.java
@@ -34,6 +34,7 @@ import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.organization.OrganizationTesting;
import org.sonar.server.es.EsTester;
+import org.sonar.server.es.textsearch.ComponentTextSearchFeatureRule;
import org.sonar.server.permission.index.AuthorizationTypeSupport;
import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.tester.UserSessionRule;
@@ -56,7 +57,7 @@ public abstract class ComponentIndexTest {
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
- public ComponentIndexSearchFeatureRule features = new ComponentIndexSearchFeatureRule();
+ public ComponentTextSearchFeatureRule features = new ComponentTextSearchFeatureRule();
protected ComponentIndexer indexer = new ComponentIndexer(db.getDbClient(), es.client());
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexSearchFeatureRule.java b/server/sonar-server/src/test/java/org/sonar/server/es/textsearch/ComponentTextSearchFeatureRule.java
index 2f05501b18e..c49cf8033cf 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexSearchFeatureRule.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/es/textsearch/ComponentTextSearchFeatureRule.java
@@ -17,24 +17,24 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.server.component.index;
+package org.sonar.server.es.textsearch;
import org.junit.rules.ExternalResource;
-public class ComponentIndexSearchFeatureRule extends ExternalResource {
+public class ComponentTextSearchFeatureRule extends ExternalResource {
- private ComponentIndexSearchFeature[] features;
+ private ComponentTextSearchFeature[] features;
@Override
protected void before() throws Throwable {
- features = ComponentIndexSearchFeature.values();
+ features = ComponentTextSearchFeature.values();
}
- public ComponentIndexSearchFeature[] get() {
+ public ComponentTextSearchFeature[] get() {
return features;
}
- public void set(ComponentIndexSearchFeature... features) {
+ public void set(ComponentTextSearchFeature... features) {
this.features = features;
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/textsearch/ComponentTextSearchQueryFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/textsearch/ComponentTextSearchQueryFactoryTest.java
new file mode 100644
index 00000000000..dbf143f1bfa
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/es/textsearch/ComponentTextSearchQueryFactoryTest.java
@@ -0,0 +1,89 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.es.textsearch;
+
+import org.elasticsearch.index.query.QueryBuilder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.server.es.textsearch.ComponentTextSearchQueryFactory.ComponentTextSearchQuery;
+
+import static org.sonar.server.es.textsearch.ComponentTextSearchQueryFactory.createQuery;
+import static org.sonar.test.JsonAssert.assertJson;
+
+public class ComponentTextSearchQueryFactoryTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void create_query() throws Exception {
+ QueryBuilder result = createQuery(ComponentTextSearchQuery.builder()
+ .setQueryText("SonarQube").setFieldKey("key").setFieldName("name").build(),
+ ComponentTextSearchFeature.KEY);
+
+ assertJson(result.toString()).isSimilarTo("{" +
+ " \"bool\" : {" +
+ " \"should\" : {" +
+ " \"match\" : {" +
+ " \"key.sortable_analyzer\" : {" +
+ " \"query\" : \"SonarQube\"," +
+ " \"type\" : \"boolean\"," +
+ " \"boost\" : 50.0\n" +
+ " }" +
+ " }" +
+ " }" +
+ " }" +
+ "}");
+ }
+
+ @Test
+ public void fail_to_create_query_when_no_feature() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("features cannot be empty");
+
+ createQuery(ComponentTextSearchQuery.builder()
+ .setQueryText("SonarQube").setFieldKey("key").setFieldName("name").build());
+ }
+
+ @Test
+ public void fail_to_create_query_when_no_query_text() throws Exception {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("query text cannot be null");
+
+ ComponentTextSearchQuery.builder().setFieldKey("key").setFieldName("name").build();
+ }
+
+ @Test
+ public void fail_to_create_query_when_no_field_key() throws Exception {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("field key cannot be null");
+
+ ComponentTextSearchQuery.builder().setQueryText("SonarQube").setFieldName("name").build();
+ }
+
+ @Test
+ public void fail_to_create_query_when_no_field_name() throws Exception {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("field name cannot be null");
+
+ ComponentTextSearchQuery.builder().setQueryText("SonarQube").setFieldKey("key").build();
+ }
+}