diff --git a/content-for-demo/.gitignore b/content-for-demo/.gitignore new file mode 100644 index 000000000..616a8a1e7 --- /dev/null +++ b/content-for-demo/.gitignore @@ -0,0 +1 @@ +/mongo \ No newline at end of file diff --git a/content-for-demo/docker-compose-mongodb.yaml b/content-for-demo/docker-compose-mongodb.yaml new file mode 100644 index 000000000..c248196c5 --- /dev/null +++ b/content-for-demo/docker-compose-mongodb.yaml @@ -0,0 +1,13 @@ +version: '3.8' +services: + mongodb: + image: mongo + hostname: "mongo" + restart: always + volumes: + - ./mongo/data:/data/db + ports: + - '27017:27017' + environment: + - MONGO_INITDB_ROOT_USERNAME=mongo + - MONGO_INITDB_ROOT_PASSWORD=mongo \ No newline at end of file diff --git a/src/AasxServerBlazor/Program.cs b/src/AasxServerBlazor/Program.cs index 3d9e09aa2..2bd194769 100644 --- a/src/AasxServerBlazor/Program.cs +++ b/src/AasxServerBlazor/Program.cs @@ -5,13 +5,14 @@ using Microsoft.Extensions.Hosting; using System; using System.IO; +using System.Linq; using System.Threading; namespace AasxServerBlazor { public class Program1 { - + public static bool withMongodb = false; public static void Main(string[] args) { Console.WriteLine(Directory.GetCurrentDirectory()); @@ -25,6 +26,7 @@ public static void Main(string[] args) if (url[2] != null) AasxServer.Program.blazorPort = url[2]; + withMongodb = args.Contains("--with-mongodb"); var host = CreateHostBuilder(args).Build(); host.RunAsync(); diff --git a/src/AasxServerBlazor/Properties/launchSettings.json b/src/AasxServerBlazor/Properties/launchSettings.json index 6ac907bf7..681ff22d0 100644 --- a/src/AasxServerBlazor/Properties/launchSettings.json +++ b/src/AasxServerBlazor/Properties/launchSettings.json @@ -10,7 +10,7 @@ }, "AasxServerBlazor": { "commandName": "Project", - "commandLineArgs": "--no-security --secret-string-api 1234 --aasx-in-memory 1000 --data-path \"C:\\Development\\Ronny\" --edit --external-blazor http://localhost:5001", + "commandLineArgs": "--no-security --aasx-in-memory 1000 --data-path \"C:\\GitClones\\aasx-server\\content-for-demo\\aasxs\" --edit --external-blazor http://localhost:5001 --with-mongodb \"mongodb://mongo:mongo@localhost:27017/\"", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", diff --git a/src/AasxServerBlazor/Startup.cs b/src/AasxServerBlazor/Startup.cs index 2cca49dfc..3d5749b4f 100644 --- a/src/AasxServerBlazor/Startup.cs +++ b/src/AasxServerBlazor/Startup.cs @@ -95,8 +95,17 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton(); services.AddSingleton(); services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>)); - services.AddTransient(); - services.AddTransient(); + + if (Program1.withMongodb) + { + services.AddTransient(); + services.AddTransient(); + } + else + { + services.AddTransient(); + services.AddTransient(); + } services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/src/AasxServerBlazor/startForDemo.sh b/src/AasxServerBlazor/startForDemo.sh index bdf52e0f6..3fac751d2 100755 --- a/src/AasxServerBlazor/startForDemo.sh +++ b/src/AasxServerBlazor/startForDemo.sh @@ -1 +1 @@ -dotnet AasxServerBlazor.dll --no-security --data-path ./aasxs --host 0.0.0.0 $OPTIONSAASXSERVER \ No newline at end of file +dotnet AasxServerBlazor.dll --no-security --aasx-in-memory 1000 --data-path ./aasxs --edit --external-blazor http://localhost:5001 --with-mongodb "mongodb://mongo:mongo@mongodb-server:27017/" $OPTIONSAASXSERVER \ No newline at end of file diff --git a/src/AasxServerStandardBib/AasxServerStandardBib.csproj b/src/AasxServerStandardBib/AasxServerStandardBib.csproj index bdb6ae39f..f06de2f10 100644 --- a/src/AasxServerStandardBib/AasxServerStandardBib.csproj +++ b/src/AasxServerStandardBib/AasxServerStandardBib.csproj @@ -32,6 +32,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/src/AasxServerStandardBib/Database.cs b/src/AasxServerStandardBib/Database.cs new file mode 100644 index 000000000..f69826b9e --- /dev/null +++ b/src/AasxServerStandardBib/Database.cs @@ -0,0 +1,258 @@ +using MongoDB.Bson.Serialization.Serializers; +using MongoDB.Bson.Serialization; +using MongoDB.Driver; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AasxServerStandardBib.Exceptions; +using MongoDB.Bson; +using MongoDB.Driver.Linq; +using System.Collections; +using AasCore.Aas3_0; +using AdminShellNS; +using MongoDB.Driver.GridFS; +using static AasxServerStandardBib.TimeSeriesPlotting.PlotArguments; +using System.IO; + + +//Author: Jonas Graubner +//contact: jogithub@graubner-bayern.de +namespace AasxServerStandardBib +{ + public interface IDatabase + { + void Initialize(String connectionString); + + #region AssetAdministrationShell + public void WriteDBAssetAdministrationShell(IAssetAdministrationShell shell); + public IQueryable GetLINQAssetAdministrationShell(); + public void UpdateDBAssetAdministrationShellById(IAssetAdministrationShell body, string aasIdentifier); + public bool DeleteDBAssetAdministrationShellById(IAssetAdministrationShell shell); + #endregion + + #region Submodel + public void WriteDBSubmodel(ISubmodel submodel); + public IQueryable GetLINQSubmodel(); + public void UpdateDBSubmodelById(string submodelIdentifier, ISubmodel newSubmodel); + public void DeleteDBSubmodelById(string submodelIdentifier); + #endregion + + #region ConceptDescription + public void WriteDBConceptDescription(IConceptDescription conceptDescription); + public IQueryable GetLINQConceptDescription(); + public void UpdateDBConceptDescriptionById(IConceptDescription newConceptDescription, string cdIdentifier); + public void DeleteDBConceptDescriptionById(string conceptDescription); + #endregion + + #region Filestream + public void WriteFile(Stream stream, string filename); + public Stream ReadFile(string filename); + public void DeleteFile(string filename); + #endregion + + public void importAASCoreEnvironment(IEnvironment environment); + public void importAdminShellPackageEnv(AdminShellPackageEnv adminShellPackageEnv); + } + + + public class MongoDatabase : IDatabase + { + private MongoClient _client; + private IMongoDatabase _database; + private GridFSBucket _bucket; + + public void Initialize(String connectionString) + { + //_client = new MongoClient("mongodb://AAS:SefuSWE63811!@192.168.0.22:27017/?authSource=AAS"); + _client = new MongoClient(connectionString); + try + { + _client.StartSession(); + } + catch (System.TimeoutException ex) + { + System.Console.WriteLine(ex.Message); + System.Environment.Exit(1); + } + + _database = _client.GetDatabase("AAS"); + var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) || type.FullName.StartsWith("AasCore") || type.FullName.StartsWith("MongoDB")); + BsonSerializer.RegisterSerializer(objectSerializer); + _bucket = new GridFSBucket(_database, new GridFSBucketOptions + { + BucketName = "aasxFiles", + }); + } + private IMongoCollection getAasCollection() + { + return _database.GetCollection("AssetAdministrationShells"); + } + private IMongoCollection getSubmodelCollection() + { + return _database.GetCollection("Submodels"); + } + private IMongoCollection getConceptDescriptionCollection() + { + return _database.GetCollection("ConceptDescriptions"); + } + + + #region AssetAdministrationShell + public void WriteDBAssetAdministrationShell(IAssetAdministrationShell shell) + { + try + { + getAasCollection().InsertOne((AssetAdministrationShell)shell); + } + catch (MongoWriteException) + { + } + } + public bool DeleteDBAssetAdministrationShellById(IAssetAdministrationShell shell) + { + throw new NotImplementedException(); + } + public IQueryable GetLINQAssetAdministrationShell() + { + return getAasCollection().AsQueryable(); + } + public async void UpdateDBAssetAdministrationShellById(IAssetAdministrationShell body, string aasIdentifier) + { + await getAasCollection().ReplaceOneAsync(r => r.Id.Equals(aasIdentifier), (AssetAdministrationShell)body); + } + #endregion + + #region Submodel + public void WriteDBSubmodel(ISubmodel submodel) + { + try + { + getSubmodelCollection().InsertOne((Submodel)submodel); + } + catch (MongoWriteException) + { + } + } + public IQueryable GetLINQSubmodel() + { + return getSubmodelCollection().AsQueryable(); + } + public async void UpdateDBSubmodelById(string submodelIdentifier, ISubmodel newSubmodel) + { + await getSubmodelCollection().ReplaceOneAsync(r => r.Id.Equals(submodelIdentifier), (Submodel)newSubmodel); + } + public async void DeleteDBSubmodelById(string submodelIdentifier) + { + await getSubmodelCollection().DeleteOneAsync(a => a.Id.Equals(submodelIdentifier)); + } + #endregion + + #region ConceptDescription + public void WriteDBConceptDescription(IConceptDescription conceptDescription) + { + try + { + getConceptDescriptionCollection().InsertOne((ConceptDescription)conceptDescription); + } + catch (MongoWriteException) + { + } + } + public IQueryable GetLINQConceptDescription() + { + return getConceptDescriptionCollection().AsQueryable(); + } + public async void UpdateDBConceptDescriptionById(IConceptDescription newConceptDescription, string cdIdentifier) + { + await getConceptDescriptionCollection().ReplaceOneAsync(r => r.Id.Equals(cdIdentifier), (ConceptDescription)newConceptDescription); + } + public async void DeleteDBConceptDescriptionById(string conceptDescription) + { + await getConceptDescriptionCollection().DeleteOneAsync(a => a.Id.Equals(conceptDescription)); + } + #endregion + + #region Filestream + public async void WriteFile(Stream stream, string filename) + { + if (stream != null) + { + Console.WriteLine("New File"); + var id = await _bucket.UploadFromStreamAsync(filename, stream); + stream.Close(); + }else + { + //throw new ArgumentNullException(nameof(stream)); + } + } + public Stream ReadFile(string filename) + { + return _bucket.OpenDownloadStream(getFileIdFromFilename(filename)); + } + + public async void DeleteFile(string filename) + { + ObjectId fileId = getFileIdFromFilename(filename); + await _bucket.DeleteAsync(fileId); + } + + private ObjectId getFileIdFromFilename(string filename) + { + var filter = Builders.Filter.Eq(x => x.Filename, filename); + var sort = Builders.Sort.Descending(x => x.UploadDateTime); + var options = new GridFSFindOptions + { + Limit = 1, + Sort = sort + }; + + using (var cursor = _bucket.Find(filter, options)) + { + var fileInfo = cursor.ToList().FirstOrDefault(); + // fileInfo either has the matching file information or is null + return fileInfo.Id; + } + } + + + #endregion + + + public void importAASCoreEnvironment(IEnvironment environment) + { + environment.AssetAdministrationShells.ForEach(shell => { + WriteDBAssetAdministrationShell(shell); + }); + + environment.Submodels.ForEach(submodel => + { + WriteDBSubmodel(submodel); + }); + + environment.ConceptDescriptions.ForEach(conceptDescription => + { + WriteDBConceptDescription(conceptDescription); + }); + } + + public void importAdminShellPackageEnv(AdminShellPackageEnv adminShellPackageEnv) + { + importAASCoreEnvironment(adminShellPackageEnv.AasEnv); + + //now import Files + var files = adminShellPackageEnv.GetListOfSupplementaryFiles(); + var assetid = adminShellPackageEnv.AasEnv.AssetAdministrationShells[0].AssetInformation.GlobalAssetId; //unique identifier + foreach ( var file in files ) + { + if (file.Location == AdminShellNS.AdminShellPackageSupplementaryFile.LocationType.InPackage) + { + WriteFile(adminShellPackageEnv.GetLocalStreamFromPackage(file.Uri.ToString()), assetid+file.Uri.ToString()); + //ReadFile(assetid + file.Uri.ToString()); + } + } + + } + } +} diff --git a/src/AasxServerStandardBib/Program.cs b/src/AasxServerStandardBib/Program.cs index f13c1b288..24957c590 100644 --- a/src/AasxServerStandardBib/Program.cs +++ b/src/AasxServerStandardBib/Program.cs @@ -1,6 +1,8 @@ using AasOpcUaServer; using AasxMqttServer; using AasxRestServerLibrary; +using AasxServerStandardBib; + //using AasxServerStandardBib.Migrations; using AdminShellNS; using Extensions; @@ -34,6 +36,7 @@ using System.Timers; using System.Xml; using System.Xml.Serialization; +using static AasxServerStandardBib.IDatabase; using Formatting = Newtonsoft.Json.Formatting; /* Copyright (c) 2019-2020 PHOENIX CONTACT GmbH & Co. KG , author: Andreas Orzelski @@ -530,6 +533,7 @@ public static bool loadPackageForSubmodel(string submodelIdentifier, out ISubmod public static string[] envFileName = null; public static string[] envSymbols = null; public static string[] envSubjectIssuer = null; + public static IDatabase database = null; /* public static AdminShellPackageEnv[] env = new AdminShellPackageEnv[envimax]; { @@ -688,6 +692,7 @@ public static bool loadPackageForSubmodel(string submodelIdentifier, out ISubmod public static bool withPolicy = false; public static bool showWeight = false; + public static string withMongoDB { get; set; } private class CommandLineArguments { // ReSharper disable UnusedAutoPropertyAccessor.Local @@ -717,6 +722,7 @@ private class CommandLineArguments public bool WithDb { get; set; } public bool NoDbFiles { get; set; } public int StartIndex { get; set; } + public string WithMongoDB { get; set; } #pragma warning restore 8618 // ReSharper enable UnusedAutoPropertyAccessor.Local } @@ -872,6 +878,7 @@ private static async Task Run(CommandLineArguments a) { Console.WriteLine("Recommend an OPC client update rate > 200 ms."); } + Program.withMongoDB = a.WithMongoDB; // allocate memory env = new AdminShellPackageEnv[envimax]; @@ -1026,6 +1033,14 @@ private static async Task Run(CommandLineArguments a) int envi = 0; int count = 0; + //Mongo Database + if (!withMongoDB.IsNullOrEmpty()) + { + database = new MongoDatabase(); + //database.Initialize("mongodb://mongo:mongo@localhost:27017/"); + database.Initialize(withMongoDB); + } + // Migrate always if (withDb) { @@ -1124,6 +1139,11 @@ private static async Task Run(CommandLineArguments a) // try { fn = fileNames[fi]; + + //Insert into DB + //database.importAASCoreEnvironment(new AdminShellPackageEnv(fn, true, false).AasEnv); + database.importAdminShellPackageEnv(new AdminShellPackageEnv(fn, true, false)); + if (fn.ToLower().Contains("globalsecurity")) { envFileName[envi] = fn; @@ -1679,7 +1699,11 @@ public static void Main(string[] args) new Option( new[] {"--start-index"}, - "If set, start index in list of AASX files") + "If set, start index in list of AASX files"), + + new Option( + new[] {"--with-mongodb"}, + "If set, will use MongoDB Data save") }; if (args.Length == 0) diff --git a/src/AasxServerStandardBib/Services-DB/AdminShellPackageEnvironmentServiceDB.cs b/src/AasxServerStandardBib/Services-DB/AdminShellPackageEnvironmentServiceDB.cs new file mode 100644 index 000000000..7b1b645bf --- /dev/null +++ b/src/AasxServerStandardBib/Services-DB/AdminShellPackageEnvironmentServiceDB.cs @@ -0,0 +1,368 @@ +/* Copyright (c) 2019-2023 Fraunhofer IOSB-INA Lemgo, +    eine rechtlich nicht selbstaendige Einrichtung der Fraunhofer-Gesellschaft +    zur Foerderung der angewandten Forschung e.V. + */ +using AasxServer; +using AasxServerStandardBib.Exceptions; +using AasxServerStandardBib.Interfaces; +using AasxServerStandardBib.Logging; +using AdminShellNS; +using Extensions; +using Microsoft.IdentityModel.Tokens; +using SharpCompress.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace AasxServerStandardBib.Services +{ + public class AdminShellPackageEnvironmentServiceDB : IAdminShellPackageEnvironmentService + { + private readonly IAppLogger _logger; + private readonly Lazy _aasService; + private IDatabase _database; + + public AdminShellPackageEnvironmentServiceDB(IAppLogger logger, Lazy aasService) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _aasService = aasService; + _database = Program.database; + } + + #region private + private List GetAssetAdministrationShellsBySubmodelIdentifier(string submodelIdentifier) { + // Get all AssetAdministrationShells that Reference the given submodelIdentifier + return _database.GetLINQAssetAdministrationShell() + .Where(aas => aas.Submodels + .Any(s => s.Keys + .Any(k => k.Value.Equals(submodelIdentifier)))) + .ToList(); + } + #endregion + + #region AssetAdministrationShell + public IAssetAdministrationShell CreateAssetAdministrationShell(IAssetAdministrationShell body) + { + var timeStamp = DateTime.UtcNow; + body.TimeStampCreate = timeStamp; + body.SetTimeStamp(timeStamp); + _database.WriteDBAssetAdministrationShell(body); + Program.signalNewData(2); + return body; + } + public void DeleteAssetAdministrationShell(int packageIndex, IAssetAdministrationShell aas) + { + bool deleted = _database.DeleteDBAssetAdministrationShellById(aas); + if (deleted) + { + _logger.LogDebug($"Deleted Asset Administration Shell with id {aas.Id}"); + Program.signalNewData(2); + } + else + { + _logger.LogError($"Could not delete Asset Administration Shell with id {aas.Id}"); + } + } + public List GetAllAssetAdministrationShells() + { + return _database.GetLINQAssetAdministrationShell().ToList().Cast().ToList(); + } + public IAssetAdministrationShell GetAssetAdministrationShellById(string aasIdentifier, out int packageIndex) + { + packageIndex = -1; //TODO unused -> remove in the future + var output = _database.GetLINQAssetAdministrationShell() + .Where(r => r.Id.Equals(aasIdentifier)) + .ToList(); + + if (output.Any()) + { + _logger.LogDebug($"Asset Administration Shell with id {aasIdentifier} found."); + return output.First(); + } + else + { + throw new NotFoundException($"Asset Administration Shell with id {aasIdentifier} not found."); + } + } + public bool IsAssetAdministrationShellPresent(string aasIdentifier) + { + return _database.GetLINQAssetAdministrationShell() + .Where(r => r.Id.Equals(aasIdentifier)) + .ToList().Any(); + } + public void UpdateAssetAdministrationShellById(IAssetAdministrationShell body, string aasIdentifier) + { + //TODO Test -> should work -> function unused + var timeStamp = DateTime.UtcNow; + body.TimeStampCreate = timeStamp; + body.SetTimeStamp(timeStamp); + + _database.UpdateDBAssetAdministrationShellById(body, aasIdentifier); + + Program.signalNewData(1); //0 not working, hence 1 = same tree, structure may change + _logger.LogDebug($"Successfully updated the AAS with requested AAS"); + } + public void ReplaceAssetAdministrationShellById(string aasIdentifier, IAssetAdministrationShell newAas) + { + var timeStamp = DateTime.UtcNow; + newAas.TimeStampCreate = timeStamp; + newAas.SetTimeStamp(timeStamp); + _database.UpdateDBAssetAdministrationShellById(newAas, aasIdentifier); + Program.signalNewData(1); + } + + public void DeleteAssetInformationThumbnail(int packageIndex, IResource defaultThumbnail) + { + //TODO + throw new NotImplementedException(); + //_packages[packageIndex].DeleteAssetInformationThumbnail(defaultThumbnail); + Program.signalNewData(0); + } + public Stream GetAssetInformationThumbnail(int packageIndex) + { + //TODO find a solution to get the right Thumbnail + throw new NotImplementedException(); + //return _packages[packageIndex].GetLocalThumbnailStream(); + } + public void UpdateAssetInformationThumbnail(IResource defaultThumbnail, Stream fileContent, int packageIndex) + { + //TODO find a solution to get the right Thumbnail + throw new NotImplementedException(); + /* + _packages[packageIndex].EmbeddAssetInformationThumbnail(defaultThumbnail, fileContent); + Program.signalNewData(0); + */ + } + #endregion + + #region Submodel + public ISubmodel CreateSubmodel(ISubmodel newSubmodel, string aasIdentifier = null) + { + //Check if Submodel exists + var found = IsSubmodelPresent(newSubmodel.Id); + if (found) + { + throw new DuplicateException($"Submodel with id {newSubmodel.Id} already exists."); + } + DateTime timeStamp = DateTime.UtcNow; + //Check if corresponding AAS exist. If yes, then add to the same environment + if (!string.IsNullOrEmpty(aasIdentifier)) + { + IAssetAdministrationShell aas = GetAssetAdministrationShellById(aasIdentifier, out int packageIndex); //Throws Exception if not found + newSubmodel.SetAllParents(timeStamp); + + aas.Submodels ??= new List(); + aas.Submodels.Add(newSubmodel.GetReference()); + aas.SetTimeStamp(timeStamp); + _database.UpdateDBAssetAdministrationShellById(aas, aasIdentifier); //Save aas Changes in db + + newSubmodel.TimeStampCreate = timeStamp; + newSubmodel.SetTimeStamp(timeStamp); + _database.WriteDBSubmodel(newSubmodel); + + AasxServer.Program.signalNewData(2); + return newSubmodel; // TODO: jtikekar find proper solution + } + + newSubmodel.TimeStampCreate = timeStamp; + newSubmodel.SetTimeStamp(timeStamp); + _database.WriteDBSubmodel(newSubmodel); + Program.signalNewData(2); + return newSubmodel; + } + public List GetAllSubmodels(IReference reqSemanticId = null, string idShort = null) + { + //Get All Submodels + List output = _database.GetLINQSubmodel().ToList().Cast().ToList(); + // TODO (jtikekar, 2023-09-04): uncomment and support + //if (SecurityCheckTestOnly(s.IdShort, "", s)) + + //Apply filters + if (output.Any()) + { + //Filter w.r.t idShort + if (!string.IsNullOrEmpty(idShort)) + { + var submodels = output.Where(s => s.IdShort.Equals(idShort)).ToList(); + if (submodels.IsNullOrEmpty()) + { + _logger.LogInformation($"Submodels with IdShort {idShort} Not Found."); + } + + output = submodels; + } + + //Filter w.r.t. SemanticId + if (reqSemanticId != null) + { + if (output.Any()) + { + var submodels = output.Where(s => s.SemanticId.Matches(reqSemanticId)).ToList(); + if (submodels.IsNullOrEmpty()) + { + _logger.LogInformation($"Submodels with requested SemnaticId Not Found."); + } + + output = submodels; + } + } + } + + return output; + } + public ISubmodel GetSubmodelById(string submodelIdentifier, out int packageIndex) + { + packageIndex = -1; //TODO unused -> remove in the future + List output = _database.GetLINQSubmodel() + .Where(r => r.Id.Equals(submodelIdentifier)) + .ToList(); + + if (output.Any()) + { + _logger.LogDebug($"Found the submodel with Id {submodelIdentifier}"); + return output.First(); + } + else + { + throw new NotFoundException($"Submodel with id {submodelIdentifier} NOT found."); + } + } + public bool IsSubmodelPresent(string submodelIdentifier) + { + return _database.GetLINQSubmodel() + .Where(r => r.Id.Equals(submodelIdentifier)) + .ToList().Any(); + } + public void ReplaceSubmodelById(string submodelIdentifier, ISubmodel newSubmodel) + { + var timeStamp = DateTime.UtcNow; + newSubmodel.TimeStampCreate = timeStamp; + newSubmodel.SetParentAndTimestamp(timeStamp); + _database.UpdateDBSubmodelById(submodelIdentifier, newSubmodel); + Program.signalNewData(1); + } + public void DeleteSubmodelById(string submodelIdentifier) + { + List aasToModify = GetAssetAdministrationShellsBySubmodelIdentifier(submodelIdentifier); + + foreach (var aas in aasToModify) + { + _aasService.Value.DeleteSubmodelReferenceById(aas.Id, submodelIdentifier); //Just in Memory Modification + UpdateAssetAdministrationShellById(aas, aas.Id); //Update the Asset in the DB + //TODO Jonas Graubner make sure, that reference is deleted in DB + } + _database.DeleteDBSubmodelById(submodelIdentifier); + _logger.LogDebug($"Deleted submodel with id {submodelIdentifier}."); + AasxServer.Program.signalNewData(1); + } + + public void DeleteSupplementaryFileInPackage(string submodelIdentifier, string filePath) + { + //TODO tests & maybe optimization + // Get all AssetAdministrationShells that Reference the given submodelIdentifier + List aasWithSubmodel = GetAssetAdministrationShellsBySubmodelIdentifier(submodelIdentifier); + + foreach (var aas in aasWithSubmodel) + { + string GlobalAssetId = aas.AssetInformation.GlobalAssetId; + string filename = GlobalAssetId + filePath; + _database.DeleteFile(filename); + } + } + public Stream GetFileFromPackage(string submodelIdentifier, string fileName) + { + //TODO + if (!string.IsNullOrEmpty(fileName)) + { + List aasWithSubmodel = GetAssetAdministrationShellsBySubmodelIdentifier(submodelIdentifier); + + + string GlobalAssetId = aasWithSubmodel.First().AssetInformation.GlobalAssetId; + string filename = GlobalAssetId + fileName; + return _database.ReadFile(filename); + } + else + { + _logger.LogError($"File name is empty."); + throw new UnprocessableEntityException($"File name is empty."); + } + } + public Task ReplaceSupplementaryFileInPackage(string submodelIdentifier, string sourceFile, string targetFile, string contentType, MemoryStream fileContent) + { + //TODO + throw new NotImplementedException(); + /* + var submodel = GetSubmodelById(submodelIdentifier, out int packageIndex); + return _packages[packageIndex].ReplaceSupplementaryFileInPackageAsync(sourceFile, targetFile, contentType, fileContent); + */ + } + #endregion + + + #region ConceptDescription + public IConceptDescription CreateConceptDescription(IConceptDescription body) + { + var timeStamp = DateTime.UtcNow; + body.TimeStampCreate = timeStamp; + body.SetTimeStamp(timeStamp); + _database.WriteDBConceptDescription(body); + Program.signalNewData(2); + return body; + } + public IConceptDescription GetConceptDescriptionById(string cdIdentifier, out int packageIndex) + { + packageIndex = -1; //TODO unused -> remove in the future + List output = _database.GetLINQConceptDescription() + .Where(c => c.Id.Equals(cdIdentifier)) + .ToList(); + + if (output.Any()) + { + _logger.LogDebug($"Found the conceptDescription with id {cdIdentifier}"); + return output.First(); //List will always contain just 1 entry -> Primary Key in DB + } + else + { + throw new NotFoundException($"ConceptDescription with id {cdIdentifier} NOT found."); + } + } + public List GetAllConceptDescriptions() + { + return _database.GetLINQConceptDescription().ToList().Cast().ToList(); ; + } + public bool IsConceptDescriptionPresent(string cdIdentifier) + { + return _database.GetLINQConceptDescription() + .Where(c => c.Id.Equals(cdIdentifier)) + .ToList().Any(); + } + public void UpdateConceptDescriptionById(IConceptDescription body, string cdIdentifier) + { + var timeStamp = DateTime.UtcNow; + body.TimeStampCreate = timeStamp; + body.SetTimeStamp(timeStamp); + + _database.UpdateDBConceptDescriptionById(body, cdIdentifier); + Program.signalNewData(1); //0 not working, hence 1 = same tree, structure may change + _logger.LogDebug($"Successfully updated the ConceptDescription."); + } + public void DeleteConceptDescriptionById(string cdIdentifier) + { + _database.DeleteDBConceptDescriptionById(cdIdentifier); + _logger.LogDebug($"Delete ConceptDescription with id {cdIdentifier}"); + AasxServer.Program.signalNewData(1); + } + #endregion + public void setWrite(int packageIndex, bool status) + { + throw new NotImplementedException(); + } + + public bool IsSubmodelPresent(string submodelIdentifier, out ISubmodel output, out int packageIndex) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AasxServerStandardBib/Services-DB/AssetAdministrationShellServiceDB.cs b/src/AasxServerStandardBib/Services-DB/AssetAdministrationShellServiceDB.cs new file mode 100644 index 000000000..92459d6ce --- /dev/null +++ b/src/AasxServerStandardBib/Services-DB/AssetAdministrationShellServiceDB.cs @@ -0,0 +1,561 @@ + +using AasxServer; +using AasxServerStandardBib.Exceptions; +using AasxServerStandardBib.Interfaces; +using AasxServerStandardBib.Logging; +using AdminShellNS.Extensions; +using Extensions; +using Microsoft.IdentityModel.Tokens; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace AasxServerStandardBib.Services +{ + public class AssetAdministrationShellServiceDB : IAssetAdministrationShellService + { + private readonly IAppLogger _logger; + private readonly IAdminShellPackageEnvironmentService _packageEnvService; + private readonly IMetamodelVerificationService _verificationService; + private readonly ISubmodelService _submodelService; + private IDatabase _database; + + + public AssetAdministrationShellServiceDB(IAppLogger logger, IAdminShellPackageEnvironmentService packageEnvService, IMetamodelVerificationService verificationService, ISubmodelService submodelService) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); ; + _packageEnvService = packageEnvService; + _verificationService = verificationService; + _submodelService = submodelService; + _database = Program.database; + } + + public IAssetAdministrationShell CreateAssetAdministrationShell(IAssetAdministrationShell body) + { + //Verify the body first + _verificationService.VerifyRequestBody(body); + + var found = _packageEnvService.IsAssetAdministrationShellPresent(body.Id); + if (found) + { + _logger.LogDebug($"Cannot create requested AAS !!"); + throw new DuplicateException($"AssetAdministrationShell with id {body.Id} already exists."); + } + + var output = _packageEnvService.CreateAssetAdministrationShell(body); + + return output; + } + + public IReference CreateSubmodelReferenceInAAS(IReference body, string aasIdentifier) + { + IReference output = null; + //Verify request body + _verificationService.VerifyRequestBody(body); + + // TODO (jtikekar, 2023-09-04): to check if submodel with requested submodelReference exists in the server + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out _); + + if (aas != null) + { + if (aas.Submodels.IsNullOrEmpty()) + { + aas.Submodels = new List + { + body + }; + output = aas.Submodels.Last(); + } + else + { + bool found = false; + //Check if duplicate + foreach (var submodelReference in aas.Submodels) + { + if (submodelReference.Matches(body)) + { + found = true; + break; + } + } + + if (found) + { + _logger.LogDebug($"Cannot create requested Submodel-Reference in the AAS !!"); + throw new DuplicateException($"Requested SubmodelReference already exists in the AAS with Id {aasIdentifier}."); + } + else + { + aas.Submodels.Add(body); + output = aas.Submodels.Last(); + } + } + } + + return output; + } + + + + public void DeleteAssetAdministrationShellById(string aasIdentifier) + { + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out int packageIndex); + + if (aas != null && packageIndex != -1) + { + _packageEnvService.DeleteAssetAdministrationShell(packageIndex, aas); + } + } + + public void DeleteFileByPath(string aasIdentifier, string submodelIdentifier, string idShortPath) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + _submodelService.DeleteFileByPath(submodelIdentifier, idShortPath); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public void DeleteSubmodelById(string aasIdentifier, string submodelIdentifier) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + //delete the submodel first, this should eventually delete the submodel reference from all the AASs + _submodelService.DeleteSubmodelById(submodelIdentifier); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public void DeleteSubmodelElementByPath(string aasIdentifier, string submodelIdentifier, string idShortPath) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + _submodelService.DeleteSubmodelElementByPath(submodelIdentifier, idShortPath); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + + } + + + + public void DeleteSubmodelReferenceById(string aasIdentifier, string submodelIdentifier) + { + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out _); + + if (aas != null) + { + var submodelReference = aas.Submodels.Where(s => s.Matches(submodelIdentifier)); + if (submodelReference.Any()) + { + _logger.LogDebug($"Found requested submodel reference in the aas."); + bool deleted = aas.Submodels.Remove(submodelReference.First()); + if (deleted) + { + _logger.LogDebug($"Deleted submodel reference with id {submodelIdentifier} from the AAS with id {aasIdentifier}."); + Program.signalNewData(1); + } + else + { + _logger.LogError($"Could not delete submodel reference with id {submodelIdentifier} from the AAS with id {aasIdentifier}."); + } + } + else + { + throw new NotFoundException($"SubmodelReference with id {submodelIdentifier} not found in AAS with id {aasIdentifier}"); + } + } + } + + + + public List GetAllAssetAdministrationShells(List assetIds = null, string idShort = null) + { + var output = _packageEnvService.GetAllAssetAdministrationShells(); + + //Apply filters + + if (output.Any()) + { + if (!string.IsNullOrEmpty(idShort)) + { + _logger.LogDebug($"Filtering AASs with idShort {idShort}."); + output = output.Where(a => a.IdShort.Equals(idShort)).ToList(); + if (output.IsNullOrEmpty()) + { + _logger.LogInformation($"No AAS with idShhort {idShort} found."); + } + } + + if (!assetIds.IsNullOrEmpty()) + { + _logger.LogDebug($"Filtering AASs with requested specific assetIds."); + var aasList = new List(); + foreach (var assetId in assetIds) + { + aasList = output.Where(a => a.AssetInformation.SpecificAssetIds.ContainsSpecificAssetId(assetId)).ToList(); + } + + if (aasList.Any()) + { + output = aasList; + } + else + { + _logger.LogInformation($"No AAS with requested specific assetId found."); + } + } + } + + return output; + } + + public List GetAllSubmodelElements(string aasIdentifier, string submodelIdentifier) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + return _submodelService.GetAllSubmodelElements(submodelIdentifier); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public List GetAllSubmodelReferencesFromAas(string aasIdentifier) + { + List output = new List(); + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out _); + + if (aas != null) + { + if (aas.Submodels.IsNullOrEmpty()) + { + _logger.LogDebug($"No submodels present in the AAS with Id {aasIdentifier}"); + } + + output = aas.Submodels; + } + + return output; + } + + public IAssetAdministrationShell GetAssetAdministrationShellById(string aasIdentifier) + { + return _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out _); + } + + public IAssetInformation GetAssetInformation(string aasIdentifier) + { + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out _); + return aas.AssetInformation; + } + + public void DeleteThumbnail(string aasIdentifier) + { + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out int packageIndex); + if (aas != null) + { + if (aas.AssetInformation != null) + { + if (aas.AssetInformation.DefaultThumbnail != null && !string.IsNullOrEmpty(aas.AssetInformation.DefaultThumbnail.Path)) + { + _packageEnvService.DeleteAssetInformationThumbnail(packageIndex, aas.AssetInformation.DefaultThumbnail); + } + else + { + throw new NotFoundException($"No default thumbnail embedded in the AssetInformation of the requested AAS."); + } + } + } + } + + public string GetThumbnail(string aasIdentifier, out byte[] byteArray, out long fileSize) + { + string fileName = null; + byteArray = null; + fileSize = 0; + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out int packageIndex); + if (aas != null) + { + if (aas.AssetInformation != null) + { + if (aas.AssetInformation.DefaultThumbnail != null && !string.IsNullOrEmpty(aas.AssetInformation.DefaultThumbnail.Path)) + { + fileName = aas.AssetInformation.GlobalAssetId + aas.AssetInformation.DefaultThumbnail.Path; + + Stream stream = _database.ReadFile(fileName); + byteArray = stream.ToByteArray(); + fileSize = byteArray.Length; + + _logger.LogDebug($"Retrived the thumbnail in AAS with Id {aasIdentifier}"); + } + else + { + throw new NotFoundException($"No default thumbnail embedded in the AssetInformation of the requested AAS."); + } + } + else + { + throw new NotFoundException($"AssetInformation is NULL in requested AAS with id {aasIdentifier}"); + } + } + + return fileName; + } + + public void UpdateAssetAdministrationShellById(IAssetAdministrationShell body, string aasIdentifier) + { + //Verify the body first + _verificationService.VerifyRequestBody(body); + + _packageEnvService.UpdateAssetAdministrationShellById(body, aasIdentifier); + + } + + public void UpdateAssetInformation(AssetInformation body, string aasIdentifier) + { + _verificationService.VerifyRequestBody(body); + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out _); + if (aas != null) + { + aas.AssetInformation = body; + Program.signalNewData(0); + + _logger.LogDebug($"AssetInformation from AAS with id {aasIdentifier} updated successfully."); + } + } + + public void UpdateThumbnail(string aasIdentifier, string fileName, string contentType, Stream fileContent) + { + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out int packageIndex); + if (aas != null) + { + if (aas.AssetInformation != null) + { + var asset = aas.AssetInformation; + + if (string.IsNullOrEmpty(contentType)) + { + contentType = "application/octet-stream"; + } + + if (asset.DefaultThumbnail == null) + { + //If thumbnail is not set, set to default path + asset.DefaultThumbnail ??= new Resource(Path.Combine("/aasx/files", fileName).Replace('/', Path.DirectorySeparatorChar), contentType); + } + else + { + asset.DefaultThumbnail.Path = asset.DefaultThumbnail.Path.Replace('/', Path.DirectorySeparatorChar); + } + + _packageEnvService.UpdateAssetInformationThumbnail(asset.DefaultThumbnail, fileContent, packageIndex); + + + } + else + { + throw new NotFoundException($"AssetInformation is NULL in requested AAS with id {aasIdentifier}"); + } + } + } + + #region PrivateMethods + + private bool IsSubmodelPresentWithinAAS(string aasIdentifier, string submodelIdentifier) + { + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out _); + if (aas != null) + { + foreach (var submodelReference in aas.Submodels) + { + if (submodelReference.GetAsExactlyOneKey().Value.Equals(submodelIdentifier)) + { return true; } + } + } + + return false; + } + + public string GetFileByPath(string aasIdentifier, string submodelIdentifier, string idShortPath, out byte[] content, out long fileSize) + { + content = null; + fileSize = 0; + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + return _submodelService.GetFileByPath(submodelIdentifier, idShortPath, out content, out fileSize); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + + } + + public ISubmodel GetSubmodelById(string aasIdentifier, string submodelIdentifier) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + return _submodelService.GetSubmodelById(submodelIdentifier); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public ISubmodelElement GetSubmodelElementByPath(string aasIdentifier, string submodelIdentifier, string idShortPath) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + return _submodelService.GetSubmodelElementByPath(submodelIdentifier, idShortPath); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public ISubmodelElement CreateSubmodelElement(string aasIdentifier, string submodelIdentifier, bool first, ISubmodelElement newSubmodelElement) + { + var smFound = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (smFound) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + return _submodelService.CreateSubmodelElement(submodelIdentifier, newSubmodelElement, first); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public ISubmodelElement CreateSubmodelElementByPath(string aasIdentifier, string submodelIdentifier, string idShortPath, bool first, ISubmodelElement newSubmodelElement) + { + var smFound = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (smFound) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + return _submodelService.CreateSubmodelElementByPath(submodelIdentifier, idShortPath, first, newSubmodelElement); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public void ReplaceAssetAdministrationShellById(string aasIdentifier, IAssetAdministrationShell newAas) + { + _verificationService.VerifyRequestBody(newAas); + _packageEnvService.ReplaceAssetAdministrationShellById(aasIdentifier, newAas); + } + + public void ReplaceAssetInformation(string aasIdentifier, IAssetInformation newAssetInformation) + { + var aas = _packageEnvService.GetAssetAdministrationShellById(aasIdentifier, out _); + if (aas != null) + { + _verificationService.VerifyRequestBody(newAssetInformation); + aas.AssetInformation = newAssetInformation; + Program.signalNewData(0); + } + } + + public void ReplaceSubmodelById(string aasIdentifier, string submodelIdentifier, Submodel newSubmodel) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + _submodelService.ReplaceSubmodelById(submodelIdentifier, newSubmodel); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + + } + + public void ReplaceSubmodelElementByPath(string aasIdentifier, string submodelIdentifier, string idShortPath, ISubmodelElement newSme) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + _submodelService.ReplaceSubmodelElementByPath(submodelIdentifier, idShortPath, newSme); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public void UpdateSubmodelById(string aasIdentifier, string submodelIdentifier, ISubmodel newSubmodel) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + _submodelService.UpdateSubmodelById(submodelIdentifier, newSubmodel); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public void UpdateSubmodelElementByPath(string aasIdentifier, string submodelIdentifier, string idShortPath, ISubmodelElement newSme) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + _submodelService.UpdateSubmodelElementByPath(submodelIdentifier, idShortPath, newSme); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + public void ReplaceFileByPath(string aasIdentifier, string submodelIdentifier, string idShortPath, string fileName, string contentType, MemoryStream fileContent) + { + var found = IsSubmodelPresentWithinAAS(aasIdentifier, submodelIdentifier); + if (found) + { + _logger.LogDebug($"Found submodel with id {submodelIdentifier} in AAS with id {aasIdentifier}"); + _submodelService.ReplaceFileByPath(submodelIdentifier, idShortPath, fileName, contentType, fileContent); + } + else + { + throw new($"Submodel with id {submodelIdentifier} NOT found in AAS with id {aasIdentifier}"); + } + } + + #endregion + } +} diff --git a/src/docker/docker-compose-demo.yaml b/src/docker/docker-compose-demo.yaml index 87d5c12c7..152ec13df 100644 --- a/src/docker/docker-compose-demo.yaml +++ b/src/docker/docker-compose-demo.yaml @@ -2,10 +2,14 @@ services: aasx-server: container_name: aasx-server hostname: aasx-server - image: adminshellio/aasx-server-blazor-for-demo:v3latest + image: adminshellio/aasx-server-blazor-for-demo:main restart: unless-stopped ports: - "5001:5001" volumes: - - ./aasxs:/usr/share/aasxs - command: --start-index 0 --no-security --edit --data-path /usr/share/aasxs --external-blazor http://localhost:5001 + - C:\GitClones\aasx-server\content-for-demo\aasxs:/AasxServerBlazor/aasxs + deploy: + resources: + limits: + memory: 3G + command: --start-index 0 --no-security --edit --data-path /AasxServerBlazor/aasxs --external-blazor http://localhost:5001 diff --git a/src/docker/docker-compose-mongodb.yaml b/src/docker/docker-compose-mongodb.yaml new file mode 100644 index 000000000..24b33ac11 --- /dev/null +++ b/src/docker/docker-compose-mongodb.yaml @@ -0,0 +1,30 @@ +version: '3.8' +services: + mongodb: + image: mongo + hostname: "mongodb-server" + container_name: "mongodb-server" + restart: unless-stopped + volumes: + - ./mongo/data:/data/db + ports: + - '27017:27017' + environment: + - MONGO_INITDB_ROOT_USERNAME=mongo + - MONGO_INITDB_ROOT_PASSWORD=mongo + aasx-server: + container_name: aasx-server + hostname: aasx-server + image: aasx-server-blazor-for-demo:latest + restart: unless-stopped + ports: + - "5001:5001" + depends_on: + - mongodb + volumes: + - C:\GitClones\aasx-server\content-for-demo\aasxs:/AasxServerBlazor/aasxs + deploy: + resources: + limits: + memory: 3G + command: --start-index 0 --no-security --aasx-in-memory 1000 --data-path "./aasxs" --edit --external-blazor http://localhost:5001 --with-mongodb "mongodb://mongo:mongo@localhost:27017/" \ No newline at end of file diff --git a/src/docker/docker-compose.yaml b/src/docker/docker-compose.yaml index 9189fb998..8e80e352b 100644 --- a/src/docker/docker-compose.yaml +++ b/src/docker/docker-compose.yaml @@ -9,5 +9,5 @@ services: ports: - "5001:5001" volumes: - - ./aasxs:/usr/share/aasxs - command: --start-index 0 --no-security --edit --data-path /usr/share/aasxs --external-blazor http://localhost:5001 \ No newline at end of file + - C:\GitClones\aasx-server\content-for-demo\aasxs:/usr/share/aasxs + command: --start-index 0 --no-security --aasx-in-memory 1000 --data-path "./aasxs" --edit --external-blazor http://localhost:5001 --with-mongodb "mongodb://mongo:mongo@localhost:27017/"