private static async Task <Command_Summary_Projection_Return> ProcessCommandStatusInformationProjection( string commandId, string commandName, ILogger log) { Command_Summary_Projection_Return ret = null; 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 HandleCreateLeagueCommand"); } #endregion // Get the current state of the command... Projection getCommandState = new Projection(@"Command", commandName, commandGuid.ToString(), nameof(Command_Summary_Projection)); if (null != getCommandState) { #region Logging if (null != log) { log.LogDebug($"Projection processor created in HandleCreateLeagueCommand"); } #endregion Command_Summary_Projection cmdProjection = new Command_Summary_Projection(log); await getCommandState.Process(cmdProjection); if ((cmdProjection.CurrentSequenceNumber > 0) || (cmdProjection.ProjectionValuesChanged())) { ret = new Command_Summary_Projection_Return() { AsOfDate = cmdProjection.CurrentAsOfDate, AsOfStepNumber = (int)cmdProjection.CurrentSequenceNumber, Status = cmdProjection.CurrentState.ToString(), CommandName = commandName, CorrelationIdentifier = cmdProjection.CorrelationIdentifier }; } } } } return(ret); }
/// <summary> /// Perform the underlying processing on the specified command /// </summary> /// <param name="commandId"> /// The unique identifier of the command to process /// </param> private static async Task HandleCreateLeagueCommand(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 HandleCreateLeagueCommand"); } #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 HandleCreateLeagueCommand"); } #endregion Command_Summary_Projection cmdProjection = new Command_Summary_Projection(log); await getCommandState.Process(cmdProjection); if ((cmdProjection.CurrentSequenceNumber > 0) || (cmdProjection.ProjectionValuesChanged())) { if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Completed) { // No need to process a completed projection #region Logging if (null != log) { log.LogWarning($"Command {commandId} is complete so no need to process in HandleCreateLeagueCommand"); } #endregion return; } if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Created) { // No need to process a completed projection #region Logging if (null != log) { log.LogWarning($"Command {commandId} is not yet validated so cannot process in HandleCreateLeagueCommand"); } #endregion return; } if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Invalid) { // No need to process a completed projection #region Logging if (null != log) { log.LogWarning($"Command {commandId} is not yet marked as invalid so cannot process in HandleCreateLeagueCommand"); } #endregion return; } if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Validated) { string leagueName = string.Empty; // New or previously invalid command can be validated if (cmdProjection.ParameterIsSet(nameof(Create_New_League_Definition.LeagueName))) { // League name may not be blank leagueName = cmdProjection.GetParameter <string>(nameof(Create_New_League_Definition.LeagueName)); } string location = string.Empty; if (cmdProjection.ParameterIsSet(nameof(Create_New_League_Definition.Location))) { location = cmdProjection.GetParameter <string>(nameof(Create_New_League_Definition.Location)); } DateTime dateIncorporated = DateTime.UtcNow; if (cmdProjection.ParameterIsSet(nameof(Create_New_League_Definition.Date_Incorporated))) { dateIncorporated = cmdProjection.GetParameter <DateTime>(nameof(Create_New_League_Definition.Date_Incorporated)); } // Create a new "League Created" event Leagues.League.eventDefinition.Formed formedEvent = new Leagues.League.eventDefinition.Formed(dateIncorporated, location, $"{leagueName} created by command {commandGuid} "); EventStream leagueEvents = new EventStream(@"Leagues", "League", leagueName); if ((null != leagueEvents) && (null != formedEvent)) { if (null != writeContext) { leagueEvents.SetContext(writeContext); } await leagueEvents.AppendEvent(formedEvent); } // if there is contact details, add an event for that string emailAddress = string.Empty; if (cmdProjection.ParameterIsSet(nameof(Create_New_League_Definition.Email_Address))) { emailAddress = cmdProjection.GetParameter <string>(nameof(Create_New_League_Definition.Email_Address)); } string twitterHandle = string.Empty; if (cmdProjection.ParameterIsSet(nameof(Create_New_League_Definition.Twitter_Handle))) { twitterHandle = cmdProjection.GetParameter <string>(nameof(Create_New_League_Definition.Twitter_Handle)); } if ((!string.IsNullOrWhiteSpace(emailAddress)) || (!string.IsNullOrWhiteSpace(twitterHandle))) { // Create a new "Contact details changed" event Leagues.League.eventDefinition.Contact_Details_Changed contactDetailsEvent = new Leagues.League.eventDefinition.Contact_Details_Changed(DateTime.UtcNow, twitterHandle, emailAddress); if ((null != leagueEvents) && (null != contactDetailsEvent)) { if (null != writeContext) { leagueEvents.SetContext(writeContext); } await leagueEvents.AppendEvent(contactDetailsEvent); } } } } 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 } } } } }
/// <summary> /// Perform the underlying processing on the specified command /// </summary> /// <param name="commandId"> /// The unique identifier of the command to process /// </param> private static async Task HandleSetLeagueEmailAddressCommand(string commandId, ILogger log, IWriteContext writeContext = null) { 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 HandleSetLeagueEmailAddressCommand"); } #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 HandleSetLeagueEmailAddressCommand"); } #endregion Command_Summary_Projection cmdProjection = new Command_Summary_Projection(log); await getCommandState.Process(cmdProjection); if ((cmdProjection.CurrentSequenceNumber > 0) || (cmdProjection.ProjectionValuesChanged())) { if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Completed) { // No need to process a completed projection #region Logging if (null != log) { log.LogWarning($"Command {commandId} is complete so no need to process in HandleSetLeagueEmailAddressCommand"); } #endregion return; } if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Created) { // No need to process a completed projection #region Logging if (null != log) { log.LogWarning($"Command {commandId} is not yet validated so cannot process in HandleSetLeagueEmailAddressCommand"); } #endregion return; } if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Invalid) { // No need to process a completed projection #region Logging if (null != log) { log.LogWarning($"Command {commandId} is not yet marked as invalid so cannot process in HandleSetLeagueEmailAddressCommand"); } #endregion return; } if (cmdProjection.CurrentState == Command_Summary_Projection.CommandState.Validated) { string leagueName = string.Empty; // New or previously invalid command can be validated if (cmdProjection.ParameterIsSet(nameof(Set_Email_Address_Definition.LeagueName))) { // Get the league name we want to set the email address leagueName = cmdProjection.GetParameter <string>(nameof(Set_Email_Address_Definition.LeagueName)); } string twitterHandle = string.Empty; if (cmdProjection.ParameterIsSet(nameof(Create_New_League_Definition.Twitter_Handle))) { twitterHandle = cmdProjection.GetParameter <string>(nameof(Create_New_League_Definition.Twitter_Handle)); } string emailAddress = string.Empty; if (cmdProjection.ParameterIsSet(nameof(Set_Email_Address_Definition.New_Email_Address))) { emailAddress = cmdProjection.GetParameter <string>(nameof(Set_Email_Address_Definition.New_Email_Address)); } string notes = string.Empty; if (cmdProjection.ParameterIsSet(nameof(Set_Email_Address_Definition.Notes))) { notes = cmdProjection.GetParameter <string>(nameof(Set_Email_Address_Definition.Notes)); } // Create a new "Contact Details Changed" event Leagues.League.eventDefinition.Contact_Details_Changed changedEvent = new Leagues.League.eventDefinition.Contact_Details_Changed(DateTime.UtcNow, twitterHandle, emailAddress); EventStream leagueEvents = new EventStream(@"Leagues", "League", leagueName); if ((null != leagueEvents) && (null != changedEvent)) { if (null != writeContext) { leagueEvents.SetContext(writeContext); } await leagueEvents.AppendEvent(changedEvent); } } } } 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 HandleSetLeagueEmailAddressCommand"); } #endregion } } }
/// <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); }