]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6247 Add createdInLast parameter to search issues by lifetime
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Mon, 9 Mar 2015 13:28:36 +0000 (14:28 +0100)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 10 Mar 2015 09:25:22 +0000 (10:25 +0100)
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java
server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java

index 0f738d16220f367f9d622e638a3d59ba47dcdb82..576cc5a587f6d0a0b588322d1b96a6ab0121597c 100644 (file)
 package org.sonar.server.issue;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
+import com.google.common.base.*;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.apache.commons.lang.BooleanUtils;
 import org.apache.commons.lang.ObjectUtils;
+import org.joda.time.DateTime;
+import org.joda.time.format.ISOPeriodFormat;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.ws.Request;
+import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.persistence.DbSession;
@@ -48,10 +48,7 @@ import org.sonar.server.util.RubyUtils;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import static com.google.common.collect.Lists.newArrayList;
 
@@ -65,10 +62,12 @@ public class IssueQueryService implements ServerComponent {
   private static final String UNKNOWN = "<UNKNOWN>";
   private final DbClient dbClient;
   private final ComponentService componentService;
+  private final System2 system;
 
-  public IssueQueryService(DbClient dbClient, ComponentService componentService) {
+  public IssueQueryService(DbClient dbClient, ComponentService componentService, System2 system) {
     this.dbClient = dbClient;
     this.componentService = componentService;
+    this.system = system;
   }
 
   public IssueQuery createFromMap(Map<String, Object> params) {
@@ -91,7 +90,7 @@ public class IssueQueryService implements ServerComponent {
         .planned(RubyUtils.toBoolean(params.get(IssueFilterParameters.PLANNED)))
         .hideRules(RubyUtils.toBoolean(params.get(IssueFilterParameters.HIDE_RULES)))
         .createdAt(RubyUtils.toDate(params.get(IssueFilterParameters.CREATED_AT)))
-        .createdAfter(RubyUtils.toDate(params.get(IssueFilterParameters.CREATED_AFTER)))
+        .createdAfter(buildCreatedAfter(RubyUtils.toDate(params.get(IssueFilterParameters.CREATED_AFTER)), (String) params.get(IssueFilterParameters.CREATED_IN_LAST)))
         .createdBefore(RubyUtils.toDate(params.get(IssueFilterParameters.CREATED_BEFORE)));
 
       Set<String> allComponentUuids = Sets.newHashSet();
@@ -135,6 +134,16 @@ public class IssueQueryService implements ServerComponent {
     }
   }
 
+  private Date buildCreatedAfter(@Nullable Date createdAfter, @Nullable String createdSince) {
+    Preconditions.checkArgument(createdAfter == null || createdSince == null, "createdAfter and createdSince cannot be set simultaneously");
+
+    Date actualCreatedAfter = createdAfter;
+    if (createdSince != null) {
+      actualCreatedAfter = new DateTime(system.now()).minus(ISOPeriodFormat.standard().parsePeriod("P" + createdSince.toUpperCase())).toDate();
+    }
+    return actualCreatedAfter;
+  }
+
   public IssueQuery createFromRequest(Request request) {
     DbSession session = dbClient.openSession(false);
     try {
@@ -153,7 +162,7 @@ public class IssueQueryService implements ServerComponent {
         .assigned(request.paramAsBoolean(IssueFilterParameters.ASSIGNED))
         .planned(request.paramAsBoolean(IssueFilterParameters.PLANNED))
         .createdAt(request.paramAsDateTime(IssueFilterParameters.CREATED_AT))
-        .createdAfter(request.paramAsDateTime(IssueFilterParameters.CREATED_AFTER))
+        .createdAfter(buildCreatedAfter(request.paramAsDateTime(IssueFilterParameters.CREATED_AFTER), request.param(IssueFilterParameters.CREATED_IN_LAST)))
         .createdBefore(request.paramAsDateTime(IssueFilterParameters.CREATED_BEFORE))
         .ignorePaging(request.paramAsBoolean(IssueFilterParameters.IGNORE_PAGING));
 
index 24c4b2b7ab83a30ffe2c66b15fecaab14fa4bbad..d8fb99c16dc53bf102863f5b86060976acc5a4c8 100644 (file)
@@ -64,6 +64,7 @@ public class IssueFilterParameters {
   public static final String CREATED_AFTER = "createdAfter";
   public static final String CREATED_AT = "createdAt";
   public static final String CREATED_BEFORE = "createdBefore";
+  public static final String CREATED_IN_LAST = "createdInLast";
   public static final String PAGE_SIZE = "pageSize";
   public static final String PAGE_INDEX = "pageIndex";
   public static final String SORT = "sort";
@@ -73,8 +74,8 @@ public class IssueFilterParameters {
   public static final String FACET_ASSIGNED_TO_ME = "assigned_to_me";
 
   public static final List<String> ALL = ImmutableList.of(ISSUES, SEVERITIES, STATUSES, RESOLUTIONS, RESOLVED, COMPONENTS, COMPONENT_ROOTS, RULES, ACTION_PLANS, REPORTERS, TAGS,
-    ASSIGNEES, LANGUAGES, ASSIGNED, PLANNED, HIDE_RULES, CREATED_AT, CREATED_AFTER, CREATED_BEFORE, PAGE_SIZE, PAGE_INDEX, SORT, ASC, COMPONENT_UUIDS, COMPONENT_ROOT_UUIDS,
-    PROJECTS, PROJECT_UUIDS, IGNORE_PAGING, PROJECT_KEYS, COMPONENT_KEYS, MODULE_UUIDS, DIRECTORIES, FILE_UUIDS, AUTHORS, HIDE_COMMENTS);
+    ASSIGNEES, LANGUAGES, ASSIGNED, PLANNED, HIDE_RULES, CREATED_AT, CREATED_AFTER, CREATED_BEFORE, CREATED_IN_LAST, COMPONENT_UUIDS, COMPONENT_ROOT_UUIDS,
+    PROJECTS, PROJECT_UUIDS, IGNORE_PAGING, PROJECT_KEYS, COMPONENT_KEYS, MODULE_UUIDS, DIRECTORIES, FILE_UUIDS, AUTHORS, HIDE_COMMENTS, PAGE_SIZE, PAGE_INDEX, SORT, ASC);
 
   public static final List<String> ALL_WITHOUT_PAGINATION = newArrayList(Iterables.filter(ALL, new Predicate<String>() {
     @Override
index 35c1574850ab47a469b932be3e9c8950f4118401..90be2256abaabe1d49a8f4a6ea01f25b3ee845a0 100644 (file)
@@ -187,11 +187,16 @@ public class SearchAction implements BaseIssuesWsAction {
       .setDescription("To retrieve issues created at a given date. Format: date or datetime ISO formats")
       .setExampleValue("2013-05-01 (or 2013-05-01T13:00:00+0100)");
     action.createParam(IssueFilterParameters.CREATED_AFTER)
-      .setDescription("To retrieve issues created after the given date (exclusive). Format: date or datetime ISO formats")
+      .setDescription("To retrieve issues created after the given date (exclusive). Format: date or datetime ISO formats. If this parameter is set, createdSince must not be set")
       .setExampleValue("2013-05-01 (or 2013-05-01T13:00:00+0100)");
     action.createParam(IssueFilterParameters.CREATED_BEFORE)
       .setDescription("To retrieve issues created before the given date (exclusive). Format: date or datetime ISO formats")
       .setExampleValue("2013-05-01 (or 2013-05-01T13:00:00+0100)");
+    action.createParam(IssueFilterParameters.CREATED_IN_LAST)
+      .setDescription("To retrieve issues created during a time span before the current time (exclusive). " +
+        "Accepted units are 'y' for year, 'm' for month, 'w' for week and 'd' for day. " +
+        "If this parameter is set, createdAfter must not be set")
+      .setExampleValue("1m2w (1 month 2 weeks)");
     action.createParam(IssueFilterParameters.IGNORE_PAGING)
       .setDescription("Return the full list of issues, regardless of paging. For internal use only")
       .setBooleanPossibleValues()
index 1a301b8cc66ca3890654c9d2eaea94a843a01d01..4e0db201be03c5a906281ee54e130066ad40ee87 100644 (file)
@@ -35,6 +35,7 @@ import org.mockito.stubbing.Answer;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.persistence.DbSession;
@@ -44,10 +45,7 @@ import org.sonar.server.component.db.ComponentDao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.user.MockUserSession;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
+import java.util.*;
 
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Maps.newHashMap;
@@ -78,6 +76,9 @@ public class IssueQueryServiceTest {
   @Mock
   ComponentService componentService;
 
+  @Mock
+  System2 system;
+
   IssueQueryService issueQueryService;
 
   @Before
@@ -94,7 +95,7 @@ public class IssueQueryServiceTest {
       }
     });
 
-    issueQueryService = new IssueQueryService(dbClient, componentService);
+    issueQueryService = new IssueQueryService(dbClient, componentService, system);
   }
 
   @After
@@ -434,4 +435,29 @@ public class IssueQueryServiceTest {
     IssueQuery query = issueQueryService.createFromMap(map);
     assertThat(query.fileUuids()).containsExactly(fileUuid);
   }
+
+  @Test
+  public void fail_if_created_after_and_created_since_are_both_set() {
+    Map<String, Object> map = newHashMap();
+    map.put("createdAfter", "2013-07-25T07:35:00+0100");
+    map.put("createdInLast", "palap");
+
+    try {
+      issueQueryService.createFromMap(map);
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("createdAfter and createdSince cannot be set simultaneously");
+    }
+  }
+
+  @Test
+  public void set_created_after_from_created_since() {
+    Date now = DateUtils.parseDateTime("2013-07-25T07:35:00+0100");
+    when(system.now()).thenReturn(now.getTime());
+    Map<String, Object> map = newHashMap();
+
+    map.put("createdInLast", "1y2m3w4d");
+    assertThat(issueQueryService.createFromMap(map).createdAfter()).isEqualTo(DateUtils.parseDateTime("2012-04-30T07:35:00+0100"));
+
+  }
 }
index 79a5f5c0085fa40bc1bad4146b221e627ac08820..2595a65d48ed87d587d5604a43e52dcc8f34b724 100644 (file)
@@ -88,7 +88,7 @@ public class SearchActionMediumTest {
     assertThat(show.isPost()).isFalse();
     assertThat(show.isInternal()).isFalse();
     assertThat(show.responseExampleAsString()).isNotEmpty();
-    assertThat(show.params()).hasSize(39);
+    assertThat(show.params()).hasSize(40);
   }
 
   @Test