/// <summary> /// This is the entry point of the service host process. /// </summary> private static void Main() { try { if (EnvironmentHelper.IsInFabric) { // The ServiceManifest.XML file defines one or more service type names. // Registering a service maps a service type name to a .NET type. // When Service Fabric creates an instance of this service type, // an instance of the class is created in this host process. ServiceRuntime.RegisterServiceAsync("WebAPIServiceType", context => new WebAPIService(context)).GetAwaiter().GetResult(); ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(WebAPIService).Name); // Prevents this host process from terminating so services keeps running. Thread.Sleep(Timeout.Infinite); } else { var host = WebHost.CreateDefaultBuilder() .UseStartup <Startup>() .Build(); host.Run(); } } catch (Exception e) { BigBrother.Write(e); throw; } }
public void EntryPoint_PushTimed() { var bb = new BigBrother(DevKey, DevKey).DeveloperMode(); bb.Publish(new TestTimedEvent()); bb.Flush(); }
public async Task Test_KustoTestEvent_StreamsToKusto() { KustoQueryClient.Should().NotBeNull(); var bb = new BigBrother("", ""); bb.UseKusto(KustoName, KustoLocation, KustoDatabase, KustoTenantId); var evt = new KustoTestEvent(); bb.Publish(evt); await Policy.Handle <Exception>() .WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30) }) .ExecuteAsync(async() => { var reader = await KustoQueryClient.ExecuteQueryAsync( KustoDatabase, $"{nameof(KustoTestEvent)} | where {nameof(KustoTestEvent.Id)} == \"{evt.Id}\" | summarize count()", ClientRequestProperties.FromJsonString("{}")); reader.Read().Should().BeTrue(); reader.GetInt64(0).Should().Be(1); }); }
/// <summary> /// This is the entry point of the service host process. /// </summary> private static async Task Main() { try { if (EnvironmentHelper.IsInFabric) { var builder = new ContainerBuilder(); builder.RegisterModule <ServiceFabricModule>(); builder.RegisterServiceFabricSupport(); builder.RegisterStatelessService <BullfrogNotificationApiService>("BullfrogNotificationApiServiceType"); using (var container = builder.Build()) { await Task.Delay(Timeout.Infinite); } } else { var host = WebHost.CreateDefaultBuilder() .UseStartup <Startup>() .Build(); host.Run(); } } catch (Exception e) { BigBrother.Write(e); throw; } }
/// <summary> /// Configures how the <see cref="BigBrother"/> instance processes domain events. /// </summary> /// <param name="bigBrother">The BigBrother instance to configure.</param> /// <param name="componentContext">The component context.</param> public void Initialize(BigBrother bigBrother, IComponentContext componentContext) { if (_publishEvents != null) { bigBrother.PublishEventsToTopics(_publishEvents); } }
static void Main(string[] args) { BigBrother.Publish(new BulkImportEvent("some message", Guid.NewGuid(), Guid.NewGuid(), false)); BigBrother.Flush(); Console.ReadKey(false); }
public void EntryPoint_PushEvent() { IBigBrother bb = BigBrother.CreateDefault(DevKey, DevKey).DeveloperMode(); bb.Publish(new TestTelemetryEvent()); bb.Flush(); }
public void Test_WriteEvent_WithTraceEvent() { const string exceptionMessage = "KABUM"; var completed = Task.Factory.StartNew( () => { using var session = new TraceEventSession($"TestSession_{nameof(Test_WriteEvent_WithTraceEvent)}"); session.Source.Dynamic.AddCallbackForProviderEvent( ErrorEventSource.EventSourceName, nameof(ErrorEventSource.Tasks.ExceptionEvent), e => { e.PayloadByName("message").Should().Be(exceptionMessage); e.PayloadByName("eventPayload").Should().NotBeNull(); // ReSharper disable once AccessToDisposedClosure session.Source?.Dispose(); }); session.EnableProvider(ErrorEventSource.EventSourceName); Task.Factory.StartNew(() => { var brother = BigBrother.CreateDefault("blah", "blah"); // to initialize internal Rx subscriptions Task.Delay(TimeSpan.FromSeconds(3)); BigBrother.Write(new ExceptionEvent(new Exception(exceptionMessage))); }); session.Source.Process(); }) .Wait(TimeSpan.FromSeconds(30)); completed.Should().BeTrue(); }
public Task Queued_buffer_1s(int count) { var kustoName = Environment.GetEnvironmentVariable("kusto_name"); var kustoLocation = Environment.GetEnvironmentVariable("kusto_location"); var kustoDatabase = Environment.GetEnvironmentVariable("kusto_database"); var kustoTenantId = Environment.GetEnvironmentVariable("kusto_tenant_id"); var source = new TaskCompletionSource <bool>(); var brother = new BigBrother(); brother .UseKusto() .WithCluster(kustoName, kustoLocation, kustoDatabase, kustoTenantId) .WithBufferOptions(new BufferedClientOptions { BufferSizeItems = 50, IngestionInterval = TimeSpan.FromSeconds(1), FlushImmediately = true }) .RegisterType <KustoBenchmarkEvent>() .WithQueuedClient() .Build(n => { if (n >= count) { source.SetResult(true); } }); for (int i = 0; i < count; i++) { brother.Publish(new KustoBenchmarkEvent()); } return(source.Task); }
private async Task InternalHandle(object _) { var handle = string.Empty; try { UnregisterTimer(_handleTimer); var handleList = (await StateManager.GetStateNamesAsync()).ToList(); if (!handleList.Any()) { return; } var messageDataConditional = await StateManager.TryGetStateAsync <MessageData>(handleList.First()); if (!messageDataConditional.HasValue) { _bigBrother.Publish(new WebhookEvent("message was empty")); return; } var messageData = messageDataConditional.Value; handle = messageData.HandleAsString; var handler = _eventHandlerFactory.CreateEventHandler(messageData.Type); await handler.Call(messageData); await StateManager.RemoveStateAsync(messageData.HandleAsString); await ActorProxy.Create <IPoolManagerActor>(new ActorId(0)).CompleteWork(messageData.Handle); } catch (Exception e) { //don't want msg state managed by fabric just yet, let failures be backed by the service bus subscriptions if (handle != string.Empty) { await StateManager.RemoveStateAsync(handle); } BigBrother.Write(e.ToExceptionEvent()); } finally { //restarts the timer in case there are more than one msg in the state, if not then let it be restarted in the standard msg population flow. if ((await StateManager.GetStateNamesAsync()).Any()) { _handleTimer = RegisterTimer( InternalHandle, null, TimeSpan.FromMilliseconds(100), TimeSpan.MaxValue); } } }
public void InitializerExecutesCallback() { var bigBrother = new BigBrother(); var initializer = new ConfigureBigBrotherInitializer((bb, cc) => bb.KustoDbName = "aab"); var componentContext = new FakeComponentContext(); initializer.Initialize(bigBrother, componentContext); bigBrother.KustoDbName.Should().Be("aab"); }
public async Task Test_HighContention() { var tasks = new List <Task>(); for (var x = 0; x < 10; x++) { tasks.Add(Task.Run(() => BigBrother.CreateDefault("blah", "blah"))); } //this will blow up in V2 await Task.WhenAll(tasks.ToArray()); }
public void Test_Publish_NoTopics_WhenNotSetup() { var bb = new BigBrother("", ""); bb.TelemetrySubscriptions.Clear(); // disable normal telemetry var dEvent = new TestDomainEvent(); var mPublisher = new Mock <IPublishEvents>(); bb.Publish(dEvent); mPublisher.Verify(x => x.Publish(It.IsAny <TelemetryEvent>()), Times.Never); }
public void EntryPoint_PushAnonymous() { IBigBrother bb = new BigBrother(DevKey, DevKey).DeveloperMode(); bb.Publish(new { SomeStuff = Lorem.GetSentence(), SomeMoreStuff = Lorem.GetSentence(), AndEvenMoreStuff = Lorem.GetSentence() }); bb.Flush(); }
public KustoBenchmark() { var kustoName = Environment.GetEnvironmentVariable("kusto_name"); var kustoLocation = Environment.GetEnvironmentVariable("kusto_location"); var kustoDatabase = Environment.GetEnvironmentVariable("kusto_database"); var kustoTenantId = Environment.GetEnvironmentVariable("kusto_tenant_id"); _bbForHandle = BigBrother.CreateDefault("", ""); _bbForHandle.UseKusto() .WithCluster(kustoName, kustoLocation, kustoDatabase, kustoTenantId) .RegisterType <KustoBenchmarkEvent>() .WithDirectClient() .Build(); }
public override async Task CallAsync <TRequest>(TRequest request, IDictionary <string, object> metadata, CancellationToken cancellationToken) { if (!(request is MessageData messageData)) { throw new Exception("injected wrong implementation"); } var uri = RequestBuilder.BuildUri(WebhookConfig, messageData.Payload); var httpMethod = RequestBuilder.SelectHttpMethod(WebhookConfig, messageData.Payload); var payload = RequestBuilder.BuildPayload(this.WebhookConfig, messageData.Payload, metadata); var config = RequestBuilder.SelectWebhookConfig(WebhookConfig, messageData.Payload); var headers = RequestBuilder.GetHttpHeaders(WebhookConfig, messageData); var authenticationConfig = RequestBuilder.GetAuthenticationConfig(WebhookConfig, messageData.Payload); var httpClient = HttpClientFactory.Get(config); await AddAuthenticationHeaderAsync(cancellationToken, authenticationConfig, headers); var response = await httpClient.SendRequestReliablyAsync(httpMethod, uri, headers, payload, cancellationToken); BigBrother.Publish( new WebhookEvent( messageData.EventHandlerActorId, messageData.Type, $"Response status code {response.StatusCode}", uri.AbsoluteUri, httpMethod, response.StatusCode, messageData.CorrelationId )); if (metadata == null) { metadata = new Dictionary <string, object>(); } else { metadata.Clear(); } var content = await response.Content.ReadAsStringAsync(); metadata.Add("HttpStatusCode", (int)response.StatusCode); metadata.Add("HttpResponseContent", content); //call callback var eswHandler = _eventHandlerFactory.CreateWebhookHandler(_subscriberConfiguration.Callback.Name); await eswHandler.CallAsync(messageData, metadata, cancellationToken); }
protected override async Task RunAsync(CancellationToken cancellationToken) { try { await base.RunAsync(cancellationToken); var proxy = ActorProxy.Create <IMessagingDirector>(new ActorId(0)); await proxy.Run(); } catch (Exception e) { BigBrother.Write(e); throw; } }
public void EntryPoint_PushException() { const string message = "KABOOM!!!"; IBigBrother bb = new BigBrother(DevKey, DevKey).DeveloperMode(); try { BlowUp(message); } catch (Exception ex) { bb.Publish(ex.ToExceptionEvent()); bb.Flush(); } }
public void Test_Publish_WontSendNonDomainEvents_ToTopics() { var bb = new BigBrother("", ""); bb.TelemetrySubscriptions.Clear(); // disable normal telemetry var dEvent = new TestTimedEvent(); var mPublisher = new Mock <IPublishEvents>(); bb.PublishEventsToTopics(mPublisher.Object); bb.Publish(dEvent); mPublisher.Verify(x => x.Publish(It.IsAny <TelemetryEvent>()), Times.Never); }
public Startup(IHostingEnvironment env) { try { _configuration = EswDevOpsSdk.BuildConfiguration(env.ContentRootPath, env.EnvironmentName); var internalKey = _configuration["BBInstrumentationKey"]; _bb = new BigBrother(internalKey, internalKey); _bb.UseEventSourceSink().ForExceptions(); } catch (Exception e) { BigBrother.Write(e); throw; } }
/// <summary> /// This is the entry point of the service host process. /// </summary> private static async Task Main() { try { ActorRuntime.RegisterActorAsync <MessagingDirector>((context, actorType) => new MessagingDirectorService(context, actorType, (service, id) => new MessagingDirector(service, id))) .GetAwaiter() .GetResult(); await Task.Delay(Timeout.Infinite); } catch (Exception e) { BigBrother.Write(e); throw; } }
public void Test_Publish_UsesTopics_WhenSetup() { var bb = new BigBrother("", ""); bb.TelemetrySubscriptions.Clear(); // disable normal telemetry var dEvent = new TestDomainEvent(); var mPublisher = new Mock <IPublishEvents>(); mPublisher.Setup(x => x.Publish(It.IsAny <TelemetryEvent>())).Returns(Task.CompletedTask); bb.PublishEventsToTopics(mPublisher.Object); bb.Publish(dEvent); mPublisher.VerifyAll(); }
private async Task InternalHandle(object state) { var messageDelivered = true; MessageData messageData = null; try { UnregisterTimer(_handleTimer); messageData = state as MessageData; if (messageData == null) { _bigBrother.Publish(new ActorError($" actor timer state could not be parsed to a guid so removing it.", this)); return; } if (string.IsNullOrWhiteSpace(messageData.Type)) { _bigBrother.Publish(new ActorError($"message is missing type - it cannot be processed", this)); return; } var handler = _eventHandlerFactory.CreateEventHandler(messageData.Type, messageData.SubscriberName); await handler.CallAsync(messageData, new Dictionary <string, object>(), CancellationToken.None); } catch (Exception e) { BigBrother.Write(e.ToExceptionEvent()); messageDelivered = false; } finally { if (messageData != null) { try { await StateManager.RemoveStateAsync(messageData.HandlerId.ToString()); await ServiceProxy.Create <IEventReaderService>(new Uri(messageData.ReplyTo)).CompleteMessageAsync(messageData, messageDelivered); } catch (Exception e) { BigBrother.Write(e.ToExceptionEvent()); } } } }
/// <summary> /// Completes the messages if the delivery was successful, else message is not removed from service bus and allowed to be redelivered /// </summary> /// <param name="messageData"></param> /// <param name="messageDelivered"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task CompleteMessageAsync(MessageData messageData, bool messageDelivered, CancellationToken cancellationToken = default) { try { if (!_inflightMessages.TryRemove(messageData.CorrelationId, out var handle)) { throw new LockTokenNotFoundException("lock token was not found in inflight message queue") { EventType = messageData.Type, HandlerId = messageData.HandlerId, CorrelationId = messageData.CorrelationId }; } try { //let the message naturally expire if it's an unsuccessful delivery if (messageDelivered) { //try to lookup the receiver if (_messageReceivers.TryGetValue(handle.ReceiverId, out var receiverWrapper)) { Interlocked.Decrement(ref receiverWrapper.ReceivedCount); await receiverWrapper.Receiver.CompleteAsync(handle.LockToken); } else { _bigBrother.Publish(new MessageReceiverNoLongerAvailable { FabricId = Context.ServiceName.ToString() }); } } } catch (MessageLockLostException e) { BigBrother.Write(e.ToExceptionEvent()); } } catch (Exception e) { BigBrother.Write(e.ToExceptionEvent()); } finally { _freeHandlers.Enqueue(messageData.HandlerId); } }
/// <inheritdoc /> /// <summary> /// </summary> /// <returns></returns> public override async Task <string> GetTokenAsync(CancellationToken cancellationToken) { if (string.IsNullOrEmpty(OidcAuthenticationConfig.ClientId)) { throw new ArgumentNullException(nameof(OidcAuthenticationConfig.ClientId)); } if (string.IsNullOrEmpty(OidcAuthenticationConfig.ClientSecret)) { throw new ArgumentNullException(nameof(OidcAuthenticationConfig.ClientSecret)); } var httpClient = HttpClientFactory.Get(OidcAuthenticationConfig.Uri); var headers = new WebHookHeaders(); headers.AddContentHeader(Constants.Headers.ContentType, "application/json-patch+json"); headers.AddRequestHeader("client_id", OidcAuthenticationConfig.ClientId); headers.AddRequestHeader("client_secret", OidcAuthenticationConfig.ClientSecret); var authProviderResponse = await httpClient.SendRequestReliablyAsync( HttpMethod.Post, new Uri(OidcAuthenticationConfig.Uri), headers, string.Empty, cancellationToken); if (authProviderResponse.StatusCode != HttpStatusCode.Created || authProviderResponse.Content == null) { throw new Exception("didn't get a token from the provider"); } var responseContent = await authProviderResponse.Content.ReadAsStringAsync(); var stsResult = JsonConvert.DeserializeObject <OidcAuthenticationToken>(responseContent); OidcAuthenticationToken = stsResult; BigBrother.Publish(new ClientTokenRequest { ClientId = OidcAuthenticationConfig.ClientId, Authority = OidcAuthenticationConfig.Uri }); return($"Bearer {stsResult.AccessToken}"); }
public override async Task Call <TRequest>(TRequest request, IDictionary <string, object> metadata = null) { if (!(request is MessageData messageData)) { throw new Exception("injected wrong implementation"); } if (WebhookConfig.AuthenticationConfig.Type != AuthenticationType.None) { await AcquireTokenHandler.GetToken(_client); } var uri = RequestBuilder.BuildUri(WebhookConfig, messageData.Payload); var httpVerb = RequestBuilder.SelectHttpVerb(WebhookConfig, messageData.Payload); var payload = RequestBuilder.BuildPayload(WebhookConfig, messageData.Payload, metadata); void TelemetryEvent(string msg) { BigBrother.Publish(new HttpClientFailure(messageData.Handle, messageData.Type, messageData.Payload, msg)); } var response = await _client.ExecuteAsJsonReliably(httpVerb, uri, payload, TelemetryEvent); BigBrother.Publish(new WebhookEvent(messageData.Handle, messageData.Type, messageData.Payload, response.IsSuccessStatusCode.ToString())); if (metadata == null) { metadata = new Dictionary <string, object>(); } else { metadata.Clear(); } var content = await response.Content.ReadAsStringAsync(); metadata.Add("HttpStatusCode", (int)response.StatusCode); metadata.Add("HttpResponseContent", content); BigBrother.Publish(new WebhookEvent(messageData.Handle, messageData.Type, content)); //call callback var eswHandler = _eventHandlerFactory.CreateWebhookHandler(_eventHandlerConfig.CallbackConfig.Name); await eswHandler.Call(messageData, metadata); }
/// <summary> /// The entry point of the service host process. /// </summary> private static async Task Main() { try { var builder = new ContainerBuilder(); builder.RegisterModule(new CoreModule()); builder.RegisterModule(new VstsModule()); builder.RegisterModule(new AzureManagementFluentModule()); builder.RegisterServiceFabricSupport(); builder.RegisterActor <TenantActor>(); builder.RegisterActor <LockerActor>(); builder.RegisterActor <RepositoryActor>(); builder.RegisterActor <TestActor>(); builder.RegisterActor <ManagedIdentityActor>(); builder.RegisterActor <ResourceGroupActor>(); builder.RegisterActor <BuildDefinitionActor>(); builder.RegisterActor <ReleaseDefinitionActor>(); builder.RegisterActor <ScaleSetIdentityActor>(); builder.Register(c => new SierraDbContext { ConnectionString = c.Resolve <IConfigurationRoot>()["SierraDbConnectionString"] }); using (var container = builder.Build()) { try { var dbCtx = container.Resolve <SierraDbContext>(); dbCtx.Database.Migrate(); } catch (Exception e) { container.Resolve <IBigBrother>().Publish(e.ToExceptionEvent()); } await Task.Delay(Timeout.Infinite); } } catch (Exception e) { BigBrother.Write(e); throw; } }
public void Test_ReleaseHandleNotAlive() { using (ShimsContext.Create()) { var now = DateTime.Now.AddMinutes(15); // offset now by 15 minutes, this way we don't need to play around with the internal handle var handle = new object(); ShimDateTime.NowGet = () => now; var bb = new BigBrother(); bb.Publish(new TestTelemetryEvent(), handle); // no setup on the subscriptions, so nothing will get published bb.ReleaseCorrelationVectors(null); bb.CorrelationHandles.Should().BeEmpty(); } }
public async Task Test_KustoTestEvent_StreamsToKusto(bool useDirect) { _kustoQueryClient.Should().NotBeNull(); var bb = BigBrother.CreateDefault("", ""); var builder = bb.UseKusto() .WithCluster(_kustoName, _kustoLocation, _kustoDatabase, _kustoTenantId); if (useDirect) { builder.RegisterType <KustoTestEvent>().WithDirectClient().Build(); } else { builder.RegisterType <KustoTestEvent>().WithQueuedClient().Build(); } var evt = new KustoTestEvent(); bb.Publish(evt); await Policy.Handle <Exception>() .WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5) }) .ExecuteAsync(async() => { var reader = await _kustoQueryClient.ExecuteQueryAsync( _kustoDatabase, $"{nameof(KustoTestEvent)} | where {nameof(KustoTestEvent.Id)} == \"{evt.Id}\" | summarize count()", ClientRequestProperties.FromJsonString("{}")); _output.WriteLine("Checking if event is in Kusto ..."); reader.Read().Should().BeTrue(); reader.GetInt64(0).Should().Be(1); _output.WriteLine("Event verified."); }); }
/// <summary> /// This is the entry point of the service host process. /// </summary> private static async Task Main() { try { var builder = new ContainerBuilder(); builder.RegisterModule <CoreModule>(); builder.RegisterServiceFabricSupport(); builder.RegisterStatefulService <BullfrogNotificationBackendService>("BullfrogNotificationBackendServiceType"); using (var container = builder.Build()) { await Task.Delay(Timeout.Infinite); } } catch (Exception e) { BigBrother.Write(e); ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString()); throw; } }