/// <summary> /// Gets the availability of a specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The availability of the specified cell. /// </returns> public static Availability GetAvailability( this IAvailabilityCheckCell cell) { if (cell == null) { throw new ArgumentNullException(nameof(cell)); } var availabilityCheckStatus = cell.GetAvailabilityCheckStatus(); switch (availabilityCheckStatus) { case AvailabilityCheckStatus.AvailabilityCheckMissing: case AvailabilityCheckStatus.Unchecked: return(cell.DefaultAvailability); case AvailabilityCheckStatus.DeterminedSubjectIsEnabled: return(Availability.Enabled); case AvailabilityCheckStatus.DeterminedSubjectIsDisabled: return(Availability.Disabled); default: return(Availability.Unknown); } }
/// <summary> /// Gets the availability check message for a specified cell or null if none exists. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The availability check message for the specified cell or null if none exists. /// </returns> public static string GetAvailabilityCheckMessageOrNull( this IAvailabilityCheckCell cell) { if (cell == null) { throw new ArgumentNullException(nameof(cell)); } string result; var lastAvailabilityCheckEvent = cell.AvailabilityCheckEvents?.LastOrDefault(); if (lastAvailabilityCheckEvent == null) { result = null; } else if (lastAvailabilityCheckEvent is IHaveMessage haveMessageEvent) { result = haveMessageEvent.Message; } else { result = null; } return(result); }
public CheckAvailabilityOfCellIfNecessaryOp DeepCloneWithCell(IAvailabilityCheckCell cell) { var result = new CheckAvailabilityOfCellIfNecessaryOp( cell); return(result); }
private async Task CheckAvailabilityOfCellIfNecessaryAsync( IAvailabilityCheckCell cell) { // NOTE: THIS CODE IS A NEAR DUPLICATE OF THE SYNC METHOD ABOVE; NO GOOD WAY TO D.R.Y. IT OUT var availabilityCheckStatus = cell.GetAvailabilityCheckStatus(); if (availabilityCheckStatus == AvailabilityCheckStatus.AvailabilityCheckMissing) { // no-op } else if (availabilityCheckStatus == AvailabilityCheckStatus.Unchecked) { CellAvailabilityCheckEventBase availabilityCheckEvent; try { var availabilityCheck = cell.AvailabilityCheck; var availabilityCheckResult = await this.protocolFactory.GetProtocolAndExecuteViaReflectionAsync <AvailabilityCheckResult>(availabilityCheck.Operation); string message = null; if (availabilityCheckResult.MessageOp != null) { message = await this.protocolFactory.GetProtocolAndExecuteViaReflectionAsync <string>(availabilityCheckResult.MessageOp); } var availability = await this.protocolFactory.GetProtocolAndExecuteViaReflectionAsync <Availability>(availabilityCheckResult.AvailabilityOp); if (availability == Availability.Disabled) { availabilityCheckEvent = new CellAvailabilityCheckDeterminedCellDisabledEvent(this.timestampUtc, null, message); } else if (availability == Availability.Enabled) { availabilityCheckEvent = new CellAvailabilityCheckDeterminedCellEnabledEvent(this.timestampUtc, null, message); } else { throw new NotSupportedException(Invariant($"This {nameof(Availability)} is not supported: {availability}.")); } } catch (Exception ex) { // The "proper" exception for a protocol to throw is an OpExecutionFailedExceptionBase. // Protocol authors might not comply. availabilityCheckEvent = new CellAvailabilityCheckFailedEvent(this.timestampUtc, ex.ToString()); } cell.Record(availabilityCheckEvent); } else if (cell.AvailabilityCheckEvents.Last().TimestampUtc != this.timestampUtc) { throw new InvalidOperationException("Something went wrong. The cell was checked for availability, but the recorded timestamp doesn't match this timestamp."); } }
/// <summary> /// Initializes a new instance of the <see cref="CheckAvailabilityOfCellIfNecessaryOp"/> class. /// </summary> /// <param name="cell">The cell.</param> public CheckAvailabilityOfCellIfNecessaryOp( IAvailabilityCheckCell cell) { if (cell == null) { throw new ArgumentNullException(nameof(cell)); } this.Cell = cell; }
/// <summary> /// Gets the availability check status of a specified cell. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The availability check status of the specified cell. /// </returns> public static AvailabilityCheckStatus GetAvailabilityCheckStatus( this IAvailabilityCheckCell cell) { if (cell == null) { throw new ArgumentNullException(nameof(cell)); } AvailabilityCheckStatus result; var lastAvailabilityCheckEvent = cell.AvailabilityCheckEvents?.LastOrDefault(); if (cell.AvailabilityCheck == null) { result = AvailabilityCheckStatus.AvailabilityCheckMissing; } else if (lastAvailabilityCheckEvent == null) { result = AvailabilityCheckStatus.Unchecked; } else if (lastAvailabilityCheckEvent is CellAvailabilityCheckClearedEvent) { result = AvailabilityCheckStatus.Unchecked; } else if (lastAvailabilityCheckEvent is CellAvailabilityCheckDeterminedCellEnabledEvent) { result = AvailabilityCheckStatus.DeterminedSubjectIsEnabled; } else if (lastAvailabilityCheckEvent is CellAvailabilityCheckDeterminedCellDisabledEvent) { result = AvailabilityCheckStatus.DeterminedSubjectIsDisabled; } else if (lastAvailabilityCheckEvent is CellAvailabilityCheckFailedEvent) { result = AvailabilityCheckStatus.Failed; } else { throw new InvalidOperationException(Invariant($"Cannot determine the {nameof(AvailabilityCheckStatus)} of the specified cell.")); } return(result); }