blob: f8a44758a87c19950f9d54ad4136739203ad767e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020, 2021 Robert Bosch GmbH
* Author: Constantin Ziesche (constantin.ziesche@bosch.com)
*
* 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.AAS.Server.Http;
using BaSyx.API.AssetAdministrationShell.Extensions;
using BaSyx.API.Components;
using BaSyx.Common.UI;
using BaSyx.Common.UI.Swagger;
using BaSyx.Models.Core.AssetAdministrationShell.Generics;
using BaSyx.Models.Core.AssetAdministrationShell.Identification;
using BaSyx.Models.Core.AssetAdministrationShell.Implementations;
using BaSyx.Models.Export;
using BaSyx.Utils.Settings.Sections;
using BaSyx.Utils.Settings.Types;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;
using NLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using System.Web;
namespace BaSyx.WebUI
{
public class Program
{
private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
private static ServerSettings serverSettings;
private static AssetAdministrationShellHttpServer shellServer;
private static IAssetAdministrationShellServiceProvider shellProvider;
public static void Main(string[] args)
{
serverSettings = ServerSettings.LoadSettings();
shellServer = new AssetAdministrationShellHttpServer(serverSettings);
string websiteHostName = Environment.ExpandEnvironmentVariables("%WEBSITE_HOSTNAME%");
if (!(string.IsNullOrEmpty(websiteHostName) || websiteHostName == "%WEBSITE_HOSTNAME%"))
{
string websiteUrl = string.Format("https://{0}", websiteHostName);
serverSettings.ServerConfig = new ServerConfiguration()
{
Hosting = new HostingConfiguration() { Urls = new List<string>() { websiteUrl } }
};
}
//Add BaSyx Web UI
shellServer.AddBaSyxUI(PageNames.AssetAdministrationShellServer);
//Add Swagger Documentation and UI
shellServer.AddSwagger(Interface.AssetAdministrationShell);
shellServer.ConfigureServices(services =>
{
services.AddTransient<IAssetAdministrationShellServiceProvider>(factory =>
{
if (shellProvider == null)
return CreateDefaultShellProvider();
else
return shellProvider;
});
});
shellServer.Configure(app =>
{
app.Use(async (context, next) =>
{
try
{
string contentPath = Path.Combine(ServerSettings.ExecutingDirectory + "Content");
if (Directory.Exists(contentPath))
Directory.Delete(contentPath, true);
var requestPath = context.Request.Path.ToUriComponent();
if (requestPath.Contains("/ui"))
{
if (context.Request.Query.TryGetValue("path", out StringValues pathValue))
{
logger.Info("Middleware-Query-String: " + pathValue);
bool success = false;
if (Uri.TryCreate(pathValue, UriKind.Absolute, out Uri pathUri))
{
var net = new System.Net.WebClient();
var data = net.DownloadData(pathUri);
MemoryStream memoryStream = new MemoryStream(data);
Package package = Package.Open(memoryStream, FileMode.Open, FileAccess.Read);
AASX aasx = new AASX(package);
success = LoadAASX(aasx);
}
else
success = false;
if (!success)
{
logger.Info("success is false on " + pathValue);
shellProvider = null;
}
context.Request.Path = new PathString("/ui");
}
}
}
catch (Exception e)
{
logger.Error(e, "Middleware-Exception: " + e.Message);
}
await next();
});
});
shellServer.Run();
}
private static IAssetAdministrationShellServiceProvider CreateDefaultShellProvider()
{
IAssetAdministrationShell shell = new AssetAdministrationShell("DefaultShell", new Identifier(Guid.NewGuid().ToString(), KeyType.Custom))
{
Asset = new Asset("DefaultAsset", new Identifier(Guid.NewGuid().ToString(), KeyType.Custom)),
Submodels = { new Submodel("DefaultSubmodel", new Identifier(Guid.NewGuid().ToString(), KeyType.Custom)) }
};
var provider = shell.CreateServiceProvider(true);
provider.UseAutoEndpointRegistration(serverSettings.ServerConfig);
return provider;
}
private static bool LoadAASX(AASX aasx)
{
using (aasx)
{
IAssetAdministrationShell shell;
try
{
AssetAdministrationShellEnvironment_V2_0 environment = aasx.GetEnvironment_V2_0();
shell = environment.AssetAdministrationShells.FirstOrDefault();
if (shell == null)
{
logger.Error("Asset Administration Shell cannot be obtained from AASX-Package");
return false;
}
}
catch (Exception e1)
{
logger.Warn(e1, "Error obtaining Asset Administration Shell from package. Trying AAS-Version 1.0 ...");
try
{
AssetAdministrationShellEnvironment_V1_0 environment = aasx.GetEnvironment_V1_0();
shell = environment.AssetAdministrationShells.FirstOrDefault();
if (shell == null)
{
logger.Error("Asset Administration Shell cannot be obtained from AASX-Package");
return false;
}
}
catch (Exception e2)
{
logger.Error(e2, "Asset Administration Shell cannot be obtained from AASX-Package");
return false;
}
}
logger.Info("AASX-Package successfully loaded");
PackagePart thumbnailPart = aasx.GetThumbnailAsPackagePart();
RegisterShellServiceProvider(shell, aasx.SupplementaryFiles, thumbnailPart);
}
return true;
}
private static void RegisterShellServiceProvider(IAssetAdministrationShell shell, List<PackagePart> supplementaryFiles, PackagePart thumbnailPart)
{
var aasServiceProvider = shell.CreateServiceProvider(true);
aasServiceProvider.UseAutoEndpointRegistration(serverSettings.ServerConfig);
foreach (var file in supplementaryFiles)
using (Stream stream = file.GetStream())
shellServer.ProvideContent(file.Uri, stream);
if (thumbnailPart != null)
using (Stream thumbnailStream = thumbnailPart.GetStream())
shellServer.ProvideContent(thumbnailPart.Uri, thumbnailStream);
shellProvider = aasServiceProvider;
}
}
}