aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-webserver-es
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2020-12-03 09:37:58 +0100
committersonartech <sonartech@sonarsource.com>2020-12-03 20:06:38 +0000
commit6741d92467d65179e77e910612d91e55b84e660d (patch)
tree32c8cb53394f16f09609438435ea3062c5fc281e /server/sonar-webserver-es
parent19c1858b5e72a19332e6a77fd532712e07b47a77 (diff)
downloadsonarqube-6741d92467d65179e77e910612d91e55b84e660d.tar.gz
sonarqube-6741d92467d65179e77e910612d91e55b84e660d.zip
SONAR-8427 Add a timeZone param to api/issues/search
Diffstat (limited to 'server/sonar-webserver-es')
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java2
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java2
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java14
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java28
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java2
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java8
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java89
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java2
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java54
9 files changed, 158 insertions, 43 deletions
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java
index 489e18e758b..886f81583ec 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java
@@ -104,7 +104,7 @@ public class ComponentIndex {
SearchRequest request = EsClient.prepareSearch(TYPE_COMPONENT.getMainType())
.source(source);
- return new SearchIdResult<>(client.search(request), id -> id, system2.getDefaultTimeZone());
+ return new SearchIdResult<>(client.search(request), id -> id, system2.getDefaultTimeZone().toZoneId());
}
public ComponentIndexResults searchSuggestions(SuggestionQuery query) {
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index 1446e48f4ab..0f016ac6c26 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -809,7 +809,7 @@ public class IssueIndex {
.dateHistogramInterval(bucketSize)
.minDocCount(0L)
.format(DateUtils.DATETIME_FORMAT)
- .timeZone(system.getDefaultTimeZone().toZoneId())
+ .timeZone(Optional.ofNullable(query.timeZone()).orElse(system.getDefaultTimeZone().toZoneId()))
// ES dateHistogram bounds are inclusive while createdBefore parameter is exclusive
.extendedBounds(new ExtendedBounds(startInclusive ? startTime : (startTime + 1), endTime - 1L));
addEffortAggregationIfNeeded(query, dateHistogram);
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
index c58511323c8..38eb36bb7af 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
@@ -20,6 +20,7 @@
package org.sonar.server.issue.index;
import com.google.common.collect.ImmutableSet;
+import java.time.ZoneId;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@@ -96,6 +97,7 @@ public class IssueQuery {
private final String organizationUuid;
private final String branchUuid;
private final boolean mainBranch;
+ private final ZoneId timeZone;
private IssueQuery(Builder builder) {
this.issueKeys = defaultCollection(builder.issueKeys);
@@ -133,6 +135,7 @@ public class IssueQuery {
this.organizationUuid = builder.organizationUuid;
this.branchUuid = builder.branchUuid;
this.mainBranch = builder.mainBranch;
+ this.timeZone = builder.timeZone;
}
public Collection<String> issueKeys() {
@@ -294,6 +297,11 @@ public class IssueQuery {
return new Builder();
}
+ @CheckForNull
+ public ZoneId timeZone() {
+ return timeZone;
+ }
+
public static class Builder {
private Collection<String> issueKeys;
private Collection<String> severities;
@@ -330,6 +338,7 @@ public class IssueQuery {
private String organizationUuid;
private String branchUuid;
private boolean mainBranch = true;
+ private ZoneId timeZone;
private Builder() {
@@ -536,6 +545,11 @@ public class IssueQuery {
this.mainBranch = mainBranch;
return this;
}
+
+ public Builder timeZone(ZoneId timeZone) {
+ this.timeZone = timeZone;
+ return this;
+ }
}
private static <T> Collection<T> defaultCollection(@Nullable Collection<T> c) {
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
index 3e93bf5c4ef..65b79e2c509 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
@@ -23,8 +23,10 @@ import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import java.time.Clock;
+import java.time.DateTimeException;
import java.time.OffsetDateTime;
import java.time.Period;
+import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -66,7 +68,6 @@ import static org.sonar.api.issue.Issue.STATUSES;
import static org.sonar.api.issue.Issue.STATUS_REVIEWED;
import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW;
import static org.sonar.api.utils.DateUtils.longToDate;
-import static org.sonar.api.utils.DateUtils.parseDateOrDateTime;
import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime;
import static org.sonar.api.utils.DateUtils.parseStartingDateOrDateTime;
import static org.sonar.core.util.stream.MoreCollectors.toHashSet;
@@ -108,6 +109,7 @@ public class IssueQueryFactory {
public IssueQuery create(SearchRequest request) {
try (DbSession dbSession = dbClient.openSession(false)) {
+ final ZoneId timeZone = parseTimeZone(request.getTimeZone()).orElse(clock.getZone());
IssueQuery.Builder builder = IssueQuery.builder()
.issueKeys(request.getIssues())
.severities(request.getSeverities())
@@ -126,16 +128,17 @@ public class IssueQueryFactory {
.cwe(request.getCwe())
.sonarsourceSecurity(request.getSonarsourceSecurity())
.assigned(request.getAssigned())
- .createdAt(parseDateOrDateTime(request.getCreatedAt()))
- .createdBefore(parseEndingDateOrDateTime(request.getCreatedBefore()))
+ .createdAt(parseStartingDateOrDateTime(request.getCreatedAt(), timeZone))
+ .createdBefore(parseEndingDateOrDateTime(request.getCreatedBefore(), timeZone))
.facetMode(request.getFacetMode())
- .organizationUuid(convertOrganizationKeyToUuid(dbSession, request.getOrganization()));
+ .organizationUuid(convertOrganizationKeyToUuid(dbSession, request.getOrganization()))
+ .timeZone(timeZone);
List<ComponentDto> allComponents = new ArrayList<>();
boolean effectiveOnComponentOnly = mergeDeprecatedComponentParameters(dbSession, request, allComponents);
addComponentParameters(builder, dbSession, effectiveOnComponentOnly, allComponents, request);
- setCreatedAfterFromRequest(dbSession, builder, request, allComponents);
+ setCreatedAfterFromRequest(dbSession, builder, request, allComponents, timeZone);
String sort = request.getSort();
if (!Strings.isNullOrEmpty(sort)) {
builder.sort(sort);
@@ -145,6 +148,17 @@ public class IssueQueryFactory {
}
}
+ private Optional<ZoneId> parseTimeZone(@Nullable String timeZone) {
+ if (timeZone == null) {
+ return Optional.empty();
+ }
+ try {
+ return Optional.of(ZoneId.of(timeZone));
+ } catch (DateTimeException e) {
+ throw new IllegalArgumentException("TimeZone '" + timeZone + "' cannot be parsed as a valid zone ID");
+ }
+ }
+
private void setCreatedAfterFromDates(IssueQuery.Builder builder, @Nullable Date createdAfter, @Nullable String createdInLast, boolean createdAfterInclusive) {
Date actualCreatedAfter = createdAfter;
if (createdInLast != null) {
@@ -165,8 +179,8 @@ public class IssueQueryFactory {
return organization.map(OrganizationDto::getUuid).orElse(UNKNOWN);
}
- private void setCreatedAfterFromRequest(DbSession dbSession, IssueQuery.Builder builder, SearchRequest request, List<ComponentDto> componentUuids) {
- Date createdAfter = parseStartingDateOrDateTime(request.getCreatedAfter());
+ private void setCreatedAfterFromRequest(DbSession dbSession, IssueQuery.Builder builder, SearchRequest request, List<ComponentDto> componentUuids, ZoneId timeZone) {
+ Date createdAfter = parseStartingDateOrDateTime(request.getCreatedAfter(), timeZone);
String createdInLast = request.getCreatedInLast();
if (request.getSinceLeakPeriod() == null || !request.getSinceLeakPeriod()) {
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java
index 4231f0d42be..bf81c3a02d7 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java
@@ -226,7 +226,7 @@ public class ProjectMeasuresIndex {
filtersComputer.getPostFilters().ifPresent(searchSourceBuilder::postFilter);
SearchResponse response = client.search(EsClient.prepareSearch(TYPE_PROJECT_MEASURES.getMainType())
.source(searchSourceBuilder));
- return new SearchIdResult<>(response, id -> id, system2.getDefaultTimeZone());
+ return new SearchIdResult<>(response, id -> id, system2.getDefaultTimeZone().toZoneId());
}
private static RequestFiltersComputer createFiltersComputer(SearchOptions searchOptions, AllFilters allFilters) {
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java
index 74d67113b28..35ed6595a36 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java
@@ -197,7 +197,7 @@ public class IssueIndexDebtTest {
IssueDocTesting.newDoc("I3", file).setAssigneeUuid("uuid-simon").setEffort(10L),
IssueDocTesting.newDoc("I4", file).setAssigneeUuid(null).setEffort(10L));
- Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("assignees"))), system2.getDefaultTimeZone());
+ Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("assignees"))), system2.getDefaultTimeZone().toZoneId());
assertThat(facets.getNames()).containsOnly("assignees", FACET_MODE_EFFORT);
assertThat(facets.get("assignees")).containsOnly(entry("uuid-steph", 10L), entry("uuid-simon", 20L), entry("", 10L));
assertThat(facets.get(FACET_MODE_EFFORT)).containsOnly(entry("total", 40L));
@@ -214,7 +214,7 @@ public class IssueIndexDebtTest {
IssueDocTesting.newDoc("I3", file).setAuthorLogin("simon").setEffort(10L),
IssueDocTesting.newDoc("I4", file).setAuthorLogin(null).setEffort(10L));
- Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("authors"))), system2.getDefaultTimeZone());
+ Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("authors"))), system2.getDefaultTimeZone().toZoneId());
assertThat(facets.getNames()).containsOnly("authors", FACET_MODE_EFFORT);
assertThat(facets.get("authors")).containsOnly(entry("steph", 10L), entry("simon", 20L));
assertThat(facets.get(FACET_MODE_EFFORT)).containsOnly(entry("total", 40L));
@@ -225,7 +225,7 @@ public class IssueIndexDebtTest {
SearchOptions searchOptions = fixtureForCreatedAtFacet();
Builder query = newQueryBuilder().createdBefore(parseDateTime("2016-01-01T00:00:00+0100"));
- Map<String, Long> createdAt = new Facets(underTest.search(query.build(), searchOptions), system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> createdAt = new Facets(underTest.search(query.build(), searchOptions), system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
entry("2011-01-01", 10L),
entry("2012-01-01", 0L),
@@ -257,7 +257,7 @@ public class IssueIndexDebtTest {
}
private Facets search(String additionalFacet) {
- return new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(singletonList(additionalFacet))), system2.getDefaultTimeZone());
+ return new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(singletonList(additionalFacet))), system2.getDefaultTimeZone().toZoneId());
}
private Builder newQueryBuilder() {
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
index 11437d42c90..fb9bbaa04eb 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
@@ -19,7 +19,10 @@
*/
package org.sonar.server.issue.index;
+import java.time.ZoneId;
+import java.util.Date;
import java.util.Map;
+import java.util.TimeZone;
import org.elasticsearch.action.search.SearchResponse;
import org.junit.Rule;
import org.junit.Test;
@@ -80,7 +83,8 @@ public class IssueIndexFacetsTest {
public UserSessionRule userSessionRule = UserSessionRule.standalone();
@Rule
public ExpectedException expectedException = none();
- private System2 system2 = new TestSystem2().setNow(1_500_000_000_000L).setDefaultTimeZone(getTimeZone("GMT-01:00"));
+ private final TimeZone defaultTimezone = getTimeZone("GMT-01:00");
+ private System2 system2 = new TestSystem2().setNow(1_500_000_000_000L).setDefaultTimeZone(defaultTimezone);
@Rule
public DbTester db = DbTester.create(system2);
@@ -431,7 +435,7 @@ public class IssueIndexFacetsTest {
}
@Test
- public void facet_on_created_at_with_less_than_20_days() {
+ public void facet_on_created_at_with_less_than_20_days_use_system_timezone_by_default() {
SearchOptions options = fixtureForCreatedAtFacet();
IssueQuery query = IssueQuery.builder()
@@ -439,7 +443,7 @@ public class IssueIndexFacetsTest {
.createdBefore(parseDateTime("2014-09-08T00:00:00+0100"))
.build();
SearchResponse result = underTest.search(query, options);
- Map<String, Long> buckets = new Facets(result, system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> buckets = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(buckets).containsOnly(
entry("2014-08-31", 0L),
entry("2014-09-01", 2L),
@@ -452,6 +456,53 @@ public class IssueIndexFacetsTest {
}
@Test
+ public void facet_on_created_at_with_less_than_20_days_use_user_timezone_if_provided() {
+ // Use timezones very far from each other in order to see some issues moving to a different calendar day
+ final ZoneId plus14 = ZoneId.of("Pacific/Kiritimati");
+ final ZoneId minus11 = ZoneId.of("Pacific/Pago_Pago");
+
+
+ SearchOptions options = fixtureForCreatedAtFacet();
+
+ final Date startDate = parseDateTime("2014-09-01T00:00:00+0000");
+ final Date endDate = parseDateTime("2014-09-08T00:00:00+0000");
+
+ IssueQuery queryPlus14 = IssueQuery.builder()
+ .createdAfter(startDate)
+ .createdBefore(endDate)
+ .timeZone(plus14)
+ .build();
+ SearchResponse resultPlus14 = underTest.search(queryPlus14, options);
+ Map<String, Long> bucketsPlus14 = new Facets(resultPlus14, plus14).get("createdAt");
+ assertThat(bucketsPlus14).containsOnly(
+ entry("2014-09-01", 0L),
+ entry("2014-09-02", 2L),
+ entry("2014-09-03", 1L),
+ entry("2014-09-04", 0L),
+ entry("2014-09-05", 0L),
+ entry("2014-09-06", 1L),
+ entry("2014-09-07", 0L),
+ entry("2014-09-08", 0L));
+
+ IssueQuery queryMinus11 = IssueQuery.builder()
+ .createdAfter(startDate)
+ .createdBefore(endDate)
+ .timeZone(minus11)
+ .build();
+ SearchResponse resultMinus11 = underTest.search(queryMinus11, options);
+ Map<String, Long> bucketsMinus11 = new Facets(resultMinus11, minus11).get("createdAt");
+ assertThat(bucketsMinus11).containsOnly(
+ entry("2014-08-31", 1L),
+ entry("2014-09-01", 1L),
+ entry("2014-09-02", 1L),
+ entry("2014-09-03", 0L),
+ entry("2014-09-04", 0L),
+ entry("2014-09-05", 1L),
+ entry("2014-09-06", 0L),
+ entry("2014-09-07", 0L));
+ }
+
+ @Test
public void facet_on_created_at_with_less_than_20_weeks() {
SearchOptions options = fixtureForCreatedAtFacet();
@@ -459,7 +510,7 @@ public class IssueIndexFacetsTest {
.createdAfter(parseDateTime("2014-09-01T00:00:00+0100"))
.createdBefore(parseDateTime("2014-09-21T00:00:00+0100")).build(),
options);
- Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
entry("2014-08-25", 0L),
entry("2014-09-01", 4L),
@@ -475,7 +526,7 @@ public class IssueIndexFacetsTest {
.createdAfter(parseDateTime("2014-09-01T00:00:00+0100"))
.createdBefore(parseDateTime("2015-01-19T00:00:00+0100")).build(),
options);
- Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
entry("2014-08-01", 0L),
entry("2014-09-01", 5L),
@@ -493,7 +544,7 @@ public class IssueIndexFacetsTest {
.createdAfter(parseDateTime("2011-01-01T00:00:00+0100"))
.createdBefore(parseDateTime("2016-01-01T00:00:00+0100")).build(),
options);
- Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
entry("2010-01-01", 0L),
entry("2011-01-01", 1L),
@@ -511,7 +562,7 @@ public class IssueIndexFacetsTest {
.createdAfter(parseDateTime("2014-09-01T00:00:00-0100"))
.createdBefore(parseDateTime("2014-09-02T00:00:00-0100")).build(),
options);
- Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
entry("2014-09-01", 2L));
}
@@ -524,7 +575,7 @@ public class IssueIndexFacetsTest {
.createdAfter(parseDateTime("2009-01-01T00:00:00+0100"))
.createdBefore(parseDateTime("2016-01-01T00:00:00+0100"))
.build(), options);
- Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
entry("2008-01-01", 0L),
entry("2009-01-01", 0L),
@@ -543,7 +594,7 @@ public class IssueIndexFacetsTest {
SearchResponse result = underTest.search(IssueQuery.builder()
.createdBefore(parseDateTime("2016-01-01T00:00:00+0100")).build(),
searchOptions);
- Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
entry("2011-01-01", 1L),
entry("2012-01-01", 0L),
@@ -557,7 +608,7 @@ public class IssueIndexFacetsTest {
SearchOptions searchOptions = new SearchOptions().addFacets("createdAt");
SearchResponse result = underTest.search(IssueQuery.builder().build(), searchOptions);
- Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt");
+ Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).isNull();
}
@@ -566,12 +617,12 @@ public class IssueIndexFacetsTest {
ComponentDto file = newFileDto(project, null);
IssueDoc issue0 = newDoc("ISSUE0", file).setFuncCreationDate(parseDateTime("2011-04-25T00:05:13+0000"));
- IssueDoc issue1 = newDoc("I1", file).setFuncCreationDate(parseDateTime("2014-09-01T12:34:56+0100"));
- IssueDoc issue2 = newDoc("I2", file).setFuncCreationDate(parseDateTime("2014-09-01T10:46:00-1200"));
- IssueDoc issue3 = newDoc("I3", file).setFuncCreationDate(parseDateTime("2014-09-02T23:34:56+1200"));
- IssueDoc issue4 = newDoc("I4", file).setFuncCreationDate(parseDateTime("2014-09-05T12:34:56+0100"));
- IssueDoc issue5 = newDoc("I5", file).setFuncCreationDate(parseDateTime("2014-09-20T12:34:56+0100"));
- IssueDoc issue6 = newDoc("I6", file).setFuncCreationDate(parseDateTime("2015-01-18T12:34:56+0100"));
+ IssueDoc issue1 = newDoc("I1", file).setFuncCreationDate(parseDateTime("2014-09-01T10:34:56+0000"));
+ IssueDoc issue2 = newDoc("I2", file).setFuncCreationDate(parseDateTime("2014-09-01T22:46:00+0000"));
+ IssueDoc issue3 = newDoc("I3", file).setFuncCreationDate(parseDateTime("2014-09-02T11:34:56+0000"));
+ IssueDoc issue4 = newDoc("I4", file).setFuncCreationDate(parseDateTime("2014-09-05T11:34:56+0000"));
+ IssueDoc issue5 = newDoc("I5", file).setFuncCreationDate(parseDateTime("2014-09-20T11:34:56+0000"));
+ IssueDoc issue6 = newDoc("I6", file).setFuncCreationDate(parseDateTime("2015-01-18T11:34:56+0000"));
indexIssues(issue0, issue1, issue2, issue3, issue4, issue5, issue6);
@@ -586,7 +637,7 @@ public class IssueIndexFacetsTest {
@SafeVarargs
private final void assertThatFacetHasExactly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet)));
- Facets facets = new Facets(result, system2.getDefaultTimeZone());
+ Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId());
assertThat(facets.getNames()).containsOnly(facet, "effort");
assertThat(facets.get(facet)).containsExactly(expectedEntries);
}
@@ -594,14 +645,14 @@ public class IssueIndexFacetsTest {
@SafeVarargs
private final void assertThatFacetHasOnly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet)));
- Facets facets = new Facets(result, system2.getDefaultTimeZone());
+ Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId());
assertThat(facets.getNames()).containsOnly(facet, "effort");
assertThat(facets.get(facet)).containsOnly(expectedEntries);
}
private void assertThatFacetHasSize(IssueQuery issueQuery, String facet, int expectedSize) {
SearchResponse result = underTest.search(issueQuery, new SearchOptions().addFacets(singletonList(facet)));
- Facets facets = new Facets(result, system2.getDefaultTimeZone());
+ Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId());
assertThat(facets.get(facet)).hasSize(expectedSize);
}
}
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java
index 054986e98fe..cb5e38dcd29 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java
@@ -142,7 +142,7 @@ public class IssueIndexSecurityHotspotsTest {
@SafeVarargs
private final void assertThatFacetHasOnly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet)));
- Facets facets = new Facets(result, system2.getDefaultTimeZone());
+ Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId());
assertThat(facets.getNames()).containsOnly(facet, "effort");
assertThat(facets.get(facet)).containsOnly(expectedEntries);
}
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java
index 0ebb3805a41..d73c46b97ef 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java
@@ -20,6 +20,7 @@
package org.sonar.server.issue.index;
import java.time.Clock;
+import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Collections;
@@ -30,7 +31,6 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.DateUtils;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
@@ -50,6 +50,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.utils.DateUtils.addDays;
+import static org.sonar.api.utils.DateUtils.parseDateTime;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.db.component.ComponentTesting.newDirectory;
import static org.sonar.db.component.ComponentTesting.newFileDto;
@@ -123,9 +124,9 @@ public class IssueQueryFactoryTest {
assertThat(query.assigned()).isTrue();
assertThat(query.rules()).hasSize(2);
assertThat(query.directories()).containsOnly("aDirPath");
- assertThat(query.createdAfter().date()).isEqualTo(DateUtils.parseDateTime("2013-04-16T09:08:24+0200"));
+ assertThat(query.createdAfter().date()).isEqualTo(parseDateTime("2013-04-16T09:08:24+0200"));
assertThat(query.createdAfter().inclusive()).isTrue();
- assertThat(query.createdBefore()).isEqualTo(DateUtils.parseDateTime("2013-04-17T09:08:24+0200"));
+ assertThat(query.createdBefore()).isEqualTo(parseDateTime("2013-04-17T09:08:24+0200"));
assertThat(query.sort()).isEqualTo(IssueQuery.SORT_BY_CREATION_DATE);
assertThat(query.asc()).isTrue();
}
@@ -154,25 +155,49 @@ public class IssueQueryFactoryTest {
@Test
public void dates_are_inclusive() {
+ when(clock.getZone()).thenReturn(ZoneId.of("Europe/Paris"));
SearchRequest request = new SearchRequest()
.setCreatedAfter("2013-04-16")
.setCreatedBefore("2013-04-17");
IssueQuery query = underTest.create(request);
- assertThat(query.createdAfter().date()).isEqualTo(DateUtils.parseDate("2013-04-16"));
+ assertThat(query.createdAfter().date()).isEqualTo(parseDateTime("2013-04-16T00:00:00+0200"));
assertThat(query.createdAfter().inclusive()).isTrue();
- assertThat(query.createdBefore()).isEqualTo(DateUtils.parseDate("2013-04-18"));
+ assertThat(query.createdBefore()).isEqualTo(parseDateTime("2013-04-18T00:00:00+0200"));
}
@Test
public void creation_date_support_localdate() {
+ when(clock.getZone()).thenReturn(ZoneId.of("Europe/Paris"));
SearchRequest request = new SearchRequest()
.setCreatedAt("2013-04-16");
IssueQuery query = underTest.create(request);
- assertThat(query.createdAt()).isEqualTo(DateUtils.parseDate("2013-04-16"));
+ assertThat(query.createdAt()).isEqualTo(parseDateTime("2013-04-16T00:00:00+0200"));
+ }
+
+ @Test
+ public void use_provided_timezone_to_parse_createdAfter() {
+ SearchRequest request = new SearchRequest()
+ .setCreatedAfter("2020-04-16")
+ .setTimeZone("Europe/Volgograd");
+
+ IssueQuery query = underTest.create(request);
+
+ assertThat(query.createdAfter().date()).isEqualTo(parseDateTime("2020-04-16T00:00:00+0400"));
+ }
+
+ @Test
+ public void use_provided_timezone_to_parse_createdBefore() {
+ SearchRequest request = new SearchRequest()
+ .setCreatedBefore("2020-04-16")
+ .setTimeZone("Europe/Moscow");
+
+ IssueQuery query = underTest.create(request);
+
+ assertThat(query.createdBefore()).isEqualTo(parseDateTime("2020-04-17T00:00:00+0300"));
}
@Test
@@ -182,7 +207,7 @@ public class IssueQueryFactoryTest {
IssueQuery query = underTest.create(request);
- assertThat(query.createdAt()).isEqualTo(DateUtils.parseDateTime("2013-04-16T09:08:24+0200"));
+ assertThat(query.createdAt()).isEqualTo(parseDateTime("2013-04-16T09:08:24+0200"));
}
@Test
@@ -225,6 +250,17 @@ public class IssueQueryFactoryTest {
}
@Test
+ public void fail_if_invalid_timezone() {
+ SearchRequest request = new SearchRequest()
+ .setTimeZone("Poitou-Charentes");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("TimeZone 'Poitou-Charentes' cannot be parsed as a valid zone ID");
+
+ underTest.create(request);
+ }
+
+ @Test
public void param_componentUuids_enables_search_in_view_tree_if_user_has_permission_on_view() {
ComponentDto view = db.components().insertView();
SearchRequest request = new SearchRequest()
@@ -499,12 +535,12 @@ public class IssueQueryFactoryTest {
@Test
public void set_created_after_from_created_since() {
- Date now = DateUtils.parseDateTime("2013-07-25T07:35:00+0100");
+ Date now = parseDateTime("2013-07-25T07:35:00+0100");
when(clock.instant()).thenReturn(now.toInstant());
when(clock.getZone()).thenReturn(ZoneOffset.UTC);
SearchRequest request = new SearchRequest()
.setCreatedInLast("1y2m3w4d");
- assertThat(underTest.create(request).createdAfter().date()).isEqualTo(DateUtils.parseDateTime("2012-04-30T07:35:00+0100"));
+ assertThat(underTest.create(request).createdAfter().date()).isEqualTo(parseDateTime("2012-04-30T07:35:00+0100"));
assertThat(underTest.create(request).createdAfter().inclusive()).isTrue();
}