use of com.mesosphere.sdk.config.validate.ConfigValidator in project dcos-commons by mesosphere.
the class SchedulerBuilder method getDefaultScheduler.
/**
* Creates a new scheduler instance with the provided values or their defaults.
*
* @return a new scheduler instance
* @throws IllegalArgumentException if config validation failed when updating the target config.
*/
private DefaultScheduler getDefaultScheduler(ServiceSpec serviceSpec, FrameworkStore frameworkStore, StateStore stateStore, ConfigStore<ServiceSpec> configStore) throws ConfigStoreException {
// Determine whether deployment had previously completed BEFORE we update the config.
// Plans may be generated from the config content.
boolean hasCompletedDeployment = StateStoreUtils.getDeploymentWasCompleted(stateStore);
if (!hasCompletedDeployment) {
try {
// Check for completion against the PRIOR service spec. For example, if the new service spec has n+1
// nodes, then we want to check that the prior n nodes had successfully deployed.
ServiceSpec lastServiceSpec = configStore.fetch(configStore.getTargetConfig());
Optional<Plan> deployPlan = getDeployPlan(getPlans(stateStore, configStore, lastServiceSpec, yamlPlans));
if (deployPlan.isPresent() && deployPlan.get().isComplete()) {
logger.info("Marking deployment as having been previously completed");
StateStoreUtils.setDeploymentWasCompleted(stateStore);
hasCompletedDeployment = true;
}
} catch (ConfigStoreException e) {
// This is expected during initial deployment, when there is no prior configuration.
logger.info("Unable to retrieve last configuration. Assuming that no prior deployment has completed");
}
}
// Update/validate config as needed to reflect the new service spec:
Collection<ConfigValidator<ServiceSpec>> configValidators = new ArrayList<>();
configValidators.addAll(DefaultConfigValidators.getValidators(schedulerConfig));
configValidators.addAll(customConfigValidators);
final ConfigurationUpdater.UpdateResult configUpdateResult = updateConfig(serviceSpec, stateStore, configStore, configValidators);
if (!configUpdateResult.getErrors().isEmpty()) {
logger.warn("Failed to update configuration due to validation errors: {}", configUpdateResult.getErrors());
try {
// If there were errors, stick with the last accepted target configuration.
serviceSpec = configStore.fetch(configStore.getTargetConfig());
} catch (ConfigStoreException e) {
// Uh oh. Bail.
logger.error("Failed to retrieve previous target configuration", e);
throw new IllegalArgumentException(e);
}
}
// Now that a ServiceSpec has been chosen, generate the plans.
Collection<Plan> plans = getPlans(stateStore, configStore, serviceSpec, yamlPlans);
plans = selectDeployPlan(plans, hasCompletedDeployment);
Optional<Plan> deployPlan = getDeployPlan(plans);
if (!deployPlan.isPresent()) {
throw new IllegalArgumentException("No deploy plan provided: " + plans);
}
List<String> errors = configUpdateResult.getErrors().stream().map(ConfigValidationError::toString).collect(Collectors.toList());
if (!errors.isEmpty()) {
plans = setDeployPlanErrors(plans, deployPlan.get(), errors);
}
PlanManager deploymentPlanManager = DefaultPlanManager.createProceeding(getDeployPlan(plans).get());
PlanManager recoveryPlanManager = getRecoveryPlanManager(serviceSpec, Optional.ofNullable(recoveryPlanOverriderFactory), stateStore, configStore, plans);
Optional<PlanManager> decommissionPlanManager = getDecommissionPlanManager(serviceSpec, stateStore);
PlanCoordinator planCoordinator = buildPlanCoordinator(serviceSpec.getName(), deploymentPlanManager, recoveryPlanManager, decommissionPlanManager, plans);
return new DefaultScheduler(serviceSpec, FrameworkConfig.fromServiceSpec(serviceSpec), schedulerConfig, namespace, customResources, planCoordinator, Optional.ofNullable(planCustomizer), frameworkStore, stateStore, configStore, templateUrlFactory.orElse(ArtifactResource.getUrlFactory(serviceSpec.getName())), endpointProducers);
}
Aggregations