Browse Source

SONAR-15574 move Project export API to community edition

tags/9.2.0.49834
Pierre 2 years ago
parent
commit
f1d08dcbf0

+ 36
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/projectdump/ExportSubmitter.java View File

@@ -0,0 +1,36 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.ce.projectdump;

import javax.annotation.Nullable;
import org.sonar.api.server.ServerSide;
import org.sonar.ce.task.CeTask;

@ServerSide
public interface ExportSubmitter {
/**
* Adds a Project Export CE task for the specified project.
*
* @throws NullPointerException if {@code projectKey} is {@code null}
* @throws IllegalArgumentException if the specified project does not exist
*/
CeTask submitProjectExport(String projectKey, @Nullable String submitterUuid);

}

+ 62
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/projectdump/ExportSubmitterImpl.java View File

@@ -0,0 +1,62 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.ce.projectdump;

import java.util.Optional;
import javax.annotation.Nullable;
import org.sonar.ce.queue.CeQueue;
import org.sonar.ce.queue.CeTaskSubmit;
import org.sonar.ce.task.CeTask;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;
import static org.sonar.ce.queue.CeTaskSubmit.Component.fromDto;

public class ExportSubmitterImpl implements ExportSubmitter {
private final CeQueue ceQueue;
private final DbClient dbClient;

public ExportSubmitterImpl(CeQueue ceQueue, DbClient dbClient) {
this.ceQueue = ceQueue;
this.dbClient = dbClient;
}

@Override
public CeTask submitProjectExport(String projectKey, @Nullable String submitterUuid) {
requireNonNull(projectKey, "Project key can not be null");

try (DbSession dbSession = dbClient.openSession(false)) {
Optional<ComponentDto> project = dbClient.componentDao().selectByKey(dbSession, projectKey);
checkArgument(project.isPresent(), "Project with key [%s] does not exist", projectKey);

CeTaskSubmit submit = ceQueue.prepareSubmit()
.setComponent(fromDto(project.get()))
.setType("PROJECT_EXPORT")
.setSubmitterUuid(submitterUuid)
.setCharacteristics(emptyMap())
.build();
return ceQueue.submit(submit);
}
}
}

+ 38
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/projectdump/ProjectExportWsModule.java View File

@@ -0,0 +1,38 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.ce.projectdump;

import org.sonar.core.platform.Module;
import org.sonar.server.projectdump.ws.ExportAction;
import org.sonar.server.projectdump.ws.ProjectDumpWs;
import org.sonar.server.projectdump.ws.ProjectDumpWsSupport;

public class ProjectExportWsModule extends Module {
@Override
protected void configureModule() {
super.add(
ProjectDumpWsSupport.class,
ProjectDumpWs.class,
ExportAction.class,
ExportSubmitterImpl.class
);

}
}

+ 79
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/ExportAction.java View File

@@ -0,0 +1,79 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.projectdump.ws;

import org.sonar.server.ce.projectdump.ExportSubmitter;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.ce.task.CeTask;
import org.sonar.server.user.UserSession;

