/// <inheritdoc /> public async Task <Schematic <TState, TInput> > StoreSchematicAsync(Schematic <TState, TInput> schematic, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } if (schematic.SchematicName == null) { throw new ArgumentException("Schematic must have a name to be stored.", nameof(schematic)); } var schematicBytes = schematic.ToSchematicRepresentation(); var record = new Schematic { SchematicName = schematic.SchematicName, SchematicBytes = schematicBytes }; using (var context = DbContextFactory.CreateContext()) { context.Schematics.Add(record); await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); } return(schematic); }
/// <inheritdoc /> public async Task <Schematic <TState, TInput> > StoreSchematicAsync(Schematic <TState, TInput> schematic, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } if (schematic.SchematicName == null) { throw new ArgumentException("Schematic must have a name to be stored.", nameof(schematic)); } var schematicJson = MessagePackSerializer.ToJson( obj: schematic, resolver: ContractlessStandardResolver.Instance); var record = new Schematic { SchematicName = schematic.SchematicName, SchematicJson = schematicJson }; DbContext.Schematics.Add(record); await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false); return(schematic); }
public static byte[] ToSchematicRepresentation <TState, TInput>(this Schematic <TState, TInput> schematic) { return(LZ4MessagePackSerializer.Serialize(schematic, ContractlessStandardResolver.Instance)); }
/// <inheritdoc /> public async Task <ICollection <MachineStatus <TState, TInput> > > BulkCreateMachinesAsync( Schematic <TState, TInput> schematic, IEnumerable <IDictionary <string, string> > metadata, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } var schematicBytes = LZ4MessagePackSerializer.Serialize( obj: schematic, resolver: ContractlessStandardResolver.Instance); var stateJson = MessagePackSerializer.ToJson( obj: schematic.InitialState, resolver: ContractlessStandardResolver.Instance); const long commitNumber = 0L; var updatedTime = DateTimeOffset.UtcNow; var records = new List <Machine>(); var machineStatuses = new List <MachineStatus <TState, TInput> >(); foreach (var dictionary in metadata) { var machineId = Guid.NewGuid().ToString(); List <MetadataEntry> metadataEntries = null; if (dictionary != null) { metadataEntries = dictionary.Select(kvp => new MetadataEntry { Key = kvp.Key, Value = kvp.Value }).ToList(); } records.Add(new Machine { MachineId = machineId, SchematicBytes = schematicBytes, StateJson = stateJson, CommitNumber = commitNumber, UpdatedTime = updatedTime, MetadataEntries = metadataEntries }); machineStatuses.Add(new MachineStatus <TState, TInput> { MachineId = machineId, Schematic = schematic.Clone(), State = schematic.InitialState, Metadata = dictionary, CommitNumber = commitNumber, UpdatedTime = updatedTime, StateBag = new Dictionary <string, string>(0) }); } await DbContext.AddRangeAsync(records, cancellationToken); await DbContext.SaveChangesAsync(cancellationToken); return(machineStatuses); }
/// <inheritdoc /> public async Task <MachineStatus <TState, TInput> > CreateMachineAsync( Schematic <TState, TInput> schematic, string machineId, IDictionary <string, string> metadata, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } var id = machineId ?? Guid.NewGuid().ToString(); var schematicBytes = LZ4MessagePackSerializer.Serialize( obj: schematic, resolver: ContractlessStandardResolver.Instance); var stateJson = MessagePackSerializer.ToJson( obj: schematic.InitialState, resolver: ContractlessStandardResolver.Instance); const long commitNumber = 0L; var updatedTime = DateTimeOffset.UtcNow; var record = new Machine { MachineId = id, SchematicBytes = schematicBytes, StateJson = stateJson, CommitNumber = commitNumber, UpdatedTime = updatedTime }; if (metadata != null) { record.MetadataEntries = metadata.Select(kvp => new MetadataEntry { Key = kvp.Key, Value = kvp.Value }).ToList(); } DbContext.Machines.Add(record); try { await DbContext.SaveChangesAsync(cancellationToken); } catch (DbUpdateException dbEx) when(dbEx.InnerException is SqlException sqlEx && sqlEx.Number == 2627) { throw new MachineAlreadyExistException(record.MachineId); } return(new MachineStatus <TState, TInput> { MachineId = id, Schematic = schematic.Clone(), State = schematic.InitialState, Metadata = metadata, CommitNumber = commitNumber, UpdatedTime = updatedTime, StateBag = new Dictionary <string, string>(0) }); }
/// <inheritdoc /> public async Task <ICollection <MachineStatus <TState, TInput> > > BulkCreateMachinesAsync( Schematic <TState, TInput> schematic, IEnumerable <IDictionary <string, string> > metadata, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } var schematicBytes = schematic.ToSchematicRepresentation(); var stateJson = schematic.InitialState.ToStateRepresentation(); var naturalStateName = schematic.InitialState is TypeState typeState?typeState.GetStateName() : null; const long commitNumber = 0L; var updatedTime = DateTimeOffset.UtcNow; var records = new List <Machine>(); var machineStatuses = new List <MachineStatus <TState, TInput> >(); foreach (var dictionary in metadata) { var machineId = Guid.NewGuid().ToString(); List <MetadataEntry> metadataEntries = null; if (dictionary != null) { metadataEntries = dictionary.Select(kvp => new MetadataEntry { Key = kvp.Key, Value = kvp.Value }).ToList(); } records.Add(new Machine { MachineId = machineId, SchematicBytes = schematicBytes, StateJson = stateJson, NaturalStateName = naturalStateName, CommitNumber = commitNumber, UpdatedTime = updatedTime, MetadataEntries = metadataEntries }); machineStatuses.Add(new MachineStatus <TState, TInput> { MachineId = machineId, Schematic = schematic.Clone(), State = schematic.InitialState, Metadata = dictionary, CommitNumber = commitNumber, UpdatedTime = updatedTime, StateBag = new Dictionary <string, string>(0) }); } using (var context = DbContextFactory.CreateContext()) { await context.AddRangeAsync(records, cancellationToken); await context.SaveChangesAsync(cancellationToken); } return(machineStatuses); }
/// <inheritdoc /> public async Task <MachineStatus <TState, TInput> > CreateMachineAsync( Schematic <TState, TInput> schematic, string machineId, IDictionary <string, string> metadata, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } var id = machineId ?? Guid.NewGuid().ToString(); var schematicBytes = schematic.ToSchematicRepresentation(); var stateJson = schematic.InitialState.ToStateRepresentation(); var naturalStateName = schematic.InitialState is TypeState typeState?typeState.GetStateName() : null; const long commitNumber = 0L; var updatedTime = DateTimeOffset.UtcNow; var record = new Machine { MachineId = id, SchematicName = schematic.SchematicName, SchematicBytes = schematicBytes, StateJson = stateJson, NaturalStateName = naturalStateName, CommitNumber = commitNumber, UpdatedTime = updatedTime }; if (metadata != null) { record.MetadataEntries = metadata.Select(kvp => new MetadataEntry { Key = kvp.Key, Value = kvp.Value }).ToList(); } using (var context = DbContextFactory.CreateContext()) { context.Machines.Add(record); try { await context.SaveChangesAsync(cancellationToken); } catch (DbUpdateException dbEx) when(dbEx.InnerException is SqlException sqlEx && sqlEx.Number == 2627) { throw new MachineAlreadyExistException(record.MachineId); } } return(new MachineStatus <TState, TInput> { MachineId = id, Schematic = schematic.Clone(), State = schematic.InitialState, Metadata = metadata, CommitNumber = commitNumber, UpdatedTime = updatedTime, StateBag = new Dictionary <string, string>(0) }); }
/// <summary> /// Creates a new Machine from a provided Schematic. /// </summary> /// <param name="schematic">The Schematic of the Machine</param> /// <param name="machineId">The Id of Machine to create; if null, an Id will be generated.</param> /// <param name="metadata">Related metadata for the Machine</param> /// <param name="cancellationToken"></param> /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="schematic"/> is null.</exception> /// <exception cref="SchematicDoesNotExistException">Thrown when no matching Schematic was found for the given name.</exception> public async Task <MachineStatus <TState, TInput> > CreateMachineAsync( Schematic <TState, TInput> schematic, string machineId, IDictionary <string, string> metadata, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } var id = machineId ?? Guid.NewGuid().ToString(); var schematicJson = MessagePackSerializer.ToJson( obj: schematic, resolver: ContractlessStandardResolver.Instance); var stateJson = MessagePackSerializer.ToJson( obj: schematic.InitialState, resolver: ContractlessStandardResolver.Instance); string metadataJson = null; if (metadata != null) { metadataJson = MessagePackSerializer.ToJson( obj: metadata); } var commitNumber = 0L; var updatedTime = DateTimeOffset.UtcNow; var record = new EntityFrameworkCoreMachineStatus { MachineId = id, SchematicJson = schematicJson, StateJson = stateJson, CommitNumber = commitNumber, UpdatedTime = updatedTime, MetadataJson = metadataJson }; DbContext.Machines.Add(record); try { await DbContext.SaveChangesAsync(cancellationToken); } catch (DbUpdateException dbEx) when(dbEx.InnerException is SqlException sqlEx && sqlEx.Number == 2627) { throw new MachineAlreadyExistException(record.MachineId); } return(new MachineStatus <TState, TInput> { MachineId = id, Schematic = schematic.Clone(), State = schematic.InitialState, Metadata = metadata, CommitNumber = commitNumber, UpdatedTime = updatedTime }); }