Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

control-service: job resources validation on job deployment #2793

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@

package com.vmware.taurus.datajobs.it;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.vmware.taurus.ControlplaneApplication;
import com.vmware.taurus.controlplane.model.data.DataJobDeploymentStatus;
import com.vmware.taurus.controlplane.model.data.DataJobMode;
import com.vmware.taurus.controlplane.model.data.DataJobVersion;
import com.vmware.taurus.controlplane.model.data.*;
import com.vmware.taurus.datajobs.it.common.BaseIT;
import com.vmware.taurus.service.deploy.JobImageDeployer;
import com.vmware.taurus.service.model.JobDeploymentStatus;
Expand Down Expand Up @@ -175,6 +174,16 @@ public void testDataJobDeploymentCrud() throws Exception {
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound());

// Execute build and deploy job with job resources
mockMvc
.perform(
post(String.format(
"/data-jobs/for-team/%s/jobs/%s/deployments", TEST_TEAM_NAME, testJobName))
.with(user("user"))
.content(getDataJobDeploymentRequestBodyWithJobResources(testJobVersionSha))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest());

String jobDeploymentName = JobImageDeployer.getCronJobName(testJobName);
// Verify job deployment created
Optional<JobDeploymentStatus> cronJobOptional =
Expand Down Expand Up @@ -386,4 +395,21 @@ public void testDataJobDeleteSource() throws Exception {
.contentType(MediaType.APPLICATION_OCTET_STREAM))
.andExpect(status().isOk());
}

private String getDataJobDeploymentRequestBodyWithJobResources(String jobVersionSha)
throws JsonProcessingException {
var jobDeployment = new com.vmware.taurus.controlplane.model.data.DataJobDeployment();
jobDeployment.setJobVersion(jobVersionSha);
jobDeployment.setMode(DataJobMode.RELEASE);
DataJobResources dataJobResources = new DataJobResources();
dataJobResources.setCpuRequest(100F);
dataJobResources.setCpuLimit(1000F);
dataJobResources.setMemoryRequest(500);
dataJobResources.setMemoryLimit(1000);
jobDeployment.setResources(dataJobResources);
jobDeployment.setSchedule(new DataJobSchedule());
jobDeployment.setId(TEST_JOB_DEPLOYMENT_ID);

return mapper.writeValueAsString(jobDeployment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.vmware.taurus.controlplane.model.data.DataJobDeploymentStatus;
import com.vmware.taurus.controlplane.model.data.DataJobMode;
import com.vmware.taurus.exception.ExternalSystemError;
import com.vmware.taurus.exception.ValidationException;
import com.vmware.taurus.service.JobsService;
import com.vmware.taurus.service.deploy.DataJobDeploymentPropertiesConfig;
import com.vmware.taurus.service.deploy.DataJobDeploymentPropertiesConfig.WriteTo;
Expand Down Expand Up @@ -76,6 +77,7 @@ public ResponseEntity<Void> deploymentDelete(
public ResponseEntity<Void> deploymentPatch(
String teamName, String jobName, String deploymentId, DataJobDeployment dataJobDeployment) {
deploymentService.validatePythonVersionIsSupported(dataJobDeployment.getPythonVersion());
validateJobResources(dataJobDeployment);
if (jobsService.jobWithTeamExists(jobName, teamName)) {
// TODO: deploymentId not implemented
Optional<com.vmware.taurus.service.model.DataJob> job = jobsService.getByName(jobName);
Expand Down Expand Up @@ -132,6 +134,7 @@ public ResponseEntity<Void> deploymentUpdate(
Boolean sendNotification,
DataJobDeployment dataJobDeployment) {
deploymentService.validatePythonVersionIsSupported(dataJobDeployment.getPythonVersion());
validateJobResources(dataJobDeployment);
if (jobsService.jobWithTeamExists(jobName, teamName)) {
Optional<com.vmware.taurus.service.model.DataJob> job =
jobsService.getByName(jobName.toLowerCase());
Expand All @@ -154,4 +157,19 @@ public ResponseEntity<Void> deploymentUpdate(
}
return ResponseEntity.notFound().build();
}

private void validateJobResources(DataJobDeployment dataJobDeployment) {
if (dataJobDeployment != null
&& dataJobDeployment.getResources() != null
&& (dataJobDeployment.getResources().getCpuRequest() != null
|| dataJobDeployment.getResources().getCpuLimit() != null
|| dataJobDeployment.getResources().getMemoryRequest() != null
&& dataJobDeployment.getResources().getMemoryLimit() != null)) {
throw new ValidationException(
"The setting of job resources like CPU and memory is not allowed.",
"The setting of job resources like CPU and memory is not supported by the platform.",
"The deployment of the data job will not proceed.",
"To deploy the data job, please do not configure job resources.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2021-2023 VMware, Inc.
* SPDX-License-Identifier: Apache-2.0
*/

package com.vmware.taurus.exception;

import org.springframework.http.HttpStatus;


public class ValidationException extends DomainError implements UserFacingError {
public ValidationException(String what, String why, String consequences, String countermeasures) {
super(what, why, consequences, countermeasures, null);
}

@Override
public HttpStatus getHttpStatus() {
return HttpStatus.BAD_REQUEST;
}
}