Coder Social home page Coder Social logo

fiskaltrust / middleware-launcher Goto Github PK

View Code? Open in Web Editor NEW
1.0 7.0 1.0 1.26 MB

The Middleware Launcher is used to host fiskaltrust's Middleware for POS systems on desktop operating systems like Windows, Linux and macOS.

Home Page: https://docs.fiskaltrust.cloud

License: European Union Public License 1.2

C# 97.73% Shell 1.24% Batchfile 1.03%
middleware pos-systems fiscalization pos pos-software

middleware-launcher's People

Contributors

bluette-c-riviere avatar forsthug avatar leilazarban avatar mijomilicevic avatar pawelvds avatar stefankert avatar tschmiedlechner avatar volllly avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

runningjack

middleware-launcher's Issues

Send console logs go stdout / stderr

When sending logs to the console we do have two different streams that we can send data to. Stdout and sterror. Currently we are not differentiating these things which is especially annoying when calling the launcher via another application or a script.

Especially when working with bash or powershell you usually have the option to log thise streams differently with a standard pipe

E.g sendung error stream to different file and keeping just errors

dir 'C:\', 'fakepath' 2> .\dir.log

Legacy configuration file support

User story

As a user of the Middleware Launcher, I want to be able to continue using my existing configuration file from v1, so that I update as easily as possible.

Context

The previous version of the Middleware was using a fiskaltrust.exe.config file to enable configuring the Middleware. We should consider supporting this for migration paths, but should emphasize that the v2 config file is the primary source of configuration.

Change offline mode package cache behaviour

We want to introduce an "offline package" directory where offline packages are downloaded from into the package cache.

Background

Right now when using offline mode the Launcher does not download packages. The Launcher just looks for the packages inside the package cache directory.

When downloading an offline launcher from the portal the packages will be put in a folder packages in the downloaded .zip file.

The original idea was to set the packageCache config parameter to this folder in the downloaded launcher configuration file like this:

fiskaltrust.Launcher.<cashboxid>.zip/
├── packages/
│   ├── <package1>.zip
│   ├── <package2>.zip
│   └── ...
├── launcher.configuration.json
└── fiskaltrust.Launcher.exe

launcher.configuration.json:

{
  // ...,
  "packageCache": "./packages"
}

Poroposed Change to this Process

Instead of changing the configuration to the change package cache folder we want to automatically copy the packages from the "packages" folder next to the launcher executable to the package cache.

fiskaltrust.Launcher.<cashboxid>.zip/
├── packages/
│   ├── <package1>.zip
│   ├── <package2>.zip
│   └── ...
├── launcher.configuration.json
└── fiskaltrust.Launcher.exe

package cache before starting the Launcher:

<package-cache>/

package cache after starting the Launcher:

<package-cache>/
├── <package1>.zip
├── <package2>.zip
└── ...

Allow dynamic port for LauncherPort

Right now the LauncherPort is configured in the configuration. If this port is not free the launcher cannot start.

Error handling in this case is very bad at the moment and needs to be improved.

Also we should add a way for the launcher to choose its own port.

This could for example be achieved by allowing the port to be set to 0 and have the the launcher get a port assigned by the os.

Another solution is to have the launcher count up from the configured port until it finds an open port.

The solution should possibly prevent the launcher from taking a port that is used by a queue, scu or helper package.

Improved documentation for command line parameters

The current Launcher includes information about the available commands by adding the --help flag. This is indeed helpful but IMO it would also be good to have some sort of documentation in GitHub or docs based on the given commands. This description can be also more detailed from my perspective.

Helipad cannot be loaded

Describe the bug

The Helipad package cannot be loaded by the current assembly loading mechanism.

Exceptions (if any)

System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Method 'JournalAsync' in type 'fiskaltrust.Middleware.Helper.Helipad.AsyncEnumerablePOSWrapper' from assembly 'fiskaltrust.Middleware.Helper.Helipad, Version=1.3.1.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.Assembly.GetTypes()
   at fiskaltrust.Launcher.AssemblyLoading.PluginLoader.LoadComponent[T](String path, Type[] sharedTypes) in C:\Users\...\source\middleware-launcher\src\fiskaltrust.Launcher\AssemblyLoading\PluginLoader.cs:line 13
   at fiskaltrust.Launcher.Commands.HostCommandHandler.<>c__DisplayClass14_0.<InvokeAsync>b__2(IServiceCollection services) in C:\Users\...\source\middleware-launcher\src\fiskaltrust.Launcher\Commands\HostCommand.cs:line 99
