/// <summary> /// <para> /// Initializes session parameters and calls open session. Only for cluster computation. /// </para> /// </summary> /// <param name="headNode"> /// <para>Name of cluster head node</para> /// </param> /// <param name="remoteWorkbookPath"> /// <para>Workbook location relative to compute node</para> /// </param> /// <param name="minResources"> /// <para>minimum number of resources requested</para> /// </param> /// <param name="maxResources"> /// <para>Maximum number of resources required</para> /// </param> /// <param name="resourceType"> /// <para>Name of resource requested (core, node, or socket)</para> /// </param> /// <param name="jobTemplate"> /// <para> Name of the job template to be used </para> /// </param> /// <param name="serviceName"> /// <para> Name of the service to use </para> /// </param> /// <param name="jobName"> /// <para>Specify the job name</para> /// </param> /// <param name="projectName"> /// <para>Specify the project name</para> /// </param> /// <param name="transportScheme"> /// <para>The transport scheme (Http or NetTcp)</para> /// </param> /// <param name="useAzureQueue"> /// <para>Specify if Azure storage queue is used (True or False)</para> /// </param> /// <param name="username"> /// <para>Specify the user name</para> /// </param> /// <param name="password"> /// <para>Specify the password</para> /// </param> /// <param name="jobPriority"> /// <para>Specify the job priority</para> /// </param> /// <returns> /// <para> ID of opened session </para> /// </returns> public int OpenSession(string headNode, string remoteWorkbookPath, [Optional] object minResources, [Optional] object maxResources, [Optional] object resourceType, [Optional] string jobTemplate, [Optional] string serviceName, [Optional] string jobName, [Optional] string projectName, [Optional] string transportScheme, [Optional] object useAzureQueue, [Optional] string username, [Optional] string password, [Optional] object jobPriority) { // Check if workbook path has been provided (ExcelClient initialize called) if (!this.initialized) { Tracing.WriteDebugTextError(Tracing.ComponentId.ExcelClient, Resources.ExcelClientOpenSessionBeforeInit); throw new InvalidOperationException(Resources.ExcelClientOpenSessionBeforeInit); } SessionStartInfo info; bool useWebApi = false; if (headNode.StartsWith("d:", StringComparison.OrdinalIgnoreCase)) { // HACK: using head node string to pass actual parameters var param = headNode.Split('?'); string serviceRegDirectory = null; string[] computeNodeIpList = null; string storageCredential = null; string[] dependFiles = null; bool CheckParameterSwitch(string parameter, string switchStr) { return(parameter.StartsWith(switchStr, StringComparison.OrdinalIgnoreCase)); } foreach (var p in param) { if (CheckParameterSwitch(p, "d:")) { serviceRegDirectory = p.Substring(p.IndexOf(":") + 1); } else if (CheckParameterSwitch(p, "c:")) { computeNodeIpList = p.Substring(p.IndexOf(":") + 1).Split(','); } else if (CheckParameterSwitch(p, "s:")) { storageCredential = p.Substring(p.IndexOf(":") + 1); } else if (CheckParameterSwitch(p, "f:")) { dependFiles = p.Substring(p.IndexOf(":") + 1).Split(','); } } if (serviceRegDirectory == null || computeNodeIpList == null) { throw new ArgumentNullException(); } // Standalone mode if (string.IsNullOrEmpty(serviceName)) { info = new SessionStartInfo(Microsoft.Hpc.Excel.ExcelClient.SERVICE, serviceRegDirectory, null, computeNodeIpList); } else { info = new SessionStartInfo(serviceName, serviceRegDirectory, null, computeNodeIpList); } if (dependFiles != null && dependFiles.Any()) { // Start data client related logic // TODO: move logic into ExcelClient try { if (string.IsNullOrEmpty(storageCredential)) { throw new ArgumentNullException(nameof(storageCredential)); } StandaloneDataClient dataClient = new StandaloneDataClient(storageCredential); var sasTokens = dataClient.UploadFilesAsync(dependFiles).GetAwaiter().GetResult(); if (sasTokens.Length != dependFiles.Length) { throw new InvalidOperationException($"Number of sas token ({sasTokens.Length}) does not equal to depend files ({dependFiles.Length})"); } var depFileInfo = new Dictionary <string, string>(); for (int i = 0; i != sasTokens.Length; ++i) { depFileInfo[Path.GetFileName(dependFiles[i])] = sasTokens[i]; } info.DependFilesStorageInfo = depFileInfo; remoteWorkbookPath = Path.GetFileName(remoteWorkbookPath); } catch (Exception ex) { Tracing.SoaTrace( XlTraceLevel.Error, "error when uploading files {0}", ex.ToString()); throw; } // End data client related logic } info.UseInprocessBroker = true; info.IsNoSession = true; } else { // If https prefix from head node name useWebApi = Microsoft.Hpc.Excel.ExcelClient.TryRemoveWebApiPrefix(ref headNode); // If the service name is provided, use it rather than the default in ExcelClient if (string.IsNullOrEmpty(serviceName)) { info = new SessionStartInfo(headNode, Microsoft.Hpc.Excel.ExcelClient.SERVICE); } else { info = new SessionStartInfo(headNode, serviceName); } } if (useWebApi) { info.TransportScheme = TransportScheme.WebAPI; } if (!string.IsNullOrEmpty(transportScheme)) { if (transportScheme.Equals("Http", StringComparison.InvariantCultureIgnoreCase)) { info.TransportScheme = TransportScheme.Http; } else if (transportScheme.Equals("NetTcp", StringComparison.InvariantCultureIgnoreCase)) { info.TransportScheme = TransportScheme.NetTcp; } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.ExcelClient_InvalidTransportScheme, transportScheme), "transportScheme"); } } if (!(useAzureQueue == null || System.Reflection.Missing.Value.Equals(useAzureQueue) || DBNull.Value.Equals(useAzureQueue))) { bool useAQ; if (bool.TryParse(useAzureQueue.ToString(), out useAQ)) { info.UseAzureQueue = useAQ; } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.ExcelClient_InvalidBoolParamValue, "useAzureQueue", useAzureQueue), "useAzureQueue"); } } if (!string.IsNullOrEmpty(username)) { info.Username = username; } if (!string.IsNullOrEmpty(password)) { info.Password = password; } if (!string.IsNullOrEmpty(jobName)) { info.ServiceJobName = jobName; } if (!string.IsNullOrEmpty(projectName)) { info.Project = projectName; } // If jobPriority is specified, try to parse it into an integer. if (!(jobPriority == null || System.Reflection.Missing.Value.Equals(jobPriority) || DBNull.Value.Equals(jobPriority))) { int priority; if (int.TryParse(jobPriority.ToString(), out priority)) { info.SessionPriority = priority; } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.ExcelClient_InvalidMinCores, jobPriority), "minResources"); } } // If minResources is specified, try to parse it into an integer. if (!(minResources == null || System.Reflection.Missing.Value.Equals(minResources) || DBNull.Value.Equals(minResources))) { int minUnits; if (int.TryParse(minResources.ToString(), out minUnits)) { info.MinimumUnits = minUnits; } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.ExcelClient_InvalidMinCores, minResources), "minResources"); } } // If maxResources is specified, try to parse it into an integer if (!(maxResources == null || System.Reflection.Missing.Value.Equals(maxResources) || DBNull.Value.Equals(maxResources))) { int maxUnits; if (int.TryParse(maxResources.ToString(), out maxUnits)) { info.MaximumUnits = maxUnits; } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.ExcelClient_InvalidMaxCores, maxResources), "maxResources"); } } // If job template is specified, set it if (!string.IsNullOrEmpty(jobTemplate)) { info.JobTemplate = jobTemplate; } // Set resource type (defaults to core) if (!(resourceType == null || System.Reflection.Missing.Value.Equals(resourceType) || DBNull.Value.Equals(resourceType))) { int resIndex; if (int.TryParse(resourceType.ToString(), out resIndex)) { info.SessionResourceUnitType = ResourceToSessionUnitType((Microsoft.Hpc.Excel.Com.SessionUnitType)resIndex); } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.ExcelClient_InvalidResType, resourceType), "resourceType"); } } // Set interface mode to UI to ensure that Excel asks for credentials in the UI when not cached SessionBase.SetInterfaceMode(false, new IntPtr(this.client.Driver.App.Hwnd)); return(this.client.OpenSession(info, remoteWorkbookPath)); }