Skip to content

Commit

Permalink
SONAR-9961 Support cluster in marketplace
Browse files Browse the repository at this point in the history
  • Loading branch information
dbmeneses authored and gregaubert committed Oct 23, 2017
1 parent 6a37a9a commit 13b8590
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 15 deletions.
Expand Up @@ -29,6 +29,7 @@
import org.sonar.server.edition.MutableEditionManagementState;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.license.LicenseCommit;
import org.sonar.server.platform.WebServer;
import org.sonar.server.plugins.edition.EditionInstaller;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.WsUtils;
Expand All @@ -42,18 +43,21 @@ public class ApplyLicenseAction implements EditionsWsAction {
private final UserSession userSession;
private final MutableEditionManagementState editionManagementState;
private final EditionInstaller editionInstaller;
private final WebServer webServer;
@CheckForNull
private final LicenseCommit licenseCommit;

public ApplyLicenseAction(UserSession userSession, MutableEditionManagementState editionManagementState, EditionInstaller editionInstaller) {
this(userSession, editionManagementState, editionInstaller, null);
public ApplyLicenseAction(UserSession userSession, MutableEditionManagementState editionManagementState,
EditionInstaller editionInstaller, WebServer webServer) {
this(userSession, editionManagementState, editionInstaller, webServer, null);
}

public ApplyLicenseAction(UserSession userSession, MutableEditionManagementState editionManagementState, EditionInstaller editionInstaller,
@Nullable LicenseCommit licenseCommit) {
public ApplyLicenseAction(UserSession userSession, MutableEditionManagementState editionManagementState,
EditionInstaller editionInstaller, WebServer webServer, @Nullable LicenseCommit licenseCommit) {
this.userSession = userSession;
this.editionManagementState = editionManagementState;
this.editionInstaller = editionInstaller;
this.webServer = webServer;
this.licenseCommit = licenseCommit;
}

Expand Down Expand Up @@ -85,19 +89,26 @@ public void handle(Request request, Response response) throws Exception {
String licenseParam = request.mandatoryParam(PARAM_LICENSE);
License newLicense = License.parse(licenseParam).orElseThrow(() -> BadRequestException.create("The license provided is invalid"));

if (editionInstaller.requiresInstallationChange(newLicense.getPluginKeys())) {
if (!webServer.isStandalone()) {
checkState(licenseCommit != null, "LicenseCommit instance not found. License-manager plugin should be installed.");
setLicenseWithoutInstall(newLicense);
} else if (editionInstaller.requiresInstallationChange(newLicense.getPluginKeys())) {
editionInstaller.install(newLicense);
} else {
checkState(licenseCommit != null,
"Can't decide edition does not require install if LicenseCommit instance is null. " +
"License-manager plugin should be installed.");
editionManagementState.newEditionWithoutInstall(newLicense.getEditionKey());
licenseCommit.update(newLicense.getContent());
setLicenseWithoutInstall(newLicense);
}

WsUtils.writeProtobuf(buildResponse(), request, response);
}

private void setLicenseWithoutInstall(License newLicense) {
editionManagementState.newEditionWithoutInstall(newLicense.getEditionKey());
licenseCommit.update(newLicense.getContent());
}

private WsEditions.StatusResponse buildResponse() {
WsEditions.StatusResponse.Builder builder = WsEditions.StatusResponse.newBuilder()
.setNextEditionKey(editionManagementState.getPendingEditionKey().orElse(""))
Expand Down
Expand Up @@ -27,6 +27,7 @@
import org.sonar.server.edition.EditionManagementState;
import org.sonar.server.edition.License;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.platform.WebServer;
import org.sonar.server.plugins.edition.EditionInstaller;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.WsUtils;
Expand All @@ -43,11 +44,14 @@ public class PreviewAction implements EditionsWsAction {
private final UserSession userSession;
private final EditionManagementState editionManagementState;
private final EditionInstaller editionInstaller;
private final WebServer webServer;

public PreviewAction(UserSession userSession, EditionManagementState editionManagementState, EditionInstaller editionInstaller) {
public PreviewAction(UserSession userSession, EditionManagementState editionManagementState, EditionInstaller editionInstaller,
WebServer webServer) {
this.userSession = userSession;
this.editionManagementState = editionManagementState;
this.editionInstaller = editionInstaller;
this.webServer = webServer;
}

@Override
Expand Down Expand Up @@ -91,7 +95,7 @@ private static WsEditions.PreviewResponse buildResponse(NextState nextState) {
}

private NextState computeNextState(License newLicense) {
if (!editionInstaller.requiresInstallationChange(newLicense.getPluginKeys())) {
if (!webServer.isStandalone() || !editionInstaller.requiresInstallationChange(newLicense.getPluginKeys())) {
return new NextState(newLicense.getEditionKey(), NO_INSTALL);
// this won't refresh the update center (uses cached state). Preview is called while typing (must be fast)
// and anyway the status is refreshed when arriving at the marketplace page.
Expand Down
Expand Up @@ -43,6 +43,7 @@
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.license.LicenseCommit;
import org.sonar.server.platform.WebServer;
import org.sonar.server.plugins.edition.EditionInstaller;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
Expand All @@ -59,6 +60,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTOMATIC_IN_PROGRESS;
import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE;
Expand All @@ -76,7 +78,9 @@ public class ApplyLicenseActionTest {
private EditionInstaller editionInstaller = mock(EditionInstaller.class);
private MutableEditionManagementState mutableEditionManagementState = mock(MutableEditionManagementState.class);
private LicenseCommit licenseCommit = mock(LicenseCommit.class);
private ApplyLicenseAction underTest = new ApplyLicenseAction(userSessionRule, mutableEditionManagementState, editionInstaller, licenseCommit);
private WebServer webServer = mock(WebServer.class);
private ApplyLicenseAction underTest = new ApplyLicenseAction(userSessionRule, mutableEditionManagementState, editionInstaller,
webServer, licenseCommit);
private WsActionTester actionTester = new WsActionTester(underTest);

@Test
Expand Down Expand Up @@ -157,6 +161,54 @@ public void request_fails_with_BadRequestException_if_license_is_invalid() {
request.execute();
}

@Test
public void request_fails_with_ISE_if_is_cluster_and_license_plugin_is_not_installed() throws IOException {
underTest = new ApplyLicenseAction(userSessionRule, mutableEditionManagementState, editionInstaller, webServer, null);
actionTester = new WsActionTester(underTest);
userSessionRule.logIn().setSystemAdministrator();

when(mutableEditionManagementState.getPendingInstallationStatus()).thenReturn(NONE);
when(webServer.isStandalone()).thenReturn(false);

TestRequest request = actionTester.newRequest().setParam(PARAM_LICENSE, createLicenseParam("dev", "plugin1"));

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("License-manager plugin should be installed");
request.execute();
}

@Test
public void request_fails_with_ISE_if_no_change_needed_but_license_plugin_is_not_installed() throws IOException {
underTest = new ApplyLicenseAction(userSessionRule, mutableEditionManagementState, editionInstaller, webServer, null);
actionTester = new WsActionTester(underTest);
userSessionRule.logIn().setSystemAdministrator();

setPendingLicense(NONE);
when(webServer.isStandalone()).thenReturn(true);

TestRequest request = actionTester.newRequest().setParam(PARAM_LICENSE, createLicenseParam("dev", "plugin1"));

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Can't decide edition does not require install if LicenseCommit instance is null");
request.execute();
}

@Test
public void always_apply_license_when_is_cluster() throws IOException {
userSessionRule.logIn().setSystemAdministrator();
when(webServer.isStandalone()).thenReturn(false);
setPendingLicense(NONE);

TestRequest request = actionTester.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
.setParam(PARAM_LICENSE, createLicenseParam(PENDING_EDITION_NAME, "plugin1"));

TestResponse response = request.execute();
assertResponse(response, PENDING_EDITION_NAME, "", NONE);
verify(mutableEditionManagementState).newEditionWithoutInstall(PENDING_EDITION_NAME);
verifyZeroInteractions(editionInstaller);
}

@Test
public void verify_example() throws IOException {
userSessionRule.logIn().setSystemAdministrator();
Expand All @@ -171,8 +223,9 @@ public void verify_example() throws IOException {
@Test
public void apply_without_need_to_install() throws IOException {
userSessionRule.logIn().setSystemAdministrator();
setPendingLicense(NONE, null);
setPendingLicense(NONE);
when(editionInstaller.requiresInstallationChange(singleton("plugin1"))).thenReturn(false);
when(webServer.isStandalone()).thenReturn(true);

TestRequest request = actionTester.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
Expand All @@ -186,8 +239,9 @@ public void apply_without_need_to_install() throws IOException {
@Test
public void apply_offline() throws IOException {
userSessionRule.logIn().setSystemAdministrator();
setPendingLicense(PendingStatus.MANUAL_IN_PROGRESS, null);
setPendingLicense(PendingStatus.MANUAL_IN_PROGRESS);
when(editionInstaller.requiresInstallationChange(singleton("plugin1"))).thenReturn(true);
when(webServer.isStandalone()).thenReturn(true);

TestRequest request = actionTester.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
Expand All @@ -203,8 +257,9 @@ public void apply_offline() throws IOException {
@Test
public void apply_successfully_auto_installation() throws IOException {
userSessionRule.logIn().setSystemAdministrator();
setPendingLicense(PendingStatus.AUTOMATIC_IN_PROGRESS, null);
setPendingLicense(PendingStatus.AUTOMATIC_IN_PROGRESS);
when(editionInstaller.requiresInstallationChange(singleton("plugin1"))).thenReturn(true);
when(webServer.isStandalone()).thenReturn(true);

TestRequest request = actionTester.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
Expand Down Expand Up @@ -243,6 +298,10 @@ private void assertResponse(TestResponse response, String expectedNextEditionKey
assertThat(parsedResponse.getInstallationStatus()).isEqualTo(WsEditions.InstallationStatus.valueOf(expectedPendingStatus.toString()));
}

private void setPendingLicense(PendingStatus pendingStatus) {
setPendingLicense(pendingStatus, null);
}

private void setPendingLicense(PendingStatus pendingStatus, @Nullable String errorMessage) {
when(mutableEditionManagementState.getCurrentEditionKey()).thenReturn(Optional.empty());
when(mutableEditionManagementState.getPendingEditionKey()).thenReturn(Optional.of(PENDING_EDITION_NAME));
Expand Down
Expand Up @@ -38,6 +38,7 @@
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.platform.WebServer;
import org.sonar.server.plugins.edition.EditionInstaller;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
Expand Down Expand Up @@ -65,7 +66,8 @@ public class PreviewActionTest {

private EditionManagementState editionManagementState = mock(EditionManagementState.class);
private EditionInstaller editionInstaller = mock(EditionInstaller.class);
private PreviewAction underTest = new PreviewAction(userSessionRule, editionManagementState, editionInstaller);
private WebServer webServer = mock(WebServer.class);
private PreviewAction underTest = new PreviewAction(userSessionRule, editionManagementState, editionInstaller, webServer);
private WsActionTester actionTester = new WsActionTester(underTest);

@Test
Expand Down Expand Up @@ -117,7 +119,7 @@ public void request_fails_if_license_param_is_not_provided() {

request.execute();
}

@Test
public void request_fails_if_license_param_is_empty() {
userSessionRule.logIn().setSystemAdministrator();
Expand Down Expand Up @@ -161,6 +163,7 @@ public void request_fails_with_BadRequestException_is_pendingStatus_is_not_NONE(
@Test
public void verify_example() throws IOException {
userSessionRule.logIn().setSystemAdministrator();
when(webServer.isStandalone()).thenReturn(true);
when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE);
when(editionInstaller.requiresInstallationChange(Collections.singleton("plugin1"))).thenReturn(true);
when(editionInstaller.isOffline()).thenReturn(false);
Expand All @@ -173,6 +176,21 @@ public void verify_example() throws IOException {

@Test
public void license_requires_no_installation() throws IOException {
when(webServer.isStandalone()).thenReturn(true);
userSessionRule.logIn().setSystemAdministrator();
when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE);
when(editionInstaller.requiresInstallationChange(Collections.singleton("plugin1"))).thenReturn(false);

TestRequest request = actionTester.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
.setParam(PARAM_LICENSE, createLicenseParam("developer-edition", "plugin1"));

assertResponse(request.execute(), "developer-edition", PreviewStatus.NO_INSTALL);
}

@Test
public void cluster_require_no_installation() throws IOException {
when(webServer.isStandalone()).thenReturn(false);
userSessionRule.logIn().setSystemAdministrator();
when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE);
when(editionInstaller.requiresInstallationChange(Collections.singleton("plugin1"))).thenReturn(false);
Expand All @@ -187,6 +205,7 @@ public void license_requires_no_installation() throws IOException {
@Test
public void license_will_result_in_auto_install() throws IOException {
userSessionRule.logIn().setSystemAdministrator();
when(webServer.isStandalone()).thenReturn(true);
when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE);
when(editionInstaller.requiresInstallationChange(Collections.singleton("plugin1"))).thenReturn(true);
when(editionInstaller.isOffline()).thenReturn(false);
Expand All @@ -201,6 +220,7 @@ public void license_will_result_in_auto_install() throws IOException {
@Test
public void license_will_result_in_manual_install() throws IOException {
userSessionRule.logIn().setSystemAdministrator();
when(webServer.isStandalone()).thenReturn(true);
when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE);
when(editionInstaller.requiresInstallationChange(Collections.singleton("plugin1"))).thenReturn(true);
when(editionInstaller.isOffline()).thenReturn(true);
Expand Down

0 comments on commit 13b8590

Please sign in to comment.