public class ExportAction implements ProjectDumpAction {

public static final String ACTION_KEY = "export";
private static final String PARAMETER_PROJECT_KEY = "key";

private final UserSession userSession;
private final ExportSubmitter exportSubmitter;
private final ProjectDumpWsSupport projectDumpWsSupport;

public ExportAction(ProjectDumpWsSupport projectDumpWsSupport, UserSession userSession, ExportSubmitter exportSubmitter) {
this.projectDumpWsSupport = projectDumpWsSupport;
this.userSession = userSession;
this.exportSubmitter = exportSubmitter;
}

@Override
public void define(WebService.NewController newController) {
WebService.NewAction newAction = newController.createAction(ACTION_KEY)
.setDescription("Triggers project dump so that the project can be copied to another SonarQube server " +
"(see " + ProjectDumpWs.CONTROLLER_PATH + "/import ). " +
"Requires the 'Administer' permission. " +
"This feature is provided by the Governance plugin.")
.setSince("1.0")
.setPost(true)
.setHandler(this)
.setResponseExample(getClass().getResource("example-export.json"));
newAction.createParam(PARAMETER_PROJECT_KEY)
.setRequired(true)
.setExampleValue("my_project");
}

@Override
public void handle(Request request, Response response) {
String projectKey = request.mandatoryParam(PARAMETER_PROJECT_KEY);
projectDumpWsSupport.verifyAdminOfProjectByKey(projectKey);

CeTask task = exportSubmitter.submitProjectExport(projectKey, userSession.getUuid());
try (JsonWriter writer = response.newJsonWriter()) {
CeTask.Component component = task.getComponent().get();
writer.beginObject()
.prop("taskId", task.getUuid())
.prop("projectId", component.getUuid())
.prop("projectKey", component.getKey().orElse(null))
.prop("projectName", component.getName().orElse(null))
.endObject()
.close();
}
}

}

+ 26
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/ProjectDumpAction.java View File

@@ -0,0 +1,26 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.projectdump.ws;

import org.sonar.server.ws.WsAction;

public interface ProjectDumpAction extends WsAction {

}

+ 47
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/ProjectDumpWs.java View File

@@ -0,0 +1,47 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.projectdump.ws;

import com.google.common.collect.ImmutableList;
import java.util.List;
import org.sonar.api.server.ws.WebService;

public class ProjectDumpWs implements WebService {

public static final String CONTROLLER_PATH = "api/project_dump";

private final List<ProjectDumpAction> actions;

public ProjectDumpWs(ProjectDumpAction... actions) {
this.actions = ImmutableList.copyOf(actions);
}

@Override
public void define(Context context) {
NewController controller = context.createController(CONTROLLER_PATH)
.setDescription("Project export/import")
.setSince("1.0");
for (ProjectDumpAction action : actions) {
action.define(controller);
}
controller.done();
}

}

+ 49
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/ProjectDumpWsSupport.java View File

@@ -0,0 +1,49 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.projectdump.ws;

import org.sonar.api.server.ServerSide;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.user.UserSession;

@ServerSide
public class ProjectDumpWsSupport {

private final DbClient dbClient;
private final UserSession userSession;
private final ComponentFinder componentFinder;

public ProjectDumpWsSupport(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) {
this.dbClient = dbClient;
this.userSession = userSession;
this.componentFinder = componentFinder;
}

public void verifyAdminOfProjectByKey(String projectKey) {
try (DbSession dbSession = dbClient.openSession(false)) {
ComponentDto project = componentFinder.getByKey(dbSession, projectKey);
userSession.checkComponentPermission(UserRole.ADMIN, project);
}
}
}

+ 86
- 0
server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/projectdump/ExportSubmitterImplTest.java View File

@@ -0,0 +1,86 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.ce.projectdump;

import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.ce.queue.CeQueue;
import org.sonar.ce.queue.CeQueueImpl;
import org.sonar.core.util.UuidFactoryFast;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.component.ComponentDto;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;

