diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/Orchestrator.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/Orchestrator.java index cfb5406e..0366aefa 100644 --- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/Orchestrator.java +++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/Orchestrator.java @@ -33,6 +33,7 @@ import com.sonar.orchestrator.db.Database; import com.sonar.orchestrator.db.DefaultDatabase; import com.sonar.orchestrator.http.HttpCall; +import com.sonar.orchestrator.http.HttpClientFactory; import com.sonar.orchestrator.http.HttpMethod; import com.sonar.orchestrator.http.HttpResponse; import com.sonar.orchestrator.locator.FileLocation; @@ -48,6 +49,8 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.Nullable; +import okhttp3.HttpUrl; +import org.h2.util.json.JSONValueTarget; import static java.util.Objects.requireNonNull; import static java.util.Optional.ofNullable; @@ -127,6 +130,10 @@ public void start() { if (distribution.isActivateLicense()) { activateLicense(); + } else if (distribution.isActivateOnlineLicense()) { + activateOnlineLicense(); + } else if (distribution.isActivateOfflineLicense()) { + activateOfflineLicense(); } buildRunner = new BuildRunner(config); @@ -142,6 +149,68 @@ public void activateLicense() { configureLicense(license); } + /** + * Set a test license that work for all commercial products using 3rd party service. + */ + private void activateOnlineLicense() { + //String activationCode = licenses.getActivationCode(server.getEdition(), server.version()); + String activationCode = "95AA-2DB4-5JXY-HMSQ"; // Placeholder for actual activation code retrieval logic + JSONValueTarget json = new JSONValueTarget(); + json.startObject(); + json.member("activationCode"); + json.valueString(activationCode); + json.endObject(); + + HttpCall httpCall = server.newHttpCall("api/v2/entitlements/online-activation") + .setMethod(HttpMethod.POST) + .setAdminCredentials() + .setHeader("Content-Type", "application/json") + .setBody(json.getResult().toString()); + + httpCall.execute(); + } + + private void activateOfflineLicense() { + //String activationCode = licenses.getActivationCode(server.getEdition(), server.version()); + String activationCode = "95AA-2DB4-5JXY-HMSQ"; // Placeholder for actual activation code retrieval logic + + HttpCall httpCall = server.newHttpCall("api/v2/entitlements/offline-activation") + .setMethod(HttpMethod.GET) + .setAdminCredentials() + .setHeader("Activation-Code", activationCode); + + HttpResponse execute = httpCall.execute(); + + String body = execute.getBodyAsString(); + + httpCall = server.newHttpCall("api/v2/entitlements/offline-activation") + .setMethod(HttpMethod.GET) + .setAdminCredentials() + .setHeader("Activation-Code", activationCode); + + httpCall = HttpClientFactory.create().newCall(HttpUrl.get("https://saas.licensespring.com/api/v1/offline-license/")) + .setMethod(HttpMethod.GET) + .setHeader("Content-Type", "multipart/form-data") + .setParam() + + JSONValueTarget json = new JSONValueTarget(); + json.startObject(); + json.member("activationCode"); + json.valueString(activationCode); + json.member("activationFile"); + json.valueString(body); + json.endObject(); + + + httpCall = server.newHttpCall("api/v2/entitlements/offline-activation") + .setMethod(HttpMethod.POST) + .setAdminCredentials() + .setHeader("Activation-Code", activationCode) + .setHeader("Content-Type", "application/json") + .setBody(json.getResult().toString()); + + } + /** * Removes the license that have been installed with * {@link OrchestratorBuilder#activateLicense()} diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/OrchestratorBuilder.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/OrchestratorBuilder.java index 6ef38acb..32f0c517 100644 --- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/OrchestratorBuilder.java +++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/OrchestratorBuilder.java @@ -267,6 +267,16 @@ public BUILDER activateLicense() { return (BUILDER) this; } + public BUILDER activateOnlineLicense() { + distribution.activateOnlineLicense(); + return (BUILDER) this; + } + + public BUILDER activateOfflineLicense() { + distribution.activateOfflineLicense(); + return (BUILDER) this; + } + /** * Keeps all bundled plugins */ diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/container/SonarDistribution.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/container/SonarDistribution.java index 2d25f7ba..37925ba7 100644 --- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/container/SonarDistribution.java +++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/container/SonarDistribution.java @@ -41,6 +41,8 @@ public final class SonarDistribution { private final List profileBackups = new ArrayList<>(); private final Properties serverProperties = new Properties(); private boolean activateLicense; + private boolean activateOnlineLicense; + private boolean activateOfflineLicense; private boolean emptySonarProperties = false; private boolean keepBundledPlugins = false; @@ -169,10 +171,23 @@ public SonarDistribution addServerProperties(Properties props) { } public SonarDistribution activateLicense() { + resetLicenseActivationFlags(); activateLicense = true; return this; } + public SonarDistribution activateOnlineLicense() { + resetLicenseActivationFlags(); + activateOnlineLicense = true; + return this; + } + + public SonarDistribution activateOfflineLicense() { + resetLicenseActivationFlags(); + activateOfflineLicense = true; + return this; + } + public SonarDistribution setEdition(Edition edition) { this.edition = edition; return this; @@ -186,6 +201,14 @@ public boolean isActivateLicense() { return activateLicense; } + public boolean isActivateOnlineLicense() { + return activateOnlineLicense; + } + + public boolean isActivateOfflineLicense() { + return activateOfflineLicense; + } + public boolean isKeepBundledPlugins() { return keepBundledPlugins; } @@ -203,4 +226,10 @@ public SonarDistribution addBundledPluginToKeep(String pluginJarNamePrefix) { public Set getBundledPluginNamePrefixesToKeep() { return this.bundledPluginNamePrefixesToKeep; } + + private void resetLicenseActivationFlags() { + activateLicense = false; + activateOnlineLicense = false; + activateOfflineLicense = false; + } } diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/http/HttpCall.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/http/HttpCall.java index 3f6241a4..0d8711a5 100644 --- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/http/HttpCall.java +++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/http/HttpCall.java @@ -25,6 +25,7 @@ import java.net.SocketException; import java.net.SocketTimeoutException; import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -32,12 +33,15 @@ import okhttp3.Credentials; import okhttp3.FormBody; import okhttp3.HttpUrl; +import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; +import okhttp3.RequestBody; import okhttp3.Response; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; +import org.h2.util.json.JSONObject; import static com.sonar.orchestrator.container.Server.ADMIN_LOGIN; import static com.sonar.orchestrator.container.Server.ADMIN_PASSWORD; @@ -55,6 +59,7 @@ public class HttpCall { private HttpMethod method = HttpMethod.GET; private final Map parameters = new LinkedHashMap<>(); private final Map headers = new LinkedHashMap<>(); + private String body; private Long timeoutMs = null; HttpCall(OkHttpClient okClient, HttpUrl baseUrl) { @@ -131,6 +136,12 @@ public HttpCall setTimeoutMs(long timeoutMs) { return this; } + public HttpCall setBody(String body) { + requireNonNull(body, "Body cannot be null"); + this.body = body; + return this; + } + public HttpResponse execute() { Request okRequest = buildOkHttpRequest(); try (Response okResponse = doExecute(okRequest)) { @@ -222,6 +233,9 @@ private Request buildOkHttpRequest() { .filter(e -> e.getValue() != null) .forEach(e -> schwarzy.add(e.getKey(), e.getValue())); okRequest.post(schwarzy.build()); + if (body != null) { + okRequest.setBody$okhttp(RequestBody.create(body, MediaType.parse(headers.get("Content-Type")))); + } break; case MULTIPART_POST: okRequest = new Request.Builder().url(baseUrl);