in src/AmqpLink.cs [1111:1191]
void OnReceiveAttach(Attach attach)
{
StateTransition stateTransition = this.TransitState("R:ATTACH", StateTransition.ReceiveOpen);
Error error = this.Negotiate(attach);
if (error != null)
{
this.OnLinkOpenFailed(new AmqpException(error));
return;
}
if (stateTransition.From == AmqpObjectState.OpenSent)
{
if (this.IsReceiver)
{
Source source = this.settings.Source as Source;
if (source != null && source.Dynamic())
{
source.Address = ((Source)attach.Source).Address;
}
}
else
{
Target target = this.settings.Target as Target;
if (target != null && target.Dynamic())
{
target.Address = ((Target)attach.Target).Address;
}
}
if (attach.Properties != null)
{
if (this.Settings.Properties == null)
{
this.settings.Properties = attach.Properties;
}
else
{
this.settings.Properties.Merge(attach.Properties);
}
}
}
if (stateTransition.To == AmqpObjectState.Opened)
{
if ((this.IsReceiver && attach.Source == null) ||
(!this.IsReceiver && attach.Target == null))
{
// not linkendpoint was created on the remote side
// a detach should be sent immediately by peer with error
return;
}
if (this.IsReceiver)
{
this.deliveryCount = attach.InitialDeliveryCount.Value;
this.settings.Source = attach.Source;
}
else
{
this.settings.Target = attach.Target;
}
// in some scenario (e.g. EventHub) the service
// side can override the settle type based on
// entity settings.
this.settings.SettleType = attach.SettleType();
this.CompleteOpen(false, null);
}
else if (stateTransition.To == AmqpObjectState.OpenReceived)
{
try
{
this.Session.LinkFactory.BeginOpenLink(this, this.OperationTimeout, onProviderLinkOpened, this);
}
catch (Exception exception) when (!Fx.IsFatal(exception))
{
this.OnLinkOpenFailed(exception);
}
}
}