From b2a04354f0a5467a64e6465ec5147a9e43305574 Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Wed, 18 Oct 2017 14:16:32 +0200 Subject: [PATCH] SONAR-9996 Edition management state supports uninstall --- .../edition/EditionManagementState.java | 3 +- .../MutableEditionManagementState.java | 10 ++ .../StandaloneEditionManagementStateImpl.java | 19 ++- ...ndaloneEditionManagementStateImplTest.java | 109 +++++++++++++++++- 4 files changed, 134 insertions(+), 7 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementState.java b/server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementState.java index 2a595a5b2a5..1fd56040e20 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementState.java +++ b/server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementState.java @@ -51,6 +51,7 @@ public interface EditionManagementState { AUTOMATIC_IN_PROGRESS, AUTOMATIC_READY, AUTOMATIC_FAILED, - MANUAL_IN_PROGRESS + MANUAL_IN_PROGRESS, + UNINSTALL_IN_PROGRESS } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/MutableEditionManagementState.java b/server/sonar-server/src/main/java/org/sonar/server/edition/MutableEditionManagementState.java index afa9b30bb7b..2279a213ea6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/MutableEditionManagementState.java +++ b/server/sonar-server/src/main/java/org/sonar/server/edition/MutableEditionManagementState.java @@ -62,6 +62,16 @@ public interface MutableEditionManagementState extends EditionManagementState { */ PendingStatus automaticInstallReady(); + /** + * Uninstalls the currently installed edition + * + * @return the new pending status, always {@link PendingStatus#UNINSTALL_IN_PROGRESS} + * + * @throws IllegalStateException if current status is not {@link PendingStatus#NONE} or if there is + * no edition currently installed. + */ + PendingStatus uninstall(); + /** * Finalize an automatic or manual install * diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java b/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java index 5a714a4c7da..b9c691df422 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java @@ -36,6 +36,7 @@ import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTO import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTOMATIC_READY; import static org.sonar.server.edition.EditionManagementState.PendingStatus.MANUAL_IN_PROGRESS; import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE; +import static org.sonar.server.edition.EditionManagementState.PendingStatus.UNINSTALL_IN_PROGRESS; public class StandaloneEditionManagementStateImpl implements MutableEditionManagementState, Startable { private static final String CURRENT_EDITION_KEY = "currentEditionKey"; @@ -149,7 +150,7 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag @Override public synchronized PendingStatus finalizeInstallation() { ensureStarted(); - changeStatusToFrom(NONE, AUTOMATIC_READY, MANUAL_IN_PROGRESS); + changeStatusToFrom(NONE, AUTOMATIC_READY, MANUAL_IN_PROGRESS, UNINSTALL_IN_PROGRESS); this.pendingInstallationStatus = NONE; this.currentEditionKey = this.pendingEditionKey; @@ -159,6 +160,20 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag return this.pendingInstallationStatus; } + @Override + public synchronized PendingStatus uninstall() { + ensureStarted(); + changeStatusToFrom(UNINSTALL_IN_PROGRESS, NONE); + checkState(currentEditionKey != null, "There is no edition currently installed"); + + this.pendingInstallationStatus = UNINSTALL_IN_PROGRESS; + this.pendingEditionKey = null; + this.pendingLicense = null; + this.currentEditionKey = null; + persistProperties(); + return this.pendingInstallationStatus; + } + private void ensureStarted() { checkState(pendingInstallationStatus != null, "%s is not started", getClass().getSimpleName()); } @@ -173,7 +188,7 @@ public class StandaloneEditionManagementStateImpl implements MutableEditionManag private void persistProperties() { try (DbSession dbSession = dbClient.openSession(false)) { InternalPropertiesDao internalPropertiesDao = dbClient.internalPropertiesDao(); - if (pendingInstallationStatus == NONE) { + if (pendingInstallationStatus == NONE || pendingInstallationStatus == UNINSTALL_IN_PROGRESS) { internalPropertiesDao.saveAsEmpty(dbSession, PENDING_EDITION_KEY); internalPropertiesDao.saveAsEmpty(dbSession, PENDING_LICENSE); } else { diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java index e657f951f0d..f1cbe67f43c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java @@ -35,6 +35,7 @@ import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTO import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTOMATIC_READY; import static org.sonar.server.edition.EditionManagementState.PendingStatus.MANUAL_IN_PROGRESS; import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE; +import static org.sonar.server.edition.EditionManagementState.PendingStatus.UNINSTALL_IN_PROGRESS; public class StandaloneEditionManagementStateImplTest { private static final License LICENSE_WITHOUT_PLUGINS = new License(randomAlphanumeric(3), Collections.emptyList(), randomAlphanumeric(10)); @@ -276,6 +277,90 @@ public class StandaloneEditionManagementStateImplTest { underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); } + @Test + public void uninstall_fails_with_ISE_if_not_started() { + expectISENotStarted(); + + underTest.uninstall(); + } + + @Test + public void uninstall_resets_fields_after_start_and_install() { + String value = randomAlphanumeric(10); + + underTest.start(); + underTest.newEditionWithoutInstall(value); + PendingStatus newStatus = underTest.uninstall(); + + assertThat(newStatus).isEqualTo(UNINSTALL_IN_PROGRESS); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(UNINSTALL_IN_PROGRESS); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).isEmpty(); + } + + @Test + public void uninstall_fails_with_ISE_if_called_after_uninstall() { + String value = randomAlphanumeric(10); + underTest.start(); + underTest.newEditionWithoutInstall(value); + underTest.uninstall(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to UNINSTALL_IN_PROGRESS when status is UNINSTALL_IN_PROGRESS (should be any of [NONE])"); + + underTest.uninstall(); + } + + @Test + public void uninstall_resets_fields_after_newEditionWithoutInstall() { + String value = randomAlphanumeric(10); + underTest.start(); + underTest.newEditionWithoutInstall(value); + + PendingStatus newStatus = underTest.uninstall(); + + assertThat(newStatus).isEqualTo(UNINSTALL_IN_PROGRESS); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(UNINSTALL_IN_PROGRESS); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).isEmpty(); + } + + @Test + public void uninstall_fails_with_ISE_if_called_after_startAutomaticInstall() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to UNINSTALL_IN_PROGRESS when status is AUTOMATIC_IN_PROGRESS (should be any of [NONE])"); + + underTest.uninstall(); + } + + @Test + public void uninstall_fails_with_ISE_if_called_after_automaticInstallReady() { + underTest.start(); + underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); + underTest.automaticInstallReady(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to UNINSTALL_IN_PROGRESS when status is AUTOMATIC_READY (should be any of [NONE])"); + + underTest.uninstall(); + } + + @Test + public void uninstall_fails_with_ISE_if_called_after_manualInstall() { + underTest.start(); + underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can't move to UNINSTALL_IN_PROGRESS when status is MANUAL_IN_PROGRESS (should be any of [NONE])"); + + underTest.uninstall(); + } + @Test public void startManualInstall_fails_with_ISE_if_not_started() { expectISENotStarted(); @@ -519,7 +604,7 @@ public class StandaloneEditionManagementStateImplTest { underTest.start(); expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS])"); + expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS, UNINSTALL_IN_PROGRESS])"); underTest.finalizeInstallation(); } @@ -530,7 +615,7 @@ public class StandaloneEditionManagementStateImplTest { underTest.newEditionWithoutInstall(randomAlphanumeric(3)); expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS])"); + expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS, UNINSTALL_IN_PROGRESS])"); underTest.finalizeInstallation(); } @@ -541,7 +626,7 @@ public class StandaloneEditionManagementStateImplTest { underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is AUTOMATIC_IN_PROGRESS (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS])"); + expectedException.expectMessage("Can't move to NONE when status is AUTOMATIC_IN_PROGRESS (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS, UNINSTALL_IN_PROGRESS])"); underTest.finalizeInstallation(); } @@ -575,6 +660,22 @@ public class StandaloneEditionManagementStateImplTest { assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); } + @Test + public void finalizeInstallation_set_new_edition_and_clear_pending_fields_after_uninstall() { + underTest.start(); + String value = randomAlphanumeric(10); + underTest.newEditionWithoutInstall(value); + underTest.uninstall(); + + PendingStatus newStatus = underTest.finalizeInstallation(); + + assertThat(newStatus).isEqualTo(NONE); + assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); + assertThat(underTest.getPendingEditionKey()).isEmpty(); + assertThat(underTest.getPendingLicense()).isEmpty(); + assertThat(underTest.getCurrentEditionKey()).isEmpty(); + } + @Test public void finalizeInstallation_overwrites_current_edition_and_clear_pending_fields_after_startManualInstall() { String value = randomAlphanumeric(10); @@ -598,7 +699,7 @@ public class StandaloneEditionManagementStateImplTest { underTest.finalizeInstallation(); expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS])"); + expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_READY, MANUAL_IN_PROGRESS, UNINSTALL_IN_PROGRESS])"); underTest.finalizeInstallation(); } -- 2.39.5