public class ExportSubmitterImplTest {

private static final String SOME_SUBMITTER_UUID = "some submitter uuid";

private final System2 system2 = System2.INSTANCE;
@Rule
public DbTester db = DbTester.create(system2);

private final DbClient dbClient = db.getDbClient();
private final CeQueue ceQueue = new CeQueueImpl(system2, db.getDbClient(), UuidFactoryFast.getInstance());

private final ExportSubmitterImpl underTest = new ExportSubmitterImpl(ceQueue, dbClient);

@Test
public void submitProjectExport_fails_with_NPE_if_project_key_is_null() {
assertThatThrownBy(() -> underTest.submitProjectExport(null, SOME_SUBMITTER_UUID))
.isInstanceOf(NullPointerException.class)
.hasMessage("Project key can not be null");
}

@Test
public void submitProjectExport_fails_with_IAE_if_project_with_specified_key_does_not_exist() {
assertThatThrownBy(() -> underTest.submitProjectExport("blabalble", SOME_SUBMITTER_UUID))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Project with key [blabalble] does not exist");
}

@Test
public void submitProjectExport_submits_task_with_project_uuid_and_submitterLogin_if_present() {
ComponentDto projectDto = db.components().insertPrivateProject();

underTest.submitProjectExport(projectDto.getKey(), SOME_SUBMITTER_UUID);

assertThat(dbClient.ceQueueDao().selectAllInAscOrder(db.getSession()))
.extracting(CeQueueDto::getComponentUuid, CeQueueDto::getTaskType, CeQueueDto::getSubmitterUuid)
.containsExactlyInAnyOrder(tuple(projectDto.uuid(), "PROJECT_EXPORT", SOME_SUBMITTER_UUID));
}

@Test
public void submitProjectExport_submits_task_with_project_uuid_and_no_submitterLogin_if_null() {
ComponentDto projectDto = db.components().insertPrivateProject();

underTest.submitProjectExport(projectDto.getKey(), null);

assertThat(dbClient.ceQueueDao().selectAllInAscOrder(db.getSession()))
.extracting(CeQueueDto::getComponentUuid, CeQueueDto::getTaskType, CeQueueDto::getSubmitterUuid)
.containsExactlyInAnyOrder(tuple(projectDto.uuid(), "PROJECT_EXPORT", null));
}

}

+ 160
- 0
server/sonar-webserver-webapi/src/test/java/org/sonar/server/projectdump/ws/ExportActionTest.java View File

@@ -0,0 +1,160 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.projectdump.ws;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.web.UserRole;
import org.sonar.ce.task.CeTask;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.user.UserDto;
import org.sonar.server.ce.projectdump.ExportSubmitter;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.test.JsonAssert.assertJson;

public class ExportActionTest {

private static final String TASK_ID = "THGTpxcB-iU5OvuD2ABC";
private static final String PROJECT_ID = "ABCTpxcB-iU5Ovuds4rf";
private static final String PROJECT_KEY = "the_project_key";
private static final String PROJECT_NAME = "The Project Name";

@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester db = DbTester.create();

private final ExportSubmitter exportSubmitter = mock(ExportSubmitter.class);
private final ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW);
private final ProjectDumpWsSupport projectDumpWsSupport = new ProjectDumpWsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), resourceTypes));
private final ExportAction underTest = new ExportAction(projectDumpWsSupport, userSession, exportSubmitter);
private final WsActionTester actionTester = new WsActionTester(underTest);
private ComponentDto project;

@Before
public void setUp() {
project = db.components().insertComponent(newPrivateProjectDto(PROJECT_ID).setDbKey(PROJECT_KEY).setName(PROJECT_NAME));
}

@Test
public void response_example_is_defined() {
assertThat(responseExample()).isNotEmpty();
}

@Test
public void fails_if_missing_project_key() {
logInAsProjectAdministrator("foo");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'key' parameter is missing");

actionTester.newRequest().setMethod("POST").execute();
}

@Test
public void fails_if_not_project_administrator() {
userSession.logIn();

expectedException.expect(ForbiddenException.class);

actionTester.newRequest().setMethod("POST").setParam("key", project.getDbKey()).execute();
}

@Test
public void triggers_CE_task() {
UserDto user = db.users().insertUser();
userSession.logIn(user).addProjectPermission(UserRole.ADMIN, project);

when(exportSubmitter.submitProjectExport(project.getDbKey(), user.getUuid())).thenReturn(createResponseExampleTask());
TestResponse response = actionTester.newRequest().setMethod("POST").setParam("key", project.getDbKey()).execute();

assertJson(response.getInput()).isSimilarTo(responseExample());
}

