/**
*
* 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.utils;
import java.io.IOException;
import java.util.*;
import org.apache.airavata.common.exception.AiravataException;
import org.apache.airavata.common.exception.ApplicationSettingsException;
import org.apache.airavata.common.utils.ServerSettings;
import org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription;
import org.apache.airavata.model.appcatalog.computeresource.*;
import org.apache.airavata.model.appcatalog.computeresource.JobSubmissionInterface;
import org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission;
import org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference;
import org.apache.airavata.model.appcatalog.gatewayprofile.StoragePreference;
import org.apache.airavata.model.appcatalog.userresourceprofile.UserComputeResourcePreference;
import org.apache.airavata.model.data.movement.DataMovementInterface;
import org.apache.airavata.model.data.movement.DataMovementProtocol;
import org.apache.airavata.model.data.movement.SCPDataMovement;
import org.apache.airavata.model.data.movement.SecurityProtocol;
import org.apache.airavata.model.process.ProcessModel;
import org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel;
import org.apache.airavata.orchestrator.core.OrchestratorConfiguration;
import org.apache.airavata.orchestrator.core.context.OrchestratorContext;
import org.apache.airavata.orchestrator.core.exception.OrchestratorException;
import org.apache.airavata.registry.cpi.*;
import org.apache.airavata.registry.cpi.ApplicationInterface;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This contains orchestrator specific utilities
*/
public class OrchestratorUtils {
private final static Logger logger = LoggerFactory.getLogger(OrchestratorUtils.class);
public static OrchestratorConfiguration loadOrchestratorConfiguration()
throws OrchestratorException, IOException, NumberFormatException, ApplicationSettingsException {
OrchestratorConfiguration orchestratorConfiguration = new OrchestratorConfiguration();
orchestratorConfiguration.setSubmitterInterval(
Integer.parseInt(ServerSettings.getSetting(OrchestratorConstants.SUBMIT_INTERVAL)));
orchestratorConfiguration.setThreadPoolSize(
Integer.parseInt(ServerSettings.getSetting(OrchestratorConstants.THREAD_POOL_SIZE)));
orchestratorConfiguration.setStartSubmitter(
Boolean.valueOf(ServerSettings.getSetting(OrchestratorConstants.START_SUBMITTER)));
orchestratorConfiguration.setEmbeddedMode(
Boolean.valueOf(ServerSettings.getSetting(OrchestratorConstants.EMBEDDED_MODE)));
orchestratorConfiguration.setEnableValidation(
Boolean.valueOf(ServerSettings.getSetting(OrchestratorConstants.ENABLE_VALIDATION)));
if (orchestratorConfiguration.isEnableValidation()) {
orchestratorConfiguration.setValidatorClasses(
Arrays.asList(ServerSettings.getSetting(OrchestratorConstants.JOB_VALIDATOR).split(",")));
}
return orchestratorConfiguration;
}
public static JobSubmissionProtocol getPreferredJobSubmissionProtocol(OrchestratorContext context,
ProcessModel model,
String gatewayId) throws RegistryException {
try {
String resourceHostId = model.getComputeResourceId();
return getComputeResourcePreference(context, gatewayId, resourceHostId).getPreferredJobSubmissionProtocol();
} catch (AppCatalogException e) {
logger.error("Error occurred while initializing app catalog", e);
throw new RegistryException("Error occurred while initializing app catalog", e);
}
}
public static ComputeResourcePreference getComputeResourcePreference(OrchestratorContext context,
String gatewayId,
String resourceHostId)
throws AppCatalogException, RegistryException {
GwyResourceProfile gatewayProfile = getGatewayProfile(context);
return gatewayProfile.getComputeResourcePreference(gatewayId
, resourceHostId);
}
public static GwyResourceProfile getGatewayProfile(OrchestratorContext context)
throws AppCatalogException, RegistryException {
return context.getRegistry().getAppCatalog().getGatewayProfile();
}
public static UsrResourceProfile getUserResourceProfile(OrchestratorContext context)
throws RegistryException, AppCatalogException {
return context.getRegistry().getAppCatalog().getUserResourceProfile();
}
public static String getApplicationInterfaceName(OrchestratorContext context, ProcessModel model)
throws RegistryException {
try {
ApplicationInterface applicationInterface = context.getRegistry().getAppCatalog().getApplicationInterface();
ApplicationInterfaceDescription appInterface =
applicationInterface.getApplicationInterface(model.getApplicationInterfaceId());
return appInterface.getApplicationName();
} catch (AppCatalogException e) {
throw new RegistryException("Error while retrieving application interface", e);
}
}
public static DataMovementProtocol getPreferredDataMovementProtocol(OrchestratorContext context,
ProcessModel model,
String gatewayId) throws RegistryException {
try {
String resourceHostId = model.getComputeResourceId();
return getComputeResourcePreference(context, gatewayId, resourceHostId).getPreferredDataMovementProtocol();
} catch (AppCatalogException e) {
logger.error("Error occurred while initializing app catalog", e);
throw new RegistryException("Error occurred while initializing app catalog", e);
}
}
public static ComputeResourcePreference getComputeResourcePreference(OrchestratorContext context,
ProcessModel processModel,
String gatewayId) throws RegistryException {
try {
return getComputeResourcePreference(context, gatewayId, processModel.getComputeResourceId());
} catch (AppCatalogException e) {
logger.error("Error occurred while initializing app catalog", e);
throw new RegistryException("Error occurred while initializing app catalog", e);
}
}
public static StoragePreference getStoragePreference(OrchestratorContext context,
ProcessModel processModel,
String gatewayId) throws RegistryException {
try {
GwyResourceProfile gatewayProfile = getGatewayProfile(context);
String resourceHostId = processModel.getComputeResourceId();
return gatewayProfile.getStoragePreference(gatewayId, resourceHostId);
} catch (AppCatalogException e) {
logger.error("Error occurred while initializing app catalog", e);
throw new RegistryException("Error occurred while initializing app catalog", e);
}
}
public static String getLoginUserName(OrchestratorContext context,
ProcessModel processModel,
String gatewayId) throws RegistryException, AiravataException {
try {
ComputeResourcePreference computeResourcePreference = getComputeResourcePreference(context, gatewayId,
processModel.getComputeResourceId());
ComputationalResourceSchedulingModel processResourceSchedule = processModel.getProcessResourceSchedule();
if (processModel.isUseUserCRPref()) {
UsrResourceProfile userResourceProfile = getUserResourceProfile(context);
UserComputeResourcePreference userComputeResourcePreference = userResourceProfile
.getUserComputeResourcePreference(processModel.getUserName(), gatewayId,
processModel.getComputeResourceId());
if (isValid(userComputeResourcePreference.getLoginUserName())) {
return userComputeResourcePreference.getLoginUserName();
} else if (isValid(processResourceSchedule.getOverrideLoginUserName())) {
logger.warn("User computer resource preference doesn't have valid user login name, using computer " +
"resource scheduling login name " + processResourceSchedule.getOverrideLoginUserName());
return processResourceSchedule.getOverrideLoginUserName();
} else if (isValid(computeResourcePreference.getLoginUserName())) {
logger.warn("Either User computer resource preference or computer resource scheduling " +
"doesn't have valid user login name, using gateway computer resource preference login name "
+ computeResourcePreference.getLoginUserName());
return computeResourcePreference.getLoginUserName();
}else {
throw new AiravataException("Login name is not found");
}
}else {
if (isValid(processResourceSchedule.getOverrideLoginUserName())) {
return processResourceSchedule.getOverrideLoginUserName();
} else if (isValid(computeResourcePreference.getLoginUserName())) {
logger.warn("Process compute resource scheduling doesn't have valid user login name, " +
"using gateway computer resource preference login name "
+ computeResourcePreference.getLoginUserName());
return computeResourcePreference.getLoginUserName();
}else {
throw new AiravataException("Login name is not found");
}
}
} catch (AppCatalogException e) {
logger.error("Error occurred while initializing app catalog to fetch login username", e);
throw new RegistryException("Error occurred while initializing app catalog to fetch login username", e);
}
}
public static String getScratchLocation(OrchestratorContext context,
ProcessModel processModel,
String gatewayId) throws RegistryException, AiravataException {
try {
ComputeResourcePreference computeResourcePreference = getComputeResourcePreference(context, gatewayId,
processModel.getComputeResourceId());
ComputationalResourceSchedulingModel processResourceSchedule = processModel.getProcessResourceSchedule();
if (processModel.isUseUserCRPref()) {
UsrResourceProfile userResourceProfile = getUserResourceProfile(context);
UserComputeResourcePreference userComputeResourcePreference = userResourceProfile
.getUserComputeResourcePreference(processModel.getUserName(), gatewayId,
processModel.getComputeResourceId());
if (isValid(userComputeResourcePreference.getScratchLocation())) {
return userComputeResourcePreference.getScratchLocation();
} else if (isValid(processResourceSchedule.getOverrideScratchLocation())) {
logger.warn("User computer resource preference doesn't have valid scratch location, using computer " +
"resource scheduling scratch location " + processResourceSchedule.getOverrideScratchLocation());
return processResourceSchedule.getOverrideScratchLocation();
} else if (isValid(computeResourcePreference.getScratchLocation())) {
logger.warn("Either User computer resource preference or computer resource scheduling doesn't have " +
"valid scratch location, using gateway computer resource preference scratch location"
+ computeResourcePreference.getScratchLocation());
return computeResourcePreference.getScratchLocation();
}else {
throw new AiravataException("Scratch location is not found");
}
}else {
if (isValid(processResourceSchedule.getOverrideScratchLocation())) {
return processResourceSchedule.getOverrideScratchLocation();
} else if (isValid(computeResourcePreference.getScratchLocation())) {
logger.warn("Process compute resource scheduling doesn't have valid scratch location, " +
"using gateway computer resource preference scratch location"
+ computeResourcePreference.getScratchLocation());
return computeResourcePreference.getScratchLocation();
}else {
throw new AiravataException("Scratch location is not found");
}
}
} catch (AppCatalogException e) {
logger.error("Error occurred while initializing app catalog to fetch scratch location", e);
throw new RegistryException("Error occurred while initializing app catalog to fetch scratch location", e);
}
}
public static JobSubmissionInterface getPreferredJobSubmissionInterface(OrchestratorContext context,
ProcessModel processModel,
String gatewayId) throws RegistryException {
try {
String resourceHostId = processModel.getComputeResourceId();
ComputeResourcePreference resourcePreference = getComputeResourcePreference(context, processModel, gatewayId);
JobSubmissionProtocol preferredJobSubmissionProtocol = resourcePreference.getPreferredJobSubmissionProtocol();
ComputeResourceDescription resourceDescription =
context.getRegistry().getAppCatalog().getComputeResource().getComputeResource(resourceHostId);
List<JobSubmissionInterface> jobSubmissionInterfaces = resourceDescription.getJobSubmissionInterfaces();
Map<JobSubmissionProtocol, List<JobSubmissionInterface>> orderedInterfaces = new HashMap<>();
List<JobSubmissionInterface> interfaces = new ArrayList<>();
if (jobSubmissionInterfaces != null && !jobSubmissionInterfaces.isEmpty()) {
for (JobSubmissionInterface submissionInterface : jobSubmissionInterfaces){
if (preferredJobSubmissionProtocol != null){
if (preferredJobSubmissionProtocol.toString().equals(submissionInterface.getJobSubmissionProtocol().toString())){
if (orderedInterfaces.containsKey(submissionInterface.getJobSubmissionProtocol())){
List<JobSubmissionInterface> interfaceList = orderedInterfaces.get(submissionInterface.getJobSubmissionProtocol());
interfaceList.add(submissionInterface);
}else {
interfaces.add(submissionInterface);
orderedInterfaces.put(submissionInterface.getJobSubmissionProtocol(), interfaces);
}
}
}else {
Collections.sort(jobSubmissionInterfaces,
(jobSubmissionInterface, jobSubmissionInterface2) ->
jobSubmissionInterface.getPriorityOrder() - jobSubmissionInterface2.getPriorityOrder());
}
}
interfaces = orderedInterfaces.get(preferredJobSubmissionProtocol);
Collections.sort(interfaces, (jobSubmissionInterface, jobSubmissionInterface2) ->
jobSubmissionInterface.getPriorityOrder() - jobSubmissionInterface2.getPriorityOrder());
} else {
throw new RegistryException("Compute resource should have at least one job submission interface defined...");
}
return interfaces.get(0);
} catch (AppCatalogException e) {
throw new RegistryException("Error occurred while retrieving data from app catalog", e);
}
}
public static DataMovementInterface getPrefferredDataMovementInterface(OrchestratorContext context,
ProcessModel processModel,
String gatewayId) throws RegistryException {
try {
String resourceHostId = processModel.getComputeResourceId();
ComputeResourcePreference resourcePreference = getComputeResourcePreference(context, processModel, gatewayId);
DataMovementProtocol preferredDataMovementProtocol = resourcePreference.getPreferredDataMovementProtocol();
ComputeResourceDescription resourceDescription =
context.getRegistry().getAppCatalog().getComputeResource().getComputeResource(resourceHostId);
List<DataMovementInterface> dataMovementInterfaces = resourceDescription.getDataMovementInterfaces();
if (dataMovementInterfaces != null && !dataMovementInterfaces.isEmpty()) {
for (DataMovementInterface dataMovementInterface : dataMovementInterfaces){
if (preferredDataMovementProtocol != null){
if (preferredDataMovementProtocol.toString().equals(dataMovementInterface.getDataMovementProtocol().toString())){
return dataMovementInterface;
}
}
}
} else {
throw new RegistryException("Compute resource should have at least one data movement interface defined...");
}
} catch (AppCatalogException e) {
throw new RegistryException("Error occurred while retrieving data from app catalog", e);
}
return null;
}
public static int getDataMovementPort(OrchestratorContext context,
ProcessModel processModel,
String gatewayId) throws RegistryException{
try {
DataMovementProtocol protocol = getPreferredDataMovementProtocol(context, processModel, gatewayId);
DataMovementInterface dataMovementInterface = getPrefferredDataMovementInterface(context, processModel, gatewayId);
if (protocol == DataMovementProtocol.SCP ) {
SCPDataMovement scpDataMovement = getSCPDataMovement(context, dataMovementInterface.getDataMovementInterfaceId());
if (scpDataMovement != null) {
return scpDataMovement.getSshPort();
}
}
} catch (RegistryException e) {
logger.error("Error occurred while retrieving security protocol", e);
}
return 0;
}
public static SecurityProtocol getSecurityProtocol(OrchestratorContext context,
ProcessModel processModel,
String gatewayId) throws RegistryException{
try {
JobSubmissionProtocol submissionProtocol = getPreferredJobSubmissionProtocol(context, processModel, gatewayId);
JobSubmissionInterface jobSubmissionInterface = getPreferredJobSubmissionInterface(context, processModel, gatewayId);
if (submissionProtocol == JobSubmissionProtocol.SSH ) {
SSHJobSubmission sshJobSubmission = getSSHJobSubmission(context, jobSubmissionInterface.getJobSubmissionInterfaceId());
if (sshJobSubmission != null) {
return sshJobSubmission.getSecurityProtocol();
}
} else if (submissionProtocol == JobSubmissionProtocol.LOCAL) {
LOCALSubmission localJobSubmission = getLocalJobSubmission(context, jobSubmissionInterface.getJobSubmissionInterfaceId());
if (localJobSubmission != null) {
return localJobSubmission.getSecurityProtocol();
}
} else if (submissionProtocol == JobSubmissionProtocol.SSH_FORK){
SSHJobSubmission sshJobSubmission = getSSHJobSubmission(context, jobSubmissionInterface.getJobSubmissionInterfaceId());
if (sshJobSubmission != null) {
return sshJobSubmission.getSecurityProtocol();
}
} else if (submissionProtocol == JobSubmissionProtocol.CLOUD) {
CloudJobSubmission cloudJobSubmission = getCloudJobSubmission(context, jobSubmissionInterface.getJobSubmissionInterfaceId());
if (cloudJobSubmission != null) {
return cloudJobSubmission.getSecurityProtocol();
}
}
} catch (RegistryException e) {
logger.error("Error occurred while retrieving security protocol", e);
}
return null;
}
public static LOCALSubmission getLocalJobSubmission(OrchestratorContext context,
String submissionId) throws RegistryException {
try {
AppCatalog appCatalog = context.getRegistry().getAppCatalog();
return appCatalog.getComputeResource().getLocalJobSubmission(submissionId);
} catch (Exception e) {
String errorMsg = "Error while retrieving local job submission with submission id : " + submissionId;
logger.error(errorMsg, e);
throw new RegistryException(errorMsg, e);
}
}
public static UnicoreJobSubmission getUnicoreJobSubmission(OrchestratorContext context,
String submissionId) throws RegistryException {
try {
AppCatalog appCatalog = context.getRegistry().getAppCatalog();
return appCatalog.getComputeResource().getUNICOREJobSubmission(submissionId);
} catch (Exception e) {
String errorMsg = "Error while retrieving UNICORE job submission with submission id : " + submissionId;
logger.error(errorMsg, e);
throw new RegistryException(errorMsg, e);
}
}
public static SSHJobSubmission getSSHJobSubmission(OrchestratorContext context,
String submissionId) throws RegistryException {
try {
AppCatalog appCatalog = context.getRegistry().getAppCatalog();
return appCatalog.getComputeResource().getSSHJobSubmission(submissionId);
} catch (Exception e) {
String errorMsg = "Error while retrieving SSH job submission with submission id : " + submissionId;
logger.error(errorMsg, e);
throw new RegistryException(errorMsg, e);
}
}
public static CloudJobSubmission getCloudJobSubmission(OrchestratorContext context,
String submissionId) throws RegistryException {
try {
AppCatalog appCatalog = context.getRegistry().getAppCatalog();
return appCatalog.getComputeResource().getCloudJobSubmission(submissionId);
} catch (Exception e) {
String errorMsg = "Error while retrieving SSH job submission with submission id : " + submissionId;
logger.error(errorMsg, e);
throw new RegistryException(errorMsg, e);
}
}
public static SCPDataMovement getSCPDataMovement(OrchestratorContext context,
String dataMoveId) throws RegistryException {
try {
AppCatalog appCatalog = context.getRegistry().getAppCatalog();
return appCatalog.getComputeResource().getSCPDataMovement(dataMoveId);
} catch (Exception e) {
String errorMsg = "Error while retrieving SCP Data movement with submission id : " + dataMoveId;
logger.error(errorMsg, e);
throw new RegistryException(errorMsg, e);
}
}
private static boolean isValid(String str) {
return (str != null && !str.trim().isEmpty());
}
}