/** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.airavata.orchestrator.core.validator.impl; import org.apache.airavata.model.appcatalog.computeresource.BatchQueue; import org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription; import org.apache.airavata.model.error.ValidationResults; import org.apache.airavata.model.error.ValidatorResult; import org.apache.airavata.model.experiment.*; import org.apache.airavata.model.process.ProcessModel; import org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel; import org.apache.airavata.orchestrator.core.validator.JobMetadataValidator; import org.apache.airavata.registry.core.experiment.catalog.impl.RegistryFactory; import org.apache.airavata.registry.cpi.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; public class BatchQueueValidator implements JobMetadataValidator { private final static Logger logger = LoggerFactory.getLogger(BatchQueueValidator.class); private AppCatalog appCatalog; public BatchQueueValidator() { try { this.appCatalog = RegistryFactory.getAppCatalog(); } catch (AppCatalogException e) { logger.error("Unable to initialize Application Catalog", e); } } public ValidationResults validate(ExperimentModel experiment, ProcessModel processModel) { ValidationResults validationResults = new ValidationResults(); validationResults.setValidationState(true); try { List<ValidatorResult> validatorResultList = validateUserConfiguration(experiment, processModel); for (ValidatorResult result : validatorResultList){ if (!result.isResult()){ validationResults.setValidationState(false); break; } } validationResults.setValidationResultList(validatorResultList); } catch (AppCatalogException e) { logger.error("Error while validating user configuration", e); } return validationResults; } private List<ValidatorResult> validateUserConfiguration (ExperimentModel experiment, ProcessModel processModel) throws AppCatalogException{ List<ValidatorResult> validatorResultList = new ArrayList<ValidatorResult>(); try { UserConfigurationDataModel userConfigurationData = experiment.getUserConfigurationData(); ComputationalResourceSchedulingModel computationalResourceScheduling = userConfigurationData.getComputationalResourceScheduling(); if (userConfigurationData.isAiravataAutoSchedule()) { logger.info("User enabled Auto-Schedule. Hence we don't do validation.."); ValidatorResult validatorResult = new ValidatorResult(); validatorResult.setResult(true); validatorResultList.add(validatorResult); } else { ComputeResourceDescription computeResource; if (processModel == null) { computeResource = appCatalog.getComputeResource().getComputeResource(experiment.getUserConfigurationData().getComputationalResourceScheduling().getResourceHostId()); } else { computeResource = appCatalog.getComputeResource().getComputeResource(processModel.getProcessResourceSchedule().getResourceHostId()); } List<BatchQueue> batchQueues = computeResource.getBatchQueues(); if (batchQueues != null && !batchQueues.isEmpty()) { if (computationalResourceScheduling != null) { String experimentQueueName = computationalResourceScheduling.getQueueName().trim(); int experimentWallTimeLimit = computationalResourceScheduling.getWallTimeLimit(); int experimentNodeCount = computationalResourceScheduling.getNodeCount(); int experimentCPUCount = computationalResourceScheduling.getTotalCPUCount(); ValidatorResult queueNameResult = new ValidatorResult(); //Set the validation to false. Once all the queue's are looped, if nothing matches, then this gets passed. queueNameResult.setResult(false); queueNameResult.setErrorDetails("The specified queue " + experimentQueueName + " does not exist. If you believe this is an error, contact the administrator to verify App-Catalog Configurations"); for (BatchQueue queue : batchQueues) { String resourceQueueName = queue.getQueueName(); int maxQueueRunTime = queue.getMaxRunTime(); int maxNodeCount = queue.getMaxNodes(); int maxcpuCount = queue.getMaxProcessors(); if (resourceQueueName != null && resourceQueueName.equals(experimentQueueName)) { queueNameResult.setResult(true); queueNameResult.setErrorDetails(""); //Validate if the specified wall time is within allowable limit ValidatorResult wallTimeResult = new ValidatorResult(); if (experimentWallTimeLimit == 0) { wallTimeResult.setResult(false); wallTimeResult.setErrorDetails("Walltime cannot be zero for queue " + resourceQueueName); } else { if (maxQueueRunTime == 0) { wallTimeResult.setResult(true); wallTimeResult.setErrorDetails("Maximum wall time is not configured for the queue," + "Validation is being skipped"); logger.info("Maximum wall time is not configured for the queue" + "Validation is being skipped"); } else { if (maxQueueRunTime < experimentWallTimeLimit) { wallTimeResult.setResult(false); wallTimeResult.setErrorDetails("Job Execution walltime " + experimentWallTimeLimit + "exceeds the allowable walltime" + maxQueueRunTime + "for queue " + resourceQueueName); } else { wallTimeResult.setResult(true); wallTimeResult.setErrorDetails(""); } } } //validate max node count ValidatorResult nodeCountResult = new ValidatorResult(); if (maxNodeCount == 0) { nodeCountResult.setResult(true); nodeCountResult.setErrorDetails("Max node count is not configured for the queue," + "Validation is being skipped"); logger.info("Max node count is not configured for the queue" + "Validation is being skipped"); } else { if (experimentNodeCount == 0) { nodeCountResult.setResult(false); nodeCountResult.setErrorDetails("Job Execution node count cannot be zero for queue " + resourceQueueName); } else { if (maxNodeCount < experimentNodeCount) { nodeCountResult.setResult(false); nodeCountResult.setErrorDetails("Job Execution node count " + experimentNodeCount + "exceeds the allowable node count" + maxNodeCount + "for queue " + resourceQueueName); } else { nodeCountResult.setResult(true); nodeCountResult.setErrorDetails(""); } } } // validate cpu count ValidatorResult cpuCountResult = new ValidatorResult(); if (maxcpuCount == 0) { cpuCountResult.setResult(true); cpuCountResult.setErrorDetails("Max cpu count is not configured for the queue," + "Validation is being skipped"); logger.info("Max cpu count is not configured for the queue" + "Validation is being skipped"); } else { if (experimentCPUCount == 0) { cpuCountResult.setResult(false); cpuCountResult.setErrorDetails("Job Execution cpu count cannot be zero for queue " + resourceQueueName); } else { if (maxcpuCount < experimentCPUCount) { cpuCountResult.setResult(false); cpuCountResult.setErrorDetails("Job Execution cpu count " + experimentCPUCount + "exceeds the allowable cpu count" + maxcpuCount + "for queue " + resourceQueueName); } else { cpuCountResult.setResult(true); cpuCountResult.setErrorDetails(""); } } } validatorResultList.add(wallTimeResult); validatorResultList.add(nodeCountResult); validatorResultList.add(cpuCountResult); } } validatorResultList.add(queueNameResult); } } else { // for some compute resources, you dnt need to specify queue names ValidatorResult result = new ValidatorResult(); logger.info("There are not queues defined under the compute resource. Airavata assumes this experiment " + "does not need a queue name..."); result.setResult(true); validatorResultList.add(result); } } } catch (AppCatalogException e) { logger.error("Error while getting information from App catalog", e); throw new AppCatalogException("Error while getting information from App catalog", e); } return validatorResultList; } }