private async Task <bool> HandleGetByIdRequest( HttpContext httpContext, IStateMachineContextStorage contextStorage) { var segments = this.routeMatcher.Match(this.options.RoutePrefix + "/{name}/{id}", httpContext.Request.Path); if (segments?.ContainsKey("name") == true && segments?.ContainsKey("id") == true) { this.logger.LogInformation($"statemachine: get by id (name={segments["name"]}, id={segments["id"]})"); var context = contextStorage.FindById(segments["id"] as string); if (context?.Name?.Equals(segments["name"] as string, StringComparison.OrdinalIgnoreCase) == true) { httpContext.Response.StatusCode = (int)HttpStatusCode.OK; httpContext.Response.ContentType = "application/json"; await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(context, JsonSerializerSettings.Create()), Encoding.UTF8).ConfigureAwait(false); } else { httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; } return(true); } return(false); }
private async Task <bool> HandleGetTriggersRequest( HttpContext httpContext, IStateMachineContextStorage contextStorage, IEnumerable <IStatemachineDefinition> definitions, ITransitionDispatcher dispatcher) { var segments = this.routeMatcher.Match(this.options.RoutePrefix + "/{name}/{id}/triggers", httpContext.Request.Path); if (segments?.ContainsKey("name") == true && segments?.ContainsKey("id") == true) { this.logger.LogInformation($"statemachine: get triggers (name={segments["name"]}, id={segments["id"]})"); var definition = definitions.Safe() .FirstOrDefault(d => d.Name.Equals(segments["name"] as string, StringComparison.OrdinalIgnoreCase)); if (definition == null) { httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; var details = new ProblemDetails() { Title = "state machine definition not found", Status = (int)HttpStatusCode.BadRequest, Instance = $"{this.options.RoutePrefix}/{segments["name"]}/{segments["id"]}", }; httpContext.Response.ContentType = "application/json"; await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(details, JsonSerializerSettings.Create()), Encoding.UTF8).ConfigureAwait(false); return(true); } var context = contextStorage.FindById(segments["id"] as string); if (context == null) { httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; return(true); } if (!context.Name.Equals(segments["name"] as string, StringComparison.OrdinalIgnoreCase)) { httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; return(true); } var instance = definition.CreateInstance(context, dispatcher); httpContext.Response.StatusCode = (int)HttpStatusCode.OK; httpContext.Response.ContentType = "application/json"; httpContext.Response.Headers.Add("Location", $"{this.options.RoutePrefix}/{segments["name"]}/{context.Id}"); await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(instance.PermittedTriggers, JsonSerializerSettings.Create()), Encoding.UTF8).ConfigureAwait(false); return(true); } return(false); }
private async Task <bool> HandleFireTriggerRequest( HttpContext httpContext, IStateMachineContextStorage contextStorage, IStateMachineContentStorage contentStorage, IEnumerable <IStatemachineDefinition> definitions, ITransitionDispatcher dispatcher) { var segments = this.routeMatcher.Match(this.options.RoutePrefix + "/{name}/{id}/triggers/{trigger}", httpContext.Request.Path); if (segments?.ContainsKey("name") == true && segments?.ContainsKey("id") == true && segments?.ContainsKey("trigger") == true) { this.logger.LogInformation($"statemachine: fire trigger (name={segments["name"]}, id={segments["id"]}, trigger={segments["trigger"]})"); var definition = definitions.Safe() .FirstOrDefault(d => d.Name.Equals(segments["name"] as string, StringComparison.OrdinalIgnoreCase)); if (definition == null) { httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; var details = new ProblemDetails() { Title = "state machine definition not found", Status = (int)HttpStatusCode.BadRequest, Instance = $"{this.options.RoutePrefix}/{segments["name"]}/{segments["id"]}", }; httpContext.Response.ContentType = "application/json"; await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(details, JsonSerializerSettings.Create()), Encoding.UTF8).ConfigureAwait(false); return(true); } var context = contextStorage.FindById(segments["id"] as string); if (context == null) { httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; return(true); } if (context.IsExpired()) { httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; var details = new ProblemDetails() { Title = "state machine is expired", Status = (int)HttpStatusCode.BadRequest, Instance = $"{this.options.RoutePrefix}/{context.Name}/{context.Id}", }; httpContext.Response.ContentType = "application/json"; await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(details, JsonSerializerSettings.Create()), Encoding.UTF8).ConfigureAwait(false); return(true); } if (!context.Name.Equals(segments["name"] as string, StringComparison.OrdinalIgnoreCase)) { httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; return(true); } httpContext.Request.Query.ForEach(i => context.Properties.AddOrUpdate(i.Key, i.Value)); var instance = definition.CreateInstance(context, dispatcher); try { await this.StoreContent(httpContext, "_current", context, contextStorage, contentStorage).ConfigureAwait(false); if (await instance.FireAsync(segments["trigger"] as string).ConfigureAwait(false)) { await this.StoreContent(httpContext, context.State, context, contextStorage, contentStorage).ConfigureAwait(false); this.logger.LogInformation($"statemachine: trigger successfull (name={segments["name"]}, id={segments["id"]}, trigger={segments["trigger"]})"); contextStorage.Save(context); httpContext.Response.StatusCode = (int)HttpStatusCode.OK; } else { this.logger.LogError($"statemachine: trigger invalid (name={segments["name"]}, id={segments["id"]}, trigger={segments["trigger"]})"); httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; } } catch (Exception ex) { this.logger.LogCritical(ex, $"statemachine: trigger failed (name={segments["name"]}, id={segments["id"]}, trigger={segments["trigger"]}) {ex.Message}"); httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; } finally { this.logger.LogInformation($"statemachine: permitted triggers={string.Join("|", instance.PermittedTriggers)}"); contextStorage.Save(context); } return(true); } return(false); }