use of com.netflix.titus.common.model.sanitizer.ValidationError in project titus-control-plane by Netflix.
the class JobReconciliationFrameworkFactory method validateTask.
private Optional<Task> validateTask(Task task) {
// Perform strict validation for reporting purposes
Set<ValidationError> strictViolations = strictEntitySanitizer.validate(task);
if (!strictViolations.isEmpty()) {
logger.error("No strictly consistent task record found: taskId={}, violations={}", task.getId(), EntitySanitizerUtil.toStringMap(strictViolations));
errorCollector.strictlyInvalidTask(task.getId());
}
// Required checks
Set<ValidationError> violations = permissiveEntitySanitizer.validate(task);
if (!violations.isEmpty()) {
logger.error("Bad task record found: taskId={}, violations={}", task.getId(), EntitySanitizerUtil.toStringMap(violations));
if (jobManagerConfiguration.isFailOnDataValidation()) {
return Optional.empty();
}
}
// If version is missing (old task objects) create one based on the current task state.
Task taskWithVersion = task;
if (task.getVersion() == null || task.getVersion().getTimestamp() < 0) {
Version newVersion = Version.newBuilder().withTimestamp(task.getStatus().getTimestamp()).build();
taskWithVersion = task.toBuilder().withVersion(newVersion).build();
}
return Optional.of(taskWithVersion);
}
use of com.netflix.titus.common.model.sanitizer.ValidationError in project titus-control-plane by Netflix.
the class BasicServiceJobActions method updateJobCapacityAction.
/**
* Update job capacity.
*/
public static TitusChangeAction updateJobCapacityAction(ReconciliationEngine<JobManagerReconcilerEvent> engine, CapacityAttributes capacityAttributes, JobStore jobStore, VersionSupplier versionSupplier, CallMetadata callMetadata, EntitySanitizer entitySanitizer) {
return TitusChangeAction.newAction("updateJobCapacityAction").id(engine.getReferenceView().getId()).trigger(V3JobOperations.Trigger.API).summary("Changing job capacity to: %s", capacityAttributes).callMetadata(callMetadata).changeWithModelUpdates(self -> {
Job<ServiceJobExt> serviceJob = engine.getReferenceView().getEntity();
if (serviceJob.getStatus().getState() != JobState.Accepted) {
return Observable.error(JobManagerException.jobTerminating(serviceJob));
}
Capacity currentCapacity = serviceJob.getJobDescriptor().getExtensions().getCapacity();
Capacity.Builder newCapacityBuilder = currentCapacity.toBuilder();
capacityAttributes.getDesired().ifPresent(newCapacityBuilder::withDesired);
capacityAttributes.getMax().ifPresent(newCapacityBuilder::withMax);
capacityAttributes.getMin().ifPresent(newCapacityBuilder::withMin);
if (capacityAttributes.getDesired().isPresent()) {
newCapacityBuilder.withDesired(capacityAttributes.getDesired().get());
} else {
setDesiredBasedOnMinMax(newCapacityBuilder, currentCapacity, capacityAttributes);
}
Capacity newCapacity = newCapacityBuilder.build();
if (currentCapacity.equals(newCapacity)) {
return Observable.empty();
}
// model validation for capacity
Set<ValidationError> violations = entitySanitizer.validate(newCapacity);
if (!violations.isEmpty()) {
return Observable.error(TitusServiceException.invalidArgument(String.format("Current %s", currentCapacity), violations));
}
// checking if service job processes allow changes to desired capacity
if (isDesiredCapacityInvalid(newCapacity, serviceJob)) {
return Observable.error(JobManagerException.invalidDesiredCapacity(serviceJob.getId(), newCapacity.getDesired(), serviceJob.getJobDescriptor().getExtensions().getServiceJobProcesses()));
}
// append callmetadata job attributes
Job<ServiceJobExt> serviceJobExtCallMetadata = JobFunctions.appendCallMetadataJobAttributes(serviceJob, callMetadata);
// ready to update job capacity
Job<ServiceJobExt> updatedJob = VersionSuppliers.nextVersion(JobFunctions.changeServiceJobCapacity(serviceJobExtCallMetadata, newCapacity), versionSupplier);
TitusModelAction modelAction = TitusModelAction.newModelUpdate(self).jobUpdate(jobHolder -> jobHolder.setEntity(updatedJob));
return jobStore.updateJob(updatedJob).andThen(Observable.just(ModelActionHolder.referenceAndStore(modelAction)));
});
}
use of com.netflix.titus.common.model.sanitizer.ValidationError in project titus-control-plane by Netflix.
the class FailJobValidator method validate.
@Override
public Mono<Set<ValidationError>> validate(JobDescriptor entity) {
final String errorMsg = String.format("%s %s", ERR_DESCRIPTION, UUID.randomUUID().toString());
final ValidationError error = new ValidationError(ERR_FIELD, errorMsg);
return Mono.just(new HashSet<>(Collections.singletonList(error)));
}
use of com.netflix.titus.common.model.sanitizer.ValidationError in project titus-control-plane by Netflix.
the class AggregatingValidatorTest method validateHardSoftTimeout.
// Hard/Soft validation tests
@Test
public void validateHardSoftTimeout() {
AdmissionValidator<JobDescriptor> never0 = new NeverJobValidator(ValidationError.Type.HARD);
AdmissionValidator never1 = new NeverJobValidator(ValidationError.Type.SOFT);
AdmissionValidator validator = new AggregatingValidator(configuration, registry, Arrays.asList(never0, never1));
Mono<Set<ValidationError>> mono = validator.validate(MOCK_JOB);
StepVerifier.create(mono).expectNextMatches(errors -> errors.size() == 2).verifyComplete();
Collection<ValidationError> errors = mono.block();
validateTimeoutErrors(errors);
Collection<ValidationError> hardErrors = errors.stream().filter(error -> error.getType().equals(ValidationError.Type.HARD)).collect(Collectors.toList());
assertThat(hardErrors).hasSize(1);
Collection<ValidationError> softErrors = errors.stream().filter(error -> error.getType().equals(ValidationError.Type.SOFT)).collect(Collectors.toList());
assertThat(softErrors).hasSize(1);
}
use of com.netflix.titus.common.model.sanitizer.ValidationError in project titus-control-plane by Netflix.
the class AggregatingValidatorTest method validateSoftTimeout.
// Soft validation tests
@Test
public void validateSoftTimeout() {
AdmissionValidator never = new NeverJobValidator(ValidationError.Type.SOFT);
AdmissionValidator validator = new AggregatingValidator(configuration, registry, Arrays.asList(never));
Mono<Set<ValidationError>> mono = validator.validate(MOCK_JOB);
StepVerifier.create(mono).expectNextMatches(errors -> errors.size() == 1).verifyComplete();
Collection<ValidationError> errors = mono.block();
validateTimeoutErrors(errors);
validateErrorType(errors, ValidationError.Type.SOFT);
}
Aggregations