/// <summary> /// Perform the underlying validation on the specified command /// </summary> /// <param name="commandId"> /// The unique identifier of the command to validate /// </param> private static async Task <bool> ValidateCreateLeagueCommand(string commandId, ILogger log, IWriteContext writeContext = null) { const string COMMAND_NAME = @"create-league"; Guid commandGuid; // use custom assembly resolve handler using (new AzureFunctionsResolveAssembly()) { if (Guid.TryParse(commandId, out commandGuid)) { #region Logging if (null != log) { log.LogDebug($"Validating command {commandId} in ValidateCreateLeagueCommand"); } #endregion // Get the current state of the command... Projection getCommandState = new Projection(Constants.Domain_Command, COMMAND_NAME, commandGuid.ToString(), nameof(Command_Summary_Projection)); if (null != getCommandState) { #region Logging if (null != log) { log.LogDebug($"Projection processor created in ValidateCreateLeagueCommand"); } #endregion Command_Summary_Projection cmdProjection = new Command_Summary_Projection(log); await getCommandState.Process(cmdProjection); if ((cmdProjection.CurrentSequenceNumber > 0) || (cmdProjection.ProjectionValuesChanged())) { #region Logging if (null != log) { log.LogDebug($"Command { cmdProjection.CommandName} projection run for {commandGuid} in ValidateCreateLeagueCommand"); } #endregion if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Completed) { // No need to validate a completed command #region Logging if (null != log) { log.LogWarning($"Command {commandId} is complete so no need to validate in ValidateCreateLeagueCommand"); } #endregion return(true); } if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Validated) { // No need to process a completed projection #region Logging if (null != log) { log.LogWarning($"Command {commandId} is validated so no need to validate again in ValidateCreateLeagueCommand"); } #endregion return(true); } if ((cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Created) || (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Invalid)) { bool leagueNameValid = false; bool incoporatedDateValid = false; // New or previously invalid command can be validated if (cmdProjection.ParameterIsSet(nameof(Create_New_League_Definition.LeagueName))) { // League name may not be blank string leagueName = cmdProjection.GetParameter <string>(nameof(Create_New_League_Definition.LeagueName)); if (string.IsNullOrWhiteSpace(leagueName)) { await CommandErrorLogRecord.LogCommandValidationError(commandGuid, COMMAND_NAME, true, "League name may not be blank"); #region Logging if (null != log) { log.LogWarning($"Command {COMMAND_NAME } :: {commandId} has a blank league name in ValidateCreateLeagueCommand"); } #endregion } else { leagueNameValid = true; // was the name already used? EventStream leagueEvents = new EventStream(@"Leagues", "League", leagueName); if (null != leagueEvents) { bool alreadyUsed = await leagueEvents.Exists(); if (alreadyUsed) { await CommandErrorLogRecord.LogCommandValidationError(commandGuid, COMMAND_NAME, true, $"League name '{leagueName}' already created."); #region Logging if (null != log) { log.LogWarning($"Command {COMMAND_NAME } :: {commandId} league name '{leagueName}' already created in ValidateCreateLeagueCommand"); } #endregion leagueNameValid = false; } } } } // The incoporation date may not be in the future if (cmdProjection.ParameterIsSet(nameof(ICreate_New_League_Definition.Date_Incorporated))) { DateTime dateIncorporated = cmdProjection.GetParameter <DateTime>(nameof(ICreate_New_League_Definition.Date_Incorporated)); if (dateIncorporated > DateTime.UtcNow) { await CommandErrorLogRecord.LogCommandValidationError(commandGuid, COMMAND_NAME, false, "Incorporation date is in the future"); #region Logging if (null != log) { log.LogWarning($"Command {COMMAND_NAME } :: {commandId} has a future dated incorporation date in ValidateCreateLeagueCommand"); } #endregion } else { incoporatedDateValid = true; } } if (incoporatedDateValid && leagueNameValid) { await CommandErrorLogRecord.LogCommandValidationSuccess(commandGuid, COMMAND_NAME); } return(incoporatedDateValid && leagueNameValid); } } else { // No events were read into the projection so do nothing #region Logging if (null != log) { log.LogWarning($"No command events read for {commandId} in ValidateCreateLeagueCommand"); } #endregion } } } return(false); } }
/// <summary> /// Perform the underlying validation on the specified command /// </summary> /// <param name="commandId"> /// The unique identifier of the command to validate /// </param> /// <remarks> /// This is common functionality, whether called by function chaining or by duarble functions /// </remarks> private static async Task <bool> ValidateSetLeagueEmailAddressCommand(string commandId, ILogger log) { const string COMMAND_NAME = @"set-league-email-address"; Guid commandGuid; if (Guid.TryParse(commandId, out commandGuid)) { #region Logging if (null != log) { log.LogDebug($"Validating command {commandId} in ValidateSetLeagueEmailAddressCommand"); } #endregion // Get the current state of the command... Projection getCommandState = new Projection(@"Command", COMMAND_NAME, commandGuid.ToString(), nameof(Command_Summary_Projection)); if (null != getCommandState) { #region Logging if (null != log) { log.LogDebug($"Projection processor created in ValidateSetLeagueEmailAddressCommand"); } #endregion Command_Summary_Projection cmdProjection = new Command_Summary_Projection(log); await getCommandState.Process(cmdProjection); if ((cmdProjection.CurrentSequenceNumber > 0) || (cmdProjection.ProjectionValuesChanged())) { #region Logging if (null != log) { log.LogDebug($"Command { cmdProjection.CommandName} projection run for {commandGuid} in ValidateSetLeagueEmailAddressCommand"); } #endregion if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Completed) { // No need to validate a completed command #region Logging if (null != log) { log.LogWarning($"Command {commandId} is complete so no need to validate in ValidateSetLeagueEmailAddressCommand"); } #endregion return(true); } if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Validated) { // No need to process ana lready validated command #region Logging if (null != log) { log.LogWarning($"Command {commandId} is validated so no need to validate again in ValidateSetLeagueEmailAddressCommand"); } #endregion return(true); } if ((cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Created) || (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Invalid)) { bool leagueNameValid = false; bool emailAddressValid = false; // New or previously invalid command can be validated if (cmdProjection.ParameterIsSet(nameof(Set_Email_Address_Definition.LeagueName))) { // League name may not be blank string leagueName = cmdProjection.GetParameter <string>(nameof(Create_New_League_Definition.LeagueName)); if (string.IsNullOrWhiteSpace(leagueName)) { await CommandErrorLogRecord.LogCommandValidationError(commandGuid, COMMAND_NAME, true, "League name may not be blank"); #region Logging if (null != log) { log.LogWarning($"Command {COMMAND_NAME } :: {commandId} has a blank league name in ValidateSetLeagueEmailAddressCommand"); } #endregion } else { leagueNameValid = true; } } // The email address should not be blank if (cmdProjection.ParameterIsSet(nameof(Create_New_League_Definition.Email_Address))) { string emailAddress = cmdProjection.GetParameter <string>(nameof(Create_New_League_Definition.Email_Address)); if (string.IsNullOrEmpty(emailAddress)) { await CommandErrorLogRecord.LogCommandValidationError(commandGuid, COMMAND_NAME, false, "Email address is blank"); #region Logging if (null != log) { log.LogWarning($"Command {COMMAND_NAME } :: {commandId} has a future dated incorporation date in ValidateSetLeagueEmailAddressCommand"); } #endregion } else { emailAddressValid = true; } } if (emailAddressValid && leagueNameValid) { await CommandErrorLogRecord.LogCommandValidationSuccess(commandGuid, COMMAND_NAME); return(true); } } } else { // No events were read into the projection so do nothing #region Logging if (null != log) { log.LogWarning($"No command events read for {commandId} in ValidateSetLeagueEmailAddressCommand"); } #endregion } } } // If, for any reason, we can't validate the command the default is to return false return(false); }