jj firebird

This commit is contained in:
Jonathan Jenne
2018-12-18 13:22:32 +01:00
parent 71fdc188c2
commit d33624c66c
16 changed files with 355 additions and 87 deletions

View File

@@ -16,6 +16,18 @@
<setting name="SERVICE_DISPLAY_NAME" serializeAs="String">
<value>Digital Data ZUGFeRD Service</value>
</setting>
<setting name="DB_DATASOURCE" serializeAs="String">
<value>172.24.12.41</value>
</setting>
<setting name="DB_DATABASE" serializeAs="String">
<value>172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB</value>
</setting>
<setting name="DB_USER" serializeAs="String">
<value>sysdba</value>
</setting>
<setting name="DB_PASSWORD" serializeAs="String">
<value>dd</value>
</setting>
</DDZUGFeRDService.My.MySettings>
</applicationSettings>
</configuration>

View File

@@ -6,7 +6,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7DEEC36E-EA5F-4711-AD1E-FD8894F4AD77}</ProjectGuid>
<OutputType>WinExe</OutputType>
<StartupObject>DDZUGFeRDService.Service1</StartupObject>
<StartupObject>DDZUGFeRDService.ZUGFeRDService</StartupObject>
<RootNamespace>DDZUGFeRDService</RootNamespace>
<AssemblyName>DDZUGFeRDService</AssemblyName>
<FileAlignment>512</FileAlignment>
@@ -112,6 +112,9 @@
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="ZUGFeRDService.resx">
<DependentUpon>ZUGFeRDService.vb</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">

View File

@@ -71,6 +71,42 @@ Namespace My
Return CType(Me("SERVICE_DISPLAY_NAME"),String)
End Get
End Property
<Global.System.Configuration.ApplicationScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("172.24.12.41")> _
Public ReadOnly Property DB_DATASOURCE() As String
Get
Return CType(Me("DB_DATASOURCE"),String)
End Get
End Property
<Global.System.Configuration.ApplicationScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB")> _
Public ReadOnly Property DB_DATABASE() As String
Get
Return CType(Me("DB_DATABASE"),String)
End Get
End Property
<Global.System.Configuration.ApplicationScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("sysdba")> _
Public ReadOnly Property DB_USER() As String
Get
Return CType(Me("DB_USER"),String)
End Get
End Property
<Global.System.Configuration.ApplicationScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("dd")> _
Public ReadOnly Property DB_PASSWORD() As String
Get
Return CType(Me("DB_PASSWORD"),String)
End Get
End Property
End Class
End Namespace

View File

