public void Record(string action, string reason, string message, V1ObjectReference objRef) { var occurrence = DateTime.Now; var key = new EventKey($"{objRef.ApiVersion}/{objRef.Kind}", action, reason, message, $"{objRef.NamespaceProperty}/{objRef.Name}"); if (!events.ContainsKey(key)) { Logger.LogDebug("Initializing new EventDetail entry for {objName}", key.ToString()); events.Add(key, EventDetails.Initialize(objRef.Name, occurrence)); } EventDetails details = events[key]; details.AddOccurrence(occurrence); Logger.LogDebug("Writing event to Kubernetes ({key}, Count: {count}", key.ToString(), details.Count); V1Event ev = new V1Event(objRef, new V1ObjectMeta() { Name = details.Name }, action: action, message: message, reason: reason, firstTimestamp: details.FirstSeen, lastTimestamp: details.LastSeen, count: details.Count); Kubernetes.ReplaceNamespacedEventAsync(ev, details.Name, objRef.NamespaceProperty); }
private async Task<string> DescribeObject(Kubernetes client, V1Namespace ns, V1Event o, StringBuilder buffer) { var fetched = await client.ReadNamespacedEventAsync(o.Metadata.Name, ns.Metadata.Name).ConfigureAwait(false); buffer.AppendLine($"API Veresion: {fetched.ApiVersion}"); buffer.AppendLine($"Kind: {fetched.Kind}"); buffer.AppendLine(DescribeMetadata(fetched.Metadata)); return $"Event - {fetched.Metadata.Name}"; }
/// <summary> /// Gets the matching <see cref="V1EventFilter"/> for the specified <see cref="V1Event"/> /// </summary> /// <param name="e">The <see cref="V1Event"/> to get the matching <see cref="V1EventFilter"/> for</param> /// <returns>The matching <see cref="V1EventFilter"/> for the specified <see cref="V1Event"/>, if any</returns> public virtual V1EventFilter?GetMatchingFilterFor(V1Event e) { if (e == null) { throw new ArgumentNullException(nameof(e)); } return(this.Filters.FirstOrDefault(f => f.Filters(e))); }
/// <summary> /// Determines whether or not the <see cref="V1CorrelationCondition"/> matches the specified <see cref="V1Event"/> /// </summary> /// <param name="e">The <see cref="V1Event"/> to match</param> /// <returns>A boolean indicating whether or not the <see cref="V1CorrelationCondition"/> matches the specified <see cref="V1Event"/></returns> public virtual bool Matches(V1Event e) { if (e == null) { throw new ArgumentNullException(nameof(e)); } return(this.GetMatchingFilterFor(e) != null); }
/// <summary> /// Gets the first matching <see cref="V1CorrelationCondition"/> for the specified <see cref="V1Event"/> /// </summary> /// <param name="e">The <see cref="V1Event"/> to get the <see cref="V1CorrelationCondition"/> for</param> /// <returns>The first matching <see cref="V1CorrelationCondition"/> for the specified <see cref="V1Event"/>, if any</returns> public virtual V1CorrelationCondition?GetMatchingConditionFor(V1Event e) { if (e == null) { throw new ArgumentNullException(nameof(e)); } return(this.Conditions.FirstOrDefault(c => c.Matches(e))); }
/// <summary> /// Determines whether or not the specified <see cref="V1Event"/> matches one of the <see cref="V1Correlation"/>'s conditions /// </summary> /// <param name="e">The <see cref="V1Event"/> to check</param> /// <returns>A boolean indicating whether or not the specified <see cref="V1Event"/> matches one of the <see cref="V1Correlation"/>'s conditions</returns> public virtual bool AppliesTo(V1Event e) { if (e == null) { throw new ArgumentNullException(nameof(e)); } return(this.GetMatchingConditionFor(e) != null); }
public void EmitEvent(string action, string reason, string message, CustomResource involvedObject) { var objRef = new V1ObjectReference(involvedObject.ApiVersion, kind: involvedObject.Kind, name: involvedObject.Metadata.Name, namespaceProperty: involvedObject.Metadata.NamespaceProperty); V1Event ev = new V1Event(objRef, new V1ObjectMeta() { GenerateName = involvedObject.Metadata.Name }, action: action, message: message, reason: reason, firstTimestamp: DateTime.Now); client.CreateNamespacedEvent(ev, involvedObject.Metadata.NamespaceProperty); }
/// <inheritdoc/> public virtual async Task <bool> TryCorrelateAsync(V1Event e, IEnumerable <string> mappingKeys, CancellationToken cancellationToken = default) { if (e == null) { throw new ArgumentNullException(nameof(e)); } if (mappingKeys == null) { mappingKeys = Array.Empty <string>(); } return(await this.SynapseRuntimeApi.TryCorrelateAsync(new() { WorkflowInstanceId = this.Instance.Id, Event = e, MappingKeys = mappingKeys }, cancellationToken)); }
/// <summary> /// Generates a Cloud Event for a Kubernetes Event (v1 schema) /// </summary> /// <param name="kubernetesEvent">Event that occured in Kubernetes cluster</param> public CloudEvent GenerateFromKubernetesEvent(V1Event kubernetesEvent) { Guard.NotNull(kubernetesEvent, nameof(kubernetesEvent)); var eventId = kubernetesEvent.Metadata.Uid ?? Guid.NewGuid().ToString(); var eventTime = kubernetesEvent.LastTimestamp ?? DateTime.UtcNow; var cloudEvent = new CloudEvent(CloudEventsSpecVersion.V0_1, DefaultEventType, EventSource, eventId, eventTime) { ContentType = new ContentType(contentType: "application/json"), Data = kubernetesEvent }; return(cloudEvent); }
/// <summary> /// Ingests the specified <see cref="CloudEvent"/> /// </summary> /// <param name="serviceProvider">The current <see cref="IServiceProvider"/></param> /// <param name="e">The <see cref="CloudEvent"/> to ingest</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/></param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual async Task CorrelateAsync(IServiceProvider serviceProvider, CloudEvent e, CancellationToken cancellationToken) { try { var mediator = serviceProvider.GetRequiredService <IMediator>(); await mediator.ExecuteAndUnwrapAsync(new V1CorrelateEventCommand(V1Event.CreateFrom(e)), cancellationToken); } catch (TaskCanceledException) { throw; } catch (Exception ex) { this.Logger.LogError("An error occured while processing an incoming cloud event: {ex}", ex.ToString()); } }
/// <summary> /// Handles an incoming <see cref="CloudEvent"/> /// </summary> /// <param name="e">The <see cref="CloudEvent"/> to handle</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/></param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual async Task OnEventAsync(CloudEvent e) { using (await this.Lock.LockAsync(this.CancellationTokenSource.Token)) { if (this.IdleTimer != null) { this.IdleTimer.Dispose(); this.IdleTimer = null !; } if ((!string.IsNullOrWhiteSpace(this.EventDefinition.Source) && !Regex.IsMatch(e.Source !.ToString(), this.EventDefinition.Source, RegexOptions.IgnoreCase)) || (!string.IsNullOrWhiteSpace(this.EventDefinition.Type) && !Regex.IsMatch(e.Type !, this.EventDefinition.Type, RegexOptions.IgnoreCase))) { return; } if (!await this.Context.Workflow.TryCorrelateAsync(V1Event.CreateFrom(e), this.EventDefinition.Correlations?.Select(c => c.ContextAttributeName) !, this.CancellationTokenSource.Token)) { return; } await this.OnNextAsync(new V1WorkflowActivityCompletedIntegrationEvent(this.Activity.Id, e.Data), this.CancellationTokenSource.Token); await this.OnCompletedAsync(this.CancellationTokenSource.Token); } }
private async Task Update() { Item = await State.Client.ReadNamespacedEventAsync(Name, Namespace); StateHasChanged(); }
private async Task HandleKubernetesEvent(WatchEventType type, V1Event kubernetesEvent) { var cloudEvent = _cloudEventsSchematizer.GenerateFromKubernetesEvent(kubernetesEvent); await _cloudEventsPublisher.Publish(cloudEvent); }
/// <summary> /// Initializes a new <see cref="V1GetEventCorrelationsQuery"/> /// </summary> /// <param name="e">The <see cref="V1Event"/> to get the matching <see cref="V1Correlation"/>s for</param> public V1GetEventCorrelationsQuery(V1Event e) { this.Event = e; }
/// <summary> /// Performs a correlation on a <see cref="V1Event"/>, in a given <see cref="V1CorrelationContext"/> and using the specified <see cref="V1EventFilter"/> /// </summary> /// <param name="correlation">The <see cref="V1Correlation"/> to perform</param> /// <param name="correlationContext">The <see cref="V1CorrelationContext"/> in which to perform the <see cref="V1Correlation"/></param> /// <param name="e">The <see cref="V1Event"/> to correlate</param> /// <param name="filter">The <see cref="V1EventFilter"/> used to correlate the <see cref="V1Event"/></param> /// <param name="cancellationToken">A <see cref="CancellationToken"/></param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual async Task CorrelateAsync(V1Correlation correlation, V1CorrelationContext correlationContext, V1Event e, V1EventFilter filter, CancellationToken cancellationToken = default) { this.Logger.LogInformation("Correlating event to context with id '{contextId}'...", correlationContext.Id); correlationContext.Correlate(e, filter.CorrelationMappings.Keys, true); correlation = await this.Correlations.UpdateAsync(correlation, cancellationToken); await this.Correlations.SaveChangesAsync(cancellationToken); this.Logger.LogInformation("Event successfully correlated to context with id '{contextId}'", correlationContext.Id); this.Logger.LogInformation("Attempting to complete the correlation with id '{correlationId}' in context with id '{contextId}'...", correlation.Id, correlationContext.Id); if (!correlation.TryComplete(correlationContext)) { this.Logger.LogInformation("Correlations conditions are not met in the specified correlation context"); return; } this.Logger.LogInformation("Correlation with id '{correlationId}' has been completed in context with id '{contextId}. Computing outcome...", correlation.Id, correlationContext.Id); switch (correlation.Outcome.Type) { case V1CorrelationOutcomeType.Start: await this.Mediator.ExecuteAndUnwrapAsync(new V1CreateWorkflowInstanceCommand(correlation.Outcome.Target, V1WorkflowInstanceActivationType.Trigger, new(), correlationContext, true, null), cancellationToken); break; case V1CorrelationOutcomeType.Correlate: await this.Mediator.ExecuteAndUnwrapAsync(new V1CorrelateWorkflowInstanceCommand(correlation.Outcome.Target, correlationContext), cancellationToken); break; default: throw new NotSupportedException($"The specified {nameof(V1CorrelationOutcomeType)} '{correlation.Outcome.Type}' is not supported"); } correlation.ReleaseContext(correlationContext); correlation = await this.Correlations.UpdateAsync(correlation, cancellationToken); await this.Correlations.SaveChangesAsync(cancellationToken); if (correlation.Lifetime == V1CorrelationLifetime.Singleton) { this.Logger.LogInformation("The correlation with id '{correlationId}' is a singleton and its context has been released. Disposing of it...", correlation.Id); await this.Mediator.ExecuteAndUnwrapAsync(new V1DeleteCorrelationCommand(correlation.Id), cancellationToken); this.Logger.LogInformation("The correlation with id '{correlationId}' has been successfully disposed of", correlation.Id); } this.Logger.LogInformation("Correlation outcome successfully computed"); }
/// <summary> /// Initializes a new <see cref="V1CorrelateEventCommand"/> /// </summary> /// <param name="e">The <see cref="V1Event"/> to correlate</param> public V1CorrelateEventCommand(V1Event e) { this.Event = e; }
/// <summary> /// Initializes a new <see cref="V1TryCorrelateWorkflowInstanceCommand"/> /// </summary> /// <param name="workflowInstanceId">The id of the <see cref="V1WorkflowInstance"/> to correlate</param> /// <param name="e">The <see cref="V1Event"/> to correlate</param> /// <param name="mappingKeys">An <see cref="IEnumerable{T}"/> containing the mapping keys to use to correlate the <see cref="V1WorkflowInstance"/></param> public V1TryCorrelateWorkflowInstanceCommand(string workflowInstanceId, V1Event e, IEnumerable <string> mappingKeys) { this.WorkflowInstanceId = workflowInstanceId; this.Event = e; this.MappingKeys = mappingKeys; }