Java tutorial
/** * * 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.gfac.core; import org.apache.airavata.common.exception.ApplicationSettingsException; import org.apache.airavata.common.utils.*; import org.apache.airavata.credential.store.store.CredentialReader; import org.apache.airavata.credential.store.store.impl.CredentialReaderImpl; import org.apache.airavata.gfac.core.context.ProcessContext; import org.apache.airavata.gfac.core.context.TaskContext; import org.apache.airavata.messaging.core.MessageContext; import org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription; import org.apache.airavata.model.appcatalog.appdeployment.CommandObject; import org.apache.airavata.model.appcatalog.computeresource.*; import org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference; import org.apache.airavata.model.application.io.DataType; import org.apache.airavata.model.application.io.InputDataObjectType; import org.apache.airavata.model.application.io.OutputDataObjectType; import org.apache.airavata.model.commons.ErrorModel; import org.apache.airavata.model.data.replica.*; import org.apache.airavata.model.experiment.ExperimentModel; import org.apache.airavata.model.job.JobModel; import org.apache.airavata.model.messaging.event.*; import org.apache.airavata.model.parallelism.ApplicationParallelismType; import org.apache.airavata.model.process.ProcessModel; import org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel; import org.apache.airavata.model.status.*; import org.apache.airavata.model.task.JobSubmissionTaskModel; import org.apache.airavata.registry.core.experiment.catalog.impl.RegistryFactory; import org.apache.airavata.registry.cpi.*; import org.apache.airavata.registry.cpi.utils.Constants; import org.apache.commons.io.FileUtils; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.utils.ZKPaths; import org.apache.thrift.TException; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.data.ACL; import org.apache.zookeeper.data.Stat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.transform.*; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import javax.xml.xpath.*; import java.io.*; import java.net.InetAddress; import java.net.URISyntaxException; import java.net.URL; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.security.SecureRandom; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; //import org.apache.airavata.commons.gfac.type.ActualParameter; public class GFacUtils { private final static Logger log = LoggerFactory.getLogger(GFacUtils.class); public static final ArrayList<ACL> OPEN_ACL_UNSAFE = ZooDefs.Ids.OPEN_ACL_UNSAFE; private GFacUtils() { } /** * Read data from inputStream and convert it to String. * * @param in * @return String read from inputStream * @throws java.io.IOException */ public static String readFromStream(InputStream in) throws IOException { try { StringBuffer wsdlStr = new StringBuffer(); int read; byte[] buf = new byte[1024]; while ((read = in.read(buf)) > 0) { wsdlStr.append(new String(buf, 0, read)); } return wsdlStr.toString(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { log.warn("Cannot close InputStream: " + in.getClass().getName(), e); } } } } /** * This will read * * @param maxWalltime * @return */ public static String maxWallTimeCalculator(int maxWalltime) { if (maxWalltime < 60) { return "00:" + maxWalltime + ":00"; } else { int minutes = maxWalltime % 60; int hours = maxWalltime / 60; return hours + ":" + minutes + ":00"; } } public static String maxWallTimeCalculatorForLSF(int maxWalltime) { if (maxWalltime < 60) { return "00:" + maxWalltime; } else { int minutes = maxWalltime % 60; int hours = maxWalltime / 60; return hours + ":" + minutes; } } public static String readFileToString(String file) throws FileNotFoundException, IOException { BufferedReader instream = null; try { instream = new BufferedReader(new FileReader(file)); StringBuffer buff = new StringBuffer(); String temp = null; while ((temp = instream.readLine()) != null) { buff.append(temp); buff.append(GFacConstants.NEWLINE); } return buff.toString(); } finally { if (instream != null) { try { instream.close(); } catch (IOException e) { log.warn("Cannot close FileinputStream", e); } } } } public static boolean isLocalHost(String appHost) throws UnknownHostException { String localHost = InetAddress.getLocalHost().getCanonicalHostName(); return (localHost.equals(appHost) || GFacConstants.LOCALHOST.equals(appHost) || GFacConstants._127_0_0_1.equals(appHost)); } public static String createUniqueNameWithDate(String name) { String date = new Date().toString(); date = date.replaceAll(" ", "_"); date = date.replaceAll(":", "_"); return name + "_" + date; } public static List<Element> getElementList(Document doc, String expression) throws XPathExpressionException { XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); XPathExpression expr = xPath.compile(expression); NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); List<Element> elementList = new ArrayList<Element>(); for (int i = 0; i < nodeList.getLength(); i++) { Node item = nodeList.item(i); if (item instanceof Element) { elementList.add((Element) item); } } return elementList; } public static String createGsiftpURIAsString(String host, String localPath) throws URISyntaxException { StringBuffer buf = new StringBuffer(); if (!host.startsWith("gsiftp://")) buf.append("gsiftp://"); buf.append(host); if (!host.endsWith("/")) buf.append("/"); buf.append(localPath); return buf.toString(); } public static void saveJobStatus(ProcessContext processContext, JobModel jobModel) throws GFacException { try { // first we save job jobModel to the registry for sa and then save the job status. JobStatus jobStatus = jobModel.getJobStatus(); ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); jobModel.setJobStatus(jobStatus); if (jobStatus.getTimeOfStateChange() == 0 || jobStatus.getTimeOfStateChange() > 0) { jobStatus.setTimeOfStateChange(AiravataUtils.getCurrentTimestamp().getTime()); } else { jobStatus.setTimeOfStateChange(jobStatus.getTimeOfStateChange()); } CompositeIdentifier ids = new CompositeIdentifier(jobModel.getTaskId(), jobModel.getJobId()); experimentCatalog.add(ExpCatChildDataType.JOB_STATUS, jobStatus, ids); JobIdentifier identifier = new JobIdentifier(jobModel.getJobId(), jobModel.getTaskId(), processContext.getProcessId(), processContext.getProcessModel().getExperimentId(), processContext.getGatewayId()); JobStatusChangeEvent jobStatusChangeEvent = new JobStatusChangeEvent(jobStatus.getJobState(), identifier); MessageContext msgCtx = new MessageContext(jobStatusChangeEvent, MessageType.JOB, AiravataUtils.getId(MessageType.JOB.name()), processContext.getGatewayId()); msgCtx.setUpdatedTime(AiravataUtils.getCurrentTimestamp()); processContext.getStatusPublisher().publish(msgCtx); } catch (Exception e) { throw new GFacException("Error persisting job status" + e.getLocalizedMessage(), e); } } public static void saveAndPublishTaskStatus(TaskContext taskContext) throws GFacException { try { TaskState state = taskContext.getTaskState(); // first we save job jobModel to the registry for sa and then save the job status. ProcessContext processContext = taskContext.getParentProcessContext(); ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); TaskStatus status = taskContext.getTaskStatus(); if (status.getTimeOfStateChange() == 0 || status.getTimeOfStateChange() > 0) { status.setTimeOfStateChange(AiravataUtils.getCurrentTimestamp().getTime()); } else { status.setTimeOfStateChange(status.getTimeOfStateChange()); } experimentCatalog.add(ExpCatChildDataType.TASK_STATUS, status, taskContext.getTaskId()); TaskIdentifier identifier = new TaskIdentifier(taskContext.getTaskId(), processContext.getProcessId(), processContext.getProcessModel().getExperimentId(), processContext.getGatewayId()); TaskStatusChangeEvent taskStatusChangeEvent = new TaskStatusChangeEvent(state, identifier); MessageContext msgCtx = new MessageContext(taskStatusChangeEvent, MessageType.TASK, AiravataUtils.getId(MessageType.TASK.name()), taskContext.getParentProcessContext().getGatewayId()); msgCtx.setUpdatedTime(AiravataUtils.getCurrentTimestamp()); processContext.getStatusPublisher().publish(msgCtx); } catch (Exception e) { throw new GFacException("Error persisting task status" + e.getLocalizedMessage(), e); } } public static void saveAndPublishProcessStatus(ProcessContext processContext) throws GFacException { try { // first we save job jobModel to the registry for sa and then save the job status. ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); ProcessStatus status = processContext.getProcessStatus(); if (status.getTimeOfStateChange() == 0 || status.getTimeOfStateChange() > 0) { status.setTimeOfStateChange(AiravataUtils.getCurrentTimestamp().getTime()); } else { status.setTimeOfStateChange(status.getTimeOfStateChange()); } experimentCatalog.add(ExpCatChildDataType.PROCESS_STATUS, status, processContext.getProcessId()); ProcessIdentifier identifier = new ProcessIdentifier(processContext.getProcessId(), processContext.getProcessModel().getExperimentId(), processContext.getGatewayId()); ProcessStatusChangeEvent processStatusChangeEvent = new ProcessStatusChangeEvent(status.getState(), identifier); MessageContext msgCtx = new MessageContext(processStatusChangeEvent, MessageType.PROCESS, AiravataUtils.getId(MessageType.PROCESS.name()), processContext.getGatewayId()); msgCtx.setUpdatedTime(AiravataUtils.getCurrentTimestamp()); processContext.getStatusPublisher().publish(msgCtx); } catch (Exception e) { throw new GFacException("Error persisting process status" + e.getLocalizedMessage(), e); } } private static void removeCancelDeliveryTagNode(String experimentPath, CuratorFramework curatorClient) throws Exception { Stat exists = curatorClient.checkExists() .forPath(experimentPath + AiravataZKUtils.CANCEL_DELIVERY_TAG_POSTFIX); if (exists != null) { ZKPaths.deleteChildren(curatorClient.getZookeeperClient().getZooKeeper(), experimentPath + AiravataZKUtils.CANCEL_DELIVERY_TAG_POSTFIX, true); } } private static void copyChildren(CuratorFramework curatorClient, String oldPath, String newPath, int depth) throws Exception { for (String childNode : curatorClient.getChildren().forPath(oldPath)) { String oldChildPath = oldPath + File.separator + childNode; Stat stat = curatorClient.checkExists().forPath(oldChildPath); // no need to check exists String newChildPath = newPath + File.separator + childNode; log.info("Creating new znode: " + newChildPath); curatorClient.create().withMode(CreateMode.PERSISTENT).withACL(OPEN_ACL_UNSAFE).forPath(newChildPath, curatorClient.getData().storingStatIn(stat).forPath(oldChildPath)); if (--depth > 0) { copyChildren(curatorClient, oldChildPath, newChildPath, depth); } } } // Fixme - remove this method. with new changes we don't need to use this method. public static boolean setExperimentCancelRequest(String processId, CuratorFramework curatorClient, long deliveryTag) throws Exception { String experimentNode = ZKPaths.makePath(ZkConstants.ZOOKEEPER_EXPERIMENT_NODE, processId); String cancelListenerNodePath = ZKPaths.makePath(experimentNode, ZkConstants.ZOOKEEPER_CANCEL_LISTENER_NODE); curatorClient.setData().withVersion(-1).forPath(cancelListenerNodePath, ZkConstants.ZOOKEEPER_CANCEL_REQEUST.getBytes()); return true; } public static CredentialReader getCredentialReader() throws ApplicationSettingsException, IllegalAccessException, InstantiationException { try { String jdbcUrl = ServerSettings.getCredentialStoreDBURL(); String jdbcUsr = ServerSettings.getCredentialStoreDBUser(); String jdbcPass = ServerSettings.getCredentialStoreDBPassword(); String driver = ServerSettings.getCredentialStoreDBDriver(); return new CredentialReaderImpl(new DBUtil(jdbcUrl, jdbcUsr, jdbcPass, driver)); } catch (ClassNotFoundException e) { log.error("Not able to find driver: " + e.getLocalizedMessage()); return null; } } public static LOCALSubmission getLocalJobSubmission(String submissionId) throws AppCatalogException { try { AppCatalog appCatalog = RegistryFactory.getAppCatalog(); return appCatalog.getComputeResource().getLocalJobSubmission(submissionId); } catch (Exception e) { String errorMsg = "Error while retrieving local job submission with submission id : " + submissionId; log.error(errorMsg, e); throw new AppCatalogException(errorMsg, e); } } public static UnicoreJobSubmission getUnicoreJobSubmission(String submissionId) throws AppCatalogException { try { AppCatalog appCatalog = RegistryFactory.getAppCatalog(); return appCatalog.getComputeResource().getUNICOREJobSubmission(submissionId); } catch (Exception e) { String errorMsg = "Error while retrieving UNICORE job submission with submission id : " + submissionId; log.error(errorMsg, e); throw new AppCatalogException(errorMsg, e); } } public static SSHJobSubmission getSSHJobSubmission(String submissionId) throws AppCatalogException { try { AppCatalog appCatalog = RegistryFactory.getAppCatalog(); return appCatalog.getComputeResource().getSSHJobSubmission(submissionId); } catch (Exception e) { String errorMsg = "Error while retrieving SSH job submission with submission id : " + submissionId; log.error(errorMsg, e); throw new AppCatalogException(errorMsg, e); } } /** * To convert list to separated value * * @param listOfStrings * @param separator * @return */ public static String listToCsv(List<String> listOfStrings, char separator) { StringBuilder sb = new StringBuilder(); // all but last for (int i = 0; i < listOfStrings.size() - 1; i++) { sb.append(listOfStrings.get(i)); sb.append(separator); } // last string, no separator if (listOfStrings.size() > 0) { sb.append(listOfStrings.get(listOfStrings.size() - 1)); } return sb.toString(); } public static byte[] longToBytes(long x) { ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.putLong(x); return buffer.array(); } public static long bytesToLong(byte[] bytes) { ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.put(bytes); buffer.flip();//need flip return buffer.getLong(); } public static String getZKGfacServersParentPath() { return ZKPaths.makePath(ZkConstants.ZOOKEEPER_SERVERS_NODE, ZkConstants.ZOOKEEPER_GFAC_SERVER_NODE); } public static JobDescriptor createJobDescriptor(ProcessContext processContext, TaskContext taskContext) throws GFacException, AppCatalogException, ApplicationSettingsException { JobDescriptor jobDescriptor = new JobDescriptor(); String emailIds = null; ProcessModel processModel = processContext.getProcessModel(); ResourceJobManager resourceJobManager = getResourceJobManager(processContext); if (isEmailBasedJobMonitor(processContext)) { emailIds = ServerSettings.getEmailBasedMonitorAddress(); } if (ServerSettings.getSetting(ServerSettings.JOB_NOTIFICATION_ENABLE).equalsIgnoreCase("true")) { String flags = ServerSettings.getSetting(ServerSettings.JOB_NOTIFICATION_FLAGS); if (flags != null && processContext.getComputeResourceDescription().getHostName() .equals("stampede.tacc.xsede.org")) { flags = "ALL"; } jobDescriptor.setMailOptions(flags); String userJobNotifEmailIds = ServerSettings.getSetting(ServerSettings.JOB_NOTIFICATION_EMAILIDS); if (userJobNotifEmailIds != null && !userJobNotifEmailIds.isEmpty()) { if (emailIds != null && !emailIds.isEmpty()) { emailIds += ("," + userJobNotifEmailIds); } else { emailIds = userJobNotifEmailIds; } } if (processModel.isEnableEmailNotification()) { List<String> emailList = processModel.getEmailAddresses(); String elist = GFacUtils.listToCsv(emailList, ','); if (elist != null && !elist.isEmpty()) { if (emailIds != null && !emailIds.isEmpty()) { emailIds = emailIds + "," + elist; } else { emailIds = elist; } } } } if (emailIds != null && !emailIds.isEmpty()) { log.info("Email list: " + emailIds); jobDescriptor.setMailAddress(emailIds); } jobDescriptor.setInputDirectory(processContext.getInputDir()); jobDescriptor.setOutputDirectory(processContext.getOutputDir()); jobDescriptor.setExecutablePath(processContext.getApplicationDeploymentDescription().getExecutablePath()); jobDescriptor.setStandardOutFile(processContext.getStdoutLocation()); jobDescriptor.setStandardErrorFile(processContext.getStderrLocation()); ComputeResourcePreference crp = getComputeResourcePreference(processContext); if (crp.getAllocationProjectNumber() != null) { jobDescriptor.setAcountString(crp.getAllocationProjectNumber()); } if (crp.getQualityOfService() != null) { // qos per queue jobDescriptor.setQoS(getQoS(crp.getQualityOfService(), crp.getPreferredBatchQueue())); } jobDescriptor.setReservation(crp.getReservation()); // To make job name alpha numeric jobDescriptor.setJobName("A" + String.valueOf(generateJobName())); jobDescriptor.setWorkingDirectory(processContext.getWorkingDir()); List<String> inputValues = new ArrayList<String>(); List<InputDataObjectType> processInputs = processModel.getProcessInputs(); if (processInputs != null) { // sort the inputs first and then build the command ListR Comparator<InputDataObjectType> inputOrderComparator = new Comparator<InputDataObjectType>() { @Override public int compare(InputDataObjectType inputDataObjectType, InputDataObjectType t1) { return inputDataObjectType.getInputOrder() - t1.getInputOrder(); } }; Set<InputDataObjectType> sortedInputSet = new TreeSet<InputDataObjectType>(inputOrderComparator); for (InputDataObjectType input : processInputs) { sortedInputSet.add(input); } for (InputDataObjectType inputDataObjectType : sortedInputSet) { if (!inputDataObjectType.isRequiredToAddedToCommandLine()) { continue; } if (inputDataObjectType.getApplicationArgument() != null && !inputDataObjectType.getApplicationArgument().equals("")) { inputValues.add(inputDataObjectType.getApplicationArgument()); } if (inputDataObjectType.getValue() != null && !inputDataObjectType.getValue().equals("")) { if (inputDataObjectType.getType() == DataType.URI) { // set only the relative path String filePath = inputDataObjectType.getValue(); filePath = filePath.substring(filePath.lastIndexOf(File.separatorChar) + 1, filePath.length()); inputValues.add(filePath); } else if (inputDataObjectType.getType() == DataType.URI_COLLECTION) { String filePaths = inputDataObjectType.getValue(); String[] paths = filePaths.split(GFacConstants.MULTIPLE_INPUTS_SPLITTER); String filePath; String inputs = ""; int i = 0; for (; i < paths.length - 1; i++) { filePath = paths[i]; filePath = filePath.substring(filePath.lastIndexOf(File.separatorChar) + 1, filePath.length()); // File names separate by a space inputs += filePath + " "; } inputs += paths[i]; inputValues.add(inputs); } else { inputValues.add(inputDataObjectType.getValue()); } } } } List<OutputDataObjectType> processOutputs = processModel.getProcessOutputs(); if (processOutputs != null) { for (OutputDataObjectType output : processOutputs) { if (output.getApplicationArgument() != null && !output.getApplicationArgument().equals("")) { inputValues.add(output.getApplicationArgument()); } if (output.getValue() != null && !output.getValue().equals("") && output.isRequiredToAddedToCommandLine()) { if (output.getType() == DataType.URI) { String filePath = output.getValue(); filePath = filePath.substring(filePath.lastIndexOf(File.separatorChar) + 1, filePath.length()); inputValues.add(filePath); } } } } jobDescriptor.setInputValues(inputValues); jobDescriptor.setUserName(processContext.getJobSubmissionRemoteCluster().getServerInfo().getUserName()); jobDescriptor.setShellName("/bin/bash"); jobDescriptor.setAllEnvExport(true); jobDescriptor.setOwner(processContext.getJobSubmissionRemoteCluster().getServerInfo().getUserName()); // get walltime try { JobSubmissionTaskModel jobSubmissionTaskModel = ((JobSubmissionTaskModel) taskContext .getSubTaskModel()); if (jobSubmissionTaskModel.getWallTime() > 0) { jobDescriptor.setMaxWallTime(jobSubmissionTaskModel.getWallTime() + ""); } } catch (TException e) { log.error("Error while getting job submissiont sub task model", e); } ComputationalResourceSchedulingModel scheduling = processModel.getResourceSchedule(); if (scheduling != null) { int totalNodeCount = scheduling.getNodeCount(); int totalCPUCount = scheduling.getTotalCPUCount(); if (scheduling.getQueueName() != null) { jobDescriptor.setQueueName(scheduling.getQueueName()); } if (totalNodeCount > 0) { jobDescriptor.setNodes(totalNodeCount); } if (scheduling.getQueueName() != null) { jobDescriptor.setQueueName(scheduling.getQueueName()); } if (totalCPUCount > 0) { int ppn = totalCPUCount / totalNodeCount; jobDescriptor.setProcessesPerNode(ppn); jobDescriptor.setCPUCount(totalCPUCount); } // max wall time may be set before this level if jobsubmission task has wall time configured to this job, // if so we ignore scheduling configuration. if (scheduling.getWallTimeLimit() > 0 && jobDescriptor.getMaxWallTime() == null) { jobDescriptor.setMaxWallTime(String.valueOf(scheduling.getWallTimeLimit())); if (resourceJobManager != null) { if (resourceJobManager.getResourceJobManagerType().equals(ResourceJobManagerType.LSF)) { jobDescriptor.setMaxWallTimeForLSF(String.valueOf(scheduling.getWallTimeLimit())); } } } if (scheduling.getTotalPhysicalMemory() > 0) { jobDescriptor.setUsedMemory(scheduling.getTotalPhysicalMemory() + ""); } } else { log.error("Task scheduling cannot be null at this point.."); } ApplicationDeploymentDescription appDepDescription = processContext.getApplicationDeploymentDescription(); List<CommandObject> moduleCmds = appDepDescription.getModuleLoadCmds(); if (moduleCmds != null) { Collections.sort(moduleCmds, (o1, o2) -> ((CommandObject) o1).getCommandOrder() - ((CommandObject) o2).getCommandOrder()); for (CommandObject moduleCmd : moduleCmds) { jobDescriptor.addModuleLoadCommands(moduleCmd.getCommand()); } } List<CommandObject> preJobCommands = appDepDescription.getPreJobCommands(); if (preJobCommands != null) { Collections.sort(preJobCommands, (o1, o2) -> ((CommandObject) o1).getCommandOrder() - ((CommandObject) o2).getCommandOrder()); for (CommandObject preJobCommand : preJobCommands) { jobDescriptor.addPreJobCommand(parseCommand(preJobCommand.getCommand(), processContext)); } } List<CommandObject> postJobCommands = appDepDescription.getPostJobCommands(); if (postJobCommands != null) { Collections.sort(postJobCommands, (o1, o2) -> ((CommandObject) o1).getCommandOrder() - ((CommandObject) o2).getCommandOrder()); for (CommandObject postJobCommand : postJobCommands) { jobDescriptor.addPostJobCommand(parseCommand(postJobCommand.getCommand(), processContext)); } } ApplicationParallelismType parallelism = appDepDescription.getParallelism(); Map<ApplicationParallelismType, String> parallelismPrefix = processContext.getResourceJobManager() .getParallelismPrefix(); if (parallelism != null) { if (parallelism != ApplicationParallelismType.SERIAL) { if (parallelismPrefix != null) { String parallelismCommand = parallelismPrefix.get(parallelism); if (parallelismCommand != null) { jobDescriptor.setJobSubmitter(parallelismCommand); } else { throw new GFacException("Parallelism prefix is not defined for given parallelism type " + parallelism + ".. Please define the parallelism prefix at App Catalog"); } } } } return jobDescriptor; } private static String getQoS(String qualityOfService, String preferredBatchQueue) { final String qos = "qos"; Pattern pattern = Pattern.compile(preferredBatchQueue + "=(?<" + qos + ">[^,]*)"); Matcher matcher = pattern.matcher(qualityOfService); if (matcher.matches()) { return matcher.group(qos); } return null; } private static int generateJobName() { Random random = new Random(); int i = random.nextInt(Integer.MAX_VALUE); i = i + 99999999; if (i < 0) { i = i * (-1); } return i; } private static String parseCommand(String value, ProcessContext context) { String parsedValue = value.replaceAll("\\$workingDir", context.getWorkingDir()); parsedValue = parsedValue.replaceAll("\\$inputDir", context.getInputDir()); parsedValue = parsedValue.replaceAll("\\$outputDir", context.getOutputDir()); return parsedValue; } public static ResourceJobManager getResourceJobManager(ProcessContext processContext) { try { JobSubmissionProtocol submissionProtocol = getPreferredJobSubmissionProtocol(processContext); JobSubmissionInterface jobSubmissionInterface = getPreferredJobSubmissionInterface(processContext); if (submissionProtocol == JobSubmissionProtocol.SSH) { SSHJobSubmission sshJobSubmission = GFacUtils .getSSHJobSubmission(jobSubmissionInterface.getJobSubmissionInterfaceId()); if (sshJobSubmission != null) { return sshJobSubmission.getResourceJobManager(); } } else if (submissionProtocol == JobSubmissionProtocol.LOCAL) { LOCALSubmission localJobSubmission = GFacUtils .getLocalJobSubmission(jobSubmissionInterface.getJobSubmissionInterfaceId()); if (localJobSubmission != null) { return localJobSubmission.getResourceJobManager(); } } else if (submissionProtocol == JobSubmissionProtocol.SSH_FORK) { SSHJobSubmission sshJobSubmission = GFacUtils .getSSHJobSubmission(jobSubmissionInterface.getJobSubmissionInterfaceId()); if (sshJobSubmission != null) { return sshJobSubmission.getResourceJobManager(); } } } catch (AppCatalogException e) { log.error("Error occured while retrieving resource job manager", e); } return null; } public static boolean isEmailBasedJobMonitor(ProcessContext processContext) throws GFacException, AppCatalogException { JobSubmissionProtocol jobSubmissionProtocol = getPreferredJobSubmissionProtocol(processContext); JobSubmissionInterface jobSubmissionInterface = getPreferredJobSubmissionInterface(processContext); if (jobSubmissionProtocol == JobSubmissionProtocol.SSH) { String jobSubmissionInterfaceId = jobSubmissionInterface.getJobSubmissionInterfaceId(); SSHJobSubmission sshJobSubmission = processContext.getAppCatalog().getComputeResource() .getSSHJobSubmission(jobSubmissionInterfaceId); MonitorMode monitorMode = sshJobSubmission.getMonitorMode(); return monitorMode != null && monitorMode == MonitorMode.JOB_EMAIL_NOTIFICATION_MONITOR; } else { return false; } } public static JobSubmissionInterface getPreferredJobSubmissionInterface(ProcessContext context) throws AppCatalogException { try { String resourceHostId = context.getComputeResourceDescription().getComputeResourceId(); ComputeResourcePreference resourcePreference = context.getComputeResourcePreference(); JobSubmissionProtocol preferredJobSubmissionProtocol = resourcePreference .getPreferredJobSubmissionProtocol(); ComputeResourceDescription resourceDescription = context.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, new Comparator<JobSubmissionInterface>() { @Override public int compare(JobSubmissionInterface jobSubmissionInterface, JobSubmissionInterface jobSubmissionInterface2) { return jobSubmissionInterface.getPriorityOrder() - jobSubmissionInterface2.getPriorityOrder(); } }); } } interfaces = orderedInterfaces.get(preferredJobSubmissionProtocol); Collections.sort(interfaces, new Comparator<JobSubmissionInterface>() { @Override public int compare(JobSubmissionInterface jobSubmissionInterface, JobSubmissionInterface jobSubmissionInterface2) { return jobSubmissionInterface.getPriorityOrder() - jobSubmissionInterface2.getPriorityOrder(); } }); } else { throw new AppCatalogException( "Compute resource should have at least one job submission interface defined..."); } return interfaces.get(0); } catch (AppCatalogException e) { throw new AppCatalogException("Error occurred while retrieving data from app catalog", e); } } public static JobSubmissionProtocol getPreferredJobSubmissionProtocol(ProcessContext context) throws AppCatalogException { try { GwyResourceProfile gatewayProfile = context.getAppCatalog().getGatewayProfile(); String resourceHostId = context.getComputeResourceDescription().getComputeResourceId(); ComputeResourcePreference preference = gatewayProfile .getComputeResourcePreference(context.getGatewayId(), resourceHostId); return preference.getPreferredJobSubmissionProtocol(); } catch (AppCatalogException e) { log.error("Error occurred while initializing app catalog", e); throw new AppCatalogException("Error occurred while initializing app catalog", e); } } public static ComputeResourcePreference getComputeResourcePreference(ProcessContext context) throws AppCatalogException { try { GwyResourceProfile gatewayProfile = context.getAppCatalog().getGatewayProfile(); String resourceHostId = context.getComputeResourceDescription().getComputeResourceId(); return gatewayProfile.getComputeResourcePreference(context.getGatewayId(), resourceHostId); } catch (AppCatalogException e) { log.error("Error occurred while initializing app catalog", e); throw new AppCatalogException("Error occurred while initializing app catalog", e); } } public static File createJobFile(TaskContext taskContext, JobDescriptor jobDescriptor, JobManagerConfiguration jobManagerConfiguration) throws GFacException { try { TransformerFactory factory = TransformerFactory.newInstance(); URL resource = GFacUtils.class.getClassLoader() .getResource(jobManagerConfiguration.getJobDescriptionTemplateName()); if (resource == null) { String error = "System configuration file '" + jobManagerConfiguration.getJobDescriptionTemplateName() + "' not found in the classpath"; throw new GFacException(error); } Source xslt = new StreamSource(new File(resource.getPath())); Transformer transformer; StringWriter results = new StringWriter(); File tempJobFile = null; // generate the pbs script using xslt transformer = factory.newTransformer(xslt); Source text = new StreamSource(new ByteArrayInputStream(jobDescriptor.toXML().getBytes())); transformer.transform(text, new StreamResult(results)); String scriptContent = results.toString().replaceAll("^[ |\t]*\n$", ""); if (scriptContent.startsWith("\n")) { scriptContent = scriptContent.substring(1); } // creating a temporary file using pbs script generated above int number = new SecureRandom().nextInt(); number = (number < 0 ? -number : number); tempJobFile = new File(GFacUtils.getLocalDataDir(taskContext), "job_" + Integer.toString(number) + jobManagerConfiguration.getScriptExtension()); FileUtils.writeStringToFile(tempJobFile, scriptContent); return tempJobFile; } catch (IOException e) { throw new GFacException("Error occurred while creating the temp job script file", e); } catch (TransformerConfigurationException e) { throw new GFacException("Error occurred while creating the temp job script file", e); } catch (TransformerException e) { throw new GFacException("Error occurred while creating the temp job script file", e); } } public static File getLocalDataDir(TaskContext taskContext) { String outputPath = ServerSettings.getLocalDataLocation(); outputPath = (outputPath.endsWith(File.separator) ? outputPath : outputPath + File.separator); return new File(outputPath + taskContext.getParentProcessContext().getProcessId()); } public static String getExperimentNodePath(String experimentId) { return ZKPaths.makePath(ZkConstants.ZOOKEEPER_EXPERIMENT_NODE, experimentId); } public static long getProcessDeliveryTag(CuratorFramework curatorClient, String experimentId, String processId) throws Exception { String deliveryTagPath = ZKPaths.makePath(ZKPaths.makePath(getExperimentNodePath(experimentId), processId), ZkConstants.ZOOKEEPER_DELIVERYTAG_NODE); Stat stat = curatorClient.checkExists().forPath(deliveryTagPath); if (stat != null) { byte[] bytes = curatorClient.getData().forPath(deliveryTagPath); return GFacUtils.bytesToLong(bytes); } else { throw new GFacException("Couldn't fine the deliveryTag path: " + deliveryTagPath); } } public static void saveJobModel(ProcessContext processContext, JobModel jobModel) throws GFacException { try { ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); experimentCatalog.add(ExpCatChildDataType.JOB, jobModel, processContext.getProcessId()); } catch (RegistryException e) { String msg = "expId: " + processContext.getExperimentId() + " processId: " + processContext.getProcessId() + " jobId: " + jobModel.getJobId() + " : - Error while saving Job Model"; throw new GFacException(msg, e); } } public static void saveExperimentInput(ProcessContext processContext, String inputName, String inputVal) throws GFacException { try { ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); String experimentId = processContext.getExperimentId(); ExperimentModel experiment = (ExperimentModel) experimentCatalog .get(ExperimentCatalogModelType.EXPERIMENT, experimentId); List<InputDataObjectType> experimentInputs = experiment.getExperimentInputs(); if (experimentInputs != null && !experimentInputs.isEmpty()) { for (InputDataObjectType expInput : experimentInputs) { if (expInput.getName().equals(inputName)) { expInput.setValue(inputVal); } } } experimentCatalog.update(ExperimentCatalogModelType.EXPERIMENT, experiment, experimentId); } catch (RegistryException e) { String msg = "expId: " + processContext.getExperimentId() + " processId: " + processContext.getProcessId() + " : - Error while updating experiment inputs"; throw new GFacException(msg, e); } } public static void saveProcessInput(ProcessContext processContext, String inputName, String inputVal) throws GFacException { try { ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); String processId = processContext.getProcessId(); ProcessModel processModel = (ProcessModel) experimentCatalog.get(ExperimentCatalogModelType.PROCESS, processId); List<InputDataObjectType> processInputs = processModel.getProcessInputs(); if (processInputs != null && !processInputs.isEmpty()) { for (InputDataObjectType processInput : processInputs) { if (processInput.getName().equals(inputName)) { processInput.setValue(inputVal); } } } experimentCatalog.update(ExperimentCatalogModelType.PROCESS, processModel, processId); } catch (RegistryException e) { String msg = "expId: " + processContext.getExperimentId() + " processId: " + processContext.getProcessId() + " : - Error while updating experiment inputs"; throw new GFacException(msg, e); } } public static void saveExperimentOutput(ProcessContext processContext, String outputName, String outputVal) throws GFacException { try { ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); String experimentId = processContext.getExperimentId(); ExperimentModel experiment = (ExperimentModel) experimentCatalog .get(ExperimentCatalogModelType.EXPERIMENT, experimentId); List<OutputDataObjectType> experimentOutputs = experiment.getExperimentOutputs(); if (experimentOutputs != null && !experimentOutputs.isEmpty()) { for (OutputDataObjectType expOutput : experimentOutputs) { if (expOutput.getName().equals(outputName)) { DataProductModel dataProductModel = new DataProductModel(); dataProductModel.setGatewayId(processContext.getGatewayId()); dataProductModel.setOwnerName(processContext.getProcessModel().getUserName()); dataProductModel.setProductName(outputName); dataProductModel.setDataProductType(DataProductType.FILE); DataReplicaLocationModel replicaLocationModel = new DataReplicaLocationModel(); replicaLocationModel .setStorageResourceId(processContext.getStorageResource().getStorageResourceId()); replicaLocationModel.setReplicaName(outputName + " gateway data store copy"); replicaLocationModel.setReplicaLocationCategory(ReplicaLocationCategory.GATEWAY_DATA_STORE); replicaLocationModel.setReplicaPersistentType(ReplicaPersistentType.TRANSIENT); replicaLocationModel.setFilePath(outputVal); dataProductModel.addToReplicaLocations(replicaLocationModel); ReplicaCatalog replicaCatalog = RegistryFactory.getReplicaCatalog(); String productUri = replicaCatalog.registerDataProduct(dataProductModel); expOutput.setValue(productUri); } } } experimentCatalog.update(ExperimentCatalogModelType.EXPERIMENT, experiment, experimentId); } catch (RegistryException e) { String msg = "expId: " + processContext.getExperimentId() + " processId: " + processContext.getProcessId() + " : - Error while updating experiment outputs"; throw new GFacException(msg, e); } } public static void saveProcessOutput(ProcessContext processContext, String outputName, String outputVal) throws GFacException { try { ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); String processId = processContext.getProcessId(); List<OutputDataObjectType> processOutputs = (List<OutputDataObjectType>) experimentCatalog .get(ExperimentCatalogModelType.PROCESS_OUTPUT, processId); if (processOutputs != null && !processOutputs.isEmpty()) { for (OutputDataObjectType processOutput : processOutputs) { if (processOutput.getName().equals(outputName)) { processOutput.setValue(outputVal); } } } ProcessModel processModel = processContext.getProcessModel(); processModel.setProcessOutputs(processOutputs); experimentCatalog.update(ExperimentCatalogModelType.PROCESS, processModel, processId); } catch (RegistryException e) { String msg = "expId: " + processContext.getExperimentId() + " processId: " + processContext.getProcessId() + " : - Error while updating experiment outputs"; throw new GFacException(msg, e); } } public static void saveExperimentError(ProcessContext processContext, ErrorModel errorModel) throws GFacException { try { ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); String experimentId = processContext.getExperimentId(); errorModel.setErrorId(AiravataUtils.getId("EXP_ERROR")); experimentCatalog.add(ExpCatChildDataType.EXPERIMENT_ERROR, errorModel, experimentId); } catch (RegistryException e) { String msg = "expId: " + processContext.getExperimentId() + " processId: " + processContext.getProcessId() + " : - Error while updating experiment errors"; throw new GFacException(msg, e); } } public static void saveProcessError(ProcessContext processContext, ErrorModel errorModel) throws GFacException { try { ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); errorModel.setErrorId(AiravataUtils.getId("PROCESS_ERROR")); experimentCatalog.add(ExpCatChildDataType.PROCESS_ERROR, errorModel, processContext.getProcessId()); } catch (RegistryException e) { String msg = "expId: " + processContext.getExperimentId() + " processId: " + processContext.getProcessId() + " : - Error while updating process errors"; throw new GFacException(msg, e); } } public static void saveTaskError(TaskContext taskContext, ErrorModel errorModel) throws GFacException { try { ExperimentCatalog experimentCatalog = taskContext.getParentProcessContext().getExperimentCatalog(); String taskId = taskContext.getTaskId(); errorModel.setErrorId(AiravataUtils.getId("TASK_ERROR")); experimentCatalog.add(ExpCatChildDataType.TASK_ERROR, errorModel, taskId); } catch (RegistryException e) { String msg = "expId: " + taskContext.getParentProcessContext().getExperimentId() + " processId: " + taskContext.getParentProcessContext().getProcessId() + " taskId: " + taskContext.getTaskId() + " : - Error while updating task errors"; throw new GFacException(msg, e); } } public static void handleProcessInterrupt(ProcessContext processContext) throws GFacException { if (processContext.isCancel()) { ProcessStatus pStatus = new ProcessStatus(ProcessState.CANCELLING); pStatus.setReason("Process Cancel triggered"); pStatus.setTimeOfStateChange(AiravataUtils.getCurrentTimestamp().getTime()); processContext.setProcessStatus(pStatus); saveAndPublishProcessStatus(processContext); // do cancel operation here pStatus.setState(ProcessState.CANCELED); processContext.setProcessStatus(pStatus); pStatus.setTimeOfStateChange(AiravataUtils.getCurrentTimestamp().getTime()); saveAndPublishProcessStatus(processContext); } else if (processContext.isHandOver()) { } else { log.error("expId: {}, processId: {} :- Unknown process interrupt", processContext.getExperimentId(), processContext.getProcessId()); } } public static JobModel getJobModel(ProcessContext processContext) throws RegistryException { ExperimentCatalog experimentCatalog = processContext.getExperimentCatalog(); List<Object> objects = experimentCatalog.get(ExperimentCatalogModelType.JOB, Constants.FieldConstants.JobConstants.PROCESS_ID, processContext.getProcessId()); List<JobModel> jobModels = new ArrayList<>(); JobModel jobModel = null; if (objects != null) { for (Object object : objects) { jobModel = ((JobModel) object); if (jobModel.getJobId() != null || !jobModel.equals("")) { return jobModel; } } } return jobModel; } public static List<String> parseTaskDag(String taskDag) { // TODO - parse taskDag and create taskId list String[] tasks = taskDag.split(","); return Arrays.asList(tasks); } }