aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2014-10-01 14:59:09 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2014-10-02 15:27:36 +0200
commitbd4be93baf327fad6d21faae88ed8929039671dc (patch)
treee4910ca7933c6f1dd1779cbeb1604446510272a3 /server/sonar-server
parent22710990afe5162eba741dce85d9452ccda7ec66 (diff)
downloadsonarqube-bd4be93baf327fad6d21faae88ed8929039671dc.tar.gz
sonarqube-bd4be93baf327fad6d21faae88ed8929039671dc.zip
SONAR-5603 Remove useless select methods using IssueQuery in IssueDao
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java353
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java31
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java17
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java37
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_by_action_plan.xml29
7 files changed, 457 insertions, 16 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java
new file mode 100644
index 00000000000..e8935b5e87a
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java
@@ -0,0 +1,353 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.issue;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import org.apache.commons.lang.builder.ReflectionToStringBuilder;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.server.search.QueryContext;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * @since 3.6
+ */
+public class IssueQuery {
+
+ public static final String SORT_BY_CREATION_DATE = "CREATION_DATE";
+ public static final String SORT_BY_UPDATE_DATE = "UPDATE_DATE";
+ public static final String SORT_BY_CLOSE_DATE = "CLOSE_DATE";
+ public static final String SORT_BY_ASSIGNEE = "ASSIGNEE";
+ public static final String SORT_BY_SEVERITY = "SEVERITY";
+ public static final String SORT_BY_STATUS = "STATUS";
+ public static final Set<String> SORTS = ImmutableSet.of(SORT_BY_CREATION_DATE, SORT_BY_UPDATE_DATE, SORT_BY_CLOSE_DATE, SORT_BY_ASSIGNEE, SORT_BY_SEVERITY, SORT_BY_STATUS);
+
+ private final Collection<String> issueKeys;
+ private final Collection<String> severities;
+ private final Collection<String> statuses;
+ private final Collection<String> resolutions;
+ private final Collection<String> components;
+ private final Collection<String> componentRoots;
+ private final Collection<RuleKey> rules;
+ private final Collection<String> actionPlans;
+ private final Collection<String> reporters;
+ private final Collection<String> assignees;
+ private final Collection<String> languages;
+ private final Boolean assigned;
+ private final Boolean planned;
+ private final Boolean resolved;
+ private final Boolean hideRules;
+ private final Date createdAt;
+ private final Date createdAfter;
+ private final Date createdBefore;
+ private final String sort;
+ private final Boolean asc;
+
+ private IssueQuery(Builder builder) {
+ this.issueKeys = defaultCollection(builder.issueKeys);
+ this.severities = defaultCollection(builder.severities);
+ this.statuses = defaultCollection(builder.statuses);
+ this.resolutions = defaultCollection(builder.resolutions);
+ this.components = defaultCollection(builder.components);
+ this.componentRoots = defaultCollection(builder.componentRoots);
+ this.rules = defaultCollection(builder.rules);
+ this.actionPlans = defaultCollection(builder.actionPlans);
+ this.reporters = defaultCollection(builder.reporters);
+ this.assignees = defaultCollection(builder.assignees);
+ this.languages = defaultCollection(builder.languages);
+ this.assigned = builder.assigned;
+ this.planned = builder.planned;
+ this.resolved = builder.resolved;
+ this.hideRules = builder.hideRules;
+ this.createdAt = builder.createdAt;
+ this.createdAfter = builder.createdAfter;
+ this.createdBefore = builder.createdBefore;
+ this.sort = builder.sort;
+ this.asc = builder.asc;
+ }
+
+ public Collection<String> issueKeys() {
+ return issueKeys;
+ }
+
+ public Collection<String> severities() {
+ return severities;
+ }
+
+ public Collection<String> statuses() {
+ return statuses;
+ }
+
+ public Collection<String> resolutions() {
+ return resolutions;
+ }
+
+ public Collection<String> components() {
+ return components;
+ }
+
+ public Collection<String> componentRoots() {
+ return componentRoots;
+ }
+
+ public Collection<RuleKey> rules() {
+ return rules;
+ }
+
+ public Collection<String> actionPlans() {
+ return actionPlans;
+ }
+
+ public Collection<String> reporters() {
+ return reporters;
+ }
+
+ public Collection<String> assignees() {
+ return assignees;
+ }
+
+ public Collection<String> languages() {
+ return languages;
+ }
+
+ @CheckForNull
+ public Boolean assigned() {
+ return assigned;
+ }
+
+ @CheckForNull
+ public Boolean planned() {
+ return planned;
+ }
+
+ @CheckForNull
+ public Boolean resolved() {
+ return resolved;
+ }
+
+ /**
+ * @since 4.2
+ */
+ @CheckForNull
+ public Boolean hideRules() {
+ return hideRules;
+ }
+
+ @CheckForNull
+ public Date createdAfter() {
+ return createdAfter == null ? null : new Date(createdAfter.getTime());
+ }
+
+ @CheckForNull
+ public Date createdAt() {
+ return createdAt == null ? null : new Date(createdAt.getTime());
+ }
+
+ @CheckForNull
+ public Date createdBefore() {
+ return createdBefore == null ? null : new Date(createdBefore.getTime());
+ }
+
+ @CheckForNull
+ public String sort() {
+ return sort;
+ }
+
+ @CheckForNull
+ public Boolean asc() {
+ return asc;
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private Collection<String> issueKeys;
+ private Collection<String> severities;
+ private Collection<String> statuses;
+ private Collection<String> resolutions;
+ private Collection<String> components;
+ private Collection<String> componentRoots;
+ private Collection<RuleKey> rules;
+ private Collection<String> actionPlans;
+ private Collection<String> reporters;
+ private Collection<String> assignees;
+ private Collection<String> languages;
+ private Boolean assigned = null;
+ private Boolean planned = null;
+ private Boolean resolved = null;
+ private Boolean hideRules = false;
+ private Date createdAt;
+ private Date createdAfter;
+ private Date createdBefore;
+ private String sort;
+ private Boolean asc = false;
+
+ private Builder() {
+ }
+
+ public Builder issueKeys(@Nullable Collection<String> l) {
+ this.issueKeys = l;
+ return this;
+ }
+
+ public Builder severities(@Nullable Collection<String> l) {
+ this.severities = l;
+ return this;
+ }
+
+ public Builder statuses(@Nullable Collection<String> l) {
+ this.statuses = l;
+ return this;
+ }
+
+ public Builder resolutions(@Nullable Collection<String> l) {
+ this.resolutions = l;
+ return this;
+ }
+
+ public Builder components(@Nullable Collection<String> l) {
+ this.components = l;
+ return this;
+ }
+
+ public Builder componentRoots(@Nullable Collection<String> l) {
+ this.componentRoots = l;
+ return this;
+ }
+
+ public Builder rules(@Nullable Collection<RuleKey> rules) {
+ this.rules = rules;
+ return this;
+ }
+
+ public Builder actionPlans(@Nullable Collection<String> l) {
+ this.actionPlans = l;
+ return this;
+ }
+
+ public Builder reporters(@Nullable Collection<String> l) {
+ this.reporters = l;
+ return this;
+ }
+
+ public Builder assignees(@Nullable Collection<String> l) {
+ this.assignees = l;
+ return this;
+ }
+
+ public Builder languages(@Nullable Collection<String> l) {
+ this.languages = l;
+ return this;
+ }
+
+ /**
+ * If true, it will return all issues assigned to someone
+ * If false, it will return all issues not assigned to someone
+ */
+ public Builder assigned(@Nullable Boolean b) {
+ this.assigned = b;
+ return this;
+ }
+
+ /**
+ * If true, it will return all issues linked to an action plan
+ * If false, it will return all issues not linked to an action plan
+ */
+ public Builder planned(@Nullable Boolean planned) {
+ this.planned = planned;
+ return this;
+ }
+
+ /**
+ * If true, it will return all resolved issues
+ * If false, it will return all none resolved issues
+ */
+ public Builder resolved(@Nullable Boolean resolved) {
+ this.resolved = resolved;
+ return this;
+ }
+
+ /**
+ * If true, rules will not be loaded
+ * If false, rules will be loaded
+ *
+ * @since 4.2
+ *
+ */
+ public Builder hideRules(@Nullable Boolean b) {
+ this.hideRules = b;
+ return this;
+ }
+
+ public Builder createdAt(@Nullable Date d) {
+ this.createdAt = d == null ? null : new Date(d.getTime());
+ return this;
+ }
+
+ public Builder createdAfter(@Nullable Date d) {
+ this.createdAfter = d == null ? null : new Date(d.getTime());
+ return this;
+ }
+
+ public Builder createdBefore(@Nullable Date d) {
+ this.createdBefore = d == null ? null : new Date(d.getTime());
+ return this;
+ }
+
+ public Builder sort(@Nullable String s) {
+ if (s != null && !SORTS.contains(s)) {
+ throw new IllegalArgumentException("Bad sort field: " + s);
+ }
+ this.sort = s;
+ return this;
+ }
+
+ public Builder asc(@Nullable Boolean asc) {
+ this.asc = asc;
+ return this;
+ }
+
+ public IssueQuery build() {
+ if (issueKeys != null) {
+ Preconditions.checkArgument(issueKeys.size() <= QueryContext.MAX_LIMIT, "Number of issue keys must be less than " + QueryContext.MAX_LIMIT + " (got " + issueKeys.size() + ")");
+ }
+ return new IssueQuery(this);
+ }
+
+ }
+
+ private static <T> Collection<T> defaultCollection(@Nullable Collection<T> c) {
+ return c == null ? Collections.<T>emptyList() : Collections.unmodifiableCollection(c);
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java
index e25c14ea3c5..3b4e2d72ccc 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/actionplan/ActionPlanService.java
@@ -32,16 +32,20 @@ import org.sonar.core.issue.ActionPlanStats;
import org.sonar.core.issue.DefaultActionPlan;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.db.*;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
import org.sonar.core.resource.ResourceQuery;
+import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.issue.IssueQuery;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
-import java.util.*;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
@@ -50,19 +54,20 @@ import static com.google.common.collect.Lists.newArrayList;
*/
public class ActionPlanService implements ServerComponent {
+ private final DbClient dbClient;
+
private final ActionPlanDao actionPlanDao;
private final ActionPlanStatsDao actionPlanStatsDao;
private final ResourceDao resourceDao;
- private final IssueDao issueDao;
private final IssueUpdater issueUpdater;
private final IssueStorage issueStorage;
- public ActionPlanService(ActionPlanDao actionPlanDao, ActionPlanStatsDao actionPlanStatsDao, ResourceDao resourceDao,
- IssueDao issueDao, IssueUpdater issueUpdater, IssueStorage issueStorage) {
+ public ActionPlanService(DbClient dbClient, ActionPlanDao actionPlanDao, ActionPlanStatsDao actionPlanStatsDao, ResourceDao resourceDao,
+ IssueUpdater issueUpdater, IssueStorage issueStorage) {
+ this.dbClient = dbClient;
this.actionPlanDao = actionPlanDao;
this.actionPlanStatsDao = actionPlanStatsDao;
this.resourceDao = resourceDao;
- this.issueDao = issueDao;
this.issueUpdater = issueUpdater;
this.issueStorage = issueStorage;
}
@@ -92,10 +97,7 @@ public class ActionPlanService implements ServerComponent {
* Unplan all issues linked to an action plan
*/
private void unplanIssues(DefaultActionPlan actionPlan, UserSession userSession) {
- // Get all issues linked to this plan (need to disable pagination and authorization check)
- IssueQuery query = IssueQuery.builder().actionPlans(Arrays.asList(actionPlan.key())).requiredRole(null).build();
- // TODO use IssueService
- List<IssueDto> dtos = issueDao.selectIssues(query);
+ List<IssueDto> dtos = findIssuesByActionPlan(actionPlan.key());
IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
List<DefaultIssue> issues = newArrayList();
for (IssueDto issueDto : dtos) {
@@ -109,6 +111,15 @@ public class ActionPlanService implements ServerComponent {
issueStorage.save(issues);
}
+ private List<IssueDto> findIssuesByActionPlan(String actionPlanKey){
+ DbSession session = dbClient.openSession(false);
+ try {
+ return dbClient.issueDao().findByActionPlan(session, actionPlanKey);
+ } finally {
+ session.close();
+ }
+ }
+
public ActionPlan setStatus(String actionPlanKey, String status, UserSession userSession) {
ActionPlanDto actionPlanDto = findActionPlanDto(actionPlanKey);
checkUserIsProjectAdministrator(actionPlanDto.getProjectKey(), userSession);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java
index 7331bfe9eb2..df3dec2284c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java
@@ -56,6 +56,10 @@ public class IssueDao extends BaseDao<IssueMapper, IssueDto, String> implements
return mapper(session).selectByKeys(keys);
}
+ public List<IssueDto> findByActionPlan(DbSession session, String actionPlan) {
+ return mapper(session).selectByActionPlan(actionPlan);
+ }
+
@Override
protected IssueDto doUpdate(DbSession session, IssueDto issue) {
mapper(session).update(issue);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
index 4e7cb0f9c62..c808234d7a5 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
@@ -40,7 +40,6 @@ import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.Durations;
import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.db.IssueChangeDao;
import org.sonar.core.persistence.DbSession;
@@ -190,7 +189,6 @@ public class SearchAction extends SearchRequestHandler<IssueQuery, Issue> {
@Override
protected IssueQuery doQuery(Request request) {
IssueQuery.Builder builder = IssueQuery.builder()
- .requiredRole(UserRole.USER)
.issueKeys(request.paramAsStrings(IssueFilterParameters.ISSUES))
.severities(request.paramAsStrings(IssueFilterParameters.SEVERITIES))
.statuses(request.paramAsStrings(IssueFilterParameters.STATUSES))
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java
index 85b13f5be44..4dc67fe4c8e 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/actionplan/ActionPlanServiceTest.java
@@ -36,12 +36,13 @@ import org.sonar.core.issue.ActionPlanStats;
import org.sonar.core.issue.DefaultActionPlan;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.db.*;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
import org.sonar.core.resource.ResourceQuery;
+import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.issue.IssueQuery;
import org.sonar.server.user.MockUserSession;
import org.sonar.server.user.UserSession;
@@ -57,6 +58,12 @@ import static org.mockito.Mockito.*;
public class ActionPlanServiceTest {
@Mock
+ DbClient dbClient;
+
+ @Mock
+ DbSession session;
+
+ @Mock
ActionPlanDao actionPlanDao;
@Mock
@@ -66,7 +73,7 @@ public class ActionPlanServiceTest {
ResourceDao resourceDao;
@Mock
- IssueDao issueDao;
+ org.sonar.server.issue.db.IssueDao issueDao;
@Mock
IssueUpdater issueUpdater;
@@ -84,7 +91,9 @@ public class ActionPlanServiceTest {
@Before
public void before() {
- actionPlanService = new ActionPlanService(actionPlanDao, actionPlanStatsDao, resourceDao, issueDao, issueUpdater, issueStorage);
+ when(dbClient.openSession(false)).thenReturn(session);
+ when(dbClient.issueDao()).thenReturn(issueDao);
+ actionPlanService = new ActionPlanService(dbClient, actionPlanDao, actionPlanStatsDao, resourceDao, issueUpdater, issueStorage);
}
@Test
@@ -145,7 +154,7 @@ public class ActionPlanServiceTest {
when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
IssueDto issueDto = new IssueDto().setId(100L).setStatus(Issue.STATUS_OPEN).setRuleKey("squid", "s100");
- when(issueDao.selectIssues(any(IssueQuery.class))).thenReturn(newArrayList(issueDto));
+ when(issueDao.findByActionPlan(session, "ABCD")).thenReturn(newArrayList(issueDto));
when(issueUpdater.plan(any(DefaultIssue.class), eq((ActionPlan) null), any(IssueChangeContext.class))).thenReturn(true);
ArgumentCaptor<DefaultIssue> captor = ArgumentCaptor.forClass(DefaultIssue.class);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java
index 7a4846e12cd..074fa458a1d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java
@@ -129,6 +129,43 @@ public class IssueDaoTest extends AbstractDaoTestCase {
}
@Test
+ public void find_by_action_plan() {
+ setupData("shared", "find_by_action_plan");
+
+ List<IssueDto> issues = dao.findByActionPlan(session, "AP-1");
+ assertThat(issues).hasSize(1);
+
+ IssueDto issue = issues.get(0);
+ assertThat(issue.getKee()).isEqualTo("ABCDE");
+ assertThat(issue.getActionPlanKey()).isEqualTo("AP-1");
+ assertThat(issue.getComponentId()).isEqualTo(401);
+ assertThat(issue.getRootComponentId()).isEqualTo(399);
+ assertThat(issue.getRuleId()).isEqualTo(500);
+ assertThat(issue.getLanguage()).isEqualTo("java");
+ assertThat(issue.getSeverity()).isEqualTo("BLOCKER");
+ assertThat(issue.isManualSeverity()).isFalse();
+ assertThat(issue.getMessage()).isNull();
+ assertThat(issue.getLine()).isEqualTo(200);
+ assertThat(issue.getEffortToFix()).isEqualTo(4.2);
+ assertThat(issue.getStatus()).isEqualTo("OPEN");
+ assertThat(issue.getResolution()).isEqualTo("FIXED");
+ assertThat(issue.getChecksum()).isEqualTo("XXX");
+ assertThat(issue.getAuthorLogin()).isEqualTo("karadoc");
+ assertThat(issue.getReporter()).isEqualTo("arthur");
+ assertThat(issue.getAssignee()).isEqualTo("perceval");
+ assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
+ assertThat(issue.getIssueCreationDate()).isNotNull();
+ assertThat(issue.getIssueUpdateDate()).isNotNull();
+ assertThat(issue.getIssueCloseDate()).isNotNull();
+ assertThat(issue.getCreatedAt()).isNotNull();
+ assertThat(issue.getUpdatedAt()).isNotNull();
+ assertThat(issue.getRuleRepo()).isEqualTo("squid");
+ assertThat(issue.getRule()).isEqualTo("AvoidCycle");
+ assertThat(issue.getComponentKey()).isEqualTo("Action.java");
+ assertThat(issue.getRootComponentKey()).isEqualTo("struts");
+ }
+
+ @Test
public void find_after_dates() throws Exception {
setupData("shared", "some_issues");
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_by_action_plan.xml b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_by_action_plan.xml
new file mode 100644
index 00000000000..6ba7716170a
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_by_action_plan.xml
@@ -0,0 +1,29 @@
+<dataset>
+
+ <issues
+ id="100"
+ kee="ABCDE"
+ component_id="401"
+ root_component_id="399"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="perceval"
+ action_plan_key="AP-1"
+ author_login="karadoc"
+ issue_attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+</dataset>