/// <summary> /// Attach the broker /// </summary> /// <param name="startInfo">session start info</param> /// <param name="sessionInfo">session info</param> /// <param name="durable">whether durable session</param> /// <param name="timeoutMilliseconds">attach timeout</param> /// <param name="binding">indicating the binding</param> /// <returns>session object</returns> public override async Task <SessionBase> AttachBroker(SessionStartInfo startInfo, SessionInfoContract sessionInfo, bool durable, int timeoutMilliseconds, Binding binding) { DateTime targetTimeout; Utility.ThrowIfNull(sessionInfo, "sessionInfo"); Utility.ThrowIfInvalidTimeout(timeoutMilliseconds, "timeoutMilliseconds"); if (timeoutMilliseconds == Timeout.Infinite) { targetTimeout = DateTime.MaxValue; } else { targetTimeout = DateTime.Now.AddMilliseconds(timeoutMilliseconds); } SessionBase.TraceSource.TraceEvent(TraceEventType.Information, 0, "[Session:{0}] Start to attach broker...", sessionInfo.Id); SessionInfo info = Utility.BuildSessionInfoFromDataContract(sessionInfo); // resourceProvider.GetResourceInfo(attachInfo, SessionBase.GetTimeout(targetTimeout)); SessionAttachInfo attachInfo = new SessionAttachInfo(startInfo.Headnode, sessionInfo.Id); attachInfo.TransportScheme = startInfo.TransportScheme; attachInfo.Username = startInfo.Username; attachInfo.InternalPassword = startInfo.InternalPassword; IBrokerFactory brokerFactory = BuildBrokerFactory(attachInfo, durable); try { return(await brokerFactory.AttachBroker(attachInfo, info, SessionBase.GetTimeout(targetTimeout), binding).ConfigureAwait(false)); } finally { IDisposable disposableObject = brokerFactory as IDisposable; if (disposableObject != null) { disposableObject.Dispose(); } } }
/// <summary> /// Attach to an existing session /// </summary> /// <param name="attachInfo">indicating the session attach information</param> /// <param name="durable">indicating a value whether a durable session is to be created</param> /// <param name="timeoutMilliseconds">indicating the timeout</param> /// <param name="binding">indicating the binding</param> /// <returns>returns session instance</returns> public override async Task <SessionBase> AttachSession(SessionAttachInfo attachInfo, bool durable, int timeoutMilliseconds, Binding binding) { Debug.Assert(attachInfo is SessionAttachInfo, "[OnPremiseSessionFactory].AttachSession: attachInfo's type must be SessionAttachInfo."); DateTime targetTimeout; Utility.ThrowIfNull(attachInfo, "attachInfo"); Utility.ThrowIfInvalidTimeout(timeoutMilliseconds, "timeoutMilliseconds"); if (timeoutMilliseconds == Timeout.Infinite) { targetTimeout = DateTime.MaxValue; } else { targetTimeout = DateTime.Now.AddMilliseconds(timeoutMilliseconds); } SessionBase.TraceSource.TraceEvent(TraceEventType.Information, 0, "[Session:{0}] Start to attach session...", attachInfo.SessionId); IResourceProvider resourceProvider = null; SessionInfo info = null; CredType typeOfExpectedCred = CredType.None; try { int retry = 0; bool askForCredential = false; // allow users to try credential at most MaxRetryCount times int askForCredentialTimes = 0; while (Utility.CanRetry(retry, askForCredential, askForCredentialTimes)) { retry++; try { SessionBase.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[Session:{0}] Start to attach session.", attachInfo.SessionId); Stopwatch watch = new Stopwatch(); watch.Start(); if (attachInfo.UseAad) { // Authentication handled by AADUtil } else if (SoaHelper.IsSchedulerOnAzure(attachInfo.Headnode) || SoaHelper.IsSchedulerOnIaaS(attachInfo.Headnode) || (attachInfo.TransportScheme & TransportScheme.Http) == TransportScheme.Http) { askForCredential = HpcSessionCredUtil.RetrieveCredentialOnAzure(attachInfo); if (askForCredential) { askForCredentialTimes++; } } else { askForCredential = await HpcSessionCredUtil.RetrieveCredentialOnPremise(attachInfo, typeOfExpectedCred, binding).ConfigureAwait(false); if (askForCredential) { askForCredentialTimes++; } HpcSessionCredUtil.CheckCredential(attachInfo); HpcSessionCredUtil.CheckCredential(attachInfo); } resourceProvider = BuildResourceProvider(attachInfo, durable, binding); watch.Stop(); // re-calculate the timeout to exclude the timespan for getting credential try { targetTimeout = targetTimeout.AddMilliseconds(watch.ElapsedMilliseconds); } catch (ArgumentOutOfRangeException) { } info = await resourceProvider.GetResourceInfo(attachInfo, SessionBase.GetTimeout(targetTimeout)).ConfigureAwait(false); SessionBase.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[Session:{0}] Successfully got resource info. BrokerLauncherEpr = {1}", attachInfo.SessionId, info.BrokerLauncherEpr); // If the session is an inprocess broker session, info.UseInprocessBroker will be set // to true by HpcSession service. Need to set attachInfo.UseInprocessBroker to true // in order to build correct broker factory instance. if (info.UseInprocessBroker) { attachInfo.UseInprocessBroker = true; } // If debug mode is enabled, need to set info.UseInprocessBroker to true in order to // build correct broker factory instance. if (attachInfo.DebugModeEnabled) { info.UseInprocessBroker = true; } if (SoaHelper.IsSchedulerOnIaaS(attachInfo.Headnode)) { string suffix = SoaHelper.GetSuffixFromHeadNodeEpr(attachInfo.Headnode); info.BrokerLauncherEpr = SoaHelper.UpdateEprWithCloudServiceName(info.BrokerLauncherEpr, suffix); if (info.BrokerEpr != null) { SoaHelper.UpdateEprWithCloudServiceName(info.BrokerEpr, suffix); } if (info.ControllerEpr != null) { SoaHelper.UpdateEprWithCloudServiceName(info.ControllerEpr, suffix); } if (info.ResponseEpr != null) { SoaHelper.UpdateEprWithCloudServiceName(info.ResponseEpr, suffix); } } HpcSessionCredUtil.SaveCrendential(attachInfo); break; } catch (SessionException) { throw; } catch (EndpointNotFoundException) { SessionBase.TraceSource.TraceEvent(TraceEventType.Error, 0, "[Session:{0}] EndpointNotFoundException occured while getting resource info.", attachInfo.SessionId); SessionBase.HandleEndpointNotFoundException(attachInfo.Headnode); } catch (AuthenticationException e) { SessionBase.TraceSource.TraceEvent(TraceEventType.Warning, 0, "[Session:{0}] AuthenticationException occured while attaching session: {1}", attachInfo.SessionId, e); attachInfo.ClearCredential(); SessionBase.PurgeCredential(attachInfo); if (Utility.CanRetry(retry, askForCredential, askForCredentialTimes)) { if (typeOfExpectedCred == CredType.None) { typeOfExpectedCred = await CredUtil.GetCredTypeFromClusterAsync(attachInfo, binding).ConfigureAwait(false); } if (resourceProvider is IDisposable) { ((IDisposable)resourceProvider).Dispose(); } continue; } else { throw; } } catch (MessageSecurityException e) { SessionBase.TraceSource.TraceEvent(TraceEventType.Warning, 0, "[Session:{0}] MessageSecurityException occured while attaching session: {1}", attachInfo.SessionId, e); attachInfo.ClearCredential(); SessionBase.PurgeCredential(attachInfo); if (Utility.CanRetry(retry, askForCredential, askForCredentialTimes)) { if (typeOfExpectedCred == CredType.None) { typeOfExpectedCred = await CredUtil.GetCredTypeFromClusterAsync(attachInfo, binding).ConfigureAwait(false); } if (resourceProvider is IDisposable) { ((IDisposable)resourceProvider).Dispose(); } continue; } else { throw; } } catch (FaultException <SessionFault> ex) { typeOfExpectedCred = Utility.CanRetry(retry, askForCredential, askForCredentialTimes) ? CredUtil.GetCredTypeFromFaultCode(ex.Detail.Code) : CredType.None; SessionBase.TraceSource.TraceEvent(TraceEventType.Warning, 0, "[Session:{0}] Fault exception occured while allocating resource. FaultCode = {1}", attachInfo.SessionId, ex.Detail.Code); if (typeOfExpectedCred == CredType.None) { throw Utility.TranslateFaultException(ex); } else { attachInfo.ClearCredential(); if (resourceProvider is IDisposable) { ((IDisposable)resourceProvider).Dispose(); } continue; } } catch (CommunicationException e) { throw new SessionException(SOAFaultCode.ConnectSessionLauncherFailure, SR.ConnectSessionLauncherFailure, e); } catch (TimeoutException e) { throw new TimeoutException(string.Format(SR.ConnectSessionLauncherTimeout, Constant.DefaultCreateSessionTimeout), e); } catch (Exception e) { throw new SessionException(SOAFaultCode.UnknownError, e.ToString()); } } // while } finally { IDisposable disposableObject = resourceProvider as IDisposable; if (disposableObject != null) { disposableObject.Dispose(); } } if (String.IsNullOrEmpty(info.BrokerLauncherEpr) && !info.UseInprocessBroker) { if ((info.JobState & (JobState.Configuring | JobState.ExternalValidation | JobState.Queued | JobState.Running | JobState.Submitted | JobState.Validating)) != 0) { throw new SessionException(string.Format(SR.AttachConfiguringSession, attachInfo.SessionId)); } else { throw new SessionException(string.Format(SR.AttachNoBrokerSession, attachInfo.SessionId)); } } IBrokerFactory brokerFactory = BuildBrokerFactory(attachInfo, durable); try { return(await brokerFactory.AttachBroker(attachInfo, info, SessionBase.GetTimeout(targetTimeout), binding).ConfigureAwait(false)); } finally { IDisposable disposableObject = brokerFactory as IDisposable; if (disposableObject != null) { disposableObject.Dispose(); } } }