From: Eric Hartmann Date: Tue, 29 May 2018 15:06:16 +0000 (+0200) Subject: SONAR-10817 Cleanup of old editions X-Git-Tag: 7.5~1026 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b99727fafb5e5f2f4a844b0eebd6b7637e87f382;p=sonarqube.git SONAR-10817 Cleanup of old editions --- diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginJarExploderTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginJarExploderTest.java index 6f961fc7332..c4b911ee0ed 100644 --- a/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginJarExploderTest.java +++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/CePluginJarExploderTest.java @@ -24,9 +24,9 @@ import java.io.IOException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.server.platform.ServerFileSystem; import org.sonar.core.platform.ExplodedPlugin; import org.sonar.core.platform.PluginInfo; +import org.sonar.server.platform.ServerFileSystem; import static org.apache.commons.io.FileUtils.sizeOfDirectory; import static org.assertj.core.api.Assertions.assertThat; @@ -97,11 +97,6 @@ public class CePluginJarExploderTest { this.temp = temp; } - @Override - public File getDataDir() { - throw new UnsupportedOperationException(); - } - @Override public File getHomeDir() { throw new UnsupportedOperationException(); @@ -139,20 +134,10 @@ public class CePluginJarExploderTest { throw new UnsupportedOperationException(); } - @Override - public File getEditionDownloadedPluginsDir() { - throw new UnsupportedOperationException(); - } - @Override public File getUninstalledPluginsDir() { throw new UnsupportedOperationException(); } - @Override - public File getEditionUninstalledPluginsDir() { - throw new UnsupportedOperationException(); - } - } } 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 deleted file mode 100644 index 5360676c623..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/EditionManagementState.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import java.util.Optional; - -public interface EditionManagementState { - /** - * @return {@link Optional#empty() empty} if there is no edition installed - */ - Optional getCurrentEditionKey(); - - /** - * @return the pending installation status. - */ - PendingStatus getPendingInstallationStatus(); - - /** - * @return {@link Optional#empty() empty} when {@link #getPendingInstallationStatus()} returns {@link PendingStatus#NONE}, - * otherwise a {@link String} - */ - Optional getPendingEditionKey(); - - /** - * The license string. - * - * @return {@link Optional#empty() empty} when {@link #getPendingInstallationStatus()} returns {@link PendingStatus#NONE}, - * otherwise a {@link String} - */ - Optional getPendingLicense(); - - /** - * The message explaining the error that made the install fail (if any). - * - * @return a {@link String} if {@link #getPendingInstallationStatus()} returns {@link PendingStatus#NONE} and an error - * occurred during install, otherwise {@link Optional#empty() empty} - */ - Optional getInstallErrorMessage(); - - enum PendingStatus { - NONE, - AUTOMATIC_IN_PROGRESS, - AUTOMATIC_READY, - MANUAL_IN_PROGRESS, - UNINSTALL_IN_PROGRESS - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/EditionsWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/edition/EditionsWsModule.java deleted file mode 100644 index a58a177c0eb..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/EditionsWsModule.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import org.sonar.core.platform.Module; -import org.sonar.server.edition.ws.ApplyLicenseAction; -import org.sonar.server.edition.ws.ClearErrorMessageAction; -import org.sonar.server.edition.ws.EditionsWs; -import org.sonar.server.edition.ws.FormDataAction; -import org.sonar.server.edition.ws.PreviewAction; -import org.sonar.server.edition.ws.StatusAction; -import org.sonar.server.edition.ws.UninstallAction; - -public class EditionsWsModule extends Module { - @Override - protected void configureModule() { - add( - StandaloneEditionManagementStateImpl.class, - StatusAction.class, - ApplyLicenseAction.class, - PreviewAction.class, - FormDataAction.class, - ClearErrorMessageAction.class, - UninstallAction.class, - EditionsWs.class); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/FinalizeEditionChange.java b/server/sonar-server/src/main/java/org/sonar/server/edition/FinalizeEditionChange.java deleted file mode 100644 index 93595b21de4..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/FinalizeEditionChange.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import java.util.Optional; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.sonar.api.Startable; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.sonar.server.edition.EditionManagementState.PendingStatus; -import org.sonar.server.license.LicenseCommit; - -public class FinalizeEditionChange implements Startable { - private static final Logger LOG = Loggers.get(FinalizeEditionChange.class); - - private final MutableEditionManagementState editionManagementState; - @CheckForNull - private final LicenseCommit licenseCommit; - - /** - * Used by Pico when license-manager is not installed and therefore no implementation of {@link LicenseCommit} is - * is available. - */ - public FinalizeEditionChange(MutableEditionManagementState editionManagementState) { - this(editionManagementState, null); - } - - public FinalizeEditionChange(MutableEditionManagementState editionManagementState, @Nullable LicenseCommit licenseCommit) { - this.editionManagementState = editionManagementState; - this.licenseCommit = licenseCommit; - } - - @Override - public void start() { - EditionManagementState.PendingStatus status = editionManagementState.getPendingInstallationStatus(); - switch (status) { - case NONE: - editionManagementState.clearInstallErrorMessage(); - return; - case MANUAL_IN_PROGRESS: - case AUTOMATIC_READY: - finalizeInstall(); - break; - case AUTOMATIC_IN_PROGRESS: - editionManagementState.installFailed("SonarQube was restarted before asynchronous installation of edition completed"); - break; - case UNINSTALL_IN_PROGRESS: - failIfLicenseCommitIsPresent(); - editionManagementState.finalizeInstallation(null); - break; - default: - throw new IllegalStateException("Unsupported status " + status); - } - } - - private void failIfLicenseCommitIsPresent() { - if (licenseCommit != null) { - throw new IllegalStateException("License Manager plugin is still present after uninstallation of the edition. Please remove it."); - } - } - - private void finalizeInstall() { - String errorMessage = null; - - try { - if (licenseCommit == null) { - errorMessage = "Edition installation didn't complete. Some plugins were not installed."; - LOG.warn(errorMessage); - return; - } - - Optional newLicense = editionManagementState.getPendingLicense(); - if (!newLicense.isPresent()) { - errorMessage = "Edition installation didn't complete. License was not found."; - LOG.warn(errorMessage); - return; - } - - try { - licenseCommit.update(newLicense.get()); - } catch (IllegalArgumentException e) { - errorMessage = "Edition installation didn't complete. License is not valid. Please set a new license."; - LOG.warn(errorMessage, e); - } - } finally { - editionManagementState.finalizeInstallation(errorMessage); - } - } - - @Override - public void stop() { - EditionManagementState.PendingStatus status = editionManagementState.getPendingInstallationStatus(); - if (status == PendingStatus.UNINSTALL_IN_PROGRESS) { - if (licenseCommit != null) { - LOG.debug("Removing license"); - licenseCommit.delete(); - } else { - LOG.warn("License Manager plugin not found - cannot remove the license"); - } - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/License.java b/server/sonar-server/src/main/java/org/sonar/server/edition/License.java deleted file mode 100644 index 93318584eb3..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/License.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import com.google.common.collect.ImmutableSet; -import java.io.StringReader; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; -import java.util.Optional; -import java.util.Properties; -import java.util.Set; -import javax.annotation.concurrent.Immutable; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -@Immutable -public class License { - private static final Logger LOG = Loggers.get(License.class); - private static final String EDITION_KEY = "Edition"; - private static final String PLUGINS_KEY = "Plugins"; - - private final String editionKey; - private final Set pluginKeys; - private final String content; - - public License(String editionKey, Collection pluginKeys, String content) { - this.editionKey = enforceNotNullNorEmpty(editionKey, "editionKey"); - this.pluginKeys = ImmutableSet.copyOf(pluginKeys); - this.content = enforceNotNullNorEmpty(content, "content"); - } - - private static String enforceNotNullNorEmpty(String str, String propertyName) { - checkNotNull(str, "%s can't be null", propertyName); - checkArgument(!str.isEmpty(), "%s can't be empty", propertyName); - return str; - } - - public String getEditionKey() { - return editionKey; - } - - public Set getPluginKeys() { - return pluginKeys; - } - - public String getContent() { - return content; - } - - public static Optional parse(String base64) { - try { - String data = new String(Base64.decodeBase64(base64.trim().getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); - - Properties props = new Properties(); - props.load(new StringReader(data)); - - String[] plugins = StringUtils.split(props.getProperty(PLUGINS_KEY), ','); - String editionKey = props.getProperty(EDITION_KEY); - - if (StringUtils.isNotBlank(editionKey) && plugins.length > 0) { - return Optional.of(new License(editionKey, Arrays.asList(plugins), base64)); - } else { - LOG.debug("Failed to parse license: no edition key and/or no plugin found"); - } - } catch (Exception e) { - LOG.debug("Failed to parse license", e); - } - return Optional.empty(); - - } -} 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 deleted file mode 100644 index 817da949ab6..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/MutableEditionManagementState.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import javax.annotation.Nullable; - -/** - * Provides access to operations which will alter the Edition management state. - */ -public interface MutableEditionManagementState extends EditionManagementState { - /** - * Stage the specified license and records that an automatic install of the plugins will be performed. - * - * @return the new {@link PendingStatus}, always {@link PendingStatus#AUTOMATIC_IN_PROGRESS} - * an exception. - * - * @throws IllegalStateException if current status is not {@link PendingStatus#NONE} - */ - PendingStatus startAutomaticInstall(License license); - - /** - * Stage the specified license and records that a manual install of the plugins will be performed. - * - * @return the new {@link PendingStatus}, always {@link PendingStatus#MANUAL_IN_PROGRESS} - * - * @throws IllegalStateException if current status is not {@link PendingStatus#NONE} - */ - PendingStatus startManualInstall(License license); - - /** - * Records that the specified edition has been installed without plugin changes. - * - * @param newEditionKey can't be {@code null} nor empty - * - * @return the new {@link PendingStatus}, always {@link PendingStatus#NONE} - * - * @throws IllegalStateException if current status is not {@link PendingStatus#NONE} - */ - PendingStatus newEditionWithoutInstall(String newEditionKey); - - /** - * Records that automatic install is ready to be finalized. - * - * @return the new pending status, always {@link PendingStatus#AUTOMATIC_READY} - * - * @throws IllegalStateException if current status is not {@link PendingStatus#AUTOMATIC_IN_PROGRESS} - */ - PendingStatus automaticInstallReady(); - - /** - * Records that install failed with the specified (optional) error message to explain the cause of the - * failure. - * - * @return the new pending status, always {@link PendingStatus#NONE} - * - * @throws IllegalStateException if current status is neither {@link PendingStatus#AUTOMATIC_IN_PROGRESS} nor - * {@link PendingStatus#MANUAL_IN_PROGRESS} - */ - PendingStatus installFailed(@Nullable String errorMessage); - - /** - * Clears the error message set by {@link #installFailed(String)} (String)} if there is any and which ever the current - * status. - */ - void clearInstallErrorMessage(); - - /** - * 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 with the specified (optional) error message to explain a partially - * finalized install. - * - * @return the new pending status, always {@link PendingStatus#NONE} - * - * @throws IllegalStateException if current status is neither {@link PendingStatus#AUTOMATIC_READY} nor - * {@link PendingStatus#MANUAL_IN_PROGRESS} - */ - PendingStatus finalizeInstallation(@Nullable String errorMessage); -} 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 deleted file mode 100644 index 35ad1ba8156..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/StandaloneEditionManagementStateImpl.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import com.google.common.collect.ImmutableSet; -import java.util.Arrays; -import java.util.Map; -import java.util.Optional; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; -import org.picocontainer.Startable; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.property.InternalPropertiesDao; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; -import static java.util.Objects.requireNonNull; -import static java.util.Optional.empty; -import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTOMATIC_IN_PROGRESS; -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"; - private static final String PENDING_INSTALLATION_STATUS = "pendingInstallStatus"; - private static final String PENDING_EDITION_KEY = "pendingEditionKey"; - private static final String PENDING_LICENSE = "pendingLicense"; - private static final String INSTALL_ERROR_MESSAGE = "installError"; - - private final DbClient dbClient; - @CheckForNull - private State state; - - public StandaloneEditionManagementStateImpl(DbClient dbClient) { - this.dbClient = dbClient; - } - - @Override - public void start() { - try (DbSession dbSession = dbClient.openSession(false)) { - // load current state value - Map> internalPropertyValues = dbClient.internalPropertiesDao().selectByKeys(dbSession, - ImmutableSet.of(CURRENT_EDITION_KEY, PENDING_INSTALLATION_STATUS, PENDING_EDITION_KEY, PENDING_LICENSE, INSTALL_ERROR_MESSAGE)); - - PendingStatus pendingInstallationStatus = internalPropertyValues.getOrDefault(PENDING_INSTALLATION_STATUS, empty()) - .map(StandaloneEditionManagementStateImpl::emptyToNull) - .map(PendingStatus::valueOf) - .orElse(NONE); - State.Builder builder = State.newBuilder(pendingInstallationStatus); - builder - .setCurrentEditionKey(internalPropertyValues.getOrDefault(CURRENT_EDITION_KEY, empty()) - .map(StandaloneEditionManagementStateImpl::emptyToNull) - .orElse(null)) - .setPendingEditionKey(internalPropertyValues.getOrDefault(PENDING_EDITION_KEY, empty()) - .map(StandaloneEditionManagementStateImpl::emptyToNull) - .orElse(null)) - .setPendingLicense(internalPropertyValues.getOrDefault(PENDING_LICENSE, empty()) - .map(StandaloneEditionManagementStateImpl::emptyToNull) - .orElse(null)) - .setInstallErrorMessage(internalPropertyValues.getOrDefault(INSTALL_ERROR_MESSAGE, empty()) - .map(StandaloneEditionManagementStateImpl::emptyToNull) - .orElse(null)); - state = builder.build(); - } - } - - @Override - public void stop() { - // nothing to do - } - - @Override - public Optional getCurrentEditionKey() { - ensureStarted(); - return Optional.ofNullable(state.getCurrentEditionKey()); - } - - @Override - public PendingStatus getPendingInstallationStatus() { - ensureStarted(); - return state.getPendingInstallationStatus(); - } - - @Override - public Optional getPendingEditionKey() { - ensureStarted(); - return Optional.ofNullable(state.getPendingEditionKey()); - } - - @Override - public Optional getPendingLicense() { - ensureStarted(); - return Optional.ofNullable(state.getPendingLicense()); - } - - @Override - public Optional getInstallErrorMessage() { - ensureStarted(); - return Optional.ofNullable(state.getInstallErrorMessage()); - } - - @Override - public synchronized PendingStatus startAutomaticInstall(License license) { - ensureStarted(); - checkLicense(license); - State newState = changeStatusToFrom(AUTOMATIC_IN_PROGRESS, NONE) - .setPendingLicense(license.getContent()) - .setPendingEditionKey(license.getEditionKey()) - .clearAutomaticInstallErrorMessage() - .build(); - persistProperties(newState); - return newState.getPendingInstallationStatus(); - } - - @Override - public synchronized PendingStatus startManualInstall(License license) { - ensureStarted(); - checkLicense(license); - State newState = changeStatusToFrom(MANUAL_IN_PROGRESS, NONE) - .setPendingLicense(license.getContent()) - .setPendingEditionKey(license.getEditionKey()) - .clearAutomaticInstallErrorMessage() - .build(); - persistProperties(newState); - return newState.getPendingInstallationStatus(); - } - - @Override - public synchronized PendingStatus newEditionWithoutInstall(String newEditionKey) { - ensureStarted(); - requireNonNull(newEditionKey, "newEditionKey can't be null"); - checkArgument(!newEditionKey.isEmpty(), "newEditionKey can't be empty"); - State newState = changeStatusToFrom(NONE, NONE) - .setCurrentEditionKey(newEditionKey) - .clearAutomaticInstallErrorMessage() - .build(); - persistProperties(newState); - return newState.getPendingInstallationStatus(); - } - - @Override - public synchronized PendingStatus automaticInstallReady() { - ensureStarted(); - State newState = changeStatusToFrom(AUTOMATIC_READY, AUTOMATIC_IN_PROGRESS) - .clearAutomaticInstallErrorMessage() - .build(); - persistProperties(newState); - return newState.getPendingInstallationStatus(); - } - - @Override - public synchronized PendingStatus installFailed(@Nullable String errorMessage) { - ensureStarted(); - State newState = changeStatusToFrom(NONE, AUTOMATIC_IN_PROGRESS, MANUAL_IN_PROGRESS) - .setInstallErrorMessage(nullableTrimmedEmptyToNull(errorMessage)) - .clearPendingFields() - .build(); - persistProperties(newState); - return newState.getPendingInstallationStatus(); - } - - @Override - public synchronized void clearInstallErrorMessage() { - ensureStarted(); - State currentState = this.state; - if (currentState.getInstallErrorMessage() != null) { - State newState = State.newBuilder(currentState) - .clearAutomaticInstallErrorMessage() - .build(); - persistProperties(newState); - } - } - - @Override - public synchronized PendingStatus finalizeInstallation(@Nullable String errorMessage) { - ensureStarted(); - State newState = changeStatusToFrom(NONE, AUTOMATIC_READY, MANUAL_IN_PROGRESS, UNINSTALL_IN_PROGRESS) - .commitPendingEditionKey() - .clearPendingFields() - .setInstallErrorMessage(nullableTrimmedEmptyToNull(errorMessage)) - .build(); - persistProperties(newState); - return newState.getPendingInstallationStatus(); - } - - @Override - public synchronized PendingStatus uninstall() { - ensureStarted(); - State.Builder builder = changeStatusToFrom(UNINSTALL_IN_PROGRESS, NONE); - checkState(state.currentEditionKey != null, "There is no edition currently installed"); - State newState = builder - .clearPendingFields() - .clearCurrentEditionKey() - .clearAutomaticInstallErrorMessage() - .build(); - persistProperties(newState); - return newState.getPendingInstallationStatus(); - } - - private void ensureStarted() { - checkState(state != null, "%s is not started", getClass().getSimpleName()); - } - - private State.Builder changeStatusToFrom(PendingStatus newStatus, PendingStatus... validPendingStatuses) { - State currentState = this.state; - if (Arrays.stream(validPendingStatuses).noneMatch(s -> s == currentState.getPendingInstallationStatus())) { - throw new IllegalStateException(String.format("Can't move to %s when status is %s (should be any of %s)", - newStatus, currentState.getPendingInstallationStatus(), Arrays.toString(validPendingStatuses))); - } - - return State.newBuilder(currentState, newStatus); - } - - private void persistProperties(State newState) { - try (DbSession dbSession = dbClient.openSession(false)) { - InternalPropertiesDao internalPropertiesDao = dbClient.internalPropertiesDao(); - saveInternalProperty(internalPropertiesDao, dbSession, PENDING_EDITION_KEY, newState.getPendingEditionKey()); - saveInternalProperty(internalPropertiesDao, dbSession, PENDING_LICENSE, newState.getPendingLicense()); - saveInternalProperty(internalPropertiesDao, dbSession, INSTALL_ERROR_MESSAGE, newState.getInstallErrorMessage()); - saveInternalProperty(internalPropertiesDao, dbSession, CURRENT_EDITION_KEY, newState.getCurrentEditionKey()); - saveInternalProperty(internalPropertiesDao, dbSession, PENDING_INSTALLATION_STATUS, newState.getPendingInstallationStatus().name()); - dbSession.commit(); - this.state = newState; - } - } - - private static void saveInternalProperty(InternalPropertiesDao dao, DbSession dbSession, String key, @Nullable String value) { - if (value == null) { - dao.saveAsEmpty(dbSession, key); - } else { - dao.save(dbSession, key, value); - } - } - - private static void checkLicense(License license) { - requireNonNull(license, "license can't be null"); - } - - private static String nullableTrimmedEmptyToNull(@Nullable String s) { - if (s == null) { - return null; - } - String v = s.trim(); - return v.isEmpty() ? null : v; - } - - private static String emptyToNull(String s) { - return s.isEmpty() ? null : s; - } - - @Immutable - private static final class State { - private final String currentEditionKey; - private final PendingStatus pendingInstallationStatus; - private final String pendingEditionKey; - private final String pendingLicense; - private final String installErrorMessage; - - public State(Builder builder) { - this.currentEditionKey = builder.currentEditionKey; - this.pendingInstallationStatus = builder.pendingInstallationStatus; - this.pendingEditionKey = builder.pendingEditionKey; - this.pendingLicense = builder.pendingLicense; - this.installErrorMessage = builder.installErrorMessage; - } - - public String getCurrentEditionKey() { - return currentEditionKey; - } - - public PendingStatus getPendingInstallationStatus() { - return pendingInstallationStatus; - } - - public String getPendingEditionKey() { - return pendingEditionKey; - } - - public String getPendingLicense() { - return pendingLicense; - } - - public String getInstallErrorMessage() { - return installErrorMessage; - } - - public static Builder newBuilder(PendingStatus pendingInstallationStatus) { - return new Builder(pendingInstallationStatus); - } - - public static Builder newBuilder(State from) { - return newBuilder(from, from.getPendingInstallationStatus()); - } - - public static Builder newBuilder(State from, PendingStatus newStatus) { - return new Builder(newStatus) - .setCurrentEditionKey(from.currentEditionKey) - .setPendingEditionKey(from.pendingEditionKey) - .setPendingLicense(from.pendingLicense) - .setInstallErrorMessage(from.installErrorMessage); - } - - private static class Builder { - private PendingStatus pendingInstallationStatus; - private String currentEditionKey; - private String pendingEditionKey; - private String pendingLicense; - private String installErrorMessage; - - private Builder(PendingStatus pendingInstallationStatus) { - this.pendingInstallationStatus = requireNonNull(pendingInstallationStatus); - } - - public Builder setCurrentEditionKey(@Nullable String currentEditionKey) { - this.currentEditionKey = currentEditionKey; - return this; - } - - public Builder setPendingEditionKey(@Nullable String pendingEditionKey) { - this.pendingEditionKey = pendingEditionKey; - return this; - } - - public Builder setPendingLicense(@Nullable String pendingLicense) { - this.pendingLicense = pendingLicense; - return this; - } - - public Builder setInstallErrorMessage(@Nullable String installErrorMessage) { - this.installErrorMessage = installErrorMessage; - return this; - } - - public Builder commitPendingEditionKey() { - this.currentEditionKey = pendingEditionKey; - return this; - } - - public Builder clearCurrentEditionKey() { - this.currentEditionKey = null; - return this; - } - - public Builder clearPendingFields() { - this.pendingEditionKey = null; - this.pendingLicense = null; - return this; - } - - public Builder clearAutomaticInstallErrorMessage() { - this.installErrorMessage = null; - return this; - } - - public State build() { - return new State(this); - } - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/edition/package-info.java deleted file mode 100644 index fb738dfcf93..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.edition; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/ApplyLicenseAction.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/ApplyLicenseAction.java deleted file mode 100644 index 4cd8f7a951a..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/ApplyLicenseAction.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -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.log.Loggers; -import org.sonar.server.edition.EditionManagementState; -import org.sonar.server.edition.License; -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; -import org.sonarqube.ws.Editions; - -import static com.google.common.base.Preconditions.checkState; - -public class ApplyLicenseAction implements EditionsWsAction { - private static final String PARAM_LICENSE = "license"; - - 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, WebServer webServer) { - this(userSession, editionManagementState, editionInstaller, webServer, null); - } - - 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; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("apply_license") - .setSince("6.7") - .setPost(true) - .setDescription("Apply changes to SonarQube to match the specified license." + - " Clear error message of previous automatic install of an edition, if there is any." + - " Require 'Administer System' permission.") - .setResponseExample(getClass().getResource("example-edition-apply_license.json")) - .setHandler(this); - - action.createParam(PARAM_LICENSE) - .setRequired(true) - .setSince("6.7") - .setDescription("the license"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkIsSystemAdministrator(); - - if (editionManagementState.getPendingInstallationStatus() != EditionManagementState.PendingStatus.NONE) { - throw BadRequestException.create("Can't apply a license when applying one is already in progress"); - } - - String licenseParam = request.mandatoryParam(PARAM_LICENSE); - License newLicense = License.parse(licenseParam).orElseThrow(() -> BadRequestException.create("The license provided is invalid")); - - 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."); - setLicenseWithoutInstall(newLicense); - } - - WsUtils.writeProtobuf(buildResponse(), request, response); - } - - private void setLicenseWithoutInstall(License newLicense) { - try { - licenseCommit.update(newLicense.getContent()); - editionManagementState.newEditionWithoutInstall(newLicense.getEditionKey()); - } catch (IllegalArgumentException e) { - Loggers.get(ApplyLicenseAction.class).error("Failed to commit license", e); - throw BadRequestException.create(e.getMessage()); - } - } - - private Editions.StatusResponse buildResponse() { - Editions.StatusResponse.Builder builder = Editions.StatusResponse.newBuilder() - .setNextEditionKey(editionManagementState.getPendingEditionKey().orElse("")) - .setCurrentEditionKey(editionManagementState.getCurrentEditionKey().orElse("")) - .setInstallationStatus(Editions.InstallationStatus.valueOf(editionManagementState.getPendingInstallationStatus().name())); - editionManagementState.getInstallErrorMessage().ifPresent(builder::setInstallError); - return builder.build(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/ClearErrorMessageAction.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/ClearErrorMessageAction.java deleted file mode 100644 index ddd74df820e..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/ClearErrorMessageAction.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.edition.MutableEditionManagementState; -import org.sonar.server.user.UserSession; - -public class ClearErrorMessageAction implements EditionsWsAction { - private final UserSession userSession; - private final MutableEditionManagementState editionManagementState; - - public ClearErrorMessageAction(UserSession userSession, MutableEditionManagementState editionManagementState) { - this.userSession = userSession; - this.editionManagementState = editionManagementState; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("clear_error_message") - .setSince("6.7") - .setPost(true) - .setDescription("Clear error message of last install of an edition (if any). Require 'Administer System' permission.") - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession - .checkLoggedIn() - .checkIsSystemAdministrator(); - - editionManagementState.clearInstallErrorMessage(); - - response.noContent(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/EditionsWs.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/EditionsWs.java deleted file mode 100644 index 75511e620e8..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/EditionsWs.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import java.util.Arrays; -import org.sonar.api.server.ws.WebService; - -public class EditionsWs implements WebService { - private final EditionsWsAction[] actions; - - public EditionsWs(EditionsWsAction[] actions) { - this.actions = actions; - } - - @Override - public void define(Context context) { - NewController controller = context.createController("api/editions") - .setSince("6.7") - .setDescription("Manage SonarSource commercial editions."); - Arrays.stream(actions).forEach(action -> action.define(controller)); - controller.done(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/EditionsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/EditionsWsAction.java deleted file mode 100644 index 566ee7ecf61..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/EditionsWsAction.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import org.sonar.server.ws.WsAction; - -/** - * Marker interface for actions of {@link EditionsWs}. - */ -public interface EditionsWsAction extends WsAction { -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/FormDataAction.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/FormDataAction.java deleted file mode 100644 index 601b5b9de88..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/FormDataAction.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import org.sonar.api.platform.Server; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.server.user.UserSession; -import org.sonarqube.ws.Editions.FormDataResponse; - -import static org.sonar.server.ws.WsUtils.writeProtobuf; - -public class FormDataAction implements EditionsWsAction { - private final UserSession userSession; - private final Server server; - private final DbClient dbClient; - - public FormDataAction(UserSession userSession, Server server, DbClient dbClient) { - this.userSession = userSession; - this.server = server; - this.dbClient = dbClient; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("form_data") - .setSince("6.7") - .setPost(false) - .setDescription("Provide data to prefill license request forms: the server ID and the total number of lines of code.") - .setResponseExample(getClass().getResource("example-edition-form_data.json")) - .setInternal(true) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession - .checkLoggedIn() - .checkIsSystemAdministrator(); - - FormDataResponse responsePayload = FormDataResponse.newBuilder() - .setNcloc(computeNcloc()) - .setServerId(server.getId()) - .build(); - writeProtobuf(responsePayload, request, response); - } - - private long computeNcloc() { - try (DbSession dbSession = dbClient.openSession(false)) { - return dbClient.liveMeasureDao().sumNclocOfBiggestLongLivingBranch(dbSession); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/PreviewAction.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/PreviewAction.java deleted file mode 100644 index 49df044b9a7..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/PreviewAction.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import java.util.Optional; -import javax.annotation.Nullable; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -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; -import org.sonarqube.ws.Editions; - -import static java.util.Optional.ofNullable; -import static org.sonarqube.ws.Editions.PreviewStatus.AUTOMATIC_INSTALL; -import static org.sonarqube.ws.Editions.PreviewStatus.MANUAL_INSTALL; -import static org.sonarqube.ws.Editions.PreviewStatus.NO_INSTALL; - -public class PreviewAction implements EditionsWsAction { - private static final String PARAM_LICENSE = "license"; - - private final UserSession userSession; - private final EditionManagementState editionManagementState; - private final EditionInstaller editionInstaller; - private final WebServer webServer; - - public PreviewAction(UserSession userSession, EditionManagementState editionManagementState, EditionInstaller editionInstaller, - WebServer webServer) { - this.userSession = userSession; - this.editionManagementState = editionManagementState; - this.editionInstaller = editionInstaller; - this.webServer = webServer; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("preview") - .setSince("6.7") - .setPost(true) - .setDescription("Preview the changes to SonarQube to match the specified license. Requires 'Administer System' permission.") - .setResponseExample(getClass().getResource("example-edition-preview.json")) - .setHandler(this); - - action.createParam(PARAM_LICENSE) - .setRequired(true) - .setSince("6.7") - .setDescription("the license"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkIsSystemAdministrator(); - - if (editionManagementState.getPendingInstallationStatus() != EditionManagementState.PendingStatus.NONE) { - throw BadRequestException.create("Can't apply a license when applying one is already in progress"); - } - - String licenseParam = request.mandatoryParam(PARAM_LICENSE); - if (licenseParam.isEmpty()) { - throw new IllegalArgumentException(String.format("The '%s' parameter is empty", PARAM_LICENSE)); - } - License newLicense = License.parse(licenseParam).orElseThrow(() -> BadRequestException.create("The license provided is invalid")); - - NextState nextState = computeNextState(newLicense); - WsUtils.writeProtobuf(buildResponse(nextState), request, response); - } - - private static Editions.PreviewResponse buildResponse(NextState nextState) { - return Editions.PreviewResponse.newBuilder() - .setNextEditionKey(nextState.getPendingEditionKey().orElse("")) - .setPreviewStatus(nextState.getPreviewStatus()) - .build(); - } - - private NextState computeNextState(License newLicense) { - 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. - } else if (editionInstaller.isOffline()) { - return new NextState(newLicense.getEditionKey(), MANUAL_INSTALL); - } else { - return new NextState(newLicense.getEditionKey(), AUTOMATIC_INSTALL); - } - } - - private static final class NextState { - private final String pendingEditionKey; - private final Editions.PreviewStatus previewStatus; - - private NextState(@Nullable String pendingEditionKey, Editions.PreviewStatus previewStatus) { - this.pendingEditionKey = pendingEditionKey; - this.previewStatus = previewStatus; - } - - Optional getPendingEditionKey() { - return ofNullable(pendingEditionKey); - } - - Editions.PreviewStatus getPreviewStatus() { - return previewStatus; - } - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/StatusAction.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/StatusAction.java deleted file mode 100644 index 5c0725ee7c4..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/StatusAction.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.edition.EditionManagementState; -import org.sonar.server.user.UserSession; -import org.sonar.server.ws.WsUtils; -import org.sonarqube.ws.Editions; - -public class StatusAction implements EditionsWsAction { - private final UserSession userSession; - private final EditionManagementState editionManagementState; - - public StatusAction(UserSession userSession, EditionManagementState editionManagementState) { - this.userSession = userSession; - this.editionManagementState = editionManagementState; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("status") - .setSince("6.7") - .setPost(false) - .setDescription("Provide status of SonarSource commercial edition of the current SonarQube. Requires 'Administer System' permission.") - .setResponseExample(getClass().getResource("example-edition-status.json")) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession - .checkLoggedIn() - .checkIsSystemAdministrator(); - - Editions.StatusResponse.Builder responseBuilder = Editions.StatusResponse.newBuilder() - .setCurrentEditionKey(editionManagementState.getCurrentEditionKey().orElse("")) - .setNextEditionKey(editionManagementState.getPendingEditionKey().orElse("")) - .setInstallationStatus(Editions.InstallationStatus.valueOf(editionManagementState.getPendingInstallationStatus().name())); - editionManagementState.getInstallErrorMessage().ifPresent(responseBuilder::setInstallError); - - WsUtils.writeProtobuf(responseBuilder.build(), request, response); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/UninstallAction.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/UninstallAction.java deleted file mode 100644 index 22120f5009a..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/UninstallAction.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.edition.EditionManagementState.PendingStatus; -import org.sonar.server.edition.MutableEditionManagementState; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.plugins.edition.EditionInstaller; -import org.sonar.server.user.UserSession; - -import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE; -import static org.sonar.server.edition.EditionManagementState.PendingStatus.UNINSTALL_IN_PROGRESS; - -public class UninstallAction implements EditionsWsAction { - private final UserSession userSession; - private final MutableEditionManagementState mutableEditionManagementState; - private final EditionInstaller editionInstaller; - - public UninstallAction(UserSession userSession, MutableEditionManagementState mutableEditionManagementState, EditionInstaller editionInstaller) { - this.userSession = userSession; - this.mutableEditionManagementState = mutableEditionManagementState; - this.editionInstaller = editionInstaller; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("uninstall") - .setSince("6.7") - .setPost(true) - .setDescription("Uninstall the currently installed edition. Requires 'Administer System' permission.") - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkIsSystemAdministrator(); - PendingStatus status = mutableEditionManagementState.getPendingInstallationStatus(); - if (status != NONE && status != UNINSTALL_IN_PROGRESS) { - throw BadRequestException.create("Uninstall of the current edition is not allowed when install of an edition is in progress"); - } - - editionInstaller.uninstall(); - mutableEditionManagementState.uninstall(); - response.noContent(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/package-info.java deleted file mode 100644 index ad41d7e34aa..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.edition.ws; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/main/java/org/sonar/server/license/LicenseCommit.java b/server/sonar-server/src/main/java/org/sonar/server/license/LicenseCommit.java deleted file mode 100644 index 1549795972f..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/license/LicenseCommit.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.license; - -import org.sonar.api.ExtensionPoint; - -@ExtensionPoint -public interface LicenseCommit { - /** - * Installs the specified license on SonarQube. - * - * @throws IllegalArgumentException if new license is invalid or cannot be read - */ - void update(String newLicense); - - /** - * Remove any license installed on SonarQube. - */ - void delete(); -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/license/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/license/package-info.java deleted file mode 100644 index ab742eb3211..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/license/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.license; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystem.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystem.java index 350a1c36787..983d2639308 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystem.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystem.java @@ -27,12 +27,6 @@ import java.io.File; */ public interface ServerFileSystem { - /** - * Directory that contains the persisted data to be kept on restarts and upgrades. - * @return an existing directory - */ - File getDataDir(); - /** * Root directory of the server installation * @return an existing directory @@ -58,13 +52,6 @@ public interface ServerFileSystem { */ File getDownloadedPluginsDir(); - /** - * Directory of commercial plugins downloaded as part of the installation of an edition. Files - * will be moved to {@link #getInstalledPluginsDir()} on startup. - * @return a directory which may or not exist - */ - File getEditionDownloadedPluginsDir(); - /** * Directory of currently installed plugins. Used at startup. * @return a directory which may or not exist @@ -85,9 +72,4 @@ public interface ServerFileSystem { */ File getUninstalledPluginsDir(); - /** - * Directory where plugins that are part of an edition and are to be uninstalled are moved to. - * @return a directory which may or not exist - */ - File getEditionUninstalledPluginsDir(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystemImpl.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystemImpl.java index d7f982ad4f1..34fe69c7e87 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystemImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystemImpl.java @@ -36,18 +36,15 @@ public class ServerFileSystemImpl implements ServerFileSystem, org.sonar.api.pla private final File homeDir; private final File tempDir; - private final File dataDir; private final File deployDir; private final File uninstallDir; - private final File editionUninstallDir; public ServerFileSystemImpl(Configuration config) { this.homeDir = new File(config.get(PATH_HOME.getKey()).get()); this.tempDir = new File(config.get(PATH_TEMP.getKey()).get()); - this.dataDir = new File(config.get(PATH_DATA.getKey()).get()); - this.deployDir = new File(this.dataDir, TomcatContexts.WEB_DEPLOY_PATH_RELATIVE_TO_DATA_DIR); + File dataDir = new File(config.get(PATH_DATA.getKey()).get()); + this.deployDir = new File(dataDir, TomcatContexts.WEB_DEPLOY_PATH_RELATIVE_TO_DATA_DIR); this.uninstallDir = new File(getTempDir(), "uninstalled-plugins"); - this.editionUninstallDir = new File(getTempDir(), "uninstalled-edition-plugins"); } @Override @@ -70,11 +67,6 @@ public class ServerFileSystemImpl implements ServerFileSystem, org.sonar.api.pla return tempDir; } - @Override - public File getDataDir() { - return dataDir; - } - @Override public File getDeployedPluginsDir() { return new File(deployDir, "plugins"); @@ -85,11 +77,6 @@ public class ServerFileSystemImpl implements ServerFileSystem, org.sonar.api.pla return new File(getHomeDir(), "extensions/downloads"); } - @Override - public File getEditionDownloadedPluginsDir() { - return new File(getHomeDir(), "extensions/new-edition"); - } - @Override public File getInstalledPluginsDir() { return new File(getHomeDir(), "extensions/plugins"); @@ -105,9 +92,4 @@ public class ServerFileSystemImpl implements ServerFileSystem, org.sonar.api.pla return uninstallDir; } - @Override - public File getEditionUninstalledPluginsDir() { - return editionUninstallDir; - } - } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index 928da0fd9fa..7a5d0407cc7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -32,6 +32,7 @@ import org.sonar.ce.CeModule; import org.sonar.ce.notification.ReportAnalysisFailureNotificationModule; import org.sonar.ce.settings.ProjectConfigurationFactory; import org.sonar.core.component.DefaultResourceTypes; +import org.sonar.core.extension.CoreExtensionsInstaller; import org.sonar.core.platform.ComponentContainer; import org.sonar.core.timemachine.Periods; import org.sonar.server.authentication.AuthenticationModule; @@ -56,8 +57,6 @@ import org.sonar.server.debt.DebtRulesXMLImporter; import org.sonar.server.duplication.ws.DuplicationsParser; import org.sonar.server.duplication.ws.DuplicationsWs; import org.sonar.server.duplication.ws.ShowResponseBuilder; -import org.sonar.server.edition.EditionsWsModule; -import org.sonar.server.edition.FinalizeEditionChange; import org.sonar.server.email.ws.EmailsWsModule; import org.sonar.server.es.IndexCreator; import org.sonar.server.es.IndexDefinitions; @@ -67,7 +66,6 @@ import org.sonar.server.es.metadata.EsDbCompatibilityImpl; import org.sonar.server.es.metadata.MetadataIndex; import org.sonar.server.es.metadata.MetadataIndexDefinition; import org.sonar.server.event.NewAlerts; -import org.sonar.core.extension.CoreExtensionsInstaller; import org.sonar.server.favorite.FavoriteModule; import org.sonar.server.health.NodeHealthModule; import org.sonar.server.issue.AddTagsAction; @@ -138,10 +136,6 @@ import org.sonar.server.platform.ws.UpgradesAction; import org.sonar.server.plugins.PluginDownloader; import org.sonar.server.plugins.PluginUninstaller; import org.sonar.server.plugins.ServerExtensionInstaller; -import org.sonar.server.plugins.edition.EditionInstaller; -import org.sonar.server.plugins.edition.EditionInstallerExecutor; -import org.sonar.server.plugins.edition.EditionPluginDownloader; -import org.sonar.server.plugins.edition.EditionPluginUninstaller; import org.sonar.server.plugins.privileged.PrivilegedPluginsBootstraper; import org.sonar.server.plugins.privileged.PrivilegedPluginsStopper; import org.sonar.server.plugins.ws.AvailableAction; @@ -284,12 +278,6 @@ public class PlatformLevel4 extends PlatformLevel { IndexDefinitions.class, WebPagesFilter.class, - // edition - EditionInstaller.class, - EditionPluginDownloader.class, - EditionInstallerExecutor.class, - EditionPluginUninstaller.class, - // batch BatchWsModule.class, @@ -556,9 +544,6 @@ public class PlatformLevel4 extends PlatformLevel { CeModule.class, CeWsModule.class, - // SonarSource editions - EditionsWsModule.class, - InternalPropertiesImpl.class, ProjectConfigurationFactory.class, @@ -582,9 +567,6 @@ public class PlatformLevel4 extends PlatformLevel { add(TelemetryDataLoader.class); addIfStartupLeader(TelemetryDaemon.class, TelemetryClient.class); - // edition - addIfStartupLeader(FinalizeEditionChange.class); - // system info addIfCluster(WebSystemInfoModule.forClusterMode()).otherwiseAdd(WebSystemInfoModule.forStandaloneMode()); diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/AbstractPluginUninstaller.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/AbstractPluginUninstaller.java deleted file mode 100644 index 0629c46cb24..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/AbstractPluginUninstaller.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins; - -import java.io.File; -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import org.apache.commons.io.FileUtils; -import org.picocontainer.Startable; -import org.sonar.core.platform.PluginInfo; -import org.sonar.core.util.stream.MoreCollectors; - -import static java.lang.String.format; -import static org.apache.commons.io.FileUtils.forceMkdir; - -public abstract class AbstractPluginUninstaller implements Startable { - private static final String PLUGIN_EXTENSION = "jar"; - - private final ServerPluginRepository serverPluginRepository; - private final File uninstallDir; - - protected AbstractPluginUninstaller(ServerPluginRepository serverPluginRepository, File uninstallDir) { - this.serverPluginRepository = serverPluginRepository; - this.uninstallDir = uninstallDir; - } - - @Override - public void start() { - try { - forceMkdir(uninstallDir); - } catch (IOException e) { - throw new IllegalStateException("Fail to create the directory: " + uninstallDir, e); - } - } - - @Override - public void stop() { - // Nothing to do - } - - public void uninstall(String pluginKey) { - ensurePluginIsInstalled(pluginKey); - serverPluginRepository.uninstall(pluginKey, uninstallDir); - } - - public void cancelUninstalls() { - serverPluginRepository.cancelUninstalls(uninstallDir); - } - - /** - * @return the list of plugins to be uninstalled as {@link PluginInfo} instances - */ - public Collection getUninstalledPlugins() { - return listJarFiles(uninstallDir) - .stream() - .map(PluginInfo::create) - .collect(MoreCollectors.toList()); - } - - private static Collection listJarFiles(File dir) { - if (dir.exists()) { - return FileUtils.listFiles(dir, new String[] {PLUGIN_EXTENSION}, false); - } - return Collections.emptyList(); - } - - private void ensurePluginIsInstalled(String key) { - if (!serverPluginRepository.hasPlugin(key)) { - throw new IllegalArgumentException(format("Plugin [%s] is not installed", key)); - } - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginUninstaller.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginUninstaller.java index c70dd63c4b8..1ac1b234dea 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginUninstaller.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginUninstaller.java @@ -19,10 +19,72 @@ */ package org.sonar.server.plugins; +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import org.apache.commons.io.FileUtils; +import org.picocontainer.Startable; +import org.sonar.core.platform.PluginInfo; +import org.sonar.core.util.stream.MoreCollectors; import org.sonar.server.platform.ServerFileSystem; -public class PluginUninstaller extends AbstractPluginUninstaller { +import static java.lang.String.format; +import static org.apache.commons.io.FileUtils.forceMkdir; + +public class PluginUninstaller implements Startable { + private static final String PLUGIN_EXTENSION = "jar"; + private final ServerPluginRepository serverPluginRepository; + private final File uninstallDir; + public PluginUninstaller(ServerPluginRepository serverPluginRepository, ServerFileSystem fs) { - super(serverPluginRepository, fs.getUninstalledPluginsDir()); + this.serverPluginRepository = serverPluginRepository; + this.uninstallDir = fs.getUninstalledPluginsDir(); + } + + private static Collection listJarFiles(File dir) { + if (dir.exists()) { + return FileUtils.listFiles(dir, new String[] {PLUGIN_EXTENSION}, false); + } + return Collections.emptyList(); + } + + @Override + public void start() { + try { + forceMkdir(uninstallDir); + } catch (IOException e) { + throw new IllegalStateException("Fail to create the directory: " + uninstallDir, e); + } + } + + @Override + public void stop() { + // Nothing to do + } + + public void uninstall(String pluginKey) { + ensurePluginIsInstalled(pluginKey); + serverPluginRepository.uninstall(pluginKey, uninstallDir); + } + + public void cancelUninstalls() { + serverPluginRepository.cancelUninstalls(uninstallDir); + } + + /** + * @return the list of plugins to be uninstalled as {@link PluginInfo} instances + */ + public Collection getUninstalledPlugins() { + return listJarFiles(uninstallDir) + .stream() + .map(PluginInfo::create) + .collect(MoreCollectors.toList()); + } + + private void ensurePluginIsInstalled(String key) { + if (!serverPluginRepository.hasPlugin(key)) { + throw new IllegalArgumentException(format("Plugin [%s] is not installed", key)); + } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerPluginRepository.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerPluginRepository.java index b3d5b242b36..efdb438d6d3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerPluginRepository.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerPluginRepository.java @@ -102,7 +102,6 @@ public class ServerPluginRepository implements PluginRepository, Startable { public void start() { loadPreInstalledPlugins(); moveDownloadedPlugins(); - moveDownloadedEditionPlugins(); unloadIncompatiblePlugins(); logInstalledPlugins(); loadInstances(); @@ -149,14 +148,6 @@ public class ServerPluginRepository implements PluginRepository, Startable { } } - private void moveDownloadedEditionPlugins() { - if (fs.getEditionDownloadedPluginsDir().exists()) { - for (File sourceFile : listJarFiles(fs.getEditionDownloadedPluginsDir())) { - overrideAndRegisterPlugin(sourceFile); - } - } - } - private void registerPluginInfo(PluginInfo info) { String pluginKey = info.getKey(); if (blacklistedPluginKeys.contains(pluginKey)) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionInstaller.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionInstaller.java deleted file mode 100644 index 54cef994caa..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionInstaller.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins.edition; - -import com.google.common.base.Optional; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Semaphore; -import java.util.stream.Collectors; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.sonar.core.platform.PluginInfo; -import org.sonar.server.edition.License; -import org.sonar.server.edition.MutableEditionManagementState; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.updatecenter.common.UpdateCenter; - -public class EditionInstaller { - private static final Logger LOG = Loggers.get(EditionInstaller.class); - - private final Semaphore semaphore = new Semaphore(1); - private final EditionInstallerExecutor executor; - private final EditionPluginDownloader editionPluginDownloader; - private final EditionPluginUninstaller editionPluginUninstaller; - private final ServerPluginRepository pluginRepository; - private final UpdateCenterMatrixFactory updateCenterMatrixFactory; - private final MutableEditionManagementState editionManagementState; - - public EditionInstaller(EditionPluginDownloader editionDownloader, EditionPluginUninstaller editionPluginUninstaller, - ServerPluginRepository pluginRepository, EditionInstallerExecutor executor, UpdateCenterMatrixFactory updateCenterMatrixFactory, - MutableEditionManagementState editionManagementState) { - this.editionPluginDownloader = editionDownloader; - this.editionPluginUninstaller = editionPluginUninstaller; - this.pluginRepository = pluginRepository; - this.executor = executor; - this.updateCenterMatrixFactory = updateCenterMatrixFactory; - this.editionManagementState = editionManagementState; - } - - /** - * Refreshes the update center, and submits in a executor a task to download all the needed plugins (asynchronously). - * If the update center is disabled or if we are offline, the task is not submitted. - * - * @throws IllegalStateException if an installation is already in progress - */ - public void install(License newLicense) { - if (semaphore.tryAcquire()) { - try { - Optional updateCenter = updateCenterMatrixFactory.getUpdateCenter(true); - if (!updateCenter.isPresent()) { - LOG.info("Installation of edition '{}' needs to be done manually", newLicense.getEditionKey()); - editionManagementState.startManualInstall(newLicense); - return; - } - editionManagementState.startAutomaticInstall(newLicense); - executor.execute(() -> asyncInstall(newLicense, updateCenter.get())); - } catch (RuntimeException e) { - semaphore.release(); - throw e; - } - } else { - throw new IllegalStateException("Another installation of an edition is already running"); - } - } - - public void uninstall() { - Map pluginInfosByKeys = pluginRepository.getPluginInfosByKeys(); - Set pluginsToRemove = pluginsToRemove(Collections.emptySet(), pluginInfosByKeys.values()); - uninstallPlugins(pluginsToRemove); - } - - /** - * Check if the update center is disabled or unreachable. It uses the cached status (it doesn't refresh), - * to be a cost-free check. - */ - public boolean isOffline() { - return !updateCenterMatrixFactory.getUpdateCenter(false).isPresent(); - } - - public boolean requiresInstallationChange(Set editionPluginKeys) { - Map pluginInfosByKeys = pluginRepository.getPluginInfosByKeys(); - - return !pluginsToInstall(editionPluginKeys, pluginInfosByKeys.keySet()).isEmpty() - || !pluginsToRemove(editionPluginKeys, pluginInfosByKeys.values()).isEmpty(); - } - - private void asyncInstall(License newLicense, UpdateCenter updateCenter) { - try { - Set editionPluginKeys = newLicense.getPluginKeys(); - Map pluginInfosByKeys = pluginRepository.getPluginInfosByKeys(); - Set pluginsToRemove = pluginsToRemove(editionPluginKeys, pluginInfosByKeys.values()); - Set pluginsToInstall = pluginsToInstall(editionPluginKeys, pluginInfosByKeys.keySet()); - - LOG.info("Installing edition '{}', download: {}, remove: {}", - newLicense.getEditionKey(), pluginsToInstall, pluginsToRemove); - - editionPluginDownloader.downloadEditionPlugins(pluginsToInstall, updateCenter); - uninstallPlugins(pluginsToRemove); - editionManagementState.automaticInstallReady(); - } catch (Throwable t) { - LOG.error("Failed to install edition {} with plugins {}", newLicense.getEditionKey(), newLicense.getPluginKeys(), t); - editionManagementState.installFailed(t.getMessage()); - } finally { - semaphore.release(); - } - } - - private void uninstallPlugins(Set pluginsToRemove) { - pluginsToRemove.stream().forEach(editionPluginUninstaller::uninstall); - } - - private static Set pluginsToInstall(Set editionPluginKeys, Set installedPluginKeys) { - return editionPluginKeys.stream() - .filter(p -> !installedPluginKeys.contains(p)) - .collect(Collectors.toSet()); - } - - private static Set pluginsToRemove(Set editionPluginKeys, Collection installedPluginInfos) { - Set installedCommercialPluginKeys = installedPluginInfos.stream() - .filter(EditionBundledPlugins::isEditionBundled) - .map(PluginInfo::getKey) - .collect(Collectors.toSet()); - - return installedCommercialPluginKeys.stream() - .filter(p -> !editionPluginKeys.contains(p)) - .collect(Collectors.toSet()); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionInstallerExecutor.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionInstallerExecutor.java deleted file mode 100644 index 3dac5e4accc..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionInstallerExecutor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins.edition; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import org.sonar.server.util.AbstractStoppableExecutorService; - -public class EditionInstallerExecutor extends AbstractStoppableExecutorService { - public EditionInstallerExecutor() { - super(createExecutor()); - } - - @Override - public void execute(Runnable r) { - delegate.submit(r); - } - - private static ExecutorService createExecutor() { - ThreadFactory threadFactory = new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("edition-installation-%d") - .build(); - return Executors.newSingleThreadExecutor(threadFactory); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionPluginDownloader.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionPluginDownloader.java deleted file mode 100644 index 37a1474e842..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionPluginDownloader.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins.edition; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashSet; -import java.util.Set; -import org.sonar.api.utils.HttpDownloader; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.sonar.core.util.FileUtils; -import org.sonar.server.platform.ServerFileSystem; -import org.sonar.updatecenter.common.Release; -import org.sonar.updatecenter.common.UpdateCenter; -import org.sonar.updatecenter.common.Version; - -import static org.apache.commons.io.FileUtils.toFile; -import static org.apache.commons.lang.StringUtils.substringAfterLast; - -public class EditionPluginDownloader { - private static final Logger LOG = Loggers.get(EditionPluginDownloader.class); - private static final String PLUGIN_EXTENSION = "jar"; - - private final Path tmpDir; - private final Path downloadDir; - private final HttpDownloader downloader; - - public EditionPluginDownloader(HttpDownloader downloader, ServerFileSystem fileSystem) { - this.downloadDir = fileSystem.getEditionDownloadedPluginsDir().toPath(); - this.downloader = downloader; - this.tmpDir = downloadDir.resolveSibling(downloadDir.getFileName() + "_tmp"); - } - - public void downloadEditionPlugins(Set pluginKeys, UpdateCenter updateCenter) { - try { - Set pluginsToInstall = new HashSet<>(); - for (String pluginKey : pluginKeys) { - pluginsToInstall.addAll(updateCenter.findInstallablePlugins(pluginKey, Version.create(""))); - } - - FileUtils.deleteDirectory(tmpDir); - Files.createDirectories(tmpDir); - - for (Release r : pluginsToInstall) { - download(r); - } - - FileUtils.deleteDirectory(downloadDir); - Files.move(tmpDir, downloadDir); - } catch (IOException e) { - throw new IllegalStateException(e.getMessage(), e); - } finally { - FileUtils.deleteQuietly(tmpDir); - } - } - - protected void download(Release release) { - try { - LOG.info("Downloading plugin: {}", release.getArtifact().getKey()); - downloadRelease(release); - } catch (Exception e) { - String message = String.format("Fail to download the plugin (%s, version %s) from %s (error is : %s)", - release.getArtifact().getKey(), release.getVersion().getName(), release.getDownloadUrl(), e.getMessage()); - LOG.debug(message, e); - throw new IllegalStateException(message, e); - } - } - - private void downloadRelease(Release release) throws URISyntaxException, IOException { - String url = release.getDownloadUrl(); - - URI uri = new URI(url); - if (url.startsWith("file:")) { - // used for tests - File file = toFile(uri.toURL()); - Files.copy(file.toPath(), tmpDir.resolve(file.getName())); - } else { - String filename = substringAfterLast(uri.getPath(), "/"); - if (!filename.endsWith("." + PLUGIN_EXTENSION)) { - filename = release.getKey() + "-" + release.getVersion() + "." + PLUGIN_EXTENSION; - } - Path targetFile = tmpDir.resolve(filename); - downloader.download(uri, targetFile.toFile()); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionPluginUninstaller.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionPluginUninstaller.java deleted file mode 100644 index b6381bba35c..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionPluginUninstaller.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins.edition; - -import org.sonar.server.platform.ServerFileSystem; -import org.sonar.server.plugins.AbstractPluginUninstaller; -import org.sonar.server.plugins.ServerPluginRepository; - -public class EditionPluginUninstaller extends AbstractPluginUninstaller { - - public EditionPluginUninstaller(ServerPluginRepository serverPluginRepository, ServerFileSystem fs) { - super(serverPluginRepository, fs.getEditionUninstalledPluginsDir()); - } -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-apply_license.json b/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-apply_license.json deleted file mode 100644 index 507a64db677..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-apply_license.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "currentEditionKey": "", - "installationStatus": "AUTOMATIC_IN_PROGRESS", - "nextEditionKey": "developer-edition" -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-form_data.json b/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-form_data.json deleted file mode 100644 index 3a361124437..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-form_data.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "serverId": "uuid", - "ncloc": 12345 -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-preview.json b/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-preview.json deleted file mode 100644 index 2427d69c401..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-preview.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "nextEditionKey": "developer-edition", - "previewStatus": "AUTOMATIC_INSTALL" -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-status.json b/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-status.json deleted file mode 100644 index aff72735324..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-status.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "currentEditionKey": "", - "installationStatus": "AUTOMATIC_READY", - "nextEditionKey": "developer-edition" -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/EditionsWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/EditionsWsModuleTest.java deleted file mode 100644 index 2d5c575e1ef..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/EditionsWsModuleTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import org.junit.Test; -import org.sonar.core.platform.ComponentContainer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER; - -public class EditionsWsModuleTest { - private EditionsWsModule underTest = new EditionsWsModule(); - - @Test - public void verify_component_count() { - ComponentContainer container = new ComponentContainer(); - underTest.configure(container); - - assertThat(container.getPicoContainer().getComponentAdapters()) - .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 8); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/FinalizeEditionChangeTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/FinalizeEditionChangeTest.java deleted file mode 100644 index dc693d5ef00..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/FinalizeEditionChangeTest.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import java.util.Optional; -import org.apache.commons.lang.RandomStringUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.server.license.LicenseCommit; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -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.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 FinalizeEditionChangeTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public LogTester logTester = new LogTester(); - - private MutableEditionManagementState editionManagementState = mock(MutableEditionManagementState.class); - private LicenseCommit licenseCommit = mock(LicenseCommit.class); - private FinalizeEditionChange underTest = new FinalizeEditionChange(editionManagementState); - private FinalizeEditionChange underTestWithLicenseCommit = new FinalizeEditionChange(editionManagementState, licenseCommit); - - @Test - public void start_clears_error_message_when_status_is_NONE_without_LicenseCommit() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - - underTest.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).clearInstallErrorMessage(); - verifyNoMoreInteractions(editionManagementState); - } - - @Test - public void start_clears_error_message_when_status_is_NONE_with_LicenseCommit() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - - underTestWithLicenseCommit.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).clearInstallErrorMessage(); - verifyNoMoreInteractions(editionManagementState); - verifyZeroInteractions(licenseCommit); - } - - @Test - public void start_clears_status_when_status_is_AUTOMATIC_READY_and_no_LicenseCommit_is_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(AUTOMATIC_READY); - - underTest.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).finalizeInstallation("Edition installation didn't complete. Some plugins were not installed."); - - verifyNoMoreInteractions(editionManagementState); - verifyZeroInteractions(licenseCommit); - assertThat(logTester.logs()).hasSize(1); - assertThat(logTester.logs(LoggerLevel.WARN)) - .containsOnly("Edition installation didn't complete. Some plugins were not installed."); - } - - @Test - public void start_clears_status_when_status_is_AUTOMATIC_READY_and_license_is_not_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(AUTOMATIC_READY); - when(editionManagementState.getPendingLicense()).thenReturn(Optional.empty()); - - underTestWithLicenseCommit.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).finalizeInstallation("Edition installation didn't complete. License was not found."); - verify(editionManagementState).getPendingLicense(); - - verifyNoMoreInteractions(editionManagementState); - verifyZeroInteractions(licenseCommit); - assertThat(logTester.logs()).hasSize(1); - assertThat(logTester.logs(LoggerLevel.WARN)) - .containsOnly("Edition installation didn't complete. License was not found."); - } - - @Test - public void start_commit_license_and_finalizeInstallation_in_editionManagementState_when_status_is_AUTOMATIC_READY_and_LicenseCommit_is_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(AUTOMATIC_READY); - String license = RandomStringUtils.randomAlphanumeric(20); - when(editionManagementState.getPendingLicense()).thenReturn(Optional.of(license)); - - underTestWithLicenseCommit.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).getPendingLicense(); - verify(editionManagementState).finalizeInstallation(null); - verifyNoMoreInteractions(editionManagementState); - verify(licenseCommit).update(license); - verifyNoMoreInteractions(licenseCommit); - } - - @Test - public void start_commit_license_and_finalizeInstallation_with_error_in_editionManagementState_when_status_is_AUTOMATIC_READY_and_license_is_invalid() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(AUTOMATIC_READY); - String license = RandomStringUtils.randomAlphanumeric(20); - when(editionManagementState.getPendingLicense()).thenReturn(Optional.of(license)); - doThrow(new IllegalArgumentException("Faking an IAE because of an invalid license")) - .when(licenseCommit) - .update(license); - - underTestWithLicenseCommit.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).getPendingLicense(); - verify(editionManagementState).finalizeInstallation("Edition installation didn't complete. License is not valid. Please set a new license."); - verifyNoMoreInteractions(editionManagementState); - verify(licenseCommit).update(license); - verifyNoMoreInteractions(licenseCommit); - assertThat(logTester.logs()).hasSize(1); - assertThat(logTester.logs(LoggerLevel.WARN)) - .containsOnly("Edition installation didn't complete. License is not valid. Please set a new license."); - } - - @Test - public void start_clears_status_when_status_is_MANUAL_IN_PROGRESS_and_no_LicenseCommit_is_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(MANUAL_IN_PROGRESS); - - underTest.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).finalizeInstallation("Edition installation didn't complete. Some plugins were not installed."); - verifyNoMoreInteractions(editionManagementState); - verifyZeroInteractions(licenseCommit); - assertThat(logTester.logs()).hasSize(1); - assertThat(logTester.logs(LoggerLevel.WARN)) - .containsOnly("Edition installation didn't complete. Some plugins were not installed."); - } - - @Test - public void start_commit_license_and_finalizeInstallation_in_editionManagementState_when_status_is_MANUAL_IN_PROGRESS_and_LicenseCommit_is_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(MANUAL_IN_PROGRESS); - String license = RandomStringUtils.randomAlphanumeric(20); - when(editionManagementState.getPendingLicense()).thenReturn(Optional.of(license)); - - underTestWithLicenseCommit.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).getPendingLicense(); - verify(editionManagementState).finalizeInstallation(null); - verifyNoMoreInteractions(editionManagementState); - verify(licenseCommit).update(license); - verifyNoMoreInteractions(licenseCommit); - } - - @Test - public void start_commit_license_and_finalizeInstallation_with_error_in_editionManagementState_when_status_is_MANUAL_IN_PROGRESS_and_license_is_invalid() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(MANUAL_IN_PROGRESS); - String license = RandomStringUtils.randomAlphanumeric(20); - when(editionManagementState.getPendingLicense()).thenReturn(Optional.of(license)); - doThrow(new IllegalArgumentException("Faking an IAE because of an invalid license")) - .when(licenseCommit) - .update(license); - - underTestWithLicenseCommit.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).getPendingLicense(); - verify(editionManagementState).finalizeInstallation("Edition installation didn't complete. License is not valid. Please set a new license."); - verifyNoMoreInteractions(editionManagementState); - verify(licenseCommit).update(license); - verifyNoMoreInteractions(licenseCommit); - assertThat(logTester.logs()).hasSize(1); - assertThat(logTester.logs(LoggerLevel.WARN)) - .containsOnly("Edition installation didn't complete. License is not valid. Please set a new license."); - } - - @Test - public void start_put_editionManagement_set_in_automaticInstallError_when_status_is_AUTOMATIC_PROGRESS_and_no_LicenseCommit_is_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(AUTOMATIC_IN_PROGRESS); - - underTest.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).installFailed("SonarQube was restarted before asynchronous installation of edition completed"); - verifyNoMoreInteractions(editionManagementState); - verifyZeroInteractions(licenseCommit); - } - - @Test - public void start_put_editionManagement_set_in_automaticInstallError_when_status_is_AUTOMATIC_PROGRESS_and_LicenseCommit_is_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(AUTOMATIC_IN_PROGRESS); - - underTestWithLicenseCommit.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).installFailed("SonarQube was restarted before asynchronous installation of edition completed"); - verifyNoMoreInteractions(editionManagementState); - verifyZeroInteractions(licenseCommit); - } - - @Test - public void stop_should_remove_license_if_uninstalling_and_LicenseCommit_is_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(UNINSTALL_IN_PROGRESS); - - underTestWithLicenseCommit.stop(); - - assertThat(logTester.logs()).hasSize(1); - assertThat(logTester.logs(LoggerLevel.DEBUG)) - .containsOnly("Removing license"); - verify(licenseCommit).delete(); - verifyNoMoreInteractions(licenseCommit); - verify(editionManagementState).getPendingInstallationStatus(); - verifyNoMoreInteractions(editionManagementState); - } - - @Test - public void stop_should_log_if_uninstalling_and_LicenseCommit_is_not_available() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(UNINSTALL_IN_PROGRESS); - - underTest.stop(); - - assertThat(logTester.logs()).hasSize(1); - assertThat(logTester.logs(LoggerLevel.WARN)) - .containsOnly("License Manager plugin not found - cannot remove the license"); - verify(editionManagementState).getPendingInstallationStatus(); - verifyNoMoreInteractions(editionManagementState); - } - - @Test - public void should_commit_uninstall() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(EditionManagementState.PendingStatus.UNINSTALL_IN_PROGRESS); - - underTest.start(); - - verify(editionManagementState).getPendingInstallationStatus(); - verify(editionManagementState).finalizeInstallation(null); - verifyNoMoreInteractions(editionManagementState); - } - - @Test - public void should_fail_uninstall_if_license_commit_is_present() { - when(editionManagementState.getPendingInstallationStatus()).thenReturn(EditionManagementState.PendingStatus.UNINSTALL_IN_PROGRESS); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("License Manager plugin is still present"); - - underTestWithLicenseCommit.start(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/LicenseTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/LicenseTest.java deleted file mode 100644 index c296bba36b4..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/LicenseTest.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import com.google.common.collect.ImmutableSet; -import java.io.IOException; -import java.io.StringWriter; -import java.util.Base64; -import java.util.Collections; -import java.util.Optional; -import java.util.Properties; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static org.assertj.core.api.Assertions.assertThat; - -public class LicenseTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void constructor_fails_if_editionKey_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("editionKey can't be null"); - - new License(null, Collections.emptyList(), "content"); - } - - @Test - public void constructor_fails_if_editionKey_is_empty() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("editionKey can't be empty"); - - new License("", Collections.emptyList(), "content"); - } - - @Test - public void constructor_fails_if_plugins_is_null() { - expectedException.expect(NullPointerException.class); - - new License("edition-key", null, "content"); - } - - @Test - public void constructor_fails_if_content_is_null() { - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("content can't be null"); - - new License("edition-key", Collections.emptyList(), null); - } - - @Test - public void constructor_fails_if_content_is_empty() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("content can't be empty"); - - new License("edition-key", Collections.emptyList(), ""); - } - - @Test - public void parse_returns_empty_if_license_is_invalid_string() { - assertThat(License.parse("trash")).isEmpty(); - } - - @Test - public void parse_succeeds() throws IOException { - Properties props = new Properties(); - props.setProperty("Plugins", "plugin1,plugin2"); - props.setProperty("Edition", "dev"); - StringWriter writer = new StringWriter(); - props.store(writer, ""); - - byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes()); - - Optional license = License.parse(new String(encoded)); - assertThat(license).isPresent(); - assertThat(license.get().getEditionKey()).isEqualTo("dev"); - assertThat(license.get().getPluginKeys()).containsOnly("plugin1", "plugin2"); - } - - @Test - public void parse_is_empty_if_license_has_no_plugin() throws IOException { - Properties props = new Properties(); - props.setProperty("Plugins", ""); - props.setProperty("Edition", "dev"); - StringWriter writer = new StringWriter(); - props.store(writer, ""); - - byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes()); - - Optional license = License.parse(new String(encoded)); - assertThat(license).isEmpty(); - } - - @Test - public void parse_is_empty_if_license_has_empty_edition_key() throws IOException { - Properties props = new Properties(); - props.setProperty("Plugins", "p1"); - props.setProperty("Edition", ""); - StringWriter writer = new StringWriter(); - props.store(writer, ""); - - byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes()); - - Optional license = License.parse(new String(encoded)); - assertThat(license).isEmpty(); - } - - @Test - public void parse_is_empty_if_license_has_no_edition_key() throws IOException { - Properties props = new Properties(); - props.setProperty("Plugins", "plugin1,plugin2"); - StringWriter writer = new StringWriter(); - props.store(writer, ""); - - byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes()); - - Optional license = License.parse(new String(encoded)); - assertThat(license).isEmpty(); - } - - @Test - public void verify_getters() { - ImmutableSet pluginKeys = ImmutableSet.of("a", "b", "c"); - - License underTest = new License("edition-key", pluginKeys, "content"); - - assertThat(underTest.getEditionKey()).isEqualTo("edition-key"); - assertThat(underTest.getPluginKeys()).isEqualTo(pluginKeys); - assertThat(underTest.getContent()).isEqualTo("content"); - } -} 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 deleted file mode 100644 index b520ee38c15..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/StandaloneEditionManagementStateImplTest.java +++ /dev/null @@ -1,1311 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition; - -import java.util.Collections; -import java.util.Random; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.server.edition.EditionManagementState.PendingStatus; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.edition.EditionManagementState.PendingStatus.AUTOMATIC_IN_PROGRESS; -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)); - - @Rule - public DbTester dbTester = DbTester.create(System2.INSTANCE); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Nullable - private String nullableErrorMessage = new Random().nextBoolean() ? null : randomAlphanumeric(5); - private String errorMessage = randomAlphanumeric(5); - private DbClient dbClient = dbTester.getDbClient(); - private final StandaloneEditionManagementStateImpl underTest = new StandaloneEditionManagementStateImpl(dbClient); - - @Test - public void getCurrentEditionKey_fails_with_ISE_if_start_has_not_been_called() { - expectISENotStarted(); - - underTest.getCurrentEditionKey(); - } - - @Test - public void getCurrentEditionKey_returns_empty_when_internal_properties_table_is_empty() { - underTest.start(); - - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - } - - @Test - public void getCurrentEditionKey_returns_value_in_db_for_key_currentEditionKey() { - String value = randomAlphanumeric(10); - dbTester.properties().insertInternal("currentEditionKey", value); - underTest.start(); - - assertThat(underTest.getCurrentEditionKey()).contains(value); - } - - @Test - public void getCurrentEditionKey_returns_empty_when_value_in_db_is_empty_for_key_currentEditionKey() { - dbTester.properties().insertEmptyInternal("currentEditionKey"); - underTest.start(); - - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - } - - @Test - public void getPendingInstallationStatus_fails_with_ISE_if_start_has_not_been_called() { - expectISENotStarted(); - - underTest.getPendingInstallationStatus(); - } - - @Test - public void getPendingInstallationStatus_returns_NONE_when_internal_properties_table_is_empty() { - underTest.start(); - - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - } - - @Test - public void getPendingInstallationStatus_returns_value_in_db_for_key_pendingInstallStatus() { - PendingStatus value = PendingStatus.values()[new Random().nextInt(PendingStatus.values().length)]; - dbTester.properties().insertInternal("pendingInstallStatus", value.name()); - underTest.start(); - - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(value); - } - - @Test - public void getPendingInstallationStatus_returns_NONE_when_value_in_db_is_empty_for_key_pendingInstallStatus() { - dbTester.properties().insertEmptyInternal("pendingInstallStatus"); - underTest.start(); - - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - } - - @Test - public void start_fails_when_value_in_db_for_key_pendingInstallStatus_cannot_be_parsed_to_enum() { - String value = randomAlphanumeric(30); - dbTester.properties().insertInternal("pendingInstallStatus", value); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("No enum constant org.sonar.server.edition.EditionManagementState.PendingStatus." + value); - - underTest.start(); - } - - @Test - public void getPendingEditionKey_fails_with_ISE_if_start_has_not_been_called() { - expectISENotStarted(); - - underTest.getPendingEditionKey(); - } - - @Test - public void getPendingEditionKey_returns_empty_when_internal_properties_table_is_empty() { - underTest.start(); - - assertThat(underTest.getPendingEditionKey()).isEmpty(); - } - - @Test - public void getPendingEditionKey_returns_value_in_db_for_key_pendingEditionKey() { - String value = randomAlphanumeric(10); - dbTester.properties().insertInternal("pendingEditionKey", value); - underTest.start(); - - assertThat(underTest.getPendingEditionKey()).contains(value); - } - - @Test - public void getPendingEditionKey_returns_empty_when_value_in_db_is_empty_for_key_pendingEditionKey() { - dbTester.properties().insertEmptyInternal("pendingEditionKey"); - underTest.start(); - - assertThat(underTest.getPendingEditionKey()).isEmpty(); - } - - @Test - public void getPendingLicense_fails_with_ISE_if_start_has_not_been_called() { - expectISENotStarted(); - - underTest.getPendingLicense(); - } - - @Test - public void getPendingLicense_returns_empty_when_internal_properties_table_is_empty() { - underTest.start(); - - assertThat(underTest.getPendingLicense()).isEmpty(); - } - - @Test - public void getPendingLicense_returns_empty_value_in_db_for_key_pendingLicense() { - String value = randomAlphanumeric(10); - dbTester.properties().insertInternal("pendingLicense", value); - underTest.start(); - - assertThat(underTest.getPendingLicense()).contains(value); - } - - @Test - public void getPendingLicense_returns_empty_when_value_in_db_is_empty_for_key_pendingLicense() { - dbTester.properties().insertEmptyInternal("pendingLicense"); - underTest.start(); - - assertThat(underTest.getPendingLicense()).isEmpty(); - } - - @Test - public void getInstallErrorMessage_fails_with_ISE_if_start_has_not_been_called() { - expectISENotStarted(); - - underTest.getInstallErrorMessage(); - } - - @Test - public void getInstallErrorMessage_returns_empty_when_internal_properties_table_is_empty() { - underTest.start(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void getInstallErrorMessage_returns_value_in_db_for_key_pendingEditionKey() { - String value = randomAlphanumeric(10); - dbTester.properties().insertInternal("installError", value); - underTest.start(); - - assertThat(underTest.getInstallErrorMessage()).contains(value); - } - - @Test - public void getInstallErrorMessage_returns_empty_when_value_in_db_is_empty_for_key_pendingEditionKey() { - dbTester.properties().insertEmptyInternal("installError"); - underTest.start(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_fails_with_ISE_if_not_started() { - expectISENotStarted(); - - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startAutomaticInstall_fails_with_NPE_if_license_is_null() { - underTest.start(); - - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("license can't be null"); - - underTest.startAutomaticInstall(null); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_after_start() { - underTest.start(); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_after_start_with_existing_currentEditionKey() { - String value = randomAlphanumeric(10); - dbTester.properties().insertInternal("currentEditionKey", value); - underTest.start(); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).contains(value); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_after_newEditionWithoutInstall() { - String value = randomAlphanumeric(10); - underTest.start(); - underTest.newEditionWithoutInstall(value); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).contains(value); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_after_finalizeInstallation() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.automaticInstallReady(); - underTest.finalizeInstallation(null); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_and_clears_error_message_after_finalizeInstallation() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - underTest.finalizeInstallation(errorMessage); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_fails_with_ISE_if_called_after_startAutomaticInstall() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_IN_PROGRESS when status is AUTOMATIC_IN_PROGRESS (should be any of [NONE])"); - - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startAutomaticInstall_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 AUTOMATIC_IN_PROGRESS when status is AUTOMATIC_READY (should be any of [NONE])"); - - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startAutomaticInstall_fails_with_ISE_if_called_after_manualInstall() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_IN_PROGRESS when status is MANUAL_IN_PROGRESS (should be any of [NONE])"); - - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startAutomaticInstall_fails_with_ISE_if_called_after_uninstall() { - underTest.start(); - underTest.newEditionWithoutInstall("foo"); - underTest.uninstall(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_IN_PROGRESS when status is UNINSTALL_IN_PROGRESS (should be any of [NONE])"); - - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_after_installFailed() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(null); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_and_clears_error_message_after_installFailed_with_message() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(errorMessage); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_after_finalizeInstall() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.automaticInstallReady(); - underTest.finalizeInstallation(null); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startAutomaticInstall_sets_pending_fields_and_clears_error_message_after_finalizeInstall_with_message() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - underTest.finalizeInstallation(errorMessage); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @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(); - assertThat(underTest.getInstallErrorMessage()).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(); - assertThat(underTest.getInstallErrorMessage()).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 startAutomaticInstall_succeeds_if_called_after_installFailed_and_clears_errorMessage() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(errorMessage); - - PendingStatus newStatus = underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startManualInstall_fails_with_ISE_if_not_started() { - expectISENotStarted(); - - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startManualInstall_fails_with_NPE_if_license_is_null() { - underTest.start(); - - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("license can't be null"); - - underTest.startManualInstall(null); - } - - @Test - public void startManualInstall_sets_pending_fields_after_start() { - underTest.start(); - - PendingStatus newStatus = underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(MANUAL_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(MANUAL_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startManualInstall_sets_pending_fields_after_start_with_existing_currentEditionKey() { - String value = randomAlphanumeric(10); - dbTester.properties().insertInternal("currentEditionKey", value); - underTest.start(); - - PendingStatus newStatus = underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(MANUAL_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(MANUAL_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).contains(value); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startManualInstall_sets_pending_fields_after_newEditionWithoutInstall() { - String value = randomAlphanumeric(10); - underTest.start(); - underTest.newEditionWithoutInstall(value); - - PendingStatus newStatus = underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(MANUAL_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(MANUAL_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).contains(value); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void startManualInstall_fails_with_ISE_if_called_after_startAutomaticInstall() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to MANUAL_IN_PROGRESS when status is AUTOMATIC_IN_PROGRESS (should be any of [NONE])"); - - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startManualInstall_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 MANUAL_IN_PROGRESS when status is AUTOMATIC_READY (should be any of [NONE])"); - - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startManualInstall_fails_with_ISE_if_called_after_manualInstall() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to MANUAL_IN_PROGRESS when status is MANUAL_IN_PROGRESS (should be any of [NONE])"); - - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startManualInstall_fails_with_ISE_if_called_after_uninstall() { - underTest.start(); - underTest.newEditionWithoutInstall("foo"); - underTest.uninstall(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to MANUAL_IN_PROGRESS when status is UNINSTALL_IN_PROGRESS (should be any of [NONE])"); - - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - } - - @Test - public void startManualInstall_succeeds_if_called_after_installFailed_and_clears_errorMessage() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(errorMessage); - - PendingStatus newStatus = underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - assertThat(newStatus).isEqualTo(MANUAL_IN_PROGRESS); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(MANUAL_IN_PROGRESS); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void automaticInstallReady_fails_with_ISE_if_not_started() { - expectISENotStarted(); - - underTest.automaticInstallReady(); - } - - @Test - public void automaticInstallReady_fails_with_ISE_if_called() { - underTest.start(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_READY when status is NONE (should be any of [AUTOMATIC_IN_PROGRESS])"); - - underTest.automaticInstallReady(); - } - - @Test - public void automaticInstallReady_fails_with_ISE_if_called_after_manualInstall() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_READY when status is MANUAL_IN_PROGRESS (should be any of [AUTOMATIC_IN_PROGRESS])"); - - underTest.automaticInstallReady(); - } - - @Test - public void automaticInstallReady_fails_with_ISE_if_called_after_newEditionWithoutInstall() { - underTest.start(); - underTest.newEditionWithoutInstall("foo"); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_READY when status is NONE (should be any of [AUTOMATIC_IN_PROGRESS])"); - - underTest.automaticInstallReady(); - } - - @Test - public void automaticInstallReady_fails_with_ISE_if_called_after_uninstall() { - underTest.start(); - underTest.newEditionWithoutInstall("foo"); - underTest.uninstall(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_READY when status is UNINSTALL_IN_PROGRESS (should be any of [AUTOMATIC_IN_PROGRESS])"); - - underTest.automaticInstallReady(); - } - - @Test - public void automaticInstallReady_fails_with_ISE_if_called_after_startManualInstall() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_READY when status is MANUAL_IN_PROGRESS (should be any of [AUTOMATIC_IN_PROGRESS])"); - - underTest.automaticInstallReady(); - } - - @Test - public void automaticInstallReady_after_startAutomaticInstall_changes_status_to_AUTOMATIC_READY_but_does_not_change_editions() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - PendingStatus newStatus = underTest.automaticInstallReady(); - - assertThat(newStatus).isEqualTo(AUTOMATIC_READY); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(AUTOMATIC_READY); - assertThat(underTest.getPendingEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getPendingLicense()).contains(LICENSE_WITHOUT_PLUGINS.getContent()); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void automaticInstallReady_fails_with_ISE_if_called_after_installFailed() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(nullableErrorMessage); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to AUTOMATIC_READY when status is NONE (should be any of [AUTOMATIC_IN_PROGRESS])"); - - underTest.automaticInstallReady(); - } - - @Test - public void newEditionWithoutInstall_fails_with_ISE_if_not_started() { - expectISENotStarted(); - - underTest.newEditionWithoutInstall(randomAlphanumeric(3)); - } - - @Test - public void newEditionWithoutInstall_fails_with_NPE_if_newEditionKey_is_null() { - underTest.start(); - - expectedException.expect(NullPointerException.class); - expectedException.expectMessage("newEditionKey can't be null"); - - underTest.newEditionWithoutInstall(null); - } - - @Test - public void newEditionWithoutInstall_fails_with_IAE_if_newEditionKey_is_empty() { - underTest.start(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("newEditionKey can't be empty"); - - underTest.newEditionWithoutInstall(""); - } - - @Test - public void newEditionWithoutInstall_changes_current_edition() { - String newEditionKey = randomAlphanumeric(3); - underTest.start(); - - PendingStatus newStatus = underTest.newEditionWithoutInstall(newEditionKey); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(newEditionKey); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void newEditionWithoutInstall_overwrite_current_edition() { - String newEditionKey = randomAlphanumeric(3); - underTest.start(); - - PendingStatus newStatus = underTest.newEditionWithoutInstall(newEditionKey); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(newEditionKey); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void newEditionWithoutInstall_overwrites_from_previous_newEditionWithoutInstall() { - String newEditionKey1 = randomAlphanumeric(3); - String newEditionKey2 = randomAlphanumeric(3); - underTest.start(); - underTest.newEditionWithoutInstall(newEditionKey1); - - PendingStatus newStatus = underTest.newEditionWithoutInstall(newEditionKey2); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(newEditionKey2); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void newEditionWithoutInstall_fails_with_ISE_if_called_after_startAutomaticInstall() { - String newEditionKey = randomAlphanumeric(3); - underTest.start(); - 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 [NONE])"); - - underTest.newEditionWithoutInstall(newEditionKey); - } - - @Test - public void newEditionWithoutInstall_fails_with_ISE_if_called_after_startManualInstall() { - String newEditionKey = randomAlphanumeric(3); - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is MANUAL_IN_PROGRESS (should be any of [NONE])"); - - underTest.newEditionWithoutInstall(newEditionKey); - } - - @Test - public void newEditionWithoutInstall_fails_with_ISE_if_called_after_uninstall() { - String newEditionKey = randomAlphanumeric(3); - underTest.start(); - underTest.newEditionWithoutInstall("foo"); - underTest.uninstall(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is UNINSTALL_IN_PROGRESS (should be any of [NONE])"); - - underTest.newEditionWithoutInstall(newEditionKey); - } - - @Test - public void newEditionWithoutInstall_succeeds_if_called_after_installFailed_and_clear_error_message() { - String newEditionKey = randomAlphanumeric(3); - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(errorMessage); - - PendingStatus newStatus = underTest.newEditionWithoutInstall(newEditionKey); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(newEditionKey); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void finalizeInstallation_fails_with_ISE_if_not_started() { - expectISENotStarted(); - - underTest.finalizeInstallation(nullableErrorMessage); - } - - @Test - public void finalizeInstallation_fails_with_ISE_after_start() { - 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, UNINSTALL_IN_PROGRESS])"); - - underTest.finalizeInstallation(nullableErrorMessage); - } - - @Test - public void finalizeInstallation_fails_with_ISE_after_newEditionWithoutInstall() { - underTest.start(); - 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, UNINSTALL_IN_PROGRESS])"); - - underTest.finalizeInstallation(nullableErrorMessage); - } - - @Test - public void finalizeInstallation_fails_with_ISE_after_startAutomaticInstall() { - underTest.start(); - 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, UNINSTALL_IN_PROGRESS])"); - - underTest.finalizeInstallation(nullableErrorMessage); - } - - @Test - public void finalizeInstallation_set_new_edition_and_clear_pending_fields_after_manualInstallationReady() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.automaticInstallReady(); - - PendingStatus newStatus = underTest.finalizeInstallation(null); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void finalizeInstallation_set_new_edition_and_clear_pending_fields_and_sets_error_message_after_manualInstallationReady() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.automaticInstallReady(); - - PendingStatus newStatus = underTest.finalizeInstallation(errorMessage); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).contains(errorMessage); - } - - @Test - public void finalizeInstallation_set_new_edition_and_clear_pending_fields_after_startManualInstall() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - PendingStatus newStatus = underTest.finalizeInstallation(null); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void finalizeInstallation_set_new_edition_and_clear_pending_fields_and_sets_error_message_after_startManualInstall() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - PendingStatus newStatus = underTest.finalizeInstallation(errorMessage); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).contains(errorMessage); - } - - @Test - public void finalizeInstallation_overwrites_current_edition_and_clear_pending_fields_after_startManualInstall() { - String value = randomAlphanumeric(10); - dbTester.properties().insertInternal("currentEditionKey", value); - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - PendingStatus newStatus = underTest.finalizeInstallation(null); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void finalizeInstallation_overwrites_current_edition_and_clear_pending_fields_and_sets_error_message_after_startManualInstall() { - String value = randomAlphanumeric(10); - dbTester.properties().insertInternal("currentEditionKey", value); - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - PendingStatus newStatus = underTest.finalizeInstallation(errorMessage); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(LICENSE_WITHOUT_PLUGINS.getEditionKey()); - assertThat(underTest.getInstallErrorMessage()).contains(errorMessage); - } - - @Test - public void finalizeInstallation_fails_with_ISE_after_installFailed() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(nullableErrorMessage); - - expectedException.expect(IllegalStateException.class); - 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(nullableErrorMessage); - } - - @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(null); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void finalizeInstallation_set_new_edition_and_clear_pending_fields_and_sets_error_message_after_uninstall() { - underTest.start(); - String value = randomAlphanumeric(10); - underTest.newEditionWithoutInstall(value); - underTest.uninstall(); - - PendingStatus newStatus = underTest.finalizeInstallation(errorMessage); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).contains(errorMessage); - } - - @Test - public void finalizeInstallation_fails_with_ISE_after_finalizeInstallation() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - underTest.finalizeInstallation(nullableErrorMessage); - - expectedException.expect(IllegalStateException.class); - 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(nullableErrorMessage); - } - - @Test - public void installFailed_fails_with_ISE_if_not_started() { - expectISENotStarted(); - - underTest.installFailed(nullableErrorMessage); - } - - @Test - public void installFailed_fails_with_ISE_if_called_after_start() { - underTest.start(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_IN_PROGRESS, MANUAL_IN_PROGRESS])"); - - underTest.installFailed(nullableErrorMessage); - } - - @Test - public void installFailed_after_manualInstall_changes_status_to_NONE_stores_non_null_error_message_and_clear_pending_fields() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - String errorMessage = randomAlphanumeric(4); - - PendingStatus newStatus = underTest.installFailed(errorMessage); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).contains(errorMessage); - } - - @Test - public void installFailed_after_manualInstall_changes_status_to_NONE_without_error_message_and_clear_pending_fields() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - PendingStatus newStatus = underTest.installFailed(null); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void installFailed_after_startAutomaticInstall_changes_status_to_NONE_stores_non_null_error_message_and_clear_pending_fields() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - String errorMessage = randomAlphanumeric(4); - - PendingStatus newStatus = underTest.installFailed(errorMessage); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).contains(errorMessage); - } - - @Test - public void installFailed_after_startAutomaticInstall_changes_status_to_NONE_without_error_message_and_clear_pending_fields() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - PendingStatus newStatus = underTest.installFailed(null); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).isEmpty(); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void installFailed_after_startAutomaticInstall_changes_status_to_NONE_stores_non_null_error_message_and_clear_pending_fields_when_current_install_exists() { - underTest.start(); - String currentEdition = "current-edition"; - underTest.newEditionWithoutInstall(currentEdition); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - String errorMessage = randomAlphanumeric(4); - - PendingStatus newStatus = underTest.installFailed(errorMessage); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(currentEdition); - assertThat(underTest.getInstallErrorMessage()).contains(errorMessage); - } - - @Test - public void installFailed_after_startAutomaticInstall_changes_status_to_NONE_without_error_message_and_clear_pending_fields_when_current_install_exists() { - underTest.start(); - String currentEdition = "current-edition"; - underTest.newEditionWithoutInstall(currentEdition); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - PendingStatus newStatus = underTest.installFailed(null); - - assertThat(newStatus).isEqualTo(NONE); - assertThat(underTest.getPendingInstallationStatus()).isEqualTo(NONE); - assertThat(underTest.getPendingEditionKey()).isEmpty(); - assertThat(underTest.getPendingLicense()).isEmpty(); - assertThat(underTest.getCurrentEditionKey()).contains(currentEdition); - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void installFailed_considers_empty_message_as_no_message() { - underTest.start(); - underTest.newEditionWithoutInstall("current-edition"); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - underTest.installFailed(""); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void installFailed_considers_empty_message_after_trim_as_no_message() { - underTest.start(); - underTest.newEditionWithoutInstall("current-edition"); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - underTest.installFailed(" "); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void installFailed_fails_with_ISE_after_automaticInstallReady() { - underTest.start(); - String currentEdition = "current-edition"; - underTest.newEditionWithoutInstall(currentEdition); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.automaticInstallReady(); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is AUTOMATIC_READY (should be any of [AUTOMATIC_IN_PROGRESS, MANUAL_IN_PROGRESS])"); - - underTest.installFailed(nullableErrorMessage); - } - - @Test - public void installFailed_fails_with_ISE_after_installFailed() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(nullableErrorMessage); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Can't move to NONE when status is NONE (should be any of [AUTOMATIC_IN_PROGRESS, MANUAL_IN_PROGRESS])"); - - underTest.installFailed(nullableErrorMessage); - } - - private void expectISENotStarted() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("StandaloneEditionManagementStateImpl is not started"); - } - - @Test - public void clearInstallErrorMessage_fails_with_ISE_if_not_started() { - expectISENotStarted(); - - underTest.clearInstallErrorMessage(); - } - - @Test - public void clearInstallErrorMessage_succeeds_after_state() { - underTest.start(); - - underTest.clearInstallErrorMessage(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void clearInstallErrorMessage_succeeds_after_manualInstall() { - underTest.start(); - underTest.startManualInstall(LICENSE_WITHOUT_PLUGINS); - - underTest.clearInstallErrorMessage(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void clearInstallErrorMessage_succeeds_after_automaticInstall() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - - underTest.clearInstallErrorMessage(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void clearInstallErrorMessage_succeeds_after_automaticInstallReady() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.automaticInstallReady(); - - underTest.clearInstallErrorMessage(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void clearInstallErrorMessage_succeeds_after_automaticInstallFailed_and_clears_message() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(errorMessage); - - underTest.clearInstallErrorMessage(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void clearInstallErrorMessage_succeeds_after_automaticInstallFailed_without_message() { - underTest.start(); - underTest.startAutomaticInstall(LICENSE_WITHOUT_PLUGINS); - underTest.installFailed(null); - - underTest.clearInstallErrorMessage(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - - @Test - public void clearInstallErrorMessage_succeeds_after_newEditionWithoutInstall() { - underTest.start(); - underTest.newEditionWithoutInstall(randomAlphanumeric(4)); - - underTest.clearInstallErrorMessage(); - - assertThat(underTest.getInstallErrorMessage()).isEmpty(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/ApplyLicenseActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/ws/ApplyLicenseActionTest.java deleted file mode 100644 index 9e3de7f7445..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/ApplyLicenseActionTest.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.io.IOException; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Base64; -import java.util.Optional; -import java.util.Properties; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.edition.EditionManagementState; -import org.sonar.server.edition.EditionManagementState.PendingStatus; -import org.sonar.server.edition.License; -import org.sonar.server.edition.MutableEditionManagementState; -import org.sonar.server.exceptions.BadRequestException; -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; -import org.sonar.server.ws.TestResponse; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.JsonAssert; -import org.sonarqube.ws.MediaTypes; -import org.sonarqube.ws.Editions; -import org.sonarqube.ws.Editions.StatusResponse; - -import static java.util.Collections.singleton; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doThrow; -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; - -@RunWith(DataProviderRunner.class) -public class ApplyLicenseActionTest { - private static final String PARAM_LICENSE = "license"; - private static final String PENDING_EDITION_NAME = "developer-edition"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private EditionInstaller editionInstaller = mock(EditionInstaller.class); - private MutableEditionManagementState mutableEditionManagementState = mock(MutableEditionManagementState.class); - private LicenseCommit licenseCommit = mock(LicenseCommit.class); - private WebServer webServer = mock(WebServer.class); - private ApplyLicenseAction underTest = new ApplyLicenseAction(userSessionRule, mutableEditionManagementState, editionInstaller, - webServer, licenseCommit); - private WsActionTester actionTester = new WsActionTester(underTest); - - @Test - public void verify_definition() { - WebService.Action def = actionTester.getDef(); - - assertThat(def.key()).isEqualTo("apply_license"); - assertThat(def.since()).isEqualTo("6.7"); - assertThat(def.isPost()).isTrue(); - assertThat(def.isInternal()).isFalse(); - assertThat(def.description()).isNotEmpty(); - assertThat(def.params()).hasSize(1); - - WebService.Param licenseParam = def.param("license"); - assertThat(licenseParam.isRequired()).isTrue(); - assertThat(licenseParam.description()).isNotEmpty(); - } - - @Test - public void request_fails_if_user_not_logged_in() { - userSessionRule.anonymous(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(UnauthorizedException.class); - expectedException.expectMessage("Authentication is required"); - - request.execute(); - } - - @Test - public void request_fails_if_user_is_not_system_administer() { - userSessionRule.logIn(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - request.execute(); - } - - @Test - public void request_fails_if_license_param_is_not_provided() { - userSessionRule.logIn().setSystemAdministrator(); - when(mutableEditionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The 'license' parameter is missing"); - - request.execute(); - } - - @Test - @UseDataProvider("notNonePendingInstallationStatuses") - public void request_fails_with_BadRequestException_is_pendingStatus_is_not_NONE(EditionManagementState.PendingStatus notNone) { - userSessionRule.logIn().setSystemAdministrator(); - when(mutableEditionManagementState.getCurrentEditionKey()).thenReturn(Optional.empty()); - when(mutableEditionManagementState.getPendingEditionKey()).thenReturn(Optional.empty()); - when(mutableEditionManagementState.getPendingInstallationStatus()).thenReturn(notNone); - TestRequest request = actionTester.newRequest() - .setParam(PARAM_LICENSE, "foo"); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Can't apply a license when applying one is already in progress"); - - request.execute(); - } - - @Test - public void request_fails_with_BadRequestException_if_license_is_invalid() { - userSessionRule.logIn().setSystemAdministrator(); - TestRequest request = actionTester.newRequest() - .setParam(PARAM_LICENSE, "invalid"); - when(mutableEditionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The license provided 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(); - setPendingLicense(AUTOMATIC_IN_PROGRESS, null); - - TestRequest request = actionTester.newRequest() - .setParam(PARAM_LICENSE, createLicenseParam("dev", "plugin1")); - - JsonAssert.assertJson(request.execute().getInput()).isSimilarTo(actionTester.getDef().responseExampleAsString()); - } - - @Test - public void apply_without_need_to_install() throws IOException { - userSessionRule.logIn().setSystemAdministrator(); - setPendingLicense(NONE); - when(editionInstaller.requiresInstallationChange(singleton("plugin1"))).thenReturn(false); - String base64License = createLicenseParam(PENDING_EDITION_NAME, "plugin1"); - when(webServer.isStandalone()).thenReturn(true); - - TestRequest request = actionTester.newRequest() - .setMediaType(MediaTypes.PROTOBUF) - .setParam(PARAM_LICENSE, base64License); - - TestResponse response = request.execute(); - - assertResponse(response, PENDING_EDITION_NAME, "", NONE); - verify(mutableEditionManagementState).newEditionWithoutInstall(PENDING_EDITION_NAME); - verify(licenseCommit).update(base64License); - } - - @Test - public void execute_throws_BadRequestException_if_license_validation_fails_when_there_is_no_need_to_install() throws IOException { - userSessionRule.logIn().setSystemAdministrator(); - setPendingLicense(NONE, null); - when(editionInstaller.requiresInstallationChange(singleton("plugin1"))).thenReturn(false); - String base64License = createLicenseParam(PENDING_EDITION_NAME, "plugin1"); - TestRequest request = actionTester.newRequest() - .setMediaType(MediaTypes.PROTOBUF) - .setParam(PARAM_LICENSE, base64License); - IllegalArgumentException fakeValidationError = new IllegalArgumentException("Faking failed validation of license on update call"); - doThrow(fakeValidationError) - .when(licenseCommit) - .update(base64License); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(fakeValidationError.getMessage()); - - request.execute(); - } - - @Test - public void apply_offline() throws IOException { - userSessionRule.logIn().setSystemAdministrator(); - setPendingLicense(PendingStatus.MANUAL_IN_PROGRESS); - when(editionInstaller.requiresInstallationChange(singleton("plugin1"))).thenReturn(true); - when(webServer.isStandalone()).thenReturn(true); - - TestRequest request = actionTester.newRequest() - .setMediaType(MediaTypes.PROTOBUF) - .setParam(PARAM_LICENSE, createLicenseParam(PENDING_EDITION_NAME, "plugin1")); - - TestResponse response = request.execute(); - - assertResponse(response, PENDING_EDITION_NAME, "", PendingStatus.MANUAL_IN_PROGRESS); - verify(mutableEditionManagementState, times(0)).startManualInstall(any(License.class)); - verify(mutableEditionManagementState, times(0)).startAutomaticInstall(any(License.class)); - } - - @Test - public void apply_successfully_auto_installation() throws IOException { - userSessionRule.logIn().setSystemAdministrator(); - setPendingLicense(PendingStatus.AUTOMATIC_IN_PROGRESS); - when(editionInstaller.requiresInstallationChange(singleton("plugin1"))).thenReturn(true); - when(webServer.isStandalone()).thenReturn(true); - - TestRequest request = actionTester.newRequest() - .setMediaType(MediaTypes.PROTOBUF) - .setParam(PARAM_LICENSE, createLicenseParam(PENDING_EDITION_NAME, "plugin1")); - - TestResponse response = request.execute(); - - assertResponse(response, PENDING_EDITION_NAME, "", PendingStatus.AUTOMATIC_IN_PROGRESS); - verify(mutableEditionManagementState, times(0)).startAutomaticInstall(any(License.class)); - verify(mutableEditionManagementState, times(0)).startManualInstall(any(License.class)); - } - - @Test - public void returns_auto_install_fails_instantly() throws IOException { - userSessionRule.logIn().setSystemAdministrator(); - String errorMessage = "error! an error!"; - setPendingLicense(PendingStatus.NONE, errorMessage); - when(editionInstaller.requiresInstallationChange(singleton("plugin1"))).thenReturn(true); - when(mutableEditionManagementState.getInstallErrorMessage()).thenReturn(Optional.of(errorMessage)); - - TestRequest request = actionTester.newRequest() - .setMediaType(MediaTypes.PROTOBUF) - .setParam(PARAM_LICENSE, createLicenseParam(PENDING_EDITION_NAME, "plugin1")); - - TestResponse response = request.execute(); - - StatusResponse parsedResponse = Editions.StatusResponse.parseFrom(response.getInputStream()); - assertThat(parsedResponse.getInstallError()).isEqualTo(errorMessage); - } - - private void assertResponse(TestResponse response, String expectedNextEditionKey, String expectedEditionKey, - PendingStatus expectedPendingStatus) throws IOException { - StatusResponse parsedResponse = Editions.StatusResponse.parseFrom(response.getInputStream()); - assertThat(parsedResponse.getCurrentEditionKey()).isEqualTo(expectedEditionKey); - assertThat(parsedResponse.getNextEditionKey()).isEqualTo(expectedNextEditionKey); - assertThat(parsedResponse.getInstallationStatus()).isEqualTo(Editions.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)); - when(mutableEditionManagementState.getPendingInstallationStatus()) - .thenReturn(NONE) - .thenReturn(pendingStatus); - when(mutableEditionManagementState.getInstallErrorMessage()).thenReturn(Optional.ofNullable(errorMessage)); - } - - private static String createLicenseParam(String editionKey, String... pluginKeys) throws IOException { - Properties props = new Properties(); - props.setProperty("Plugins", String.join(",", pluginKeys)); - props.setProperty("Edition", editionKey); - StringWriter writer = new StringWriter(); - props.store(writer, ""); - - byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes()); - return new String(encoded, StandardCharsets.UTF_8); - } - - @DataProvider - public static Object[][] notNonePendingInstallationStatuses() { - return Arrays.stream(EditionManagementState.PendingStatus.values()) - .filter(s -> s != NONE) - .map(s -> new Object[] {s}) - .toArray(Object[][]::new); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/ClearErrorMessageActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/ws/ClearErrorMessageActionTest.java deleted file mode 100644 index c076389650b..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/ClearErrorMessageActionTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.Mockito; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.edition.MutableEditionManagementState; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; - -public class ClearErrorMessageActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private MutableEditionManagementState editionManagementState = Mockito.mock(MutableEditionManagementState.class); - private ClearErrorMessageAction underTest = new ClearErrorMessageAction(userSessionRule, editionManagementState); - private WsActionTester actionTester = new WsActionTester(underTest); - - @Test - public void verify_definition() { - WebService.Action def = actionTester.getDef(); - - assertThat(def.key()).isEqualTo("clear_error_message"); - assertThat(def.since()).isEqualTo("6.7"); - assertThat(def.isPost()).isTrue(); - assertThat(def.isInternal()).isFalse(); - assertThat(def.description()).isNotEmpty(); - assertThat(def.responseExample()).isNull(); - assertThat(def.params()).isEmpty(); - } - - @Test - public void request_fails_if_user_not_logged_in() { - userSessionRule.anonymous(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(UnauthorizedException.class); - expectedException.expectMessage("Authentication is required"); - - request.execute(); - } - - @Test - public void request_fails_if_user_is_not_system_administer() { - userSessionRule.logIn(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - request.execute(); - } - - @Test - public void request_clears_errorMessage_from_editionManagement_state() { - userSessionRule.logIn().setSystemAdministrator(); - - actionTester.newRequest().execute(); - - verify(editionManagementState).clearInstallErrorMessage(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/FormDataActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/ws/FormDataActionTest.java deleted file mode 100644 index 7a6e8e68dbc..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/FormDataActionTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.sonar.api.platform.Server; -import org.sonar.api.server.ws.WebService; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.metric.MetricDto; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; -import org.sonarqube.ws.Editions.FormDataResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY; -import static org.sonar.api.measures.Metric.ValueType.INT; -import static org.sonar.test.JsonAssert.assertJson; - -@RunWith(DataProviderRunner.class) -public class FormDataActionTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public DbTester db = DbTester.create(); - - private Server server = mock(Server.class); - private DbClient dbClient = db.getDbClient(); - private FormDataAction underTest = new FormDataAction(userSessionRule, server, dbClient); - - private WsActionTester ws = new WsActionTester(underTest); - - @Test - public void definition() { - WebService.Action def = ws.getDef(); - - assertThat(def.key()).isEqualTo("form_data"); - assertThat(def.since()).isEqualTo("6.7"); - assertThat(def.isPost()).isFalse(); - assertThat(def.isInternal()).isTrue(); - assertThat(def.description()).isNotEmpty(); - assertThat(def.params()).isEmpty(); - } - - @Test - public void request_fails_if_user_not_logged_in() { - userSessionRule.anonymous(); - TestRequest request = ws.newRequest(); - - expectedException.expect(UnauthorizedException.class); - expectedException.expectMessage("Authentication is required"); - - request.execute(); - } - - @Test - public void request_fails_if_user_is_not_system_administer() { - userSessionRule.logIn(); - TestRequest request = ws.newRequest(); - - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - request.execute(); - } - - @Test - public void json_example() { - userSessionRule.logIn().setSystemAdministrator(); - when(server.getId()).thenReturn("uuid"); - setNcloc(12345L); - - String result = ws.newRequest().execute().getInput(); - - assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString()); - } - - @Test - public void returns_server_id_and_nloc() { - userSessionRule.logIn().setSystemAdministrator(); - when(server.getId()).thenReturn("myserver"); - long ncloc = 256L; - setNcloc(ncloc); - - FormDataResponse expectedResponse = FormDataResponse.newBuilder() - .setServerId("myserver") - .setNcloc(ncloc) - .build(); - - FormDataResponse result = ws.newRequest().executeProtobuf(FormDataResponse.class); - - assertThat(result).isEqualTo(expectedResponse); - } - - private void setNcloc(double ncloc) { - ComponentDto project = db.components().insertMainBranch(); - MetricDto nclocMetric = db.measures().insertMetric(m -> m.setValueType(INT.toString()).setKey(NCLOC_KEY)); - db.measures().insertLiveMeasure(project, nclocMetric, m -> m.setValue(ncloc)); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/PreviewActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/ws/PreviewActionTest.java deleted file mode 100644 index d8501e1f824..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/PreviewActionTest.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.io.IOException; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Base64; -import java.util.Collections; -import java.util.Properties; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.edition.EditionManagementState; -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; -import org.sonar.server.ws.TestResponse; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.JsonAssert; -import org.sonarqube.ws.Editions; -import org.sonarqube.ws.MediaTypes; -import org.sonarqube.ws.Editions.PreviewResponse; -import org.sonarqube.ws.Editions.PreviewStatus; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE; - -@RunWith(DataProviderRunner.class) -public class PreviewActionTest { - private static final String PARAM_LICENSE = "license"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private EditionManagementState editionManagementState = mock(EditionManagementState.class); - private EditionInstaller editionInstaller = mock(EditionInstaller.class); - private WebServer webServer = mock(WebServer.class); - private PreviewAction underTest = new PreviewAction(userSessionRule, editionManagementState, editionInstaller, webServer); - private WsActionTester actionTester = new WsActionTester(underTest); - - @Test - public void verify_definition() { - WebService.Action def = actionTester.getDef(); - - assertThat(def.key()).isEqualTo("preview"); - assertThat(def.since()).isEqualTo("6.7"); - assertThat(def.isPost()).isTrue(); - assertThat(def.isInternal()).isFalse(); - assertThat(def.description()).isNotEmpty(); - assertThat(def.params()).hasSize(1); - - WebService.Param licenseParam = def.param("license"); - assertThat(licenseParam.isRequired()).isTrue(); - assertThat(licenseParam.description()).isNotEmpty(); - } - - @Test - public void request_fails_if_user_not_logged_in() { - userSessionRule.anonymous(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(UnauthorizedException.class); - expectedException.expectMessage("Authentication is required"); - - request.execute(); - } - - @Test - public void request_fails_if_user_is_not_system_administer() { - userSessionRule.logIn(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - request.execute(); - } - - @Test - public void request_fails_if_license_param_is_not_provided() { - userSessionRule.logIn().setSystemAdministrator(); - when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The 'license' parameter is missing"); - - request.execute(); - } - - @Test - public void request_fails_if_license_param_is_empty() { - userSessionRule.logIn().setSystemAdministrator(); - when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - TestRequest request = actionTester.newRequest() - .setParam(PARAM_LICENSE, ""); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("The 'license' parameter is empty"); - - request.execute(); - } - - @Test - public void request_fails_if_license_param_is_invalid() { - userSessionRule.logIn().setSystemAdministrator(); - when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - TestRequest request = actionTester.newRequest() - .setParam(PARAM_LICENSE, "foo"); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The license provided is invalid"); - - request.execute(); - } - - @Test - @UseDataProvider("notNonePendingInstallationStatuses") - public void request_fails_with_BadRequestException_is_pendingStatus_is_not_NONE(EditionManagementState.PendingStatus notNone) { - userSessionRule.logIn().setSystemAdministrator(); - when(editionManagementState.getPendingInstallationStatus()).thenReturn(notNone); - TestRequest request = actionTester.newRequest() - .setParam(PARAM_LICENSE, "foo"); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Can't apply a license when applying one is already in progress"); - - request.execute(); - } - - @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); - - TestRequest request = actionTester.newRequest() - .setParam(PARAM_LICENSE, createLicenseParam("developer-edition", "plugin1")); - - JsonAssert.assertJson(request.execute().getInput()).isSimilarTo(actionTester.getDef().responseExampleAsString()); - } - - @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); - - 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 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); - - TestRequest request = actionTester.newRequest() - .setMediaType(MediaTypes.PROTOBUF) - .setParam(PARAM_LICENSE, createLicenseParam("developer-edition", "plugin1")); - - assertResponse(request.execute(), "developer-edition", PreviewStatus.AUTOMATIC_INSTALL); - } - - @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); - - TestRequest request = actionTester.newRequest() - .setMediaType(MediaTypes.PROTOBUF) - .setParam(PARAM_LICENSE, createLicenseParam("developer-edition", "plugin1")); - - assertResponse(request.execute(), "developer-edition", PreviewStatus.MANUAL_INSTALL); - } - - private void assertResponse(TestResponse response, String expectedNextEditionKey, PreviewStatus expectedPreviewStatus) throws IOException { - PreviewResponse parsedResponse = Editions.PreviewResponse.parseFrom(response.getInputStream()); - assertThat(parsedResponse.getPreviewStatus()).isEqualTo(expectedPreviewStatus); - assertThat(parsedResponse.getNextEditionKey()).isEqualTo(expectedNextEditionKey); - } - - private static String createLicenseParam(String editionKey, String... pluginKeys) throws IOException { - Properties props = new Properties(); - props.setProperty("Plugins", String.join(",", pluginKeys)); - props.setProperty("Edition", editionKey); - StringWriter writer = new StringWriter(); - props.store(writer, ""); - - byte[] encoded = Base64.getEncoder().encode(writer.toString().getBytes()); - return new String(encoded, StandardCharsets.UTF_8); - } - - @DataProvider - public static Object[][] notNonePendingInstallationStatuses() { - return Arrays.stream(EditionManagementState.PendingStatus.values()) - .filter(s -> s != NONE) - .map(s -> new Object[] {s}) - .toArray(Object[][]::new); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/StatusActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/ws/StatusActionTest.java deleted file mode 100644 index 4a88e35f758..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/StatusActionTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.edition.EditionManagementState; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.JsonAssert; - -import static java.util.Optional.empty; -import static java.util.Optional.of; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE; - -public class StatusActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private EditionManagementState editionManagementState = mock(EditionManagementState.class); - private StatusAction underTest = new StatusAction(userSessionRule, editionManagementState); - private WsActionTester actionTester = new WsActionTester(underTest); - - @Test - public void verify_definition() { - WebService.Action def = actionTester.getDef(); - assertThat(def.key()).isEqualTo("status"); - assertThat(def.since()).isEqualTo("6.7"); - assertThat(def.isPost()).isFalse(); - assertThat(def.description()).isNotEmpty(); - assertThat(def.params()).isEmpty(); - } - - @Test - public void request_fails_if_user_not_logged_in() { - userSessionRule.anonymous(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(UnauthorizedException.class); - expectedException.expectMessage("Authentication is required"); - - request.execute(); - } - - @Test - public void request_fails_if_user_is_not_system_administer() { - userSessionRule.logIn(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - request.execute(); - } - - @Test - public void verify_example() { - userSessionRule.logIn().setSystemAdministrator(); - when(editionManagementState.getCurrentEditionKey()).thenReturn(empty()); - when(editionManagementState.getPendingEditionKey()).thenReturn(of("developer-edition")); - when(editionManagementState.getPendingInstallationStatus()).thenReturn(EditionManagementState.PendingStatus.AUTOMATIC_READY); - when(editionManagementState.getInstallErrorMessage()).thenReturn(empty()); - - TestRequest request = actionTester.newRequest(); - - JsonAssert.assertJson(request.execute().getInput()).isSimilarTo(actionTester.getDef().responseExampleAsString()); - } - - @Test - public void response_contains_optional_fields_as_empty_string() { - userSessionRule.logIn().setSystemAdministrator(); - when(editionManagementState.getCurrentEditionKey()).thenReturn(empty()); - when(editionManagementState.getPendingEditionKey()).thenReturn(empty()); - when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - when(editionManagementState.getInstallErrorMessage()).thenReturn(empty()); - - TestRequest request = actionTester.newRequest(); - - JsonAssert.assertJson(request.execute().getInput()) - .isSimilarTo("{" + - " \"currentEditionKey\": \"\"," + - " \"installationStatus\": \"NONE\"," + - " \"nextEditionKey\": \"\"" + - "}"); - } - - @Test - public void response_contains_automaticInstallError_when_present() { - userSessionRule.logIn().setSystemAdministrator(); - when(editionManagementState.getCurrentEditionKey()).thenReturn(empty()); - when(editionManagementState.getPendingEditionKey()).thenReturn(empty()); - when(editionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - String errorMessage = "an error! oh god, an error!"; - when(editionManagementState.getInstallErrorMessage()).thenReturn(of(errorMessage)); - TestRequest request = actionTester.newRequest(); - - JsonAssert.assertJson(request.execute().getInput()) - .isSimilarTo("{" + - " \"currentEditionKey\": \"\"," + - " \"installationStatus\": \"NONE\"," + - " \"nextEditionKey\": \"\"," + - " \"installError\": \"" + errorMessage + "\"" + - "}"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/UninstallActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/ws/UninstallActionTest.java deleted file mode 100644 index b4e42b0a388..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/UninstallActionTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.edition.ws; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.Arrays; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.edition.EditionManagementState; -import org.sonar.server.edition.MutableEditionManagementState; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.plugins.edition.EditionInstaller; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -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.verify; -import static org.mockito.Mockito.when; -import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE; -import static org.sonar.server.edition.EditionManagementState.PendingStatus.UNINSTALL_IN_PROGRESS; - -@RunWith(DataProviderRunner.class) -public class UninstallActionTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private EditionInstaller editionInstaller = mock(EditionInstaller.class); - private MutableEditionManagementState mutableEditionManagementState = mock(MutableEditionManagementState.class); - private UninstallAction action = new UninstallAction(userSessionRule, mutableEditionManagementState, editionInstaller); - private WsActionTester actionTester = new WsActionTester(action); - - @Test - public void check_definition() { - WebService.Action def = actionTester.getDef(); - - assertThat(def.key()).isEqualTo("uninstall"); - assertThat(def.since()).isEqualTo("6.7"); - assertThat(def.isPost()).isTrue(); - assertThat(def.isInternal()).isFalse(); - assertThat(def.responseExampleAsString()).isNull(); - assertThat(def.description()).isNotEmpty(); - assertThat(def.params()).isEmpty(); - } - - @Test - public void request_fails_if_user_not_logged_in() { - userSessionRule.anonymous(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(UnauthorizedException.class); - expectedException.expectMessage("Authentication is required"); - - request.execute(); - } - - @Test - public void request_fails_if_user_is_not_system_administer() { - userSessionRule.logIn(); - TestRequest request = actionTester.newRequest(); - - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - request.execute(); - } - - @Test - @UseDataProvider("notNoneOrUninstallStatuses") - public void request_fails_if_current_status_is_not_none_nor_uninstall(EditionManagementState.PendingStatus notNoneOrUninstall) { - userSessionRule.logIn().setSystemAdministrator(); - when(mutableEditionManagementState.getPendingInstallationStatus()).thenReturn(notNoneOrUninstall); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Uninstall of the current edition is not allowed when install of an edition"); - actionTester.newRequest().execute(); - } - - @Test - public void successful_edition_uninstall() { - userSessionRule.logIn().setSystemAdministrator(); - when(mutableEditionManagementState.getPendingInstallationStatus()).thenReturn(NONE); - - TestResponse execute = actionTester.newRequest().execute(); - assertThat(execute.getStatus()).isEqualTo(204); - verify(editionInstaller).uninstall(); - verify(mutableEditionManagementState).uninstall(); - } - - @Test - public void successful_edition_uninstall_when_state_is_already_uninstall_in_progress() { - userSessionRule.logIn().setSystemAdministrator(); - when(mutableEditionManagementState.getPendingInstallationStatus()).thenReturn(UNINSTALL_IN_PROGRESS); - - TestResponse execute = actionTester.newRequest().execute(); - assertThat(execute.getStatus()).isEqualTo(204); - verify(editionInstaller).uninstall(); - verify(mutableEditionManagementState).uninstall(); - } - - @DataProvider - public static Object[][] notNoneOrUninstallStatuses() { - return Arrays.stream(EditionManagementState.PendingStatus.values()) - .filter(s -> s != NONE) - .filter(s -> s != UNINSTALL_IN_PROGRESS) - .map(s -> new Object[] {s}) - .toArray(Object[][]::new); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionInstallerExecutorTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionInstallerExecutorTest.java deleted file mode 100644 index 151ce2732e1..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionInstallerExecutorTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins.edition; - -import org.junit.Test; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; - -public class EditionInstallerExecutorTest { - @Test - public void execute() { - Runnable r = mock(Runnable.class); - new EditionInstallerExecutor().execute(r); - verify(r, timeout(5000)).run(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionInstallerTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionInstallerTest.java deleted file mode 100644 index 7dcf06d3ca5..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionInstallerTest.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins.edition; - -import com.google.common.base.Optional; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.core.platform.PluginInfo; -import org.sonar.server.edition.License; -import org.sonar.server.edition.MutableEditionManagementState; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.updatecenter.common.UpdateCenter; - -import static java.util.Collections.singleton; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anySetOf; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; -import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; - -public class EditionInstallerTest { - @Rule - public LogTester logTester = new LogTester(); - - private static final String PLUGIN_KEY = "key"; - - private EditionPluginDownloader downloader = mock(EditionPluginDownloader.class); - private EditionPluginUninstaller uninstaller = mock(EditionPluginUninstaller.class); - private UpdateCenterMatrixFactory updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class); - private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class); - private UpdateCenter updateCenter = mock(UpdateCenter.class); - private MutableEditionManagementState editionManagementState = mock(MutableEditionManagementState.class); - - private EditionInstallerExecutor synchronousExecutor = new EditionInstallerExecutor() { - public void execute(Runnable r) { - r.run(); - } - }; - private EditionInstallerExecutor mockedExecutor = mock(EditionInstallerExecutor.class); - - private EditionInstaller underTestSynchronousExecutor = new EditionInstaller(downloader, uninstaller, pluginRepository, synchronousExecutor, updateCenterMatrixFactory, - editionManagementState); - private EditionInstaller underTestMockedExecutor = new EditionInstaller(downloader, uninstaller, pluginRepository, mockedExecutor, updateCenterMatrixFactory, - editionManagementState); - - @Before - public void setUp() { - when(updateCenterMatrixFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter)); - } - - @Test - public void launch_task_download_plugins() { - underTestSynchronousExecutor.install(licenseWithPluginKeys(PLUGIN_KEY)); - - verify(downloader).downloadEditionPlugins(singleton(PLUGIN_KEY), updateCenter); - } - - @Test - public void editionManagementState_is_changed_before_running_background_thread() { - PluginInfo commercial1 = createPluginInfo("p1", true); - PluginInfo commercial2 = createPluginInfo("p2", true); - PluginInfo open1 = createPluginInfo("p3", false); - mockPluginRepository(commercial1, commercial2, open1); - License newLicense = licenseWithPluginKeys("p1", "p4"); - - underTestMockedExecutor.install(newLicense); - - verify(editionManagementState).startAutomaticInstall(newLicense); - verify(editionManagementState, times(0)).automaticInstallReady(); - verifyNoMoreInteractions(editionManagementState); - ArgumentCaptor runnableCaptor = ArgumentCaptor.forClass(Runnable.class); - verify(mockedExecutor).execute(runnableCaptor.capture()); - - reset(editionManagementState); - runnableCaptor.getValue().run(); - - verify(editionManagementState).automaticInstallReady(); - verifyNoMoreInteractions(editionManagementState); - } - - @Test - public void editionManagementState_is_changed_to_automatic_failure_when_read_existing_plugins_fails() { - RuntimeException fakeException = new RuntimeException("Faking getPluginInfosByKeys throwing an exception"); - when(pluginRepository.getPluginInfosByKeys()) - .thenThrow(fakeException); - License newLicense = licenseWithPluginKeys("p1", "p4"); - - underTestSynchronousExecutor.install(newLicense); - - verifyMoveToAutomaticFailureAndLogsError(newLicense, fakeException.getMessage()); - } - - @Test - public void editionManagementState_is_changed_to_automatic_failure_when_downloader_fails() { - PluginInfo commercial1 = createPluginInfo("p1", true); - PluginInfo commercial2 = createPluginInfo("p2", true); - PluginInfo open1 = createPluginInfo("p3", false); - mockPluginRepository(commercial1, commercial2, open1); - RuntimeException fakeException = new RuntimeException("Faking downloadEditionPlugins throwing an exception"); - doThrow(fakeException) - .when(downloader) - .downloadEditionPlugins(anySetOf(String.class), any(UpdateCenter.class)); - License newLicense = licenseWithPluginKeys("p1", "p4"); - - underTestSynchronousExecutor.install(newLicense); - - verifyMoveToAutomaticFailureAndLogsError(newLicense, fakeException.getMessage()); - } - - @Test - public void editionManagementState_is_changed_to_automatic_failure_when_uninstaller_fails() { - PluginInfo commercial1 = createPluginInfo("p1", true); - PluginInfo commercial2 = createPluginInfo("p2", true); - PluginInfo open1 = createPluginInfo("p3", false); - mockPluginRepository(commercial1, commercial2, open1); - RuntimeException fakeException = new RuntimeException("Faking uninstall throwing an exception"); - doThrow(fakeException) - .when(uninstaller) - .uninstall(anyString()); - License newLicense = licenseWithPluginKeys("p1", "p4"); - - underTestSynchronousExecutor.install(newLicense); - - verifyMoveToAutomaticFailureAndLogsError(newLicense, fakeException.getMessage()); - } - - @Test - public void check_plugins_to_install_and_remove() { - PluginInfo commercial1 = createPluginInfo("p1", true); - PluginInfo commercial2 = createPluginInfo("p2", true); - PluginInfo open1 = createPluginInfo("p3", false); - mockPluginRepository(commercial1, commercial2, open1); - License newLicense = licenseWithPluginKeys("p1", "p4"); - - underTestSynchronousExecutor.install(newLicense); - - verify(editionManagementState).startAutomaticInstall(newLicense); - verify(editionManagementState).automaticInstallReady(); - verifyNoMoreInteractions(editionManagementState); - verify(downloader).downloadEditionPlugins(singleton("p4"), updateCenter); - verify(uninstaller).uninstall("p2"); - verifyNoMoreInteractions(uninstaller); - verifyNoMoreInteractions(downloader); - assertThat(logTester.logs()).containsOnly("Installing edition 'edition-key', download: [p4], remove: [p2]"); - - } - - @Test - public void uninstall_commercial_plugins() { - PluginInfo commercial1 = createPluginInfo("p1", true); - PluginInfo commercial2 = createPluginInfo("p2", true); - PluginInfo open1 = createPluginInfo("p3", false); - mockPluginRepository(commercial1, commercial2, open1); - - underTestSynchronousExecutor.uninstall(); - - verify(uninstaller).uninstall("p2"); - verify(uninstaller).uninstall("p1"); - - verifyNoMoreInteractions(uninstaller); - verifyZeroInteractions(downloader); - } - - @Test - public void move_to_manualInstall_state_when_offline() { - mockPluginRepository(createPluginInfo("p1", true)); - synchronousExecutor = mock(EditionInstallerExecutor.class); - when(updateCenterMatrixFactory.getUpdateCenter(true)).thenReturn(Optional.absent()); - underTestSynchronousExecutor = new EditionInstaller(downloader, uninstaller, pluginRepository, synchronousExecutor, updateCenterMatrixFactory, editionManagementState); - License newLicense = licenseWithPluginKeys("p1"); - - underTestSynchronousExecutor.install(newLicense); - - verifyZeroInteractions(synchronousExecutor); - verifyZeroInteractions(uninstaller); - verifyZeroInteractions(downloader); - verify(editionManagementState).startManualInstall(newLicense); - verifyNoMoreInteractions(editionManagementState); - assertThat(logTester.logs()).containsOnly("Installation of edition 'edition-key' needs to be done manually"); - } - - @Test - public void is_offline() { - when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.absent()); - assertThat(underTestSynchronousExecutor.isOffline()).isTrue(); - } - - @Test - public void is_not_offline() { - assertThat(underTestSynchronousExecutor.isOffline()).isFalse(); - } - - @Test - public void requires_installation_change() { - PluginInfo commercial1 = createPluginInfo("p1", true); - PluginInfo commercial2 = createPluginInfo("p2", true); - PluginInfo open1 = createPluginInfo("p3", false); - mockPluginRepository(commercial1, commercial2, open1); - - Set editionPlugins = new HashSet<>(); - editionPlugins.add("p1"); - editionPlugins.add("p4"); - - boolean flag = underTestSynchronousExecutor.requiresInstallationChange(editionPlugins); - - assertThat(flag).isTrue(); - verifyZeroInteractions(downloader); - verifyZeroInteractions(uninstaller); - verifyZeroInteractions(editionManagementState); - } - - @Test - public void does_not_require_installation_change() { - PluginInfo commercial1 = createPluginInfo("p1", true); - PluginInfo commercial2 = createPluginInfo("p2", true); - PluginInfo open1 = createPluginInfo("p3", false); - mockPluginRepository(commercial1, commercial2, open1); - - Set editionPlugins = new HashSet<>(); - editionPlugins.add("p1"); - editionPlugins.add("p2"); - - boolean flag = underTestSynchronousExecutor.requiresInstallationChange(editionPlugins); - - assertThat(flag).isFalse(); - verifyZeroInteractions(downloader); - verifyZeroInteractions(uninstaller); - verifyZeroInteractions(editionManagementState); - } - - private void mockPluginRepository(PluginInfo... installedPlugins) { - Map pluginsByKey = Arrays.stream(installedPlugins).collect(uniqueIndex(PluginInfo::getKey)); - when(pluginRepository.getPluginInfosByKeys()).thenReturn(pluginsByKey); - when(pluginRepository.getPluginInfos()).thenReturn(Arrays.asList(installedPlugins)); - } - - private static PluginInfo createPluginInfo(String pluginKey, boolean commercial) { - PluginInfo info = new PluginInfo(pluginKey); - if (commercial) { - info.setOrganizationName("SonarSource"); - info.setLicense("Commercial"); - } - return info; - } - - private static License licenseWithPluginKeys(String... pluginKeys) { - return new License("edition-key", Arrays.asList(pluginKeys), "foo"); - } - - private void verifyMoveToAutomaticFailureAndLogsError(License newLicense, String expectedErrorMessage) { - verify(editionManagementState).startAutomaticInstall(newLicense); - verify(editionManagementState).installFailed(expectedErrorMessage); - verifyNoMoreInteractions(editionManagementState); - assertThat(logTester.logs(LoggerLevel.ERROR)) - .containsOnly("Failed to install edition " + newLicense.getEditionKey() + " with plugins " + newLicense.getPluginKeys()); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionPluginDownloaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionPluginDownloaderTest.java deleted file mode 100644 index aa725052a85..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionPluginDownloaderTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins.edition; - -import com.google.common.collect.ImmutableList; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collections; -import java.util.List; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.utils.HttpDownloader; -import org.sonar.api.utils.log.LogTester; -import org.sonar.server.platform.ServerFileSystem; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.Release; -import org.sonar.updatecenter.common.UpdateCenter; -import org.sonar.updatecenter.common.Version; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class EditionPluginDownloaderTest { - @Rule - public LogTester logTester = new LogTester(); - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private ServerFileSystem fs = mock(ServerFileSystem.class); - private HttpDownloader httpDownloader = mock(HttpDownloader.class); - private UpdateCenter updateCenter = mock(UpdateCenter.class); - - private File downloadDir; - private File tmpDir; - private EditionPluginDownloader downloader; - - @Before - public void setUp() throws IOException { - downloadDir = temp.newFolder("download"); - tmpDir = new File(downloadDir.getParentFile(), downloadDir.getName() + "_tmp"); - when(fs.getEditionDownloadedPluginsDir()).thenReturn(downloadDir); - downloader = new EditionPluginDownloader(httpDownloader, fs); - } - - @Test - public void download_plugin_to_tmp() throws URISyntaxException { - List releases = ImmutableList.of(createRelease("plugin1", "1.0", "http://host/plugin1.jar"), - createRelease("plugin2", "1.0", "http://host/plugin2.jar")); - - when(updateCenter.findInstallablePlugins("plugins", Version.create(""))).thenReturn(releases); - downloader.downloadEditionPlugins(Collections.singleton("plugins"), updateCenter); - - verify(httpDownloader).download(new URI("http://host/plugin1.jar"), new File(tmpDir, "plugin1.jar")); - verify(httpDownloader).download(new URI("http://host/plugin2.jar"), new File(tmpDir, "plugin2.jar")); - - assertThat(logTester.logs()).containsOnly("Downloading plugin: plugin1", "Downloading plugin: plugin2"); - assertThat(downloadDir).isDirectory(); - assertThat(tmpDir).doesNotExist(); - } - - @Test - public void download_plugin_to_tmp_with_file_uri() throws IOException { - File plugin1 = temp.newFile("plugin1.jar"); - File plugin2 = temp.newFile("plugin2.jar"); - - List releases = ImmutableList.of(createRelease("plugin1", "1.0", plugin1.toURI().toString()), - createRelease("plugin2", "1.0", plugin2.toURI().toString())); - - when(updateCenter.findInstallablePlugins("plugins", Version.create(""))).thenReturn(releases); - downloader.downloadEditionPlugins(Collections.singleton("plugins"), updateCenter); - - assertThat(logTester.logs()).containsOnly("Downloading plugin: plugin1", "Downloading plugin: plugin2"); - assertThat(downloadDir).isDirectory(); - assertThat(tmpDir).doesNotExist(); - } - - @Test - public void dont_write_download_dir_if_download_fails() throws URISyntaxException { - List releases = ImmutableList.of(createRelease("plugin1", "1.0", "http://host/plugin1.jar"), - createRelease("plugin2", "1.0", "http://host/plugin2.jar")); - - doThrow(new IllegalStateException("error")).when(httpDownloader).download(new URI("http://host/plugin1.jar"), new File(tmpDir, "plugin1.jar")); - - when(updateCenter.findInstallablePlugins("plugins", Version.create(""))).thenReturn(releases); - - try { - downloader.downloadEditionPlugins(Collections.singleton("plugins"), updateCenter); - fail("expecting exception"); - } catch (IllegalStateException e) { - - } - - verify(httpDownloader).download(new URI("http://host/plugin1.jar"), new File(tmpDir, "plugin1.jar")); - - assertThat(downloadDir.list()).isEmpty(); - assertThat(tmpDir).doesNotExist(); - } - - private static Release createRelease(String key, String version, String url) { - Release release = mock(Release.class); - when(release.getKey()).thenReturn(key); - when(release.getVersion()).thenReturn(Version.create(version)); - when(release.getDownloadUrl()).thenReturn(url); - when(release.getArtifact()).thenReturn(Plugin.factory(key)); - return release; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionPluginUninstallerTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionPluginUninstallerTest.java deleted file mode 100644 index 8500eeea22b..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionPluginUninstallerTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.plugins.edition; - -import java.io.File; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.server.platform.ServerFileSystem; -import org.sonar.server.plugins.ServerPluginRepository; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -public class EditionPluginUninstallerTest { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Test - public void start_creates_uninstall_directory() { - File dir = new File(temp.getRoot(), "uninstall"); - ServerPluginRepository repo = mock(ServerPluginRepository.class); - ServerFileSystem fs = mock(ServerFileSystem.class); - when(fs.getEditionUninstalledPluginsDir()).thenReturn(dir); - EditionPluginUninstaller uninstaller = new EditionPluginUninstaller(repo, fs); - - uninstaller.start(); - verify(fs).getEditionUninstalledPluginsDir(); - verifyNoMoreInteractions(fs); - assertThat(dir).isDirectory(); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/License.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/License.java deleted file mode 100644 index 614843ebe0b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/License.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.api.config; - -import java.io.IOException; -import java.io.StringReader; -import java.nio.charset.StandardCharsets; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.annotation.Nullable; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.utils.DateUtils; - -/** - * SonarSource license. This class aims to extract metadata but not to validate or - of course - - * to generate license - * - * @since 3.0 - */ -public final class License { - private String product; - private String organization; - private String expirationDate; - private String type; - private String server; - private Map additionalProperties; - - private License(Map properties) { - this.additionalProperties = new HashMap<>(properties); - product = StringUtils.defaultString(get("Product", properties), get("Plugin", properties)); - organization = StringUtils.defaultString(get("Organisation", properties), get("Name", properties)); - expirationDate = StringUtils.defaultString(get("Expiration", properties), get("Expires", properties)); - type = get("Type", properties); - server = get("Server", properties); - // SONAR-4340 Don't expose Digest and Obeo properties - additionalProperties.remove("Digest"); - additionalProperties.remove("Obeo"); - } - - private String get(String key, Map properties) { - additionalProperties.remove(key); - return properties.get(key); - } - - /** - * Get additional properties available on this license (like threshold conditions) - * @since 3.6 - */ - public Map additionalProperties() { - return additionalProperties; - } - - @Nullable - public String getProduct() { - return product; - } - - @Nullable - public String getOrganization() { - return organization; - } - - @Nullable - public String getExpirationDateAsString() { - return expirationDate; - } - - @Nullable - public Date getExpirationDate() { - return DateUtils.parseDateQuietly(expirationDate); - } - - public boolean isExpired() { - return isExpired(new Date()); - } - - boolean isExpired(Date now) { - Date date = getExpirationDate(); - if (date == null) { - return false; - } - // SONAR-6079 include last day - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - cal.add(Calendar.DAY_OF_MONTH, 1); - cal.add(Calendar.SECOND, -1); - return now.after(cal.getTime()); - } - - @Nullable - public String getType() { - return type; - } - - @Nullable - public String getServer() { - return server; - } - - public static License readBase64(String base64) { - return readPlainText(new String(Base64.decodeBase64(base64.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8)); - } - - static License readPlainText(String data) { - Map props = new HashMap<>(); - try { - List lines = IOUtils.readLines(new StringReader(data)); - for (String line : lines) { - if (StringUtils.isNotBlank(line) && line.indexOf(':') > 0) { - String key = StringUtils.substringBefore(line, ":"); - String value = StringUtils.substringAfter(line, ":"); - props.put(StringUtils.trimToEmpty(key), StringUtils.trimToEmpty(value)); - } - } - - } catch (IOException e) { - // silently ignore - } - return new License(props); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/LicenseTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/LicenseTest.java deleted file mode 100644 index 52870e676c2..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/config/LicenseTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.api.config; - -import org.apache.commons.codec.binary.Base64; -import org.junit.Test; -import org.sonar.api.utils.DateUtils; - -import java.util.Calendar; -import java.util.TimeZone; - -import static org.assertj.core.api.Assertions.assertThat; - -public class LicenseTest { - - private static final String V2_FORMAT = "Foo: bar\n" + - "Organisation: ABC \n" + - "Server: 12345 \n" + - "Product: SQALE\n" + - " Expiration: 2012-05-18 \n" + - "Type: EVALUATION \n" + - "Other: field\n"; - - private static final String V1_FORMAT = "Foo: bar\n" + - "Name: ABC \n" + - "Plugin: SQALE\n" + - " Expires: 2012-05-18 \n" + - "Other: field\n" + - "Digest: abcdef\n" + - "Obeo: obeo\n"; - - @Test - public void readPlainTest() { - License license = License.readPlainText(V2_FORMAT); - - assertThat(license.getOrganization()).isEqualTo("ABC"); - assertThat(license.getServer()).isEqualTo("12345"); - assertThat(license.getProduct()).isEqualTo("SQALE"); - assertThat(license.getExpirationDateAsString()).isEqualTo("2012-05-18"); - assertThat(license.getType()).isEqualTo("EVALUATION"); - } - - @Test - public void readPlainText_empty_fields() { - License license = License.readPlainText(""); - - assertThat(license.getOrganization()).isNull(); - assertThat(license.getServer()).isNull(); - assertThat(license.getProduct()).isNull(); - assertThat(license.getExpirationDateAsString()).isNull(); - assertThat(license.getExpirationDate()).isNull(); - assertThat(license.getType()).isNull(); - } - - @Test - public void readPlainText_not_valid_input() { - License license = License.readPlainText("old pond ... a frog leaps in water’s sound"); - - assertThat(license.getOrganization()).isNull(); - assertThat(license.getServer()).isNull(); - assertThat(license.getProduct()).isNull(); - assertThat(license.getExpirationDateAsString()).isNull(); - assertThat(license.getExpirationDate()).isNull(); - assertThat(license.getType()).isNull(); - } - - @Test - public void readPlainTest_version_1() { - License license = License.readPlainText(V1_FORMAT); - - assertThat(license.getOrganization()).isEqualTo("ABC"); - assertThat(license.getServer()).isNull(); - assertThat(license.getProduct()).isEqualTo("SQALE"); - assertThat(license.getExpirationDateAsString()).isEqualTo("2012-05-18"); - assertThat(license.getType()).isNull(); - } - - @Test - public void readBase64() { - License license = License.readBase64(new String(Base64.encodeBase64(V2_FORMAT.getBytes()))); - - assertThat(license.getOrganization()).isEqualTo("ABC"); - assertThat(license.getServer()).isEqualTo("12345"); - assertThat(license.getProduct()).isEqualTo("SQALE"); - assertThat(license.getExpirationDateAsString()).isEqualTo("2012-05-18"); - assertThat(license.getType()).isEqualTo("EVALUATION"); - } - - @Test - public void trimBeforeReadingBase64() { - String encodedKeyWithTrailingWhiteSpaces = "Rm9vOiBiYXIKT3JnYW5pc2F0aW9uOiBBQkMgClNlcnZlcjogMTIzND \n" + - "UgICAKUHJvZHVjdDogU1FBTEUKICBFeHBpcmF0aW9uOiAyMDEyLTA1 \n" + - "LTE4ICAKVHlwZTogIEVWQUxVQVRJT04gICAKT3RoZXI6IGZpZWxkCg==\n"; - - License license = License.readBase64(new String(encodedKeyWithTrailingWhiteSpaces.getBytes())); - - assertThat(license.getOrganization()).isEqualTo("ABC"); - assertThat(license.getServer()).isEqualTo("12345"); - assertThat(license.getProduct()).isEqualTo("SQALE"); - assertThat(license.getExpirationDateAsString()).isEqualTo("2012-05-18"); - assertThat(license.getType()).isEqualTo("EVALUATION"); - } - - @Test - public void readBase64_not_base64() { - License license = License.readBase64("çé '123$@"); - - assertThat(license.getOrganization()).isNull(); - assertThat(license.getServer()).isNull(); - assertThat(license.getProduct()).isNull(); - assertThat(license.getExpirationDateAsString()).isNull(); - assertThat(license.getExpirationDate()).isNull(); - assertThat(license.getType()).isNull(); - } - - @Test - public void isExpired() { - License license = License.readPlainText(V2_FORMAT); - - assertThat(license.isExpired(DateUtils.parseDate("2011-01-01"))).isFalse(); - Calendar sameDay = Calendar.getInstance(TimeZone.getDefault()); - sameDay.setTime(DateUtils.parseDate("2012-05-18")); - assertThat(license.isExpired(sameDay.getTime())).isFalse(); - sameDay.set(Calendar.HOUR_OF_DAY, 15); - assertThat(license.isExpired(sameDay.getTime())).isFalse(); - sameDay.set(Calendar.HOUR_OF_DAY, 23); - sameDay.set(Calendar.MINUTE, 59); - sameDay.set(Calendar.SECOND, 59); - assertThat(license.isExpired(sameDay.getTime())).isFalse(); - // The day after - sameDay.add(Calendar.SECOND, 1); - assertThat(license.isExpired(sameDay.getTime())).isTrue(); - assertThat(license.isExpired(DateUtils.parseDate("2013-06-23"))).isTrue(); - } - - @Test - public void otherProperties() { - License license = License.readPlainText(V2_FORMAT); - - assertThat(license.additionalProperties().get("Other")).isEqualTo("field"); - assertThat(license.additionalProperties().containsKey("Digest")).isFalse(); - assertThat(license.additionalProperties().containsKey("Obeo")).isFalse(); - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java index 4a078808d03..92d59bd34c2 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java @@ -27,7 +27,6 @@ import org.sonarqube.ws.client.ce.CeService; import org.sonarqube.ws.client.components.ComponentsService; import org.sonarqube.ws.client.custommeasures.CustomMeasuresService; import org.sonarqube.ws.client.duplications.DuplicationsService; -import org.sonarqube.ws.client.editions.EditionsService; import org.sonarqube.ws.client.emails.EmailsService; import org.sonarqube.ws.client.favorites.FavoritesService; import org.sonarqube.ws.client.favourites.FavouritesService; @@ -86,7 +85,6 @@ class DefaultWsClient implements WsClient { private final ComponentsService componentsService; private final CustomMeasuresService customMeasuresService; private final DuplicationsService duplicationsService; - private final EditionsService editionsService; private final EmailsService emailsService; private final FavoritesService favoritesService; private final FavouritesService favouritesService; @@ -138,7 +136,6 @@ class DefaultWsClient implements WsClient { this.componentsService = new ComponentsService(wsConnector); this.customMeasuresService = new CustomMeasuresService(wsConnector); this.duplicationsService = new DuplicationsService(wsConnector); - this.editionsService = new EditionsService(wsConnector); this.emailsService = new EmailsService(wsConnector); this.favoritesService = new FavoritesService(wsConnector); this.favouritesService = new FavouritesService(wsConnector); @@ -218,11 +215,6 @@ class DefaultWsClient implements WsClient { return duplicationsService; } - @Override - public EditionsService editions() { - return editionsService; - } - @Override public EmailsService emails() { return emailsService; diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java index 362ee5cdd1b..f31da1069c5 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java @@ -27,7 +27,6 @@ import org.sonarqube.ws.client.ce.CeService; import org.sonarqube.ws.client.components.ComponentsService; import org.sonarqube.ws.client.custommeasures.CustomMeasuresService; import org.sonarqube.ws.client.duplications.DuplicationsService; -import org.sonarqube.ws.client.editions.EditionsService; import org.sonarqube.ws.client.emails.EmailsService; import org.sonarqube.ws.client.favorites.FavoritesService; import org.sonarqube.ws.client.favourites.FavouritesService; @@ -104,8 +103,6 @@ public interface WsClient { DuplicationsService duplications(); - EditionsService editions(); - EmailsService emails(); FavoritesService favorites(); diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/ApplyLicenseRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/ApplyLicenseRequest.java deleted file mode 100644 index 2e9fd99e45b..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/ApplyLicenseRequest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.sonarqube.ws.client.editions; - -import java.util.List; -import javax.annotation.Generated; - -/** - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 6.7 - */ -@Generated("sonar-ws-generator") -public class ApplyLicenseRequest { - - private String license; - - /** - * This is a mandatory parameter. - */ - public ApplyLicenseRequest setLicense(String license) { - this.license = license; - return this; - } - - public String getLicense() { - return license; - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/EditionsService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/EditionsService.java deleted file mode 100644 index f4534276719..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/EditionsService.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.sonarqube.ws.client.editions; - -import java.util.stream.Collectors; -import javax.annotation.Generated; -import org.sonarqube.ws.MediaTypes; -import org.sonarqube.ws.client.BaseService; -import org.sonarqube.ws.client.GetRequest; -import org.sonarqube.ws.client.PostRequest; -import org.sonarqube.ws.client.WsConnector; -import org.sonarqube.ws.Editions.FormDataResponse; -import org.sonarqube.ws.Editions.PreviewResponse; -import org.sonarqube.ws.Editions.StatusResponse; - -/** - * @see Further information about this web service online - */ -@Generated("sonar-ws-generator") -public class EditionsService extends BaseService { - - public EditionsService(WsConnector wsConnector) { - super(wsConnector, "api/editions"); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 6.7 - */ - public String applyLicense(ApplyLicenseRequest request) { - return call( - new PostRequest(path("apply_license")) - .setParam("license", request.getLicense()) - .setMediaType(MediaTypes.JSON) - ).content(); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 6.7 - */ - public void clearErrorMessage() { - call( - new PostRequest(path("clear_error_message")) - .setMediaType(MediaTypes.JSON) - ).content(); - } - - /** - * - * This is part of the internal API. - * This is a GET request. - * @see Further information about this action online (including a response example) - * @since 6.7 - */ - public FormDataResponse formData() { - return call( - new GetRequest(path("form_data")), - FormDataResponse.parser()); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 6.7 - */ - public PreviewResponse preview(PreviewRequest request) { - return call( - new PostRequest(path("preview")) - .setParam("license", request.getLicense()), - PreviewResponse.parser()); - } - - /** - * - * This is part of the internal API. - * This is a GET request. - * @see Further information about this action online (including a response example) - * @since 6.7 - */ - public StatusResponse status() { - return call( - new GetRequest(path("status")), - StatusResponse.parser()); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 6.7 - */ - public void uninstall() { - call( - new PostRequest(path("uninstall")) - .setMediaType(MediaTypes.JSON) - ).content(); - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/PreviewRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/PreviewRequest.java deleted file mode 100644 index 371e63b2da8..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/PreviewRequest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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.sonarqube.ws.client.editions; - -import java.util.List; -import javax.annotation.Generated; - -/** - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 6.7 - */ -@Generated("sonar-ws-generator") -public class PreviewRequest { - - private String license; - - /** - * This is a mandatory parameter. - */ - public PreviewRequest setLicense(String license) { - this.license = license; - return this; - } - - public String getLicense() { - return license; - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/package-info.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/package-info.java deleted file mode 100644 index fead413aafb..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/editions/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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. - */ -@ParametersAreNonnullByDefault -@Generated("sonar-ws-generator") -package org.sonarqube.ws.client.editions; - -import javax.annotation.ParametersAreNonnullByDefault; -import javax.annotation.Generated; - diff --git a/sonar-ws/src/main/protobuf/ws-editions.proto b/sonar-ws/src/main/protobuf/ws-editions.proto deleted file mode 100644 index 87531bb7331..00000000000 --- a/sonar-ws/src/main/protobuf/ws-editions.proto +++ /dev/null @@ -1,60 +0,0 @@ -// SonarQube, open source software quality management tool. -// Copyright (C) 2008-2016 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. - -syntax = "proto2"; - -package sonarqube.ws.editions; - -option java_package = "org.sonarqube.ws"; -option java_outer_classname = "Editions"; -option optimize_for = SPEED; - -// GET api/editions/status -// POST api/editions/apply_license -message StatusResponse { - optional string currentEditionKey = 1; - optional InstallationStatus installationStatus = 2; - optional string nextEditionKey = 3; - optional string installError = 4; -} - -enum InstallationStatus { - NONE = 0; - AUTOMATIC_IN_PROGRESS = 1; - AUTOMATIC_READY = 2; - MANUAL_IN_PROGRESS = 3; - UNINSTALL_IN_PROGRESS = 4; -} - -// POST api/editions/preview -message PreviewResponse { - optional string nextEditionKey = 1; - optional PreviewStatus previewStatus = 2; -} - -enum PreviewStatus { - NO_INSTALL = 0; - AUTOMATIC_INSTALL = 1; - MANUAL_INSTALL = 2; -} - -// POST api/editions/form_data -message FormDataResponse { - optional string serverId = 1; - optional int64 ncloc = 2; -}