public void RegisterCommandForProvidedSubjectGroupForSecondGroup() { var storage = new InteractionSubjectGroupStorage(); var subject = new CommunicationSubject("a"); var firstType = typeof(InteractionExtensionsTest.IMockCommandSetWithTaskReturn); var firstVersion = new Version(1, 0); var firstGroupId = "group1"; storage.RegisterCommandForProvidedSubjectGroup(subject, firstType, firstVersion, firstGroupId); var secondType = typeof(InteractionExtensionsTest.IMockCommandSetWithTypedTaskReturn); var secondVersion = new Version(1, 0); var secondGroupId = "group2"; storage.RegisterCommandForProvidedSubjectGroup(subject, secondType, secondVersion, secondGroupId); Assert.IsTrue(storage.ProvidedSubjects().Any(s => s.Equals(subject))); Assert.IsTrue(storage.Subjects().Any(s => s.Equals(subject))); Assert.IsTrue(storage.ContainsGroupProvisionsForSubject(subject)); Assert.IsFalse(storage.ContainsGroupRequirementsForSubject(subject)); var group = storage.GroupProvisionsFor(subject); Assert.AreSame(subject, group.Subject); Assert.AreEqual(0, group.Notifications.Length); Assert.AreEqual(2, group.Commands.Length); Assert.IsTrue( group.Commands[0].IsPartialMatch( new VersionedTypeFallback( new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation( firstType.FullName, firstType.Assembly.GetName()), new Version(1, 0))))); Assert.IsFalse( group.Commands[0].IsPartialMatch( new VersionedTypeFallback( new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation( secondType.FullName, secondType.Assembly.GetName()), new Version(1, 0))))); Assert.IsTrue( group.Commands[1].IsPartialMatch( new VersionedTypeFallback( new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation( secondType.FullName, secondType.Assembly.GetName()), new Version(1, 0))))); Assert.IsFalse( group.Commands[1].IsPartialMatch( new VersionedTypeFallback( new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation( firstType.FullName, firstType.Assembly.GetName()), new Version(1, 0))))); }
/// <summary> /// Creates a new <see cref="CommunicationSubjectGroup"/>. /// </summary> /// <param name="subject">The subject for the group.</param> /// <returns>The new group.</returns> public CommunicationSubjectGroup ToGroup(CommunicationSubject subject) { var commands = m_Commands .Select( pair => new VersionedTypeFallback( pair.Value .Select(subPair => new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation(subPair.Value.FullName, subPair.Value.Assembly.GetName()), subPair.Key)) .ToArray())) .ToArray(); var notifications = m_Notifications .Select( pair => new VersionedTypeFallback( pair.Value .Select( subPair => new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation(subPair.Value.FullName, subPair.Value.Assembly.GetName()), subPair.Key)) .ToArray())) .ToArray(); return(new CommunicationSubjectGroup( subject, commands, notifications)); }
public void RegisterNotificationForRequiredSubjectGroupWithFirstNotification() { var storage = new InteractionSubjectGroupStorage(); var subject = new CommunicationSubject("a"); var type = typeof(InteractionExtensionsTest.IMockNotificationSetWithEventHandler); var version = new Version(1, 0); var groupId = "group1"; storage.RegisterNotificationForRequiredSubjectGroup(subject, type, version, groupId); Assert.IsTrue(storage.RequiredSubjects().Any(s => s.Equals(subject))); Assert.IsTrue(storage.Subjects().Any(s => s.Equals(subject))); Assert.IsTrue(storage.ContainsGroupRequirementsForSubject(subject)); Assert.IsFalse(storage.ContainsGroupProvisionsForSubject(subject)); var group = storage.GroupRequirementsFor(subject); Assert.AreSame(subject, group.Subject); Assert.AreEqual(0, group.Commands.Length); Assert.AreEqual(1, group.Notifications.Length); Assert.IsTrue( group.Notifications[0].IsPartialMatch( new VersionedTypeFallback( new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation( type.FullName, type.Assembly.GetName()), new Version(1, 0))))); }
public void Create() { var subject = new CommunicationSubject("a"); var version = new Version(1, 0); var group = "b"; var identifier = new SubjectGroupIdentifier(subject, version, group); Assert.AreSame(subject, identifier.Subject); Assert.AreSame(version, identifier.Version); Assert.AreSame(group, identifier.Group); }
/// <summary> /// Initializes a new instance of the <see cref="SubjectGroupIdentifier"/> class. /// </summary> /// <param name="subject">The communication subject that is related to the subject group.</param> /// <param name="version">The 'version' of the interaction object that is related to the subject group.</param> /// <param name="group">The identifier that is used to group interaction objects that perform similar functions.</param> public SubjectGroupIdentifier(CommunicationSubject subject, Version version, string group) { { Lokad.Enforce.Argument(() => subject); Lokad.Enforce.Argument(() => version); Lokad.Enforce.Argument(() => group); } m_Subject = subject; m_Version = version; m_Group = group; }
/// <summary> /// Initializes a new instance of the <see cref="CommunicationSubjectGroup"/> class. /// </summary> /// <param name="subject">The communication subject that indicates a topic the endpoint will communicate about.</param> /// <param name="commands">The collection of all commands that should be available for the current subject.</param> /// <param name="notifications">The collection of all notifications that should be available for the current subject.</param> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="subject"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="commands"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="notifications"/> is <see langword="null" />. /// </exception> public CommunicationSubjectGroup(CommunicationSubject subject, VersionedTypeFallback[] commands, VersionedTypeFallback[] notifications) { { Lokad.Enforce.Argument(() => subject); Lokad.Enforce.Argument(() => commands); Lokad.Enforce.Argument(() => notifications); } m_Subject = subject; m_Commands = commands; m_Notifications = notifications; }
/// <summary> /// Returns the provided subject group that is related with the given subject. /// </summary> /// <param name="subject">The subject.</param> /// <returns>The provided subject group that is related with the given subject.</returns> public CommunicationSubjectGroup GroupProvisionsFor(CommunicationSubject subject) { { Lokad.Enforce.Argument(() => subject); Lokad.Enforce.With <UnknownCommunicationSubjectException>( m_ProvidedSubjects.ContainsKey(subject), Resources.Exceptions_Messages_UnknownCommunicationSubject); } var map = m_ProvidedSubjects[subject]; return(map.ToGroup(subject)); }
/// <summary> /// Registers a required command with a specific subject group. /// </summary> /// <param name="subject">The subject for the group.</param> /// <param name="commandType">The type of the command.</param> /// <param name="version">The version of the command which is used to order commands that provide similar functionality.</param> /// <param name="groupIdentifier"> /// The identifier which is used to group different versions of commands that provide similar functionality. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="subject"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="commandType"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="version"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="groupIdentifier"/> is <see langword="null" />. /// </exception> public void RegisterCommandForRequiredSubjectGroup(CommunicationSubject subject, Type commandType, Version version, string groupIdentifier) { { Lokad.Enforce.Argument(() => subject); Lokad.Enforce.Argument(() => commandType); Lokad.Enforce.Argument(() => version); Lokad.Enforce.Argument(() => groupIdentifier); } if (!m_RequiredSubjects.ContainsKey(subject)) { m_RequiredSubjects.Add(subject, new SubjectMap()); } var map = m_RequiredSubjects[subject]; map.AddCommand(groupIdentifier, commandType, version); }
/// <summary> /// Registers an existing notification with a specific subject group. /// </summary> /// <param name="subject">The subject for the group.</param> /// <param name="notificationType">The type of the notification.</param> /// <param name="version">The version of the notification which is used to order commands that provide similar functionality.</param> /// <param name="groupIdentifier"> /// The identifier which is used to group different versions of notifications that provide similar functionality. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="subject"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="notificationType"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="version"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="groupIdentifier"/> is <see langword="null" />. /// </exception> public void RegisterNotificationForProvidedSubjectGroup( CommunicationSubject subject, Type notificationType, Version version, string groupIdentifier) { { Lokad.Enforce.Argument(() => subject); Lokad.Enforce.Argument(() => notificationType); Lokad.Enforce.Argument(() => version); Lokad.Enforce.Argument(() => groupIdentifier); } if (!m_ProvidedSubjects.ContainsKey(subject)) { m_ProvidedSubjects.Add(subject, new SubjectMap()); } var map = m_ProvidedSubjects[subject]; map.AddNotification(groupIdentifier, notificationType, version); }
public void Create() { var subject = new CommunicationSubject("a"); var commands = new[] { new VersionedTypeFallback( new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation(typeof(string).FullName, typeof(string).Assembly.GetName()), new Version(1, 2))), }; var notifications = new[] { new VersionedTypeFallback( new Tuple <OfflineTypeInformation, Version>( new OfflineTypeInformation(typeof(TestAttribute).FullName, typeof(TestAttribute).Assembly.GetName()), new Version(3, 4))), }; var group = new CommunicationSubjectGroup(subject, commands, notifications); Assert.AreSame(subject, group.Subject); Assert.AreSame(commands, group.Commands); Assert.AreSame(notifications, group.Notifications); }
public void HandshakeWithLocalRejection() { var id = new EndpointId("a:10"); var subject = new CommunicationSubject("a"); var connection = new EndpointInformation( new EndpointId("a"), new DiscoveryInformation(new Uri("net.tcp://localhost/discovery/invalid")), new ProtocolInformation( new Version(1, 0), new Uri("net.tcp://localhost/protocol/invalid"))); var remoteEndpoint = new EndpointId("b:10"); var remoteMessageAddress = @"net.tcp://othermachine"; var remoteDataAddress = @"net.tcp://othermachine/data"; var communicationDescriptions = new Mock <IStoreProtocolSubjects>(); { communicationDescriptions.Setup(c => c.Subjects()) .Returns( new[] { subject }); communicationDescriptions.Setup(c => c.ToStorage()) .Returns( new ProtocolDescription( new[] { subject })); } var endpointApprover = new Mock <IApproveEndpointConnections>(); { endpointApprover.Setup(e => e.ProtocolVersion) .Returns(new Version(1, 0)); endpointApprover.Setup(e => e.IsEndpointAllowedToConnect(It.IsAny <ProtocolDescription>())) .Returns(false); } Func <ChannelTemplate, Uri> discoveryUri = t => new Uri("net.tcp://localhost/discovery/invalid"); var discoveryInformation = new LocalConnectionInformation(id, discoveryUri); var storage = new EndpointInformationStorage(); var endpointConnected = false; storage.OnEndpointConnected += (s, e) => { endpointConnected = true; Assert.AreEqual(remoteEndpoint, e.Endpoint); }; var discovery = new Mock <IDiscoverOtherServices>(); var protocolLayer = new Mock <IProtocolLayer>(); { protocolLayer.Setup(l => l.Id) .Returns(id); protocolLayer.Setup(l => l.LocalConnectionFor(It.IsAny <Version>(), It.IsAny <ChannelTemplate>())) .Returns( new Tuple <EndpointId, Uri, Uri>( connection.Id, connection.ProtocolInformation.MessageAddress, connection.ProtocolInformation.DataAddress)); protocolLayer.Setup(l => l.SendMessageToUnregisteredEndpoint( It.IsAny <EndpointInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>())) .Verifiable(); protocolLayer.Setup(l => l.SendMessageToUnregisteredEndpointAndWaitForResponse( It.IsAny <EndpointInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>(), It.IsAny <TimeSpan>())) .Returns(Task <ICommunicationMessage> .Factory.StartNew( () => new SuccessMessage(remoteEndpoint, new MessageId()), new CancellationTokenSource().Token, TaskCreationOptions.None, new CurrentThreadTaskScheduler())) .Verifiable(); } var configuration = new Mock <IConfiguration>(); { configuration.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>())) .Returns(false); } var layer = new ProtocolHandshakeConductor( storage, discoveryInformation, new[] { discovery.Object }, protocolLayer.Object, communicationDescriptions.Object, new[] { endpointApprover.Object }, new[] { ChannelTemplate.NamedPipe, ChannelTemplate.TcpIP, }, configuration.Object, new SystemDiagnostics((l, m) => { }, null)); layer.ContinueHandshakeWith( new EndpointInformation( remoteEndpoint, new DiscoveryInformation(new Uri("net.tcp://localhost/discovery/invalid")), new ProtocolInformation( new Version(1, 0), new Uri(remoteMessageAddress), new Uri(remoteDataAddress))), new ProtocolDescription(new List <CommunicationSubject> { new CommunicationSubject("b") }), new MessageId()); Assert.IsFalse(endpointConnected); Assert.IsFalse(storage.HasBeenContacted(remoteEndpoint)); Assert.IsFalse(storage.IsWaitingForApproval(remoteEndpoint)); Assert.IsFalse(storage.CanCommunicateWithEndpoint(remoteEndpoint)); protocolLayer.Verify( l => l.SendMessageToUnregisteredEndpointAndWaitForResponse( It.IsAny <EndpointInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>(), It.IsAny <TimeSpan>()), Times.Never()); }
/// <summary> /// Returns a value indicating if a subject group with provided commands and notifications exists for /// the given subject. /// </summary> /// <param name="subject">The subject.</param> /// <returns> /// <see langword="true" /> if a subject group with provided commands and notifications exists for the /// given subject; otherwise, <see langword="false"/>. /// </returns> public bool ContainsGroupProvisionsForSubject(CommunicationSubject subject) { return((subject != null) && m_ProvidedSubjects.ContainsKey(subject)); }
/// <summary> /// Returns a value indicating if a subject group with required commands and notifications exists for /// the given subject. /// </summary> /// <param name="subject">The subject.</param> /// <returns> /// <see langword="true" /> if a subject group with required commands and notifications exists for the /// given subject; otherwise, <see langword="false"/>. /// </returns> public bool ContainsGroupRequirementsForSubject(CommunicationSubject subject) { return((subject != null) && m_RequiredSubjects.ContainsKey(subject)); }
/// <summary> /// Initializes a new instance of the <see cref="CommunicationSubjectViewModel"/> class. /// </summary> /// <param name="subject">The subject.</param> public CommunicationSubjectViewModel(CommunicationSubject subject) { m_Subject = subject; }