@Test
public void fails_to_trigger_task_if_anonymous() {
userSession.anonymous();

expectedException.expect(ForbiddenException.class);
expectedException.expectMessage("Insufficient privileges");

actionTester.newRequest().setMethod("POST").setParam("key", project.getDbKey()).execute();
}

@Test
public void triggers_CE_task_if_project_admin() {
UserDto user = db.users().insertUser();
userSession.logIn(user).addProjectPermission(UserRole.ADMIN, project);

when(exportSubmitter.submitProjectExport(project.getDbKey(), user.getUuid())).thenReturn(createResponseExampleTask());
TestResponse response = actionTester.newRequest().setMethod("POST").setParam("key", project.getDbKey()).execute();

assertJson(response.getInput()).isSimilarTo(responseExample());
}

@Test
public void fail_when_using_branch_db_key() {
ComponentDto project = db.components().insertPublicProject();
ComponentDto branch = db.components().insertProjectBranch(project);
userSession.logIn().addProjectPermission(UserRole.ADMIN, project);

expectedException.expect(NotFoundException.class);

actionTester.newRequest()
.setMethod("POST")
.setParam("key", branch.getDbKey())
.execute();
}

private void logInAsProjectAdministrator(String login) {
userSession.logIn(login).addProjectPermission(UserRole.ADMIN, project);
}

private String responseExample() {
return actionTester.getDef().responseExampleAsString();
}

private CeTask createResponseExampleTask() {
CeTask.Component component = new CeTask.Component(project.uuid(), project.getDbKey(), project.name());
return new CeTask.Builder()
.setType("PROJECT_EXPORT") // TODO replace with the definitive enum
.setUuid(TASK_ID)
.setComponent(component)
.setMainComponent(component)
.build();
}
}

+ 55
- 0
server/sonar-webserver-webapi/src/test/java/org/sonar/server/projectdump/ws/ProjectDumpWsTest.java View File

@@ -0,0 +1,55 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.projectdump.ws;

import org.junit.Test;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;

import static org.assertj.core.api.Assertions.assertThat;

public class ProjectDumpWsTest {
@Test
public void testDefine() {
ProjectDumpWs underTest = new ProjectDumpWs(new DumbAction());

WebService.Context context = new WebService.Context();
underTest.define(context);

WebService.Controller controller = context.controller("api/project_dump");
assertThat(controller.since()).isNotEmpty();
assertThat(controller.description()).isNotEmpty();
assertThat(controller.isInternal()).isFalse();
assertThat(controller.action("dumb")).isNotNull();
}

private static class DumbAction implements ProjectDumpAction {
@Override
public void define(WebService.NewController newController) {
newController.createAction("dumb").setHandler(this);
}

@Override
public void handle(Request request, Response response) {

}
}
}

+ 6
- 0
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/projectdump/ws/example-export.json View File

@@ -0,0 +1,6 @@
{
"taskId": "THGTpxcB-iU5OvuD2ABC",
"projectId": "ABCTpxcB-iU5Ovuds4rf",
"projectKey": "the_project_key",
"projectName": "The Project Name"
}

+ 4
- 0
server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java View File

@@ -64,6 +64,7 @@ import org.sonar.server.branch.BranchFeatureProxyImpl;
import org.sonar.server.branch.pr.ws.PullRequestWsModule;
import org.sonar.server.branch.ws.BranchWsModule;
import org.sonar.server.ce.CeModule;
import org.sonar.server.ce.projectdump.ProjectExportWsModule;
import org.sonar.server.ce.ws.CeWsModule;
import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.component.ComponentFinder;
@@ -508,6 +509,9 @@ public class PlatformLevel4 extends PlatformLevel {
// ALM settings
AlmSettingsWsModule.class,

// Project export
ProjectExportWsModule.class,

// Branch
BranchFeatureProxyImpl.class,


Loading…
Cancel
Save