System.TypeLoadException: Method 'JournalAsync' in type 'fiskaltrust.Middleware.Helper.Helipad.AsyncEnumerablePOSWrapper' from assembly 'fiskaltrust.Middleware.Helper.Helipad, Version=1.3.1.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
[10:53:07 ERR fiskaltrust.Middleware.Helper.Helipad c32204ee-63d9-48c2-b548-acfb389fa713] An unhandled exception occured
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Method 'JournalAsync' in type 'fiskaltrust.Middleware.Helper.Helipad.AsyncEnumerablePOSWrapper' from assembly 'fiskaltrust.Middleware.Helper.Helipad, Version=1.3.1.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.Assembly.GetTypes()
   at fiskaltrust.Launcher.AssemblyLoading.PluginLoader.LoadComponent[T](String path, Type[] sharedTypes) in C:\Users\...\source\middleware-launcher\src\fiskaltrust.Launcher\AssemblyLoading\PluginLoader.cs:line 13
   at fiskaltrust.Launcher.Commands.HostCommandHandler.<>c__DisplayClass14_0.<InvokeAsync>b__2(IServiceCollection services) in C:\Users\...\source\middleware-launcher\src\fiskaltrust.Launcher\Commands\HostCommand.cs:line 99
   at Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.<>c__DisplayClass9_0.<ConfigureServices>b__0(HostBuilderContext context, IServiceCollection collection)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at fiskaltrust.Launcher.Commands.HostCommandHandler.InvokeAsync(InvocationContext context) in C:\Users\...\source\middleware-launcher\src\fiskaltrust.Launcher\Commands\HostCommand.cs:line 129
System.TypeLoadException: Method 'JournalAsync' in type 'fiskaltrust.Middleware.Helper.Helipad.AsyncEnumerablePOSWrapper' from assembly 'fiskaltrust.Middleware.Helper.Helipad, Version=1.3.1.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

Properly handle secret configuration values

User story

As a user of the Middleware Launcher, I want to ensure that my secret config values are properly encrypted, to not leak data in case the local config is accessed.

Context

We need to clarify how we want to encrypt user secrets like connection strings in the local configuration and our database, and if the current approach is still state-of-the-art.

Support WCF via NamedPipes (and maybe UnixDomainSockets)

Background

The in the 1.2 and 1.3 Launchers we support WCF (SOAP) over NamedPipes.

Since newer dotnet versions don't support WCF natively we use CoreWCF in the Launcher 2.0 which up until version 1.4 did not support NamedPipes.

Some of our users like to use NamedPipes instead of http to not have to open any ports on their machines.

Feature

We should add support for WCF via NamedPipes on Windows when the url prefix is set to net.pipe:// like we do in the 1.3 launcher.
Since 1.5 CoreWCF also supports UnixDomainSockets so we should use that instead of NamedPipes on Linux and MacOS.

looks like it should be fairly easy to support it as well with the current implementation. 😄

Open Questions

