diff --git a/BaSyx.API/Components/ServiceProvider/AssetAdministrationShellRepositoryServiceProvider.cs b/BaSyx.API/Components/ServiceProvider/AssetAdministrationShellRepositoryServiceProvider.cs index 58f2e0e..967e472 100644 --- a/BaSyx.API/Components/ServiceProvider/AssetAdministrationShellRepositoryServiceProvider.cs +++ b/BaSyx.API/Components/ServiceProvider/AssetAdministrationShellRepositoryServiceProvider.cs @@ -21,6 +21,7 @@ namespace BaSyx.API.Components { public class AssetAdministrationShellRepositoryServiceProvider : IAssetAdministrationShellRepositoryServiceProvider { + private readonly IAssetAdministrationShellServiceProviderFactory _assetAdministrationShellServiceProviderFactory; public IEnumerable AssetAdministrationShells => GetBinding(); private Dictionary AssetAdministrationShellServiceProviders { get; } @@ -40,13 +41,15 @@ private set _serviceDescriptor = value; } } - public AssetAdministrationShellRepositoryServiceProvider(IAssetAdministrationShellRepositoryDescriptor descriptor) : this() + public AssetAdministrationShellRepositoryServiceProvider(IAssetAdministrationShellRepositoryDescriptor descriptor, + IAssetAdministrationShellServiceProviderFactory assetAdministrationShellServiceProviderFactory) : this(assetAdministrationShellServiceProviderFactory) { ServiceDescriptor = descriptor; } - public AssetAdministrationShellRepositoryServiceProvider() + public AssetAdministrationShellRepositoryServiceProvider(IAssetAdministrationShellServiceProviderFactory assetAdministrationShellServiceProviderFactory) { + _assetAdministrationShellServiceProviderFactory = assetAdministrationShellServiceProviderFactory; AssetAdministrationShellServiceProviders = new Dictionary(); } @@ -77,16 +80,15 @@ public IResult CreateAssetAdministrationShell(IAssetA { if (aas == null) return new Result(new ArgumentNullException(nameof(aas))); - - var registered = RegisterAssetAdministrationShellServiceProvider(aas.Identification.Id, aas.CreateServiceProvider(true)); - if (!registered.Success) - return new Result(registered); + + var assetAdministrationShellServiceProvider = _assetAdministrationShellServiceProviderFactory.CreateServiceProvider(aas, true); + RegisterAssetAdministrationShellServiceProvider(aas.Identification.Id, assetAdministrationShellServiceProvider); var retrievedShellServiceProvider = GetAssetAdministrationShellServiceProvider(aas.Identification.Id); if (retrievedShellServiceProvider.TryGetEntity(out IAssetAdministrationShellServiceProvider serviceProvider)) return new Result(true, serviceProvider.GetBinding()); - else - return new Result(false, new Message(MessageType.Error, "Could not retrieve Asset Administration Shell Service Provider")); + + return new Result(false, new Message(MessageType.Error, "Could not retrieve Asset Administration Shell Service Provider")); } public IResult DeleteAssetAdministrationShell(string aasId) diff --git a/BaSyx.API/Components/ServiceProvider/IAssetAdministrationShellServiceProviderFactory.cs b/BaSyx.API/Components/ServiceProvider/IAssetAdministrationShellServiceProviderFactory.cs new file mode 100644 index 0000000..b31fd63 --- /dev/null +++ b/BaSyx.API/Components/ServiceProvider/IAssetAdministrationShellServiceProviderFactory.cs @@ -0,0 +1,28 @@ +// /******************************************************************************* +// * Copyright (c) 2022 LTSoft - Agentur für Leittechnik-Software GmbH +// * Author: Björn Höper +// * +// * This program and the accompanying materials are made available under the +// * terms of the Eclipse Public License 2.0 which is available at +// * http://www.eclipse.org/legal/epl-2.0 +// * +// * SPDX-License-Identifier: EPL-2.0 +// *******************************************************************************/ + +using BaSyx.API.AssetAdministrationShell.Extensions; +using BaSyx.Models.Core.AssetAdministrationShell.Generics; + +namespace BaSyx.API.Components; + +/// +/// Creates service providers for Asset Administration Shells +/// +public interface IAssetAdministrationShellServiceProviderFactory +{ + /// + /// Create a new service provider for the AAS + /// + /// Asset administration shell to create the service provider for + /// Created service provider + public IAssetAdministrationShellServiceProvider CreateServiceProvider(IAssetAdministrationShell aas, bool includeSubmodels); +} \ No newline at end of file diff --git a/BaSyx.API/Components/ServiceProvider/InternalAssetAdministrationShellServiceProviderFactory.cs b/BaSyx.API/Components/ServiceProvider/InternalAssetAdministrationShellServiceProviderFactory.cs new file mode 100644 index 0000000..49e34b1 --- /dev/null +++ b/BaSyx.API/Components/ServiceProvider/InternalAssetAdministrationShellServiceProviderFactory.cs @@ -0,0 +1,45 @@ +// /******************************************************************************* +// * Copyright (c) 2022 LTSoft - Agentur für Leittechnik-Software GmbH +// * Author: Björn Höper +// * +// * This program and the accompanying materials are made available under the +// * terms of the Eclipse Public License 2.0 which is available at +// * http://www.eclipse.org/legal/epl-2.0 +// * +// * SPDX-License-Identifier: EPL-2.0 +// *******************************************************************************/ + +using System.Linq; +using BaSyx.Models.Core.AssetAdministrationShell.Generics; + +namespace BaSyx.API.Components; + +/// +/// Creates internal In-Memory providers for the AAS +/// +public class InternalAssetAdministrationShellServiceProviderFactory : IAssetAdministrationShellServiceProviderFactory +{ + private readonly ISubmodelServiceProviderFactory _submodelServiceProviderFactory; + + public InternalAssetAdministrationShellServiceProviderFactory(ISubmodelServiceProviderFactory submodelServiceProviderFactory) + { + _submodelServiceProviderFactory = submodelServiceProviderFactory; + } + + public IAssetAdministrationShellServiceProvider CreateServiceProvider(IAssetAdministrationShell aas, + bool includeSubmodels) + { + InternalAssetAdministrationShellServiceProvider sp = new InternalAssetAdministrationShellServiceProvider(aas); + + if (includeSubmodels && aas.Submodels.Any()) + { + foreach (var submodel in aas.Submodels.Values) + { + var submodelSp = _submodelServiceProviderFactory.CreateSubmodelServiceProvider(submodel); + sp.RegisterSubmodelServiceProvider(submodel.IdShort, submodelSp); + } + } + + return sp; + } +} \ No newline at end of file diff --git a/tests/Basyx.API.Tests/Components/ServiceProvider/AssetAdministrationShellRepositoryServiceProviderTests.cs b/tests/Basyx.API.Tests/Components/ServiceProvider/AssetAdministrationShellRepositoryServiceProviderTests.cs new file mode 100644 index 0000000..bc20b8a --- /dev/null +++ b/tests/Basyx.API.Tests/Components/ServiceProvider/AssetAdministrationShellRepositoryServiceProviderTests.cs @@ -0,0 +1,40 @@ +// /******************************************************************************* +// * Copyright (c) 2022 LTSoft - Agentur für Leittechnik-Software GmbH +// * Author: Björn Höper +// * +// * This program and the accompanying materials are made available under the +// * terms of the Eclipse Public License 2.0 which is available at +// * http://www.eclipse.org/legal/epl-2.0 +// * +// * SPDX-License-Identifier: EPL-2.0 +// *******************************************************************************/ + +using BaSyx.API.Components; +using BaSyx.Models.Core.AssetAdministrationShell.Generics; +using BaSyx.Models.Core.AssetAdministrationShell.Identification; +using Moq; + +namespace Basyx.API.Tests.Components.ServiceProvider; + +public class AssetAdministrationShellRepositoryServiceProviderTests +{ + [Fact] + public async Task CreateAssetAdministrationShell_WhenSuccess_CallsFactory() + { + var aasMock = new Mock(); + aasMock.Setup(a => a.Identification) + .Returns(new Identifier("http://assetadminshell.io/1/0/0/testshell", KeyType.URI)); + + var serviceProviderMock = new Mock(); + serviceProviderMock.Setup(p => p.GetBinding()).Returns(aasMock.Object); + + var factoryMock = new Mock(); + factoryMock.Setup(f => f.CreateServiceProvider(aasMock.Object, true)).Returns(serviceProviderMock.Object); + + var aasRepoProvider = new AssetAdministrationShellRepositoryServiceProvider(factoryMock.Object); + var result = aasRepoProvider.CreateAssetAdministrationShell(aasMock.Object); + + factoryMock.Verify(f => f.CreateServiceProvider(aasMock.Object, true), Times.AtLeastOnce); + Assert.Equal(aasMock.Object, result.Entity); + } +} \ No newline at end of file