import static com.google.common.collect.Lists.newArrayList;
+@Deprecated
public class IssueSearchAction implements RequestHandler {
+ public static final String SEARCH_ACTION = "search";
+
private static final String ACTIONS_EXTRA_FIELD = "actions";
private static final String TRANSITIONS_EXTRA_FIELD = "transitions";
private static final String ASSIGNEE_NAME_EXTRA_FIELD = "assigneeName";
}
void define(WebService.NewController controller) {
- WebService.NewAction action = controller.createAction("search")
+ WebService.NewAction action = controller.createAction(SEARCH_ACTION)
.setDescription("Get a list of issues. If the number of issues is greater than 10,000, only the first 10,000 ones are returned by the web service. " +
"Requires Browse permission on project(s)")
.setSince("3.6")
private void checkFormatParameter(Request request) {
String format = request.param("format");
- if (!Strings.isNullOrEmpty(format) && !"json".equals(format)){
+ if (!Strings.isNullOrEmpty(format) && !"json".equals(format)) {
throw new BadRequestException("Only json format is supported.");
}
}
.prop("name", component.name())
.prop("longName", component.longName())
.prop("path", component.path())
- // On a root project, subProjectId is null but projectId is equal to itself, which make no sense.
+ // On a root project, subProjectId is null but projectId is equal to itself, which make no sense.
.prop("projectId", (componentDto.projectId() != null && componentDto.subProjectId() != null) ? componentDto.projectId() : null)
.prop("subProjectId", componentDto.subProjectId())
.endObject();
public class IssueShowAction implements RequestHandler {
+ public static final String SHOW_ACTION = "show";
+
private final IssueFinder issueFinder;
private final IssueChangelogService issueChangelogService;
private final IssueActionsWriter actionsWriter;
private final Durations durations;
public IssueShowAction(IssueFinder issueFinder, IssueChangelogService issueChangelogService, IssueActionsWriter actionsWriter,
- DebtModelService debtModel, I18n i18n, Durations durations) {
+ DebtModelService debtModel, I18n i18n, Durations durations) {
this.issueFinder = issueFinder;
this.issueChangelogService = issueChangelogService;
this.actionsWriter = actionsWriter;
}
void define(WebService.NewController controller) {
- WebService.NewAction action = controller.createAction("show")
+ WebService.NewAction action = controller.createAction(SHOW_ACTION)
.setDescription("Detail of issue")
.setSince("4.2")
.setInternal(true)
.prop("componentQualifier", component != null ? component.qualifier() : null)
.prop("project", issue.projectKey())
.prop("projectName", projectName)
- .prop("subProjectName", subProjectName)
- ;
+ .prop("subProjectName", subProjectName);
}
private void writeComments(IssueQueryResult queryResult, Issue issue, JsonWriter json) {
public class IssuesWs implements WebService {
+ public static final String API_ENDPOINT = "api/issues";
+
+ public static final String CHANGELOG_ACTION = "changelog";
+ public static final String ASSIGN_ACTION = "assign";
+ public static final String ADD_COMMENT_ACTION = "add_comment";
+ public static final String DELETE_COMMENT_ACTION = "delete_comment";
+ public static final String EDIT_COMMENT_ACTION = "edit_comment";
+ public static final String SET_SEVERITY_ACTION = "set_severity";
+ public static final String PLAN_ACTION = "plan";
+ public static final String DO_TRANSITION_ACTION = "do_transition";
+ public static final String TRANSITIONS_ACTION = "transitions";
+ public static final String CREATE_ACTION = "create";
+ public static final String DO_ACTION_ACTION = "do_action";
+ public static final String BULK_CHANGE_ACTION = "bulk_change";
+
private final IssueShowAction showAction;
- private final IssueSearchAction searchAction;
+ private final IssueSearchAction previousSearchAction;
+ private final SearchAction searchAction;
- public IssuesWs(IssueShowAction showAction, IssueSearchAction searchAction) {
+ public IssuesWs(IssueShowAction showAction, SearchAction searchAction, IssueSearchAction previousSearchAction) {
this.showAction = showAction;
+ this.previousSearchAction = previousSearchAction;
this.searchAction = searchAction;
}
@Override
public void define(Context context) {
- NewController controller = context.createController("api/issues");
+ NewController controller = context.createController(API_ENDPOINT);
controller.setDescription("Coding rule issues");
controller.setSince("3.6");
showAction.define(controller);
+
+ previousSearchAction.define(controller);
searchAction.define(controller);
defineChangelogAction(controller);
}
private void defineChangelogAction(NewController controller) {
- WebService.NewAction action = controller.createAction("changelog")
+ WebService.NewAction action = controller.createAction(CHANGELOG_ACTION)
.setDescription("Display changelog of an issue")
.setSince("4.1")
.setHandler(RailsHandler.INSTANCE)
}
private void defineAssignAction(NewController controller) {
- WebService.NewAction action = controller.createAction("assign")
+ WebService.NewAction action = controller.createAction(ASSIGN_ACTION)
.setDescription("Assign/Unassign an issue. Requires authentication and Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineAddCommentAction(NewController controller) {
- WebService.NewAction action = controller.createAction("add_comment")
+ WebService.NewAction action = controller.createAction(ADD_COMMENT_ACTION)
.setDescription("Add a comment. Requires authentication and Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineDeleteCommentAction(NewController controller) {
- WebService.NewAction action = controller.createAction("delete_comment")
+ WebService.NewAction action = controller.createAction(DELETE_COMMENT_ACTION)
.setDescription("Delete a comment. Requires authentication and Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineEditCommentAction(NewController controller) {
- WebService.NewAction action = controller.createAction("edit_comment")
+ WebService.NewAction action = controller.createAction(EDIT_COMMENT_ACTION)
.setDescription("Edit a comment. Requires authentication and User role on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineSetSeverityAction(NewController controller) {
- WebService.NewAction action = controller.createAction("set_severity")
+ WebService.NewAction action = controller.createAction(SET_SEVERITY_ACTION)
.setDescription("Change severity. Requires authentication and Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void definePlanAction(NewController controller) {
- WebService.NewAction action = controller.createAction("plan")
+ WebService.NewAction action = controller.createAction(PLAN_ACTION)
.setDescription("Plan/Unplan an issue. Requires authentication and Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineDoTransitionAction(NewController controller) {
- WebService.NewAction action = controller.createAction("do_transition")
+ WebService.NewAction action = controller.createAction(DO_TRANSITION_ACTION)
.setDescription("Do workflow transition on an issue. Requires authentication and Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineTransitionsAction(NewController controller) {
- WebService.NewAction action = controller.createAction("transitions")
+ WebService.NewAction action = controller.createAction(TRANSITIONS_ACTION)
.setDescription("Get Possible Workflow Transitions for an Issue. Requires Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineCreateAction(NewController controller) {
- WebService.NewAction action = controller.createAction("create")
+ WebService.NewAction action = controller.createAction(CREATE_ACTION)
.setDescription("Create a manual issue. Requires authentication and Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineDoActionAction(NewController controller) {
- WebService.NewAction action = controller.createAction("do_action")
+ WebService.NewAction action = controller.createAction(DO_ACTION_ACTION)
.setDescription("Do workflow transition on an issue. Requires authentication and Browse permission on project")
.setSince("3.6")
.setHandler(RailsHandler.INSTANCE)
}
private void defineBulkChangeAction(NewController controller) {
- WebService.NewAction action = controller.createAction("bulk_change")
+ WebService.NewAction action = controller.createAction(BULK_CHANGE_ACTION)
.setDescription("Bulk change on issues. Requires authentication and User role on project(s)")
.setSince("3.7")
.setHandler(RailsHandler.INSTANCE)
--- /dev/null
+package org.sonar.server.issue.ws;
+
+import com.google.common.io.Resources;
+import org.sonar.api.i18n.I18n;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.Durations;
+import org.sonar.server.issue.filter.IssueFilterParameters;
+import org.sonar.server.issue.index.IssueIndex;
+
+public class SearchAction implements RequestHandler {
+
+ public static final String SEARCH_ACTION = "es-search";
+
+ private static final String ACTIONS_EXTRA_FIELD = "actions";
+ private static final String TRANSITIONS_EXTRA_FIELD = "transitions";
+ private static final String ASSIGNEE_NAME_EXTRA_FIELD = "assigneeName";
+ private static final String REPORTER_NAME_EXTRA_FIELD = "reporterName";
+ private static final String ACTION_PLAN_NAME_EXTRA_FIELD = "actionPlanName";
+
+ private static final String EXTRA_FIELDS_PARAM = "extra_fields";
+
+ private final IssueIndex issueIndex;
+ private final IssueActionsWriter actionsWriter;
+ private final I18n i18n;
+ private final Durations durations;
+
+ public SearchAction(IssueIndex index, IssueActionsWriter actionsWriter, I18n i18n, Durations durations) {
+ this.issueIndex = index;
+ this.actionsWriter = actionsWriter;
+ this.i18n = i18n;
+ this.durations = durations;
+ }
+
+ void define(WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction(SEARCH_ACTION)
+ .setDescription("Get a list of issues. If the number of issues is greater than 10,000, only the first 10,000 ones are returned by the web service. " +
+ "Requires Browse permission on project(s)")
+ .setSince("3.6")
+ .setHandler(this)
+ .setResponseExample(Resources.getResource(this.getClass(), "example-search.json"));
+
+ action.createParam(IssueFilterParameters.ISSUES)
+ .setDescription("Comma-separated list of issue keys")
+ .setExampleValue("5bccd6e8-f525-43a2-8d76-fcb13dde79ef");
+ action.createParam(IssueFilterParameters.SEVERITIES)
+ .setDescription("Comma-separated list of severities")
+ .setExampleValue(Severity.BLOCKER + "," + Severity.CRITICAL)
+ .setPossibleValues(Severity.ALL);
+ action.createParam(IssueFilterParameters.STATUSES)
+ .setDescription("Comma-separated list of statuses")
+ .setExampleValue(Issue.STATUS_OPEN + "," + Issue.STATUS_REOPENED)
+ .setPossibleValues(Issue.STATUSES);
+ action.createParam(IssueFilterParameters.RESOLUTIONS)
+ .setDescription("Comma-separated list of resolutions")
+ .setExampleValue(Issue.RESOLUTION_FIXED + "," + Issue.RESOLUTION_REMOVED)
+ .setPossibleValues(Issue.RESOLUTIONS);
+ action.createParam(IssueFilterParameters.RESOLVED)
+ .setDescription("To match resolved or unresolved issues")
+ .setBooleanPossibleValues();
+ action.createParam(IssueFilterParameters.COMPONENTS)
+ .setDescription("To retrieve issues associated to a specific list of components (comma-separated list of component keys). " +
+ "Note that if you set the value to a project key, only issues associated to this project are retrieved. " +
+ "Issues associated to its sub-components (such as files, packages, etc.) are not retrieved. See also componentRoots")
+ .setExampleValue("org.apache.struts:struts:org.apache.struts.Action");
+ action.createParam(IssueFilterParameters.COMPONENT_ROOTS)
+ .setDescription("To retrieve issues associated to a specific list of components and their sub-components (comma-separated list of component keys). " +
+ "Views are not supported")
+ .setExampleValue("org.apache.struts:struts");
+ action.createParam(IssueFilterParameters.RULES)
+ .setDescription("Comma-separated list of coding rule keys. Format is <repository>:<rule>")
+ .setExampleValue("squid:AvoidCycles");
+ action.createParam(IssueFilterParameters.HIDE_RULES)
+ .setDescription("To not return rules")
+ .setBooleanPossibleValues();
+ action.createParam(IssueFilterParameters.ACTION_PLANS)
+ .setDescription("Comma-separated list of action plan keys (not names)")
+ .setExampleValue("3f19de90-1521-4482-a737-a311758ff513");
+ action.createParam(IssueFilterParameters.PLANNED)
+ .setDescription("To retrieve issues associated to an action plan or not")
+ .setBooleanPossibleValues();
+ action.createParam(IssueFilterParameters.REPORTERS)
+ .setDescription("Comma-separated list of reporter logins")
+ .setExampleValue("admin");
+ action.createParam(IssueFilterParameters.ASSIGNEES)
+ .setDescription("Comma-separated list of assignee logins")
+ .setExampleValue("admin,usera");
+ action.createParam(IssueFilterParameters.ASSIGNED)
+ .setDescription("To retrieve assigned or unassigned issues")
+ .setBooleanPossibleValues();
+ action.createParam(IssueFilterParameters.LANGUAGES)
+ .setDescription("Comma-separated list of languages. Available since 4.4")
+ .setExampleValue("java,js");
+ action.createParam(EXTRA_FIELDS_PARAM)
+ .setDescription("Add some extra fields on each issue. Available since 4.4")
+ .setPossibleValues(ACTIONS_EXTRA_FIELD, TRANSITIONS_EXTRA_FIELD, ASSIGNEE_NAME_EXTRA_FIELD, REPORTER_NAME_EXTRA_FIELD, ACTION_PLAN_NAME_EXTRA_FIELD);
+ action.createParam(IssueFilterParameters.CREATED_AT)
+ .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 (inclusive). Format: date or datetime ISO formats")
+ .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.PAGE_SIZE)
+ .setDescription("Maximum number of results per page. " +
+ "Default value: 100 (except when the 'components' parameter is set, value is set to \"-1\" in this case). " +
+ "If set to \"-1\", the max possible value is used")
+ .setExampleValue("50");
+ action.createParam(IssueFilterParameters.PAGE_INDEX)
+ .setDescription("Index of the selected page")
+ .setDefaultValue("1")
+ .setExampleValue("2");
+ action.createParam(IssueFilterParameters.SORT)
+ .setDescription("Sort field")
+ .setPossibleValues(IssueQuery.SORTS);
+ action.createParam(IssueFilterParameters.ASC)
+ .setDescription("Ascending sort")
+ .setBooleanPossibleValues();
+ action.createParam("format")
+ .setDescription("Only json format is available. This parameter is kept only for backward compatibility and shouldn't be used anymore");
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+
+ }
+}
pico.addSingleton(IssuesWs.class);
pico.addSingleton(IssueShowAction.class);
pico.addSingleton(IssueSearchAction.class);
+ pico.addSingleton(org.sonar.server.issue.ws.SearchAction.class);
pico.addSingleton(IssueActionsWriter.class);
// issue filters
result.setPaging(Paging.create(100, 1, 2));
when(i18n.formatInteger(any(Locale.class), eq(2))).thenReturn("2");
- tester = new WsTester(new IssuesWs(mock(IssueShowAction.class), new IssueSearchAction(issueFinder, new IssueActionsWriter(issueService, actionService), i18n, durations)));
+ tester = new WsTester(new IssuesWs(mock(IssueShowAction.class),
+ mock(SearchAction.class),
+ new IssueSearchAction(issueFinder, new IssueActionsWriter(issueService, actionService), i18n, durations)));
}
@Test
when(i18n.message(any(Locale.class), eq("created"), eq((String) null))).thenReturn("Created");
tester = new WsTester(new IssuesWs(new IssueShowAction(issueFinder, issueChangelogService, new IssueActionsWriter(issueService, actionService), debtModel, i18n, durations),
+ mock(SearchAction.class),
mock(IssueSearchAction.class)));
}
--- /dev/null
+package org.sonar.server.issue.ws;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.tester.ServerTester;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.ws.WsTester;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IssuesWsMediumTest {
+
+ @ClassRule
+ public static ServerTester tester = new ServerTester();
+
+ IssuesWs ws;
+ DbClient db;
+ DbSession session;
+ WsTester wsTester;
+
+ @Before
+ public void setUp() throws Exception {
+ tester.clearDbAndIndexes();
+ db = tester.get(DbClient.class);
+ ws = tester.get(IssuesWs.class);
+ wsTester = tester.get(WsTester.class);
+ session = db.openSession(false);
+ MockUserSession.set().setLogin("gandalf").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+
+ }
+
+ @After
+ public void after() {
+ session.close();
+ }
+
+ @Test
+ public void define() throws Exception {
+
+ WebService.Context context = new WebService.Context();
+ ws.define(context);
+
+ WebService.Controller controller = context.controller(IssuesWs.API_ENDPOINT);
+
+ assertThat(controller).isNotNull();
+ assertThat(controller.actions()).hasSize(15);
+ assertThat(controller.action(IssuesWs.ADD_COMMENT_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.ASSIGN_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.BULK_CHANGE_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.CHANGELOG_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.CREATE_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.DELETE_COMMENT_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.DO_ACTION_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.DO_TRANSITION_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.EDIT_COMMENT_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.PLAN_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.SET_SEVERITY_ACTION)).isNotNull();
+ assertThat(controller.action(IssuesWs.TRANSITIONS_ACTION)).isNotNull();
+
+ assertThat(controller.action(IssueSearchAction.SEARCH_ACTION)).isNotNull();
+ assertThat(controller.action(SearchAction.SEARCH_ACTION)).isNotNull();
+ }
+
+ @Test
+ public void deactivate_rule() throws Exception {
+ // QualityProfileDto profile = createProfile("java");
+ // RuleDto rule = createRule(profile.getLanguage(), "toto");
+ // createActiveRule(rule, profile);
+ // session.commit();
+ //
+ // // 0. Assert No Active Rule for profile
+ // assertThat(db.activeRuleDao().findByProfileKey(session, profile.getKey())).hasSize(1);
+ //
+ // // 1. Deactivate Rule
+ // WsTester.TestRequest request = wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, RuleActivationActions.DEACTIVATE_ACTION);
+ // request.setParam(RuleActivationActions.PROFILE_KEY, profile.getKey().toString());
+ // request.setParam(RuleActivationActions.RULE_KEY, rule.getKey().toString());
+ // request.execute();
+ // session.clearCache();
+ //
+ // // 2. Assert ActiveRule in DAO
+ // assertThat(db.activeRuleDao().findByProfileKey(session, profile.getKey())).isEmpty();
+ }
+
+}
showAction = new IssueShowAction(issueFinder, issueChangelogService, actionsWriter, debtModelService, i18n, durations);
searchAction = new IssueSearchAction(issueFinder, actionsWriter, i18n, durations);
- tester = new WsTester(new IssuesWs(showAction, searchAction));
+ tester = new WsTester(new IssuesWs(showAction, mock(SearchAction.class), searchAction));
}
@Test