/// <summary> /// Serializes the object to JSON. /// </summary> /// <param name="writer">The <see cref="T: Newtonsoft.Json.JsonWriter" /> to write to.</param> /// <param name="obj">The object to serialize to JSON.</param> internal static void Serialize(JsonWriter writer, ChaosEvent obj) { var kind = obj.Kind; if (kind.Equals(ChaosEventKind.ExecutingFaults)) { ExecutingFaultsChaosEventConverter.Serialize(writer, (ExecutingFaultsChaosEvent)obj); } else if (kind.Equals(ChaosEventKind.Started)) { StartedChaosEventConverter.Serialize(writer, (StartedChaosEvent)obj); } else if (kind.Equals(ChaosEventKind.Stopped)) { StoppedChaosEventConverter.Serialize(writer, (StoppedChaosEvent)obj); } else if (kind.Equals(ChaosEventKind.TestError)) { TestErrorChaosEventConverter.Serialize(writer, (TestErrorChaosEvent)obj); } else if (kind.Equals(ChaosEventKind.ValidationFailed)) { ValidationFailedChaosEventConverter.Serialize(writer, (ValidationFailedChaosEvent)obj); } else if (kind.Equals(ChaosEventKind.Waiting)) { WaitingChaosEventConverter.Serialize(writer, (WaitingChaosEvent)obj); } else { throw new InvalidOperationException("Unknown Kind."); } }
public static ChaosEvent GetEventFromBytes(byte[] data) { ChaosEvent e = null; ChaosEventType type = (ChaosEventType)BitConverter.ToInt32(data, 0); switch (type) { case ChaosEventType.Started: { e = new StartedEvent(); } break; case ChaosEventType.Stopped: { e = new StoppedEvent(); } break; case ChaosEventType.ExecutingFaults: { e = new ExecutingFaultsEvent(); } break; case ChaosEventType.ValidationFailed: { e = new ValidationFailedEvent(); } break; case ChaosEventType.TestError: { e = new TestErrorEvent(); } break; case ChaosEventType.Waiting: { e = new WaitingEvent(); } break; } if (e != null) { byte[] eventData = new byte[data.Length - 4]; Array.Copy(data, 4, eventData, 0, eventData.Length); e.FromBytes(eventData); } return(e); }
private static async Task RegisterChaosEventAndUpdateChaosStatusPrivateAsync( this IReliableStateManager stateManager, ChaosEvent chaosEvent, ChaosStatus currentStatus, Action postAction, CancellationToken cancellationToken) { var eventsDictionary = await stateManager.GetOrAddAsync <IReliableDictionary <long, byte[]> >(FASConstants.ChaosEventsDictionaryName).ConfigureAwait(false); var lastEventKeyDictionary = await stateManager.GetOrAddAsync <IReliableDictionary <string, byte[]> >(FASConstants.ChaosLastEventKeyDictionaryName).ConfigureAwait(false); var statusDictionary = await stateManager.GetOrAddAsync <IReliableDictionary <string, byte[]> >(FASConstants.ChaosStatusDictionaryName).ConfigureAwait(false); using (ITransaction tx = stateManager.CreateTransaction()) { long eventKey = chaosEvent.TimeStampUtc.Ticks; if (await eventsDictionary.ContainsKeyAsync(tx, eventKey, FASConstants.ReliableDictionaryTimeout, cancellationToken).ConfigureAwait(false)) { ++eventKey; chaosEvent.TimeStampUtc = chaosEvent.TimeStampUtc.AddTicks(1); } byte[] chaosEventInBytes = chaosEvent.ToBytes(); TestabilityTrace.TraceSource.WriteInfo(TraceType, "RegisterChaosEventAndUpdateChaosStatusPrivateAsync attempting to add event == {0} with key {1}.", chaosEvent, eventKey); await eventsDictionary.AddOrUpdateAsync(tx, eventKey, chaosEventInBytes, (k, v) => chaosEventInBytes, FASConstants.ReliableDictionaryTimeout, cancellationToken).ConfigureAwait(false); await lastEventKeyDictionary.UpdateLastEventKeyAsync(tx, chaosEvent.TimeStampUtc.Ticks, cancellationToken).ConfigureAwait(false); // Update status byte[] statusInBytes = BitConverter.GetBytes((int)currentStatus); if (await statusDictionary.ContainsKeyAsync(tx, FASConstants.ChaosStatusKeyName, FASConstants.ReliableDictionaryTimeout, cancellationToken).ConfigureAwait(false)) { TestabilityTrace.TraceSource.WriteInfo(TraceType, "RegisterChaosEventAndUpdateChaosStatusPrivateAsync attempting to update status == {0} with key {1}.", currentStatus, FASConstants.ChaosStatusKeyName); await statusDictionary.SetAsync(tx, FASConstants.ChaosStatusKeyName, statusInBytes, FASConstants.ReliableDictionaryTimeout, cancellationToken).ConfigureAwait(false); } else { TestabilityTrace.TraceSource.WriteInfo(TraceType, "RegisterChaosEventAndUpdateChaosStatusPrivateAsync attempting to add status == {0} with key {1}.", currentStatus, FASConstants.ChaosStatusKeyName); await statusDictionary.AddAsync(tx, FASConstants.ChaosStatusKeyName, statusInBytes, FASConstants.ReliableDictionaryTimeout, cancellationToken).ConfigureAwait(false); } if (postAction != null) { postAction(); } TestabilityTrace.TraceSource.WriteInfo(TraceType, "RegisterChaosEventAndUpdateChaosStatusPrivateAsync stored event == {0} and status {1}.", chaosEvent, currentStatus); await tx.CommitAsync().ConfigureAwait(false); } }
public static NativeTypes.FABRIC_CHAOS_EVENT_KIND GetNativeEventType(ChaosEvent e) { if (!ChaosEventTypeToIntMap.ContainsKey(e.GetType())) { throw new InvalidOperationException("Unknown Chaos event type."); } else { return((NativeTypes.FABRIC_CHAOS_EVENT_KIND)ChaosEventTypeToIntMap[e.GetType()]); } }
/// <summary> /// Registers the passed in ChaosEvent in the Reliable Dictionary, /// updates ChaosStatus in the Reliable Dictioanty, /// and do some post processing if postAction is provided, for example postAction can trace. /// </summary> /// <param name="stateManager">The statemanager which manages the event and status RD's.</param> /// <param name="chaosEvent">The chaos event to register</param> /// <param name="chaosStatus">ChaosStatus that should be registered with in the status RD.</param> /// <param name="postAction">Other than registering the chaos event and updating the chaos status, whatever action needs to be taken in the same transaction.</param> /// <param name="partition">The FAS partition.</param> /// <param name="cancellationToken">The cancellation token that was passed into (or created inside) the contaning method.</param> /// <returns></returns> public static async Task RegisterChaosEventAndUpdateChaosStatusAsync( this IReliableStateManager stateManager, ChaosEvent chaosEvent, ChaosStatus chaosStatus, IStatefulServicePartition partition, CancellationToken cancellationToken, Action postAction = null) { await FaultAnalysisServiceUtility.RunAndReportFaultOnRepeatedFailure( ChaosOperationID, () => RegisterChaosEventAndUpdateChaosStatusPrivateAsync(stateManager, chaosEvent, chaosStatus, postAction, cancellationToken), partition, "RegisterChaosEventPrivateAsync", FASConstants.MaxRetriesForReliableDictionary, cancellationToken).ConfigureAwait(false); }
/// <summary> /// Gets the object from Json properties. /// </summary> /// <param name="reader">The <see cref="T: Newtonsoft.Json.JsonReader" /> to read from.</param> /// <returns>The object Value.</returns> internal static ChaosEvent GetFromJsonProperties(JsonReader reader) { ChaosEvent obj = null; var propName = reader.ReadPropertyName(); if (!propName.Equals("Kind", StringComparison.Ordinal)) { throw new JsonReaderException($"Incorrect discriminator property name {propName}, Expected discriminator property name is Kind."); } var propValue = reader.ReadValueAsString(); if (propValue.Equals("ExecutingFaults", StringComparison.Ordinal)) { obj = ExecutingFaultsChaosEventConverter.GetFromJsonProperties(reader); } else if (propValue.Equals("Started", StringComparison.Ordinal)) { obj = StartedChaosEventConverter.GetFromJsonProperties(reader); } else if (propValue.Equals("Stopped", StringComparison.Ordinal)) { obj = StoppedChaosEventConverter.GetFromJsonProperties(reader); } else if (propValue.Equals("TestError", StringComparison.Ordinal)) { obj = TestErrorChaosEventConverter.GetFromJsonProperties(reader); } else if (propValue.Equals("ValidationFailed", StringComparison.Ordinal)) { obj = ValidationFailedChaosEventConverter.GetFromJsonProperties(reader); } else if (propValue.Equals("Waiting", StringComparison.Ordinal)) { obj = WaitingChaosEventConverter.GetFromJsonProperties(reader); } else { throw new InvalidOperationException("Unknown Kind."); } return(obj); }