public static async Task LogProjectionResult(Guid queryGuid, string queryName, string projectionTypeName, string domainName, string aggregateTypeName, string aggregateInstanceKey, Nullable <DateTime> asOfDate, object projectionValues, int sequenceNumber, IWriteContext writeContext = null) { EventStream qryEvents = EventStream.Create(Constants.Domain_Query, queryName, queryGuid.ToString()); if (null != qryEvents) { if (null != writeContext) { qryEvents.SetContext(writeContext); } await qryEvents.AppendEvent(new TheLongRun.Common.Events.Query.ProjectionValueReturned(domainName, aggregateTypeName, WebUtility.UrlDecode(aggregateInstanceKey), WebUtility.UrlDecode(projectionTypeName), asOfDate.GetValueOrDefault(DateTime.UtcNow), projectionValues, sequenceNumber)); } }
/// <summary> /// Append an event onto the event stream of the domain entity (aka aggregate) /// </summary> /// <param name="domainName"> /// The top level domain name /// </param> /// <param name="entityTypeName"> /// The name of the type (class) of the entity to append the event to /// </param> /// <param name="entityInstanceKey"> /// The unique identifier of the entity onto which we are appending the event /// </param> /// <param name="eventToAppend"> /// The event we are appending to the entity instance event stream /// </param> public async Task AppendDomainEntityEvent(string domainName, string entityTypeName, string entityInstanceKey, IEvent eventToAppend) { // Validate the parameters if (string.IsNullOrWhiteSpace(domainName)) { throw new ArgumentException("Domain name must be specified"); } if (string.IsNullOrWhiteSpace(entityTypeName)) { throw new ArgumentException("Entity type must be specified"); } if (string.IsNullOrWhiteSpace(entityInstanceKey)) { throw new ArgumentException("Entity instance unique identifier must be specified"); } if (null == eventToAppend) { throw new ArgumentException("No event specified to append to the entity event stream"); } EventStream targetStream = EventStream.Create(domainName, entityTypeName, entityInstanceKey); if (null != targetStream) { await targetStream.AppendEvent(eventToAppend); } }
public static async Task RequestProjection(Guid queryGuid, string queryName, string projectionName, string domainName, string aggregateTypeName, string aggregateInstanceKey, Nullable <DateTime> asOfDate, IWriteContext writeContext = null) { EventStream qryEvents = EventStream.Create(Constants.Domain_Query, queryName, queryGuid.ToString()); if (null != qryEvents) { if (null != writeContext) { qryEvents.SetContext(writeContext); } await qryEvents.AppendEvent(new TheLongRun.Common.Events.Query.ProjectionRequested(domainName, aggregateTypeName, WebUtility.UrlDecode(aggregateInstanceKey), WebUtility.UrlDecode(projectionName), asOfDate)); } }
public static async Task <ActivityResponse> QueryLogOutputTargetActivity( [ActivityTrigger] DurableActivityContext context, ILogger log) { ActivityResponse ret = new ActivityResponse() { FunctionName = "QueryLogOutputTargetActivity" }; #region Logging if (null != log) { log.LogDebug($"Logging query output in {ret.FunctionName} "); } #endregion QueryRequest <object> queryRequest = context.GetInput <QueryRequest <object> >(); if (null != queryRequest) { EventStream queryEvents = EventStream.Create(Constants.Domain_Query, queryRequest.QueryName, queryRequest.QueryUniqueIdentifier.ToString()); if (null != queryEvents) { // Set the context for the events to be written using queryEvents.SetContext(new WriteContext(ret.FunctionName, context.InstanceId)); if (null != queryRequest.ResponseTargets) { foreach (var responseTarget in queryRequest.ResponseTargets) { // set the parameter(s) await queryEvents.AppendEvent(new TheLongRun.Common.Events.Query.OutputLocationSet (responseTarget.ReturnPath, responseTarget.ReturnTarget)); #region Logging if (null != log) { // Unable to get the request details from the orchestration log.LogInformation($"{ret.FunctionName } : Set output path {responseTarget.ReturnPath} : {responseTarget.ReturnTarget} "); } #endregion } } } else { ret.Message = $"Unable to get the event stream for {queryRequest.QueryName} : {queryRequest.QueryUniqueIdentifier }"; ret.FatalError = true; } } return(ret); }
/// <summary> /// Subscribe to all log events for a given match /// </summary> /// <param name="matchKey"></param> /// <param name="onStreamClosed"></param> /// <returns>An awaitable task that finishes when the stream is opened</returns> public async Task SubscribeLogEvents(string matchKey, Action onStreamClosed = null) { var eventStream = await EventStream.Create($"{clientConfig.Endpoint}/fetch/log", new { matchKey }, StreamHeaders); eventStream.OnDataReceived += LogStore.Dispatch; eventStream.Start(); eventStream.OnEventsFinished += () => { onStreamClosed?.Invoke(); }; }
public static async Task <Guid> GetLeagueSummaryCreateQueryRequestActivity( [ActivityTrigger] DurableActivityContext context, ILogger log) { #region Logging if (null != log) { log.LogInformation($"GetLeagueSummaryCreateQueryRequestActivity started - instance {context.InstanceId} "); } #endregion QueryRequest <Get_League_Summary_Definition> queryRequest = context.GetInput <QueryRequest <Get_League_Summary_Definition> >(); if (queryRequest.QueryUniqueIdentifier.Equals(Guid.Empty)) { queryRequest.QueryUniqueIdentifier = Guid.NewGuid(); } // Create a new Query record to hold the event stream for this query... QueryLogRecord <Get_League_Summary_Definition> qryRecord = QueryLogRecord <Get_League_Summary_Definition> .Create( queryRequest.QueryName, queryRequest.GetParameters(), queryRequest.ResponseTargets, queryRequest.QueryUniqueIdentifier); if (null != qryRecord) { EventStream queryEvents = EventStream.Create(Constants.Domain_Query, queryRequest.QueryName, qryRecord.QueryUniqueIdentifier.ToString()); if (null != queryEvents) { await queryEvents.CreateIfNotExists(); // Set the context for the events to be written using queryEvents.SetContext(new WriteContext("GetLeagueSummaryCreateQueryRequestActivity", context.InstanceId)); // Log the query creation await queryEvents.AppendEvent(new TheLongRun.Common.Events.Query.QueryCreated(queryRequest.QueryName, qryRecord.QueryUniqueIdentifier)); } // Return the ID of the query record we created return(qryRecord.QueryUniqueIdentifier); } // If we got here there was a problem so return an empty GUID return(Guid.Empty); }
/// <summary> /// Subscribe to all session events /// </summary> /// <param name="onStreamClosed"></param> /// <returns>An awaitable task that finishes when the stream is opened</returns> public async Task SubscribeSessionEvents(Action onStreamClosed = null) { var command = new SessionQuery(); var eventStream = await EventStream.Create($"{clientConfig.Endpoint}/fetch/{command.Type}", null, StreamHeaders); eventStream.OnDataReceived += SessionStore.Dispatch; eventStream.Start(); eventStream.OnEventsFinished += () => { onStreamClosed?.Invoke(); }; }
/// <summary> /// Mark a command as being valid /// </summary> /// <param name="commandGuid"> /// The unique identifier of the command to mark as valid /// </param> /// <param name="commandName"> /// The name of the command to mark as valid /// </param> public static async Task LogCommandValidationSuccess(Guid commandGuid, string commandName, IWriteContext writeContext = null) { EventStream commandEvents = EventStream.Create(Constants.Domain_Command, commandName, commandGuid.ToString()); if (null != commandEvents) { if (null != writeContext) { commandEvents.SetContext(writeContext); } await commandEvents.AppendEvent(new TheLongRun.Common.Events.Command.ValidationSucceeded(DateTime.UtcNow)); } }
/// <summary> /// Log a validation error to the given command event stream /// </summary> /// <param name="commandGuid"> /// The unique identifier of the command to log to /// </param> /// <param name="CommandName"> /// The name of the command being validated /// </param> /// <param name="fatal"> /// True if this is considered a fatal error /// </param> /// <param name="errorMessage"> /// /// </param> public static async Task LogCommandValidationError(Guid commandGuid, string CommandName, bool fatal, string errorMessage, IWriteContext writeContext = null) { EventStream commandEvents = EventStream.Create(Constants.Domain_Command, CommandName, commandGuid.ToString()); if (null != commandEvents) { if (null != writeContext) { commandEvents.SetContext(writeContext); } await commandEvents.AppendEvent(new TheLongRun.Common.Events.Command.ValidationErrorOccured(errorMessage, fatal)); } }
/// <summary> /// Log a particular parameter validation error to the given query record /// </summary> /// <param name="queryGuid"> /// Unique identifier of the query that had the error /// </param> /// <param name="queryName"> /// Name of the query that had the error /// </param> /// <param name="fatalError"> /// Is the error considered fatal /// </param> /// <param name="errorMessage"> /// Message for the validation error /// param> public static async Task LogQueryValidationError(Guid queryGuid, string queryName, bool fatalError, string errorMessage, IWriteContext writeContext = null) { EventStream qryEvents = EventStream.Create(Constants.Domain_Query, queryName, queryGuid.ToString()); if (null != qryEvents) { if (null != writeContext) { qryEvents.SetContext(writeContext); } await qryEvents.AppendEvent(new TheLongRun.Common.Events.Query.QueryParameterValidationErrorOccured(queryName, fatalError, errorMessage)); } }
public static async Task <ActivityResponse> CommandCompleteActivity( [ActivityTrigger] DurableActivityContext context, ILogger log) { ActivityResponse ret = new ActivityResponse() { FunctionName = "CommandCompleteActivity" }; try { CommandRequest <object> cmdResponse = context.GetInput <CommandRequest <object> >(); if (null != cmdResponse) { // Create a new "command completed" event CommandCompleted commandCompletedEvent = new CommandCompleted() { Date_Completed = DateTime.UtcNow, Notes = cmdResponse.Status }; EventStream commandEvents = EventStream.Create(Constants.Domain_Command, cmdResponse.CommandName, cmdResponse.CommandUniqueIdentifier.ToString()); if ((null != commandEvents) && (null != commandCompletedEvent)) { await commandEvents.AppendEvent(commandCompletedEvent); } } } catch (Exception ex) { ret.Message = $"Error marking command complete : {ex.Message }"; } return(ret); }
public static async Task <ActivityResponse> CommandStepCompleteActivity( [ActivityTrigger] DurableActivityContext context, ILogger log) { ActivityResponse ret = new ActivityResponse() { FunctionName = "CommandStepComplete" }; try { CommandStepResponse cmdStepResponse = context.GetInput <CommandStepResponse>(); if (null != cmdStepResponse) { // Create a new "command step" event CommandStepCompleted commandStepCompletedEvent = new CommandStepCompleted() { StepName = cmdStepResponse.StepName, ImpactedEntities = cmdStepResponse.ImpactedEntities }; EventStream commandEvents = EventStream.Create(Constants.Domain_Command, cmdStepResponse.CommandName, cmdStepResponse.CommandUniqueIdentifier.ToString()); if ((null != commandEvents) && (null != commandStepCompletedEvent)) { await commandEvents.AppendEvent(commandStepCompletedEvent); } } } catch (Exception ex) { ret.Message = $"Error marking step complete : {ex.Message }"; } return(ret); }
public static async Task <ActivityResponse> GetLeagueSummaryLogParametersActivity( [ActivityTrigger] DurableActivityContext context, ILogger log = null) { ActivityResponse ret = new ActivityResponse() { FunctionName = "GetLeagueSummaryLogParametersActivity" }; try { QueryRequest <Get_League_Summary_Definition> queryRequest = context.GetInput <QueryRequest <Get_League_Summary_Definition> >(); if (null != queryRequest) { if (null != log) { // Unable to get the request details from the orchestration log.LogInformation($"GetLeagueSummaryLogParametersActivity : Logging parameters for query {queryRequest.QueryUniqueIdentifier} "); } EventStream queryEvents = EventStream.Create(Constants.Domain_Query, queryRequest.QueryName, queryRequest.QueryUniqueIdentifier.ToString()); if (null != queryEvents) { // Set the context for the events to be written using queryEvents.SetContext(new WriteContext(ret.FunctionName, context.InstanceId)); // set the parameter(s) await queryEvents.AppendEvent(new TheLongRun.Common.Events.Query.QueryParameterValueSet (nameof(Get_League_Summary_Definition.League_Name), queryRequest.GetParameters().League_Name)); if (null != log) { // Unable to get the request details from the orchestration log.LogInformation($"GetLeagueSummaryLogParametersActivity : Logged parameters - League name : {queryRequest.GetParameters().League_Name } "); } ret.Message = $"Logged parameters - League name : {queryRequest.GetParameters().League_Name } "; } else { ret.Message = $"Unable to get the event stream for {queryRequest.QueryName} : {queryRequest.QueryUniqueIdentifier }"; ret.FatalError = true; } } else { ret.Message = $"Unable to get the request details from {context.ToString()} "; ret.FatalError = true; } } catch (Exception ex) { if (null != log) { // Unable to get the request details from the orchestration log.LogError($"GetLeagueSummaryLogParametersActivity : error {ex.Message} "); } ret.Message = ex.Message; ret.FatalError = true; } return(ret); }
/// <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 commandName, string commandId, ILogger log, IWriteContext writeContext = 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 ValidateCreateLeagueCommand"); } #endregion // Get the current state of the command... Projection getCommandState = new Projection(Constants.Domain_Command, commandName, 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 = EventStream.Create(@"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 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.Invalid) { // No need to process a command marked as invalid #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 = EventStream.Create(@"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 } } } } }
public static async Task <ActivityResponse> CreateLeagueCommandLogParametersActivity( [ActivityTrigger] DurableActivityContext context, ILogger log) { ActivityResponse ret = new ActivityResponse() { FunctionName = "CreateLeagueCommandLogParametersActivity" }; try { CommandRequest <Create_New_League_Definition> cmdRequest = context.GetInput <CommandRequest <Create_New_League_Definition> >(); if (null != cmdRequest) { if (null != log) { // Unable to get the request details from the orchestration log.LogInformation($"CreateLeagueCommandLogParametersActivity : Logging parameters for command {cmdRequest.CommandUniqueIdentifier} "); } EventStream commandEvents = EventStream.Create(@"Command", cmdRequest.CommandName, cmdRequest.CommandUniqueIdentifier.ToString()); if (null != commandEvents) { // Set the event context to indicate who wrote them commandEvents.SetContext(new WriteContext(ret.FunctionName, context.InstanceId)); Create_New_League_Definition parameters = cmdRequest.GetParameters(); if (null != parameters) { // Set the parameters await commandEvents.AppendEvent(new TheLongRun.Common.Events.Command.ParameterValueSet(nameof(parameters.LeagueName), parameters.LeagueName)); await commandEvents.AppendEvent(new TheLongRun.Common.Events.Command.ParameterValueSet(nameof(parameters.Email_Address), parameters.Email_Address)); await commandEvents.AppendEvent(new TheLongRun.Common.Events.Command.ParameterValueSet(nameof(parameters.Date_Incorporated), parameters.Date_Incorporated)); await commandEvents.AppendEvent(new TheLongRun.Common.Events.Command.ParameterValueSet(nameof(parameters.Twitter_Handle), parameters.Twitter_Handle)); ret.Message = $"All parameters to set for {cmdRequest.CommandName} : {cmdRequest.CommandUniqueIdentifier}"; } else { ret.Message = $"No parameters to set for {cmdRequest.CommandName} : {cmdRequest.CommandUniqueIdentifier}"; } } else { ret.Message = $"Unable to get the event stream for {cmdRequest.CommandName} : {cmdRequest.CommandUniqueIdentifier}"; ret.FatalError = true; } } else { ret.Message = $"Unable to get the command request details from {context.ToString()} "; ret.FatalError = true; } } catch (Exception ex) { if (null != log) { // Unable to get the request details from the orchestration log.LogError($"CreateLeagueCommandLogParametersActivity : error {ex.Message} "); } ret.Message = ex.Message; ret.FatalError = true; } 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 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(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 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 = EventStream.Create(@"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 } } }