public void ConstructionByQualifiedName() { TopicName topicName = new TopicName("Dotted.Namespace.LocalName"); Assert.AreEqual("LocalName", topicName.LocalName); Assert.AreEqual("Dotted.Namespace", topicName.Namespace); }
public async Task Given_No_Topic_When_Getting_Then_Topic_List_Returned() { var mockSubscriptionTrackingService = new Mock<ISubscriptionTrackingService>(); var topics = new TopicName[] {"topic-1", "topic-2", "topic-3"}; var controller = new TopicController(mockSubscriptionTrackingService.Object, topics); var mockRequest = new Mock<IHttpResourceRequest>(); var requestUri = new UriBuilder { Scheme = "http", Host = "localhost", Path = "/platibus/topic/" }.Uri; mockRequest.Setup(r => r.HttpMethod).Returns("GET"); mockRequest.Setup(r => r.Url).Returns(requestUri); var mockResponse = new Mock<IHttpResourceResponse>(); var responseOutputStream = new MemoryStream(); var responseEncoding = Encoding.UTF8; mockResponse.Setup(r => r.ContentEncoding).Returns(responseEncoding); mockResponse.Setup(r => r.OutputStream).Returns(responseOutputStream); await controller.Process(mockRequest.Object, mockResponse.Object, Enumerable.Empty<string>()); mockResponse.VerifySet(r => r.StatusCode = 200); var responseContent = responseEncoding.GetString(responseOutputStream.GetBuffer()); var topicsFromResponse = new NewtonsoftJsonSerializer().Deserialize<string[]>(responseContent); Assert.That(topicsFromResponse.Length, Is.EqualTo(3)); Assert.That(topicsFromResponse, Contains.Item("topic-1")); Assert.That(topicsFromResponse, Contains.Item("topic-2")); Assert.That(topicsFromResponse, Contains.Item("topic-3")); }
public void ConstructionByLocalName() { TopicName topicName = new TopicName("LocalName"); Assert.AreEqual("LocalName", topicName.LocalName); Assert.IsNull(topicName.Namespace); }
public async Task Given_No_Topic_When_Posting_Then_400_Returned() { var mockSubscriptionTrackingService = new Mock<ISubscriptionTrackingService>(); var topics = new TopicName[] {"topic-1", "topic-2", "topic-3"}; var controller = new TopicController(mockSubscriptionTrackingService.Object, topics); var mockRequest = new Mock<IHttpResourceRequest>(); var requestUri = new UriBuilder { Scheme = "http", Host = "localhost", Path = "/platibus/topic/" }.Uri; mockRequest.Setup(r => r.HttpMethod).Returns("POST"); mockRequest.Setup(r => r.Url).Returns(requestUri); var mockResponse = new Mock<IHttpResourceResponse>(); var responseOutputStream = new MemoryStream(); var responseEncoding = Encoding.UTF8; mockResponse.Setup(r => r.ContentEncoding).Returns(responseEncoding); mockResponse.Setup(r => r.OutputStream).Returns(responseOutputStream); await controller.Process(mockRequest.Object, mockResponse.Object, Enumerable.Empty<string>()); mockResponse.VerifySet(r => r.StatusCode = 400); }
protected override Task DeleteSubscription(TopicName topicName, Uri subscriber) { CheckDisposed(); var op = new SQLiteOperation(() => base.DeleteSubscription(topicName, subscriber)); _operationQueue.Post(op); return op.Task; }
public async Task AddSubscription(TopicName topic, Uri subscriber, TimeSpan ttl = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken)) { CheckDisposed(); var expires = ttl <= TimeSpan.Zero ? DateTime.MaxValue : (DateTime.UtcNow + ttl); var subscription = await InsertOrUpdateSubscription(topic, subscriber, expires); _subscriptions.AddOrUpdate(topic, new[] {subscription}, (t, existing) => new[] {subscription}.Union(existing).ToList()); }
protected override Task<SQLSubscription> InsertOrUpdateSubscription(TopicName topicName, Uri subscriber, DateTime expires) { CheckDisposed(); var op = new SQLiteOperation<SQLSubscription>( () => base.InsertOrUpdateSubscription(topicName, subscriber, expires)); _operationQueue.Post(op); return op.Task; }
protected void DoSearch() { string defaultNamespace = Request.QueryString["QuickLinkNamespace"]; LinkMaker lm = TheLinkMaker; string topic = Request.Form["QuickLink"]; QualifiedTopicNameCollection hits = Federation.AllQualifiedTopicNamesThatExist(new TopicName(topic), defaultNamespace); string target = null; if (hits.Count == 0) { // No hits, create it in the default namespace, or the namespace that was specified TopicName topicName = new TopicName(topic); QualifiedTopicName qualifiedTopicName = topicName.ResolveRelativeTo(defaultNamespace); target = lm.LinkToEditTopic(qualifiedTopicName); } else if (hits.Count == 1) { // 1 hit; take it! NameValueCollection extras = new NameValueCollection(); extras.Add("DelayRedirect", "1"); target = lm.LinkToTopic(new QualifiedTopicRevision(hits[0]), false, extras); } // If we have a target, go there if (target != null) { // Response.Write(target); Response.Redirect(target); return; } // Uh, oh -- we're here because the name is ambiguous Response.Write(@" <!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"" > <HTML> <HEAD> <title id='title'>Topic is ambiguous</title> <LINK href='<%= RootUrl(Request) %>wiki.css' type='text/css' rel='stylesheet'> </HEAD> <p>The topic name you selected is ambiguous because it already exists in multiple namespaces. Please select the one you want: <ul>"); foreach (TopicName each in hits) { Response.Write("<li><a href='" + lm.LinkToTopic(each) + "'>" + each.DottedName + "</a></li>"); } Response.Write(@" </ul> </body> </HTML> "); }
public static string GetSubscriptionQueueName(this Uri subscriberUri, TopicName topicName) { if (subscriberUri == null) throw new ArgumentNullException("subscriberUri"); if (topicName == null) throw new ArgumentNullException("topicName"); var hostPortVhost = ReplaceInvalidChars(subscriberUri.Host); if (subscriberUri.Port > 0) { hostPortVhost += "_" + subscriberUri.Port; } var vhost = subscriberUri.AbsolutePath.Trim('/'); if (!string.IsNullOrWhiteSpace(vhost)) { hostPortVhost += "_" + ReplaceInvalidChars(vhost); } return ReplaceInvalidChars(topicName) + "-" + hostPortVhost; }
public void Overrides() { string projectId = _fixture.ProjectId; string topicId = _fixture.CreateTopicId(); DateTime deadline = DateTime.MaxValue; CancellationToken cancellationToken = new CancellationTokenSource().Token; // Sample: Overrides // Create a default PublisherServiceApiSettings, with customizations for CreateTopic RPCs: // * A custom "ClientVersion" header. // * A custom 5-second timeout Timing. // * No cancellation token. PublisherServiceApiSettings publisherSettings = new PublisherServiceApiSettings(); publisherSettings.CreateTopicSettings = publisherSettings.CreateTopicSettings .WithCancellationToken(CancellationToken.None) .WithTimeout(TimeSpan.FromSeconds(5)) .WithHeader("ClientVersion", "1.0.0"); // Override the above Timing and CancellationToken in the client-wide CallSettings; // the Headers are not overridden. publisherSettings.CallSettings = CallSettings .FromExpiration(Expiration.FromDeadline(deadline)) .WithCancellationToken(CancellationToken.None); // Create the client with the configured publisherSettings PublisherServiceApiClient client = new PublisherServiceApiClientBuilder { Settings = publisherSettings }.Build(); // Create a topic name from the projectId and topicId. TopicName topicName = new TopicName(projectId, topicId); // Call CreateTopic(). Override only the CancellationToken, using a per-RPC-method CallSettings. // The CallSettings used during this RPC invocation is: // * A custom "ClientVersion" header. // * A Timing deadline of 'deadline' (*not* the overridden 5-second timeout). // * The CancellationToken 'cancellationToken' (*not* CancellationToken.None). Topic topic = client.CreateTopic(topicName, CallSettings.FromCancellationToken(cancellationToken)); // End sample }
public void CreateTopicRequestObject() { moq::Mock <Publisher.PublisherClient> mockGrpcClient = new moq::Mock <Publisher.PublisherClient>(moq::MockBehavior.Strict); Topic request = new Topic { TopicName = TopicName.FromProjectTopic("[PROJECT]", "[TOPIC]"), Labels = { { "key8a0b6e3c", "value60c16320" }, }, MessageStoragePolicy = new MessageStoragePolicy(), KmsKeyName = "kms_key_name06bd122b", SchemaSettings = new SchemaSettings(), SatisfiesPzs = false, }; Topic expectedResponse = new Topic { TopicName = TopicName.FromProjectTopic("[PROJECT]", "[TOPIC]"), Labels = { { "key8a0b6e3c", "value60c16320" }, }, MessageStoragePolicy = new MessageStoragePolicy(), KmsKeyName = "kms_key_name06bd122b", SchemaSettings = new SchemaSettings(), SatisfiesPzs = false, }; mockGrpcClient.Setup(x => x.CreateTopic(request, moq::It.IsAny <grpccore::CallOptions>())).Returns(expectedResponse); PublisherServiceApiClient client = new PublisherServiceApiClientImpl(mockGrpcClient.Object, null); Topic response = client.CreateTopic(request); xunit::Assert.Same(expectedResponse, response); mockGrpcClient.VerifyAll(); }
public async Task PullAsync() { string projectId = _fixture.ProjectId; string topicId = _fixture.CreateTopicId(); string subscriptionId = _fixture.CreateSubscriptionId(); PublisherServiceApiClient publisher = PublisherServiceApiClient.Create(); TopicName topicName = new TopicName(projectId, topicId); publisher.CreateTopic(topicName); PubsubMessage newMessage = new PubsubMessage { Data = ByteString.CopyFromUtf8("Simple text") }; SubscriberServiceApiClient.Create().CreateSubscription(new SubscriptionName(projectId, subscriptionId), topicName, null, 60); publisher.Publish(topicName, new[] { newMessage }); // Snippet: PullAsync(SubscriptionName,*,*,CallSettings) // Additional: PullAsync(SubscriptionName,*,*,CancellationToken) SubscriberServiceApiClient client = SubscriberServiceApiClient.Create(); SubscriptionName subscriptionName = new SubscriptionName(projectId, subscriptionId); PullResponse pullResponse = await client.PullAsync(subscriptionName, returnImmediately : false, maxMessages : 100); foreach (ReceivedMessage message in pullResponse.ReceivedMessages) { // Messages can contain any data. We'll assume that we know this // topic publishes UTF-8-encoded text. Console.WriteLine($"Message text: {message.Message.Data.ToStringUtf8()}"); } // Acknowledge the messages after pulling them, so we don't pull them // a second time later. The ackDeadlineSeconds parameter specified when // the subscription is created determines how quickly you need to acknowledge // successfully-pulled messages before they will be redelivered. var ackIds = pullResponse.ReceivedMessages.Select(rm => rm.AckId); await client.AcknowledgeAsync(subscriptionName, ackIds); // End snippet }
public async Task PublishAsync() { Mock <Publisher.PublisherClient> mockGrpcClient = new Mock <Publisher.PublisherClient>(MockBehavior.Strict); mockGrpcClient.Setup(x => x.CreateIAMPolicyClient()) .Returns(new Mock <IAMPolicy.IAMPolicyClient>().Object); PublishRequest expectedRequest = new PublishRequest { TopicAsTopicName = new TopicName("[PROJECT]", "[TOPIC]"), Messages = { new PubsubMessage { Data = ByteString.CopyFromUtf8("-86"), }, }, }; PublishResponse expectedResponse = new PublishResponse { MessageIds = { "messageIdsElement-744837059", }, }; mockGrpcClient.Setup(x => x.PublishAsync(expectedRequest, It.IsAny <CallOptions>())) .Returns(new Grpc.Core.AsyncUnaryCall <PublishResponse>(Task.FromResult(expectedResponse), null, null, null, null)); PublisherServiceApiClient client = new PublisherServiceApiClientImpl(mockGrpcClient.Object, null); TopicName topic = new TopicName("[PROJECT]", "[TOPIC]"); IEnumerable <PubsubMessage> messages = new[] { new PubsubMessage { Data = ByteString.CopyFromUtf8("-86"), }, }; PublishResponse response = await client.PublishAsync(topic, messages); Assert.Same(expectedResponse, response); mockGrpcClient.VerifyAll(); }
public void CreateSubscription(string topicId, string subscriptionId, SubscriberClient subscriber) { // [START create_subscription] TopicName topicName = new TopicName(_projectId, topicId); SubscriptionName subscriptionName = new SubscriptionName(_projectId, subscriptionId); try { Subscription subscription = subscriber.CreateSubscription( subscriptionName, topicName, pushConfig: null, ackDeadlineSeconds: 60); } catch (RpcException e) when(e.Status.StatusCode == StatusCode.AlreadyExists) { // Already exists. That's fine. } // [END create_subscription] }
public async Task PublishAsync() { // Snippet: PublishAsync(TopicName,IEnumerable<PubsubMessage>,CallSettings) // Additional: PublishAsync(TopicName,IEnumerable<PubsubMessage>,CancellationToken) // Create client PublisherClient publisherClient = await PublisherClient.CreateAsync(); // Initialize request argument(s) TopicName topic = new TopicName("[PROJECT]", "[TOPIC]"); IEnumerable <PubsubMessage> messages = new[] { new PubsubMessage { Data = ByteString.CopyFromUtf8(""), }, }; // Make the request PublishResponse response = await publisherClient.PublishAsync(topic, messages); // End snippet }
public SendToGoogleMessageHub(ILogger <SendToGoogleMessageHub> logger) { // Get projectId fron config string googleCredentialsText = File.ReadAllText(Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS")); JObject googleCredentials = JObject.Parse(googleCredentialsText); string projectId = googleCredentials["project_id"].ToString(); // Get Topic Names string eventTopicName = Environment.GetEnvironmentVariable("EVENT_TOPIC_NAME"); string messageTopicName = Environment.GetEnvironmentVariable("MESSAGE_TOPIC_NAME"); //Create the topic name reference _eventTopicName = new TopicName(projectId, eventTopicName); _messageTopicName = new TopicName(projectId, messageTopicName); //Create Publisher _publisher = PublisherServiceApiClient.Create(); _logger = logger; _logger.LogInformation("GCP Information set. projectId: {projectId} eventTopicName: {eventTopicName},messageTopicName:{messageTopicName}, ", projectId, eventTopicName, messageTopicName); }
public static object CreateTopic(string projectId, string topicId) { // [START create_publisher_client] PublisherServiceApiClient publisher = PublisherServiceApiClient.Create(); // [END create_publisher_client] // [START create_topic] TopicName topicName = new TopicName(projectId, topicId); try { publisher.CreateTopic(topicName); } catch (RpcException e) when(e.Status.StatusCode == StatusCode.AlreadyExists) { // Already exists. That's fine. } // [END create_topic] return(0); }
public void ClientPerMethod() { string projectId = _fixture.ProjectId; string topicId = _fixture.CreateTopicId(); // Sample: ClientPerMethod // Create a default PublisherServiceApiSettings, with a custom header for calls // to the CreateTopic RPC method. PublisherServiceApiSettings publisherSettings = new PublisherServiceApiSettings(); publisherSettings.CreateTopicSettings = publisherSettings.CreateTopicSettings.WithHeader("ClientVersion", "1.0.0"); PublisherServiceApiClient client = new PublisherServiceApiClientBuilder { Settings = publisherSettings }.Build(); // Create a topic name from the projectId and topicId. TopicName topicName = new TopicName(projectId, topicId); // The custom 'ClientVersion' header will be included in the RPC call, due to // the client being configured with 'publishersettings' above. Topic topic = client.CreateTopic(topicName); // End sample }
/// <summary>Snippet for PublishAsync</summary> public async Task PublishRequestObjectAsync() { // Snippet: PublishAsync(PublishRequest, CallSettings) // Additional: PublishAsync(PublishRequest, CancellationToken) // Create client PublisherServiceApiClient publisherServiceApiClient = await PublisherServiceApiClient.CreateAsync(); // Initialize request argument(s) PublishRequest request = new PublishRequest { TopicAsTopicName = TopicName.FromProjectTopic("[PROJECT]", "[TOPIC]"), Messages = { new PubsubMessage(), }, }; // Make the request PublishResponse response = await publisherServiceApiClient.PublishAsync(request); // End snippet }
public object CreateSubscription([FromBody] CreatTopicModel attr) { // [START pubsub_create_pull_subscription] SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create(); TopicName topicName = new TopicName(attr.projectId, attr.topicId); SubscriptionName subscriptionName = new SubscriptionName(attr.projectId, attr.subscriptionID); try { Subscription subscription = subscriber.CreateSubscription( subscriptionName, topicName, pushConfig: null, ackDeadlineSeconds: 60); } catch (RpcException e) when(e.Status.StatusCode == Grpc.Core.StatusCode.AlreadyExists) { // Already exists. That's fine. } // [END pubsub_create_pull_subscription] return(0); }
private void Setup(PartitionedTopicMetadata p, string topic) { if (p.Partitions > 0) { for (var i = 0; i < p.Partitions; i++) { var partitionTopic = TopicName.Get(topic).GetPartition(i); var partitionName = partitionTopic.ToString(); var msgId = GetMessageId(); var config = PrepareConsumerConfiguration(_message.Configuration, partitionName, new MessageId(msgId.LedgerId, msgId.EntryId, i), (int)(_message.ToMessageId - _message.FromMessageId)); Context.ActorOf(PulsarTaggedSourceActor <T> .Prop(_message.ClientConfiguration, config, _client, _lookup, _cnxPool, _generator, _message.FromMessageId, _message.ToMessageId, true, _message.Tag, _schema)); } } else { var msgId = GetMessageId(); var config = PrepareConsumerConfiguration(_message.Configuration, topic, msgId, (int)(_message.ToMessageId - _message.FromMessageId)); Context.ActorOf(PulsarTaggedSourceActor <T> .Prop(_message.ClientConfiguration, config, _client, _lookup, _cnxPool, _generator, _message.FromMessageId, _message.ToMessageId, true, _message.Tag, _schema)); } }
/// <summary> /// Adds or updates a subscription /// </summary> /// <param name="topic">The topic to which the <paramref name="subscriber"/> is /// subscribing</param> /// <param name="subscriber">The base URI of the subscribing Platibus instance</param> /// <param name="ttl">(Optional) The maximum Time To Live (TTL) for the subscription</param> /// <param name="cancellationToken">(Optional) A cancellation token that can be used by /// the caller to cancel the addition of the subscription</param> /// <returns>Returns a task that will complete when the subscription has been added or /// updated</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="topic"/> or /// <paramref name="subscriber"/> is <c>null</c></exception> /// <exception cref="ObjectDisposedException">Thrown if the object is already disposed</exception> public async Task AddSubscription(TopicName topic, Uri subscriber, TimeSpan ttl = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken)) { if (topic == null) { throw new ArgumentNullException(nameof(topic)); } if (subscriber == null) { throw new ArgumentNullException(nameof(subscriber)); } CheckDisposed(); var expires = ttl <= TimeSpan.Zero ? DateTime.MaxValue : (DateTime.UtcNow + ttl); cancellationToken.ThrowIfCancellationRequested(); var subscription = await InsertOrUpdateSubscription(topic, subscriber, expires); _subscriptions.AddOrUpdate(topic, new[] { subscription }, (t, existing) => new[] { subscription }.Union(existing).ToList()); }
static void Main(string[] args) { // TODO: get projectId from configuration // configure subscriber string projectId = "jrewerts-project"; //Configuration["Google:ProjectId"]; if (string.IsNullOrWhiteSpace(projectId)) throw new InvalidOperationException("Unable to get the projectId from configuration"); var topicNameString = ANALYSIS_TOPIC_NAME; var topicName = new TopicName(projectId, topicNameString); var subscriptionClient = SubscriberClient.Create(); var subscriptionName = new SubscriptionName(projectId, ANALYSIS_SUBSCRIPTION_NAME); // create the subscription if it doesn't exist try { subscriptionClient.CreateSubscription(subscriptionName, topicName, new PushConfig(), 60); } catch (Grpc.Core.RpcException e) { /* subscription already exists */ } while (true) { var pullResult = subscriptionClient.Pull(subscriptionName, false, 1); foreach (var message in pullResult.ReceivedMessages) { try { string messageText = System.Text.Encoding.UTF8.GetString(message.Message.Data.ToByteArray()); } catch (Exception err) { // TODO: log error and continue } } } }
/// <summary> /// Initializes a new set of <see cref="HttpSubscriptionMetadata"/> for a subscription /// with the specified <paramref name="ttl"/> /// </summary> /// <param name="endpoint">The endpoint to which subscription requests will be sent</param> /// <param name="topic">The topic to which the subscriber is subscribing</param> /// <param name="ttl">The non-negative time-to-live for the subscription</param> public HttpSubscriptionMetadata(IEndpoint endpoint, TopicName topic, TimeSpan ttl) { if (ttl < TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(ttl)); } Endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint)); Topic = topic ?? throw new ArgumentNullException(nameof(topic)); if (ttl > TimeSpan.Zero) { TTL = ttl > MinTTL ? ttl : MinTTL; Expires = true; } // Attempt to renew after half of the TTL or 5 minutes (whichever is less) // to allow for issues that may occur when attempting to renew the // subscription. RenewalInterval = new TimeSpan(ttl.Ticks / 2); if (RenewalInterval > MaxRenewalInterval) { RenewalInterval = MaxRenewalInterval; } // Wait for the standard renewal interval or 30 seconds (whichever is less) before // retrying in the event of an unsuccessful subscription request RetryInterval = RenewalInterval; if (RetryInterval > MaxRetryInterval) { RetryInterval = MaxRetryInterval; } // Ensure a minimum amount of time elapses between retries to avoid overloading // both the subscriber and publisher with requests if (RetryInterval < MinRetryInterval) { RetryInterval = MinRetryInterval; } }
public async stt::Task CreateTopicRequestObjectAsync() { moq::Mock <Publisher.PublisherClient> mockGrpcClient = new moq::Mock <Publisher.PublisherClient>(moq::MockBehavior.Strict); Topic request = new Topic { TopicName = TopicName.FromProjectTopic("[PROJECT]", "[TOPIC]"), Labels = { { "key8a0b6e3c", "value60c16320" }, }, MessageStoragePolicy = new MessageStoragePolicy(), KmsKeyName = "kms_key_name06bd122b", }; Topic expectedResponse = new Topic { TopicName = TopicName.FromProjectTopic("[PROJECT]", "[TOPIC]"), Labels = { { "key8a0b6e3c", "value60c16320" }, }, MessageStoragePolicy = new MessageStoragePolicy(), KmsKeyName = "kms_key_name06bd122b", }; mockGrpcClient.Setup(x => x.CreateTopicAsync(request, moq::It.IsAny <grpccore::CallOptions>())).Returns(new grpccore::AsyncUnaryCall <Topic>(stt::Task.FromResult(expectedResponse), null, null, null, null)); PublisherServiceApiClient client = new PublisherServiceApiClientImpl(mockGrpcClient.Object, null); Topic responseCallSettings = await client.CreateTopicAsync(request, gaxgrpc::CallSettings.FromCancellationToken(st::CancellationToken.None)); xunit::Assert.Same(expectedResponse, responseCallSettings); Topic responseCancellationToken = await client.CreateTopicAsync(request, st::CancellationToken.None); xunit::Assert.Same(expectedResponse, responseCancellationToken); mockGrpcClient.VerifyAll(); }
public async Task ValidPostRequestToTopicSubscriberResourceCreatesSubscription() { var mockSubscriptionTrackingService = new Mock <ISubscriptionTrackingService>(); mockSubscriptionTrackingService.Setup(sts => sts.AddSubscription(It.IsAny <TopicName>(), It.IsAny <Uri>(), It.IsAny <TimeSpan>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(true)); var topics = new TopicName[] { "topic-1", "topic-2", "topic-3" }; var controller = new TopicController(mockSubscriptionTrackingService.Object, topics); var mockRequest = new Mock <IHttpResourceRequest>(); var encodedSubscriberUri = new UrlEncoder().Encode("http://example.com/platibus"); var requestUri = new UriBuilder { Scheme = "http", Host = "localhost", Path = "/platibus/topic/topic-1/subscriber", Query = string.Format("uri={0}&ttl=3600", encodedSubscriberUri) }.Uri; mockRequest.Setup(r => r.HttpMethod).Returns("POST"); mockRequest.Setup(r => r.Url).Returns(requestUri); mockRequest.Setup(r => r.QueryString).Returns(new NameValueCollection { { "uri", "http://example.com/platibus" }, { "ttl", "3600" } }); var mockResponse = new Mock <IHttpResourceResponse>(); await controller.Process(mockRequest.Object, mockResponse.Object, new[] { "topic-1", "subscriber", encodedSubscriberUri }); mockResponse.VerifySet(r => r.StatusCode = 200); mockSubscriptionTrackingService.Verify(ts => ts.AddSubscription( "topic-1", new Uri("http://example.com/platibus"), TimeSpan.FromSeconds(3600), It.IsAny <CancellationToken>())); }
public async Task CreateTopic(Topic topic, Capability capability, string clusterId) { await _kafkaJanitorClient.Topics.CreateAsync(new KafkaJanitor.RestClient.Features.Topics.Models.Topic { Name = topic.Name.Name, Description = topic.Description, Partitions = topic.Partitions, Configurations = topic.Configurations, ClusterId = clusterId }); await _kafkaJanitorClient.Access.RequestAsync( new ServiceAccountRequestInput { CapabilityName = capability.Name, CapabilityId = capability.Id.ToString(), CapabilityRootId = capability.RootId, TopicPrefix = TopicName.CreatePrefix(capability.RootId), ClusterId = clusterId } ); }
/// <summary> /// Creates a topic subscription if doesnt exist /// </summary> /// <returns>Subscription name</returns> private SubscriptionName CreateSubscriptionIfNotExists() { SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create(); TopicName topicName = new TopicName(this.cloud.GoogleProjectID, this.cloud.QueueName); SubscriptionName subscriptionName = new SubscriptionName(this.cloud.GoogleProjectID, this.cloud.GoogleSubscriptionName); try { _ = subscriber.CreateSubscription( subscriptionName, topicName, pushConfig: null, ackDeadlineSeconds: 60); } catch (RpcException e) when(e.Status.StatusCode == StatusCode.AlreadyExists) { // It already exists } return(subscriptionName); }
private bool DeleteTopic(TopicName _TopicInstance, Action <string> _ErrorMessageAction) { var PublisherAPIClient = PublisherServiceApiClient.Create(SubscribeChannel); try { PublisherAPIClient.DeleteTopic(_TopicInstance); } catch (Exception e) { if (e is RpcException && (e as RpcException).Status.StatusCode == StatusCode.NotFound) { //That is fine. } else { _ErrorMessageAction?.Invoke("BPubSubServiceGC->DeleteTopic: " + e.Message + ", Trace: " + e.StackTrace); return(false); } } return(true); }
public void IsWatermarkAchievedByReatcsOnNotRightOffset() { // Arrange var topicName = new TopicName("Test"); var offsets = new WatermarkOffsets(new Offset(1), new Offset(2)); var partition = new Partition(1); var result = new ConsumeResult <object, object>() { Offset = offsets.Low }; var pw = new PartitionWatermark(topicName, offsets, partition); var status = false; // Act var exception = Record.Exception(() => status = pw.IsWatermarkAchievedBy(result)); // Assert exception.Should().BeNull(); status.Should().BeFalse(); }
public void OrderingKeyResumePublish() { const string unrecoverableKey = "error-unrecoverable"; const string recoverableKey = "error-recoverable"; var topicName = new TopicName("FakeProject", "FakeTopic"); var scheduler = new TestScheduler(); TaskHelper taskHelper = scheduler.TaskHelper; var client = new FakePublisherServiceApiClient(scheduler, taskHelper, orderingKeyErrorUnrecoverable: unrecoverableKey, orderingKeyErrorRecoverable: recoverableKey); var settings = MakeSettings(scheduler, enableMessageOrdering: true); int shutdownCount = 0; var pub = new PublisherClientImpl(topicName, new[] { client }, settings, () => { Interlocked.Increment(ref shutdownCount); return(Task.FromResult(0)); }, taskHelper); scheduler.Run(async() => { // First call will trigger an unrecoverable error. var ex = await taskHelper.ConfigureAwait( Assert.ThrowsAsync <RpcException>(() => pub.PublishAsync(unrecoverableKey, "unrecoverable error"))); Assert.Equal(StatusCode.DataLoss, ex.StatusCode); // Sending again will reject the message. await taskHelper.ConfigureAwait( Assert.ThrowsAsync <OrderingKeyInErrorStateException>(() => pub.PublishAsync(unrecoverableKey, "key in error state"))); // Other ordering-keys publish OK. await taskHelper.ConfigureAwait(pub.PublishAsync("ok-key", "ok")); // Including a recoverable error. await taskHelper.ConfigureAwait(pub.PublishAsync(recoverableKey, "recoverable error")); // Including a message without an ordering key. await taskHelper.ConfigureAwait(pub.PublishAsync("key not ordered")); // Resume publishing on the ordering key. pub.ResumePublish(unrecoverableKey); await taskHelper.ConfigureAwait(pub.PublishAsync(unrecoverableKey, "unrecoverable key resumed")); var expected = new HashSet <string>(new[] { "ok", "key not ordered", "recoverable error", "unrecoverable key resumed" }); Assert.Equal(expected, new HashSet <string>(client.HandledMessages)); }); }
public static NotificationConfig UpdateNotificationConfig( string organizationId, string notificationConfigId, string projectId, string topicName) { NotificationConfigName notificationConfigName = new NotificationConfigName(organizationId, notificationConfigId); TopicName pubsubTopic = new TopicName(projectId, topicName); NotificationConfig configToUpdate = new NotificationConfig { NotificationConfigName = notificationConfigName, Description = "updated description", PubsubTopicAsTopicName = pubsubTopic }; FieldMask fieldMask = new FieldMask { Paths = { "description", "pubsub_topic" } }; SecurityCenterClient client = SecurityCenterClient.Create(); NotificationConfig updatedConfig = client.UpdateNotificationConfig(configToUpdate, fieldMask); Console.WriteLine($"Notification config updated: {updatedConfig}"); return(updatedConfig); }
public void CreateNotification() { var projectId = _fixture.ProjectId; string bucket = _fixture.BucketName; // This creates the topic, which is most of the work... var created = _fixture.CreateNotification("prefix2"); var topicId = created.Topic.Split('/').Last(); // Snippet: CreateNotification(string, Notification, *) TopicName topicName = new TopicName(projectId, topicId); StorageClient client = StorageClient.Create(); Notification notification = new Notification { Topic = $"//pubsub.googleapis.com/{topicName}", PayloadFormat = "JSON_API_V1" }; notification = client.CreateNotification(bucket, notification); Console.WriteLine($"Created notification ID: {notification.Id}"); // End snippet }
public async Task CreateSubscription( SubscriptionName subscriptionName, TopicName topicName, PushConfig?pushConfig, int ackDeadline ) { var subscriberServiceApiClient = await SubscriberServiceApiClient.CreateAsync().Ignore(); var publisherServiceApiClient = await PublisherServiceApiClient.CreateAsync().Ignore(); try { Log?.LogInformation("Checking topic {Topic}", topicName); await publisherServiceApiClient.CreateTopicAsync(topicName).Ignore(); Log?.LogInformation("Created topic {Topic}", topicName); } catch (RpcException e) when(e.Status.StatusCode == StatusCode.AlreadyExists) { Log?.LogInformation("Topic {Topic} exists", topicName); } try { Log?.LogInformation("Checking subscription {Subscription} for {Topic}", subscriptionName, topicName); await subscriberServiceApiClient.CreateSubscriptionAsync( subscriptionName, topicName, pushConfig, ackDeadline ).Ignore(); Log?.LogInformation("Created subscription {Subscription} for {Topic}", subscriptionName, topicName); } catch (RpcException e) when(e.Status.StatusCode == StatusCode.AlreadyExists) { Log?.LogInformation("Subscription {Subscription} for {Topic} exists", subscriptionName, topicName); } }
public IotTestFixture() { RegionId = "us-central1"; ProjectId = Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID"); string privateKeyPath = Environment.GetEnvironmentVariable("IOT_PRIVATE_KEY_PATH"); if (privateKeyPath.Length == 0 || !File.Exists(privateKeyPath)) { throw new NullReferenceException("Private key path is not for unit tests."); } CertPath = Environment.GetEnvironmentVariable("IOT_CERT_KEY_PATH"); PrivateKeyPath = privateKeyPath; ServiceAccount = "serviceAccount:[email protected]"; TestId = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds().ToString(); TopicName = new TopicName(ProjectId, "iot-test-" + TestId); RegistryId = "iot-test-" + TestId; CreatePubSubTopic(this.TopicName); // Check if the number of registries does not exceed 90. CheckRegistriesLimit(ProjectId, RegionId); Assert.Equal(0, CloudIotSample.CreateRegistry(ProjectId, RegionId, RegistryId, TopicName.TopicId)); }
// [START retry] public void RpcRetry(string topicId, string subscriptionId, PublisherClient publisher, SubscriberClient subscriber) { TopicName topicName = new TopicName(_projectId, topicId); // Create Subscription. SubscriptionName subscriptionName = new SubscriptionName(_projectId, subscriptionId); // Create Topic try { // This may fail if the Topic already exists. // Don't retry in that case. publisher.CreateTopic(topicName, newRetryCallSettings(3, StatusCode.AlreadyExists)); } catch (RpcException e) when(e.Status.StatusCode == StatusCode.AlreadyExists) { // Already exists. That's fine. } try { // Subscribe to Topic // This may fail if the Subscription already exists or // the Topic has not yet been created. In those cases, don't // retry, because a retry would fail the same way. subscriber.CreateSubscription(subscriptionName, topicName, pushConfig: null, ackDeadlineSeconds: 60, callSettings: newRetryCallSettings(3, StatusCode.AlreadyExists, StatusCode.NotFound)); } catch (RpcException e) when(e.Status.StatusCode == StatusCode.AlreadyExists) { // Already exists. That's fine. } }
public async Task <int> PublishProtoMessagesAsync(string projectId, string topicId, IEnumerable <Utilities.State> messageStates) { TopicName topicName = TopicName.FromProjectTopic(projectId, topicId); PublisherClient publisher = await PublisherClient.CreateAsync(topicName); PublisherServiceApiClient publishApi = PublisherServiceApiClient.Create(); var topic = publishApi.GetTopic(topicName); int publishedMessageCount = 0; var publishTasks = messageStates.Select(async state => { try { string messageId = null; switch (topic.SchemaSettings.Encoding) { case Encoding.Binary: var binaryMessage = state.ToByteString(); messageId = await publisher.PublishAsync(binaryMessage); break; case Encoding.Json: var jsonMessage = JsonFormatter.Default.Format(state); messageId = await publisher.PublishAsync(jsonMessage); break; } Console.WriteLine($"Published message {messageId}"); Interlocked.Increment(ref publishedMessageCount); } catch (Exception exception) { Console.WriteLine($"An error ocurred when publishing message {state}: {exception.Message}"); } }); await Task.WhenAll(publishTasks); return(publishedMessageCount); }
public static object CreateSubscription(string projectId, string topicId, string subscriptionId) { // [START pubsub_create_pull_subscription] SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create(); TopicName topicName = new TopicName(projectId, topicId); SubscriptionName subscriptionName = new SubscriptionName(projectId, subscriptionId); try { Subscription subscription = subscriber.CreateSubscription( subscriptionName, topicName, pushConfig: null, ackDeadlineSeconds: 60); } catch (RpcException e) when(e.Status.StatusCode == StatusCode.AlreadyExists) { // Already exists. That's fine. } // [END pubsub_create_pull_subscription] return(0); }
public async Task <int> PublishMessagesAsync(string projectId, string topicId, IEnumerable <string> messageTexts) { TopicName topicName = TopicName.FromProjectTopic(projectId, topicId); PublisherClient publisher = await PublisherClient.CreateAsync(topicName); int publishedMessageCount = 0; var publishTasks = messageTexts.Select(async text => { try { string message = await publisher.PublishAsync(text); Console.WriteLine($"Published message {message}"); Interlocked.Increment(ref publishedMessageCount); } catch (Exception exception) { Console.WriteLine($"An error ocurred when publishing message {text}: {exception.Message}"); } }); await Task.WhenAll(publishTasks); return(publishedMessageCount); }
public async Task PostOrDeleteSubscriber(IHttpResourceRequest request, IHttpResourceResponse response, TopicName topic, IEnumerable<string> subPath) { if (request == null) throw new ArgumentNullException("request"); if (response == null) throw new ArgumentNullException("response"); var uri = request.QueryString["uri"]; if (uri == null) { response.StatusCode = 400; response.StatusDescription = "Subscriber URI is required"; return; } var subscriber = new Uri(uri); if (!_topics.Contains(topic)) { response.StatusCode = 404; response.StatusDescription = "Topic not found"; return; } if ("delete".Equals(request.HttpMethod, StringComparison.OrdinalIgnoreCase)) { await _subscriptionTrackingService.RemoveSubscription(topic, subscriber); } else { var ttlStr = request.QueryString["ttl"]; var ttl = string.IsNullOrWhiteSpace(ttlStr) ? default(TimeSpan) : TimeSpan.FromSeconds(int.Parse(ttlStr)); await _subscriptionTrackingService.AddSubscription(topic, subscriber, ttl); } response.StatusCode = 202; }
public async Task RemoveSubscription(TopicName topic, Uri subscriber, CancellationToken cancellationToken = default(CancellationToken)) { CheckDisposed(); await DeleteSubscription(topic, subscriber); _subscriptions.AddOrUpdate(topic, new SQLSubscription[0], (t, existing) => existing.Where(se => se.Subscriber != subscriber).ToList()); }
protected virtual Task DeleteSubscription(TopicName topicName, Uri subscriber) { bool deleted; var connection = _connectionProvider.GetConnection(); try { using (var scope = new TransactionScope(TransactionScopeOption.Required)) { using (var command = connection.CreateCommand()) { command.CommandType = CommandType.Text; command.CommandText = _dialect.DeleteSubscriptionCommand; command.SetParameter(_dialect.TopicNameParameterName, (string) topicName); command.SetParameter(_dialect.SubscriberParameterName, subscriber.ToString()); var rowsAffected = command.ExecuteNonQuery(); deleted = rowsAffected > 0; } scope.Complete(); } } finally { _connectionProvider.ReleaseConnection(connection); } return Task.FromResult(deleted); }
public async Task PublishMessage(Message message, TopicName topicName, CancellationToken cancellationToken) { var subscribers = await _subscriptionTrackingService.GetSubscribers(topicName, cancellationToken); var transportTasks = new List<Task>(); // ReSharper disable once LoopCanBeConvertedToQuery foreach (var subscriber in subscribers) { var perEndpointHeaders = new MessageHeaders(message.Headers) { Destination = subscriber }; var addressedMessage = new Message(perEndpointHeaders, message.Content); transportTasks.Add(TransportMessage(addressedMessage, null, cancellationToken)); } await Task.WhenAll(transportTasks); }
public TopicNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { _topic = info.GetString("topic"); }
protected virtual Task<SQLSubscription> InsertOrUpdateSubscription(TopicName topicName, Uri subscriber, DateTime expires) { SQLSubscription subscription; var connection = _connectionProvider.GetConnection(); try { using (var scope = new TransactionScope(TransactionScopeOption.Required)) { using (var command = connection.CreateCommand()) { command.CommandType = CommandType.Text; command.CommandText = _dialect.InsertSubscriptionCommand; command.SetParameter(_dialect.TopicNameParameterName, (string) topicName); command.SetParameter(_dialect.SubscriberParameterName, subscriber.ToString()); command.SetParameter(_dialect.ExpiresParameterName, expires); var rowsAffected = command.ExecuteNonQuery(); if (rowsAffected == 0) { command.CommandText = _dialect.UpdateSubscriptionCommand; command.ExecuteNonQuery(); } } subscription = new SQLSubscription(topicName, subscriber, expires); scope.Complete(); } } finally { _connectionProvider.ReleaseConnection(connection); } return Task.FromResult(subscription); }
private int NameSort(TopicName topicA, TopicName topicB) { if (topicA == null) { if (topicB == null) { return 0; } else { return -1; } } else { if (topicB == null) { return 1; } else { if (topicA.LocalName == topicB.LocalName) { return topicA.Namespace.CompareTo(topicB.Namespace); } else { return topicA.LocalName.CompareTo(topicB.LocalName); } } } }
public async Task PublishMessage(Message message, TopicName topicName, CancellationToken cancellationToken) { await Task.Run(() => _accept(message, Thread.CurrentPrincipal), cancellationToken); }
public void ConstructionByIllegalLocalNameAndNamespace() { TopicName topicName = new TopicName("Dotted.LocalName", "Dotted.Namespace"); }
public void ConstructByTopicNameAndVersion() { TopicName name = new TopicName("Foo", "Bar"); TopicRevision revision = new TopicRevision(name, "1.0"); Assert.AreEqual("Foo", revision.LocalName, "Checking that local name is correct."); Assert.AreEqual("Bar", revision.Namespace, "Checking that namespace is correct."); Assert.AreEqual("1.0", revision.Version, "Checking that version is correct."); }
/// <summary> /// Initializes a new <see cref="TopicAlreadyExistsException"/> with /// the specified <paramref name="topic"/> /// </summary> /// <param name="topic">The name of the topic that was added multiple /// time</param> public TopicAlreadyExistsException(TopicName topic) { _topic = topic; }
public TopicNotFoundException(TopicName topic) { _topic = topic; }
/// <summary> /// Initializes a serialized <see cref="TopicAlreadyExistsException"/> /// from a streaming context /// </summary> /// <param name="info">The serialization info</param> /// <param name="context">The streaming context</param> public TopicAlreadyExistsException(SerializationInfo info, StreamingContext context) : base(info, context) { _topic = info.GetString("Topic"); }
/// <summary> /// Answer a formatted RSS <item> for the given topic /// </summary> /// <param name="topic"></param> /// <returns></returns> public void FormatRssItem(TopicName topic, XmlWriter newsletter) { NamespaceManager storeManager = Federation.NamespaceManagerForNamespace(topic.Namespace); IEnumerable changes = Federation.GetTopicChanges(topic); IEnumerator e = changes.GetEnumerator(); if (!e.MoveNext()) return; // No history! newsletter.WriteStartElement("item"); newsletter.WriteElementString("title", topic.LocalName); newsletter.WriteStartElement("description"); FormatRssTopicHistory(topic, false, newsletter, changes); newsletter.WriteEndElement(); newsletter.WriteStartElement("body"); newsletter.WriteAttributeString("xmlns", @"http://www.w3.org/1999/xhtml"); FormatRssTopicHistory(topic, true, newsletter, changes); newsletter.WriteEndElement(); newsletter.WriteElementString( "created", Federation.GetTopicCreationTime(topic).ToUniversalTime().ToString("r") ); Uri link = new Uri(new Uri(FullRootUrl(Request)), TheLinkMaker.LinkToTopic(new QualifiedTopicRevision(topic), true)); newsletter.WriteElementString("link", link.AbsoluteUri); newsletter.WriteElementString( "pubDate", Federation.GetTopicModificationTime(topic).ToUniversalTime().ToString("r") ); newsletter.WriteElementString("guid", link.ToString()); newsletter.WriteEndElement(); }
private void ProcessPost() { //NamespaceManager storeManager = Federation.NamespaceManagerForNamespace(_preferredNamespace); _action = Request.Form["fileaction"]; _topic = Request.Form["topic"]; TopicName topic = new TopicName(_topic); UnqualifiedTopicName unqualifiedtopic = new UnqualifiedTopicName(topic.LocalName); NamespaceManager _namespacemgr = Federation.NamespaceManagerForTopic(topic); if (_namespacemgr.HasNamespacePermission(NamespacePermission.Manage)) { if (_action == "Lock") { _namespacemgr.LockTopic(unqualifiedtopic); } else if (_action == "Unlock") { _namespacemgr.UnlockTopic(unqualifiedtopic); } } }
public Task<IEnumerable<Uri>> GetSubscribers(TopicName topic, CancellationToken cancellationToken = default(CancellationToken)) { CheckDisposed(); IEnumerable<SQLSubscription> subscriptions; _subscriptions.TryGetValue(topic, out subscriptions); var activeSubscribers = (subscriptions ?? Enumerable.Empty<SQLSubscription>()) .Where(s => s.Expires > DateTime.UtcNow) .Select(s => s.Subscriber); return Task.FromResult(activeSubscribers); }
public Task Subscribe(IEndpoint endpoint, TopicName topicName, TimeSpan ttl, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(false); }
/// <summary> /// Answer the RSS topic history for a given topic /// </summary> /// <param name="topic"></param> /// <param name="useHTML"></param> /// <returns></returns> private void FormatRssTopicHistory(TopicName topic, bool useHTML, XmlWriter newsletter, IEnumerable changesForThisTopic) { ArrayList names = new ArrayList(); Hashtable changeInfo = new Hashtable(); // key = author, value = TopicChange int count = 0; foreach (TopicChange change in changesForThisTopic) { if (count >= MaxChanges) { break; } count++; if (names.Contains(change.Author)) { continue; } names.Add(change.Author); changeInfo[change.Author] = change; } if (count == 0) { return; } if (useHTML) { Uri link = new Uri(new Uri(FullRootUrl(Request)), TheLinkMaker.LinkToTopic( new QualifiedTopicRevision(topic), true)); newsletter.WriteStartElement("a"); newsletter.WriteAttributeString("title", HtmlWriter.Escape(topic.DottedName)); newsletter.WriteAttributeString("href", link.AbsoluteUri); newsletter.WriteString(HtmlWriter.Escape(topic.LocalName)); newsletter.WriteEndElement(); } else { newsletter.WriteString(HtmlWriter.Escape(topic.LocalName)); } newsletter.WriteString( string.Format(" was most recently changed by: ") ); bool firstName = true; if (useHTML) { newsletter.WriteStartElement("ul"); } foreach (string eachAuthor in names) { if (useHTML) { newsletter.WriteStartElement("li"); } else { if (!firstName) { newsletter.WriteString(", "); } } firstName = false; newsletter.WriteString(HtmlWriter.Escape(eachAuthor) + " (" + ((TopicChange)(changeInfo[eachAuthor])).Created.ToString() + ")"); if (useHTML) { newsletter.WriteEndElement(); } } if (useHTML) { newsletter.WriteEndElement(); Uri link = new Uri(new Uri(FullRootUrl(Request)), TheLinkMaker.LinkToVersions(topic.ToString())); newsletter.WriteString("View the "); newsletter.WriteStartElement("a"); newsletter.WriteAttributeString("title", "Versions for " + HtmlWriter.Escape(topic.DottedName)); newsletter.WriteAttributeString("href", link.AbsoluteUri); newsletter.WriteString("complete version history"); newsletter.WriteEndElement(); newsletter.WriteStartElement("br"); newsletter.WriteEndElement(); } else { newsletter.WriteString("\n"); } return; }
public void DefinitionTopicName() { Federation federation = WikiTestUtilities.SetupFederation("test://NamespaceManagerTests", TestContentSets.SingleEmptyNamespace); NamespaceManager manager = federation.NamespaceManagerForNamespace("NamespaceOne"); TopicName expected = new TopicName(NamespaceManager.DefinitionTopicLocalName, manager.Namespace); Assert.AreEqual(expected.DottedName, manager.DefinitionTopicName.DottedName, "Checking that DefinitionTopicName is correct."); }
public async Task Given_Topic_And_Subscriber_When_Posting_Then_Subscription_Added() { var mockSubscriptionTrackingService = new Mock<ISubscriptionTrackingService>(); mockSubscriptionTrackingService.Setup(sts => sts.AddSubscription(It.IsAny<TopicName>(), It.IsAny<Uri>(), It.IsAny<TimeSpan>(), It.IsAny<CancellationToken>())) .Returns(Task.FromResult(true)); var topics = new TopicName[] {"topic-1", "topic-2", "topic-3"}; var controller = new TopicController(mockSubscriptionTrackingService.Object, topics); var mockRequest = new Mock<IHttpResourceRequest>(); var encodedSubscriberUri = HttpUtility.UrlEncode("http://example.com/platibus"); var requestUri = new UriBuilder { Scheme = "http", Host = "localhost", Path = "/platibus/topic/topic-1/subscriber", Query = string.Format("uri={0}&ttl=3600", encodedSubscriberUri) }.Uri; mockRequest.Setup(r => r.HttpMethod).Returns("POST"); mockRequest.Setup(r => r.Url).Returns(requestUri); mockRequest.Setup(r => r.QueryString).Returns(new NameValueCollection { {"uri", "http://example.com/platibus"}, {"ttl", "3600"} }); var mockResponse = new Mock<IHttpResourceResponse>(); await controller.Process(mockRequest.Object, mockResponse.Object, new[] {"topic-1", "subscriber", encodedSubscriberUri}); mockResponse.VerifySet(r => r.StatusCode = 202); mockSubscriptionTrackingService.Verify(ts => ts.AddSubscription( "topic-1", new Uri("http://example.com/platibus"), TimeSpan.FromSeconds(3600), It.IsAny<CancellationToken>())); }
/// <summary> /// Adds a topic to the configuration /// </summary> /// <param name="topic">The name of the topic</param> /// <remarks> /// Topics must be explicitly added in order to publish messages to them /// </remarks> public void AddTopic(TopicName topic) { if (topic == null) throw new ArgumentNullException("topic"); if (_topics.Contains(topic)) throw new TopicAlreadyExistsException(topic); _topics.Add(topic); }