Do we want to automatically use UnixDomainSockets when the url prefix is net.pipe:// or do we want to use a different url prefix.
Do we want to deprecate the net.pipe:// prefix and switch to something like ipc:// for both or
a new one for either (e.g. namedpipe:// and unixdomainsocket://)

Configuration file and CLI argument support

User story

As a user of the Middleware Launcher, I want to be able to configure the Middleware via a configuration file, so that I can automate my rollout via pre-defined settings.

Context

The previous version of the Middleware was using a fiskaltrust.exe.config file to enable configuring the Middleware. We should stick to the approach of making the MW configurable via a file, but rely on more modern approaches (like an appsettings.json).

  • Relevant configuration parameters from v1 are supported
  • Typos and ambiguities are fixed, etc.

Current config parameters: https://docs.fiskaltrust.cloud/docs/poscreators/middleware-doc/general/installation#launcher-configuration

Windows service installation

User story

As a user of the Middleware Launcher, I want to be able to install the Middleware as a Windows Service, so that I can make sure that it's automatically started and stopped with Windows.

Context

Similar to version 1, we should enable installing the Launcher as a Windows service, e.g. via a configuration parameter. The config should be taken from the appsettings.json file (as specified in #8)

Combine log files

Is your feature request related to a problem? Please describe.

The split up log files make reading logs harder.

Describe the solution you'd like

Remove the logfile splitting feature and have all logs in one file like before.

Make Launcher parameters configurable remotely

User story

As a user of the Middleware Launcher, I want to be able to change relevant parts of the configuration via the fiskaltrust.Portal, so that I can alter the config without requiring to connect to the POS system.

Context

As of now, it's only possible to set the Launcher's config locally via files or parameters. It might be helpful for users to set specific parts of the config remotely, e.g. via the Portal or an API, and have it synced to the local MW frequently, to e.g. enable verbose logging in case of issues.

We'd need to clarify how the configuration would be synced than - this could either be done via a Helper package, or directly be built into the Launcher.

Implement DownloadTimeout and Retry

The ConfigurationDownloader and PackageDownloader currently don't respect the DownloadTimeoutSec and DownloadRetry parameters of the LauncherConfiguration.

We should implement these functionalities in both downloaders and add appropriate tests.

Package Download

User story

As a user of the Middleware Launcher, I want the Launcher to be able to automatically download packages, so that I don't have to download them myself and they can be updated.

Topics that should be covered:

  • ponfig download
  • package download
  • package cache
  • package server concept

Hosting: TLS support

User story

As a user of the Middleware Launcher, I want to be able to secure my communication with TLS wherever possible, to make sure that my communication is secure.

Context

We should clarify how we want to enable TLS support:

  • For which communication protocols should TLS be enabled?
  • Should it be the default?
  • Should we provide certificates, and/or support user certificates?

Cannot start queue under linux

Describe the bug

Launcher crashes at startup on linux.

Exceptions (if any)

[12:57:21 ERR fiskaltrust.Middleware.Queue.SQLite 5614d302-e3c7-4884-be6e-2450ae5768e8] Could not load IMiddlewareBootstrapper.
System.AggregateException: One or more errors occurred. (Could not find a part of the path '/var/lib/fiskaltrust/service/054ed8e5-3c57-4309-9287-14756b6431fd/5614d302-e3c7-4884-be6e-2450ae5768e8/Migrations'.)
 ---> System.IO.DirectoryNotFoundException: Could not find a part of the path '/var/lib/fiskaltrust/service/054ed8e5-3c57-4309-9287-14756b6431fd/5614d302-e3c7-4884-be6e-2450ae5768e8/Migrations'.
   at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
   at System.IO.Enumeration.FileSystemEnumerator`1.Init()
   at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
   at System.IO.Enumeration.FileSystemEnumerableFactory.UserFiles(String directory, String expression, EnumerationOptions options)
   at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
   at fiskaltrust.Middleware.Storage.SQLite.DatabaseInitialization.DatabaseMigrator.MigrateAsync() in D:\a\1\s\queue\src\fiskaltrust.Middleware.Storage.SQLite\DatabaseInitialization\DatabaseMigrator.cs:line 49
   at fiskaltrust.Middleware.Storage.SQLite.SQLiteStorageBootstrapper.InitAsync(Guid queueId, Dictionary`2 configuration, ILogger`1 logger) in D:\a\1\s\queue\src\fiskaltrust.Middleware.Storage.SQLite\SQLiteStorageBootstrapper.cs:line 51
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at fiskaltrust.Middleware.Storage.SQLite.SQLiteStorageBootstrapper.ConfigureStorageServices(IServiceCollection serviceCollection) in D:\a\1\s\queue\src\fiskaltrust.Middleware.Storage.SQLite\SQLiteStorageBootstrapper.cs:line 42
   at fiskaltrust.Middleware.Queue.SQLite.PosBootstrapper.ConfigureServices(IServiceCollection serviceCollection)
   at fiskaltrust.Launcher.Commands.HostCommandHandler.<>c__DisplayClass18_0.<InvokeAsync>b__2(IServiceCollection services) in /mnt/c/Users/paul.volavsek/source/middleware-launcher/src/fiskaltrust.Launcher/Commands/HostCommand.cs:line 136
[12:57:21 ERR fiskaltrust.Middleware.Queue.SQLite 5614d302-e3c7-4884-be6e-2450ae5768e8] An unhandled exception occured
System.AggregateException: One or more errors occurred. (Could not find a part of the path '/var/lib/fiskaltrust/service/054ed8e5-3c57-4309-9287-14756b6431fd/5614d302-e3c7-4884-be6e-2450ae5768e8/Migrations'.)
 ---> System.IO.DirectoryNotFoundException: Could not find a part of the path '/var/lib/fiskaltrust/service/054ed8e5-3c57-4309-9287-14756b6431fd/5614d302-e3c7-4884-be6e-2450ae5768e8/Migrations'.
   at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
   at System.IO.Enumeration.FileSystemEnumerator`1.Init()
   at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
   at System.IO.Enumeration.FileSystemEnumerableFactory.UserFiles(String directory, String expression, EnumerationOptions options)
   at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
   at fiskaltrust.Middleware.Storage.SQLite.DatabaseInitialization.DatabaseMigrator.MigrateAsync() in D:\a\1\s\queue\src\fiskaltrust.Middleware.Storage.SQLite\DatabaseInitialization\DatabaseMigrator.cs:line 49
   at fiskaltrust.Middleware.Storage.SQLite.SQLiteStorageBootstrapper.InitAsync(Guid queueId, Dictionary`2 configuration, ILogger`1 logger) in D:\a\1\s\queue\src\fiskaltrust.Middleware.Storage.SQLite\SQLiteStorageBootstrapper.cs:line 51
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at fiskaltrust.Middleware.Storage.SQLite.SQLiteStorageBootstrapper.ConfigureStorageServices(IServiceCollection serviceCollection) in D:\a\1\s\queue\src\fiskaltrust.Middleware.Storage.SQLite\SQLiteStorageBootstrapper.cs:line 42
   at fiskaltrust.Middleware.Queue.SQLite.PosBootstrapper.ConfigureServices(IServiceCollection serviceCollection)
   at fiskaltrust.Launcher.Commands.HostCommandHandler.<>c__DisplayClass18_0.<InvokeAsync>b__2(IServiceCollection services) in /mnt/c/Users/paul.volavsek/source/middleware-launcher/src/fiskaltrust.Launcher/Commands/HostCommand.cs:line 136
   at Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.<>c__DisplayClass9_0.<ConfigureServices>b__0(HostBuilderContext context, IServiceCollection collection)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at fiskaltrust.Launcher.Commands.HostCommandHandler.InvokeAsync(InvocationContext context) in /mnt/c/Users/paul.volavsek/source/middleware-launcher/src/fiskaltrust.Launcher/Commands/HostCommand.cs:line 149

Further technical details & context

  • Operating system: Linux

Ignore casing in config file

Currently the config file is case sensitive. IMO this is not really necessary and could lead to further confusion when trying to configure something but just missing having a upper case l (e.g. logLevel vs loglevel). Currently I don't see any additional benefit of having the configuration values being case sensitive, but maybe I am overlooking something.

Windows defender warning - Publisher unknown

In the current version (-rc5) of the Launcher I am getting the following warning when starting the Launcher. It looks like this is due to the fact that the publisher is unknown.

image

Hosting: SOAP/WCF

User story

As a user of the Middleware Launcher, I want to be able to communicate with the Middleware via SOAP, to embed the Middleware into my existing software ecosystem and use technologies I'm familiar with.

Context

The Middleware Launcher is responsible for hosting the Middleware and should support different communication protocols. SOAP (or WCF) support should be added to support scenarios where programming languages are used that rely on SOAP communication, e.g. via referencing a WSDL contract.

The implemented solution should ideally be compatible to our existing SOAP client.

Add support for Arm CPUs

We should add support and builds for Arm CPUs, which are heavily used in modern devices. Today, our users use all three common architectures:

  • armel
  • armhf
  • arm64

We should provide separate builds at least for armhf and arm64, and ensure that the native libraries we depend on (e.g. SQLite, Swissbit, ...) also work on these platforms (also see here).

File logging

User story

As a user of the Middleware Launcher, I want to be able to easily extract log files from the Middleware, so that I can diagnose potential issues after they occured.

Context

In version 1 of the Launcher, file logging can be configured, but is somehow limited and also optional by default. We should switch this approach to provide a state-of-the-art logging experience to our users:

  • File logging should be enabled by default
  • We should use rolling log files
  • We should continue to make the log level configurable
  • We should properly log the OS version and other relevant system infos (execution path, admin rights, ...), e.g. on startup

Hosting: HTTP/REST

User story

As a user of the Middleware Launcher, I want to be able to communicate with the Middleware via a "REST" HTTP interface, to embed the Middleware into my existing software ecosystem and use technologies I'm familiar with.

Context

The Middleware Launcher is responsible for hosting the Middleware and should support different communication protocols. "RESTful" HTTP communication should be added, as it's currently the most common communication approach and very simple to use and integrate.

The implemented solution should ideally be compatible to our existing HTTP client. If it's not compatible, a migration path should be outlined and the client has to be updated for 2.0.

In our previous implementation, REST endpoints differed between operating systems. This issue should not persist in the new one.

Online logging

User story

As a user of the Middleware Launcher, I want relevant log messages to show up in the Portal, so that I can diagnose issues without having to connect to the POS system.

Context

As of now, we use Application Insights to monitor the Launcher installations, and make this information accessible to our users via the Metrics feature of our Portal. However, the current approach has several disadvantages:

  • It's not possible to differentiate between the log level for file logging and AppInsights monitoring
  • The current approach generates very high amounts of data that we have to process with high sample rates to reduce costs
  • There is no underlying concept to decide which data should be sent to AppInsights

We therefore need to define which upcoming features we might introduce for online monitoring purposes, and which data we need for that with the other development teams.

Important: we should absolutely not send any user-specific data to AppInsights, e.g. the content of requests.

Json serialization breaking change

The current launcher version returns json in a different way than the old launcher. We basically return all properties with lower case start characters. IMO we should not change this behavior since it could result in a breaking change.

There are two options IMO

  • Adapt the serializersettings
  • Change serialization to newtonsoft json

Architectural corner stones

User story

As maintainers of the Middleware Launcher, we want to clarify the components and high-level architecture together, so that we can start developing a first prototype.

Context

Before starting the first prototype, we'd like to clarify the corner stones of the upcoming Middleware Launcher. This should include:

  • Proposed components
  • Architectural principles
  • Technology to use

Make the Launcher available via Debian's APT package manager

Is your feature request related to a problem? Please describe.

Currently, users need to manually download the Launcher, e.g. from the Portal. This works in many cases, but using the inbuilt package managers to install software is far mor common on Linux.

Describe the solution you'd like

We should support using the APT package manager to install the Launcher, to e.g. allow something like this:

sudo apt install fiskaltrust-launcher

Additional context

As most of our Linux users either operate Debian or one of it's derivatives like Ubuntu, we should start with supporting APT and .deb packages, and add other package managers like YUM later on.

As it's pretty hard to get packages into the official Debian repos, I'd suggest to introduce our own repository, like e.g. Microsoft and Mono do it for their packages. This would mean that to install our software, you'd first need to add the package source and the key (with one command each), and can use the command shown below afterwards.

Steps to take

  • Create an APT repository, e.g. on an Azure Blob Storage (I found this guideline pretty useful)
  • Build .deb packages in the build pipeline (also described in the tutorial)
  • Push the packages to the package repository in the deployment pipeline
  • Update docs to explain how this can be used
  • Disable the self-update and instead print a message that a new version is available

Related to #17

Deployment strategy

User story

As a user of the Middleware Launcher, I want to be able to deploy it as simply as possible, so that I don't waste time installing dependencies.

Context

Version 1 of the Launcher only allows "manual" deployment by extracting a zip-file that can be downloaded from the Portal. While this is a very easy installation approach, it also has some disadvantages (e.g. the classic .NET framework needs to be installed on the host).

With .NET 6 and modern deployment methods, we have several alternatives to this, e.g.:

  • Single file deployments: Instead of downloading a .zip file with 100 included files that has a dependency to the correct version of the .NET framework, we could generate a single .exe file that already contains the relevant bits of the framework and has no external dependencies at all. A potential disadvantage of this approach is that this .exe would be platform-specific.

  • Package manager deployments: We could also make use of standard package managers that come with most modern OSs now, including Windows. Examples to consider:

    • Winget
    • Chocolatey
    • APT
    • Snap
    • Homebrew

    The obvious disadvantage of this approach is that there are many different package managers that we'd need to automate. Automatic updates could be a big advantage.

Allow requests with charset encoding type wrapped in quotes

We should also accept requests which send the Content-Type header like that Content-Type: application/json; charset="UTF-8" instead of that Content-Type: application/json; charset=UTF-8.

We should investigate if the newer .NET versions (7 or 8) accept these headers and if yes check if we can use their solutions as a baseline.

Possible solution:

Create our own EncodingProvider that wraps the default EncodingProvider and trims quotes " and ' from the encoding name in the GetEncoding(string) method. We can register this EncodingProvider using Encoding.RegisterProvider(EncodingProvider)

PublishTrimmed leads to Exception

Describe the bug

Project Trimming leads to a runtime error due to grpc/grpc-dotnet#1470

To Reproduce

Add <PublishTrimmed>true</PublishTrimmed> to the .csproj file.

Exceptions (if any)

Generic implementation type 'Grpc.AspNetCore.Server.Internal.DefaultGrpcServiceActivator`1' has a DynamicallyAccessedMembers attribute applied to a generic argument type, but the service type 'Grpc.AspNetCore.Server.IGrpcServiceActivator`1' doesn't have a matching DynamicallyAccessedMembers attribute on its generic argument type.

Further technical details & context

  • Version of the Middleware Launcher: 2.0.0-poc.1
  • Operating system: Windows 10 x64

Use Namedpipes and UnixDomainSockets for ProcessHostService communication

Currently the ProcessHostService is binding its gRPC service to a port.
Depending on the whole networkstack for this provides more than we need and can be error prone (two launchers cannot be started easily when using the same port).

*Note: We can not change the behaviour of Queue and SCU binding. This change only concerns communication between the Launcher Monarch and Plebeian which currently TCP binds to the LauncherConfiguration.LauncherPort.

Solution 1

Since we only have one way communication from the plebeians to the monarch we could use .NET AnonymousPipes for communication. The monarch creates the pipe server and passes the client handle string to the plebeians. We'd probably need to pass JSON messages between plebeian and monarch.

Solution 2

Continue to use gRPC but use unix domain sockets and named pipes.

Possibility to check launcher health

We need a quick way to check If everything is working (e.g. after the selfupdate) without actually doing anything.

This could be done with a --dry-run flag or a doctor (or health) command.

The --dry-run command has the disadvantages that its easy to forget something or forget It when adding a new feature, and that we would have to add a dryRun variable to a lot of classes in the launcher.

The doctor command approach has the disadvantages that we could have some duplicated code which might get out of sync, and that Its not the "real thing" were testing but a different command.

Keyring dataprotection does not work when run as a linux service

Describe the bug

When installing the launcher as a systemd service on linux the launcher will not start up because it can not access the keyring to write.

To Reproduce

sudo ./fiskaltrust.Launcher install
sudo journalctl -u fiskaltrust-<cashbox-id> --no-pager

Exceptions (if any)

 Unhandled exception. System.Security.Cryptography.CryptographicException: The provided payload could not be decrypted. Refer to the inner exception for more information. For more information go to http://aka.ms/dataprotectionwarning
 ---> System.Exception: Could not find key in keyring: errno 126
   at fiskaltrust.Launcher.Extensions.KeyUtils.Read(Int32 key)
   at fiskaltrust.Launcher.Extensions.KeyringXmlDecryptor.Decrypt(XElement encryptedElement)
   at Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.DecryptElement(XElement element, IActivator activator)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.DeferredKey.<>c__DisplayClass1_0.<GetLazyDescriptorDelegate>g__GetLazyDescriptorDelegate|0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location ---
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyBase.get_Descriptor()
   at Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngGcmAuthenticatedEncryptorFactory.CreateEncryptorInstance(IKey key)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyBase.CreateEncryptor()
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRing.KeyHolder.GetEncryptorInstance(Boolean& isRevoked)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRing.GetAuthenticatedEncryptorByKeyId(Guid keyId, Boolean& isRevoked)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
   at Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.Unprotect(IDataProtector protector, String protectedData)
   at fiskaltrust.Launcher.Commands.CommonCommandHandler.LoadCurve(String accessToken, Boolean useOffline, Boolean dryRun, Boolean useFallback)
   at fiskaltrust.Launcher.Commands.CommonCommandHandler.InvokeAsync(InvocationContext context)
   at fiskaltrust.Launcher.Commands.RunCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.CommandHandler.GetExitCodeAsync(Object value, InvocationContext context)
   at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Hosting.HostingExtensions.<>c__DisplayClass1_0.<<UseHost>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass27_0.<<UseVersionOption>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(IConsole console)
   at System.CommandLine.Parsing.ParseResultExtensions.InvokeAsync(ParseResult parseResult, IConsole console)
   at System.CommandLine.Parsing.ParserExtensions.InvokeAsync(Parser parser, String[] args, IConsole console)
   at Program.<Main>$(String[] args)
   at Program.<Main>(String[] args)

Further technical details & context

  • Version of the Middleware Launcher: 2.0.0-rc.7
  • Operating system: Ubuntu 22.04

Allow portsharing on Windows

I am trying to run two Middleware instances with Launcher 2.0 at the same time and want to use the same port with another subdirectory for the two configured Queue's/SCU's as it was possible with launcher 1.3.
e.g.:
Queue1 -> http://localhost:1500/fiskaltrust1
Queue2 -> http://localhost:1500/fiskaltrust2

I want to be able to host two Queue's/SCU's on one machine as described in the example above.

The reason for that is that a lot of our partners are using such configurations and they were working with launcher 1.3.

Unix daemon installation

User story

As a user of the Middleware Launcher, I want to be able to install the Middleware as a Unix daemon, so that I can make sure that it's automatically started and stopped with Windows.

Context

Similar to version 1, we should enable installing the Launcher as a Unix daemon, e.g. via a configuration parameter or a script. The config should be taken from the appsettings.json file (as specified in #8)

Add project skeleton and CI/CD pipelines

User story

As a developer of the Middleware Launcher, I want to have a fast CI/CD process in place, so that I can validate and deploy my changes with as less effort as possible.

Context

We need to setup a basic project skeleton (folders, solution, maybe projects) and a CI/CD pipeline in Azure DevOps to make sure that basic QA and developer experience is in place while developing the Launcher.

As in our other packages, releases should use tag-based deployments.

Support self-updates

User story

As a user of the Middleware Launcher, I want to be able to trigger an automatic update, so that I can benefit from the latest improvements without having to manually re-install it.

Context

In version 1 of the Launcher, automatic updates are not supported. Updates can only be performed manually by overwriting the Launcher files with new ones.

In version 2, we should enable automatic updates to provide the same experience to our users as we do it with regular Middleware packages. The Launcher should check for triggered updates frequently (e.g. on start or on stop), and update itself when possible.

Important: Updates should not be triggered without any user interaction/by fiskaltrust. Equally to the Middleware's packages, all local changes should require e.g. a configuration rebuild or some other form of manual step. fiskaltrust never changes on-premise installations without explicit user interaction.


  • Download update in launcher
  • Implement Updater
  • Prevent system shutdown
  • Maybe we need to prevent service restart

Service folder

User story

As a user of the Middleware Launcher, I want the Middleware's default service directory to be located in a common place, so that I can install the Launcher on all relevant OSs.

Context

The service folder is the directory that's used by the Launcher to store packages, configuration, databases and other installation-specific data. In the 'old' Middleware Launcher, we used C:\ProgramData\fiskaltrust\ on Windows /usr/share/fiskaltrust/ on Unix as the default values for this directory. Especially the latter has become problematic, as it's a non-accessible path per default in newer macOS versions.

We should define defaults for this critical directory that work on all modern operating systems.

Hosting: gRPC

User story

As a user of the Middleware Launcher, I want to be able to communicate with the Middleware via gRPC, to embed the Middleware into my existing software ecosystem and use technologies I'm familiar with.

Context

The Middleware Launcher is responsible for hosting the Middleware and should support different communication protocols. Native gRPC support should be added to simplify integration in modern applications.

The implemented solution should ideally be compatible to our existing gRPC client, but shouldn't rely on native gRPC libarries like we currently do. If it's not compatible, a migration path should be outlined and the client has to be updated for 2.0.

Add config set command

We should provide a command to set parameters in the launcher configuration file.

This is e.g. useful for storing the proxy string in an encrypted fashion.

The command could look like this fiskaltrustLauncher config set --proxy <value>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.