Skip to content

Commit

Permalink
Move license handling to LicenseService
Browse files Browse the repository at this point in the history
  • Loading branch information
magaupp committed Dec 29, 2024
1 parent d2c1ba6 commit 6e53045
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 32 deletions.
3 changes: 2 additions & 1 deletion src/main/java/de/tum/cit/aet/artemis/ArtemisApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
import org.springframework.boot.info.GitProperties;
import org.springframework.core.env.Environment;

import de.tum.cit.aet.artemis.core.config.LicenseConfiguration;
import de.tum.cit.aet.artemis.core.config.ProgrammingLanguageConfiguration;
import de.tum.cit.aet.artemis.core.config.TheiaConfiguration;
import tech.jhipster.config.DefaultProfileUtil;
import tech.jhipster.config.JHipsterConstants;

@SpringBootApplication
@EnableConfigurationProperties({ LiquibaseProperties.class, ProgrammingLanguageConfiguration.class, TheiaConfiguration.class })
@EnableConfigurationProperties({ LiquibaseProperties.class, ProgrammingLanguageConfiguration.class, TheiaConfiguration.class, LicenseConfiguration.class })
public class ArtemisApp {

private static final Logger log = LoggerFactory.getLogger(ArtemisApp.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package de.tum.cit.aet.artemis.core.config;

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import jakarta.annotation.Nullable;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Profile;

@Profile(PROFILE_CORE)
@ConfigurationProperties(prefix = "artemis.licenses")
public class LicenseConfiguration {

private final MatLabLicense matlab;

public record MatLabLicense(String licenseServer) {
}

public LicenseConfiguration(MatLabLicense matlab) {
this.matlab = matlab;
}

@Nullable
public String getMatlabLicenseServer() {
if (matlab == null) {
return null;
}
return matlab.licenseServer();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package de.tum.cit.aet.artemis.programming.service;

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import java.util.Map;
import java.util.Objects;

import jakarta.annotation.Nullable;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import de.tum.cit.aet.artemis.core.config.LicenseConfiguration;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage;
import de.tum.cit.aet.artemis.programming.domain.ProjectType;

@Profile(PROFILE_CORE)
@Service
public class LicenseService {

private final LicenseConfiguration licenseConfiguration;

public LicenseService(LicenseConfiguration licenseConfiguration) {
this.licenseConfiguration = licenseConfiguration;
}

public boolean isLicensed(ProgrammingLanguage programmingLanguage, @Nullable ProjectType projectType) {
if (programmingLanguage == ProgrammingLanguage.MATLAB && projectType == null) {
return licenseConfiguration.getMatlabLicenseServer() != null;
}

return true;
}

public Map<String, String> getEnvironment(ProgrammingLanguage programmingLanguage, @Nullable ProjectType projectType) {
if (programmingLanguage == ProgrammingLanguage.MATLAB && projectType == null) {
return Map.of("MLM_LICENSE_FILE", Objects.requireNonNull(licenseConfiguration.getMatlabLicenseServer()));
}

return Map.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

Expand All @@ -21,6 +20,7 @@
import de.tum.cit.aet.artemis.buildagent.dto.DockerRunConfig;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseBuildConfig;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage;
import de.tum.cit.aet.artemis.programming.domain.ProjectType;

@Profile(PROFILE_CORE)
@Service
Expand All @@ -30,8 +30,11 @@ public class ProgrammingExerciseBuildConfigService {

private final ObjectMapper objectMapper = new ObjectMapper();

@Value("${artemis.languages.matlab.license-server}")
private String matlabLicense;
private final LicenseService licenseService;

public ProgrammingExerciseBuildConfigService(LicenseService licenseService) {
this.licenseService = licenseService;
}

/**
* Converts a JSON string representing Docker flags (in JSON format)
Expand All @@ -52,49 +55,55 @@ public class ProgrammingExerciseBuildConfigService {
public DockerRunConfig getDockerRunConfig(ProgrammingExerciseBuildConfig buildConfig) {
DockerFlagsDTO dockerFlagsDTO = parseDockerFlags(buildConfig);

dockerFlagsDTO = addLanguageSpecificEnvironment(dockerFlagsDTO, buildConfig.getProgrammingExercise().getProgrammingLanguage());
String network;
Map<String, String> exerciseEnvironment;
if (dockerFlagsDTO != null) {
network = dockerFlagsDTO.network();
exerciseEnvironment = dockerFlagsDTO.env();
}
else {
network = null;
exerciseEnvironment = null;
}

ProgrammingLanguage programmingLanguage = buildConfig.getProgrammingExercise().getProgrammingLanguage();
ProjectType projectType = buildConfig.getProgrammingExercise().getProjectType();
Map<String, String> environment = addLanguageSpecificEnvironment(exerciseEnvironment, programmingLanguage, projectType);

return getDockerRunConfigFromParsedFlags(dockerFlagsDTO);
return createDockerRunConfig(network, environment);
}

@Nullable
private DockerFlagsDTO addLanguageSpecificEnvironment(DockerFlagsDTO dockerFlagsDTO, ProgrammingLanguage language) {
if (language == ProgrammingLanguage.MATLAB && matlabLicense != null) {
Map<String, String> env;
String network;
if (dockerFlagsDTO != null) {
env = new HashMap<>(dockerFlagsDTO.env());
network = dockerFlagsDTO.network();
}
else {
env = new HashMap<>();
network = null;
}

env.put("MLM_LICENSE_FILE", matlabLicense);
private Map<String, String> addLanguageSpecificEnvironment(@Nullable Map<String, String> exerciseEnvironment, ProgrammingLanguage language, ProjectType projectType) {
Map<String, String> licenseEnvironment = licenseService.getEnvironment(language, projectType);
if (licenseEnvironment.isEmpty()) {
return exerciseEnvironment;
}

dockerFlagsDTO = new DockerFlagsDTO(network, env);
Map<String, String> env = new HashMap<>(licenseEnvironment);
if (exerciseEnvironment != null) {
env.putAll(exerciseEnvironment);
}

return dockerFlagsDTO;
return env;
}

DockerRunConfig getDockerRunConfigFromParsedFlags(DockerFlagsDTO dockerFlagsDTO) {
if (dockerFlagsDTO == null) {
DockerRunConfig createDockerRunConfig(String network, Map<String, String> environmentMap) {
if (network == null && environmentMap == null) {
return null;
}
List<String> env = new ArrayList<>();
boolean isNetworkDisabled = dockerFlagsDTO.network() != null && dockerFlagsDTO.network().equals("none");
List<String> environmentStrings = new ArrayList<>();
boolean isNetworkDisabled = network != null && network.equals("none");

if (dockerFlagsDTO.env() != null) {
for (Map.Entry<String, String> entry : dockerFlagsDTO.env().entrySet()) {
if (environmentMap != null) {
for (Map.Entry<String, String> entry : environmentMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
env.add(key + "=" + value);
environmentStrings.add(key + "=" + value);
}
}

return new DockerRunConfig(isNetworkDisabled, env);
return new DockerRunConfig(isNetworkDisabled, environmentStrings);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ public void validateDockerFlags(ProgrammingExercise programmingExercise) {
}
}

DockerRunConfig dockerRunConfig = programmingExerciseBuildConfigService.getDockerRunConfigFromParsedFlags(dockerFlagsDTO);
DockerRunConfig dockerRunConfig = programmingExerciseBuildConfigService.createDockerRunConfig(dockerFlagsDTO.network(), dockerFlagsDTO.env());

if (List.of(ProgrammingLanguage.SWIFT, ProgrammingLanguage.HASKELL).contains(programmingExercise.getProgrammingLanguage()) && dockerRunConfig.isNetworkDisabled()) {
throw new BadRequestAlertException("This programming language does not support disabling the network access feature", "Exercise", "networkAccessNotSupported");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public TemplateUpgradePolicyService(JavaTemplateUpgradeService javaRepositoryUpg
public TemplateUpgradeService getUpgradeService(ProgrammingLanguage programmingLanguage) {
return switch (programmingLanguage) {
case JAVA -> javaRepositoryUpgradeService;
case KOTLIN, PYTHON, C, HASKELL, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST, JAVASCRIPT, R, C_PLUS_PLUS, TYPESCRIPT, C_SHARP, GO, MATLAB -> defaultRepositoryUpgradeService;
case KOTLIN, PYTHON, C, HASKELL, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST, JAVASCRIPT, R, C_PLUS_PLUS, TYPESCRIPT, C_SHARP, GO, MATLAB ->
defaultRepositoryUpgradeService;
case SQL, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> throw new UnsupportedOperationException("Unsupported programming language: " + programmingLanguage);
};
}
Expand Down

0 comments on commit 6e53045

Please sign in to comment.