@@ -8,5 +8,17 @@
<Setting Name="SERVICE_DISPLAY_NAME" Type="System.String" Scope="Application">
<Value Profile="(Default)">Digital Data ZUGFeRD Service</Value>
</Setting>
<Setting Name="DB_DATASOURCE" Type="System.String" Scope="Application">
<Value Profile="(Default)">172.24.12.41</Value>
</Setting>
<Setting Name="DB_DATABASE" Type="System.String" Scope="Application">
<Value Profile="(Default)">172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB</Value>
</Setting>
<Setting Name="DB_USER" Type="System.String" Scope="Application">
<Value Profile="(Default)">sysdba</Value>
</Setting>
<Setting Name="DB_PASSWORD" Type="System.String" Scope="Application">
<Value Profile="(Default)">dd</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@@ -12,7 +12,7 @@ Public Class ProjectInstaller
Public Sub New()
process = New ServiceProcessInstaller With {
.Account = ServiceAccount.NetworkService
.Account = ServiceAccount.LocalSystem
}
service = New ServiceInstaller With {
.ServiceName = My.Settings.SERVICE_NAME,

View File

@@ -20,62 +20,72 @@ Public Class ThreadRunner
Private _successDirectory As String
Private _errorDirectory As String
Private _zugferd As ZUGFeRDInterface
Private _jobArguments As WorkerArgs
Private Const TIMER_INTERVAL = 60_000
Private Const TIMER_INTERVAL_MS = 60_000
Public Sub New(LogConfig As LogConfig, WatchDirectories As List(Of String), SuccessDirectory As String, ErrorDirectory As String)
Public Sub New(LogConfig As LogConfig, Firebird As Firebird)
_logConfig = LogConfig
_logger = _logConfig.GetLogger()
_watchDirectories = WatchDirectories
_successDirectory = SuccessDirectory
_errorDirectory = ErrorDirectory
_firebird = Firebird
_zugferd = New ZUGFeRDInterface(_logConfig)
If Not Directory.Exists(SuccessDirectory) Then
Throw New DirectoryNotFoundException("SuccessDirectory: " & SuccessDirectory)
Dim args As New WorkerArgs()
args = LoadFolderConfig(args)
args = LoadPropertyMapFor(args, "DEFAULT")
_jobArguments = args
_logger.Info("Checking SuccessDirectory {0}", args.SuccessDirectory)
If Not Directory.Exists(args.SuccessDirectory) Then
_logger.Warn("SuccessDirectory {0} does not exist!", args.SuccessDirectory)
'Throw New DirectoryNotFoundException("SuccessDirectory: " & args.SuccessDirectory)
End If
If Not Directory.Exists(ErrorDirectory) Then
Throw New DirectoryNotFoundException("ErrorDirectory: " & ErrorDirectory)
_logger.Info("Checking ErrorDirectory {0}", args.ErrorDirectory)
If Not Directory.Exists(args.ErrorDirectory) Then
'Throw New DirectoryNotFoundException("ErrorDirectory: " & args.ErrorDirectory)
_logger.Warn("ErrorDirectory {0} does not exist!", args.ErrorDirectory)
End If
For Each oDirectory In WatchDirectories
For Each oDirectory In args.WatchDirectories
_logger.Info("Checking WatchDirectory {0}", oDirectory)
If Not Directory.Exists(oDirectory) Then
Throw New DirectoryNotFoundException("WatchDirectory: " & oDirectory)
'Throw New DirectoryNotFoundException("WatchDirectory: " & oDirectory)
_logger.Warn("WatchDirectory {0} does not exist!", oDirectory)
End If
Next
_workerThread = New BackgroundWorker() With {
.WorkerReportsProgress = True,
.WorkerReportsProgress = False,
.WorkerSupportsCancellation = True
}
_workerTimer = New Timer With {
.Interval = TIMER_INTERVAL
.Interval = TIMER_INTERVAL_MS
}
End Sub
Public Sub Start()
_workerTimer.Start()
_logger.Info("ThreadRunner started.")
_logger.Debug("ThreadRunner started.")
End Sub
Public Sub [Stop]()
If _workerThread.IsBusy Then
_workerThread.CancelAsync()
_logger.Info("Worker cancelled.")
End If
_workerTimer.Stop()
_logger.Info("ThreadRunner stopped.")
Try
If _workerThread.IsBusy Then
_workerThread.CancelAsync()
_logger.Debug("Worker cancelled.")
End If
_workerTimer.Stop()
_logger.Debug("ThreadRunner stopped.")
Catch ex As Exception
_logger.Error(ex)
End Try
End Sub
Private Sub TimerElapsed(sender As Object, e As ElapsedEventArgs) Handles _workerTimer.Elapsed
If Not _workerThread.IsBusy Then
_workerThread.RunWorkerAsync(New WorkerArgs() With {
.WatchDirectories = _watchDirectories,
.SuccessDirectory = _successDirectory,
.ErrorDirectory = _errorDirectory
})
_workerThread.RunWorkerAsync(_jobArguments)
Else
_logger.Warn("Worker is busy")
End If
@@ -84,14 +94,59 @@ Public Class ThreadRunner
Private Sub DoWork(sender As Object, e As DoWorkEventArgs) Handles _workerThread.DoWork
Dim args As WorkerArgs = e.Argument
_logger.Debug("Background worker running..")
Dim job As New ImportZUGFeRDFiles(_logConfig, _firebird)
job.Start(args)
End Sub
Private Sub WorkProgress(sender As Object, e As ProgressChangedEventArgs) Handles _workerThread.ProgressChanged
Throw New NotImplementedException()
End Sub
Private Sub WorkCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles _workerThread.RunWorkerCompleted
Throw New NotImplementedException()
_logger.Debug("Background worker completed!")
End Sub
Private Function LoadFolderConfig(args As WorkerArgs)
Dim oSQL As String = "SELECT T1.FOLDER_TYPE, T.FOLDER_PATH FROM TBEDM_FOLDER T, TBEDM_FOLDER_TYPE T1 WHERE T.FOLDER_TYPE_ID = T1.GUID AND T1.""ACTIVE"" = True AND T.""ACTIVE"" = True"
Dim oResult As DataTable = _firebird.GetDatatable(oSQL)
For Each row As DataRow In oResult.Rows
Dim oFolderType = row.Item("FOLDER_TYPE")
Select Case oFolderType
Case ZUGFERD_IN
_logger.Debug("Setting WatchDirectory: {0}", row.Item("FOLDER_PATH"))
args.WatchDirectories.Add(row.Item("FOLDER_PATH"))
Case ZUGFERD_SUCCESS
_logger.Debug("Setting SuccessDirectory: {0}", row.Item("FOLDER_PATH"))
args.SuccessDirectory = row.Item("FOLDER_PATH")
Case ZUGFERD_ERROR
_logger.Debug("Setting ErrorDirectory: {0}", row.Item("FOLDER_PATH"))
args.ErrorDirectory = row.Item("FOLDER_PATH")
End Select
Next
Return args
End Function
Private Function LoadPropertyMapFor(args As WorkerArgs, specification As String)
Dim oSQL As String = $"SELECT * FROM TBEDM_XML_ITEMS WHERE SPECIFICATION = '{specification}' AND ACTIVE = True"
Dim oResult As DataTable = _firebird.GetDatatable(oSQL)
For Each row As DataRow In oResult.Rows
Dim xmlPath = row.Item("XML_PATH")
Dim tableName = row.Item("TABLE_NAME")
Dim description = row.Item("DESCRIPTION")
Dim isRequired = row.Item("IS_REQUIRED")
args.PropertyMap.Add(xmlPath, New XmlItemProperty() With {
.Description = description,
.TableName = tableName,
.IsRequired = isRequired
})
Next
Return args
End Function
End Class

View File

@@ -41,8 +41,13 @@ Partial Class ZUGFeRDService
' Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
'
'ZUGFeRDService
'
Me.AutoLog = False
Me.CanShutdown = True
Me.ServiceName = "Service1"
End Sub
End Class

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@@ -11,19 +11,26 @@ Public Class ZUGFeRDService
Protected Overrides Sub OnStart(ByVal args() As String)
_logConfig = New LogConfig(LogConfig.PathType.CustomPath, Path.Combine(My.Application.Info.DirectoryPath, "Log"))
_logConfig.Debug = True
_logger = _logConfig.GetLogger()
_logger.Info($"{My.Settings.SERVICE_NAME} is starting.")
Dim oDataSource As String = ""
Dim oDatabase As String = ""
Dim oUser As String = ""
Dim oPassword As String = ""
Dim watchDirectories As New List(Of String) From {"E:\ZUGFeRD_Import"}
Dim oDataSource As String = My.Settings.DB_DATASOURCE
Dim oDatabase As String = My.Settings.DB_DATABASE
Dim oUser As String = My.Settings.DB_USER
Dim oPassword As String = My.Settings.DB_PASSWORD
_logger.Debug("Datasource: {0}", oDataSource)
_logger.Debug("Database: {0}", oDatabase)
_firebird = New Firebird(_logConfig, oDataSource, oDatabase, oUser, oPassword)
_threadRunner = New ThreadRunner(_logConfig, watchDirectories)
_threadRunner.Start()
Try
_threadRunner = New ThreadRunner(_logConfig, _firebird)
_threadRunner.Start()
Catch ex As Exception
_logger.Error(ex)
End Try
End Sub
Protected Overrides Sub OnStop()