Add Heartbeat Function to Service, Add Timer to ClientSuite Service Startup check

This commit is contained in:
Jonathan Jenne
2019-02-18 17:06:41 +01:00
parent bc7605bdcf
commit 4229682da0
24 changed files with 259 additions and 85 deletions

View File

@@ -36,8 +36,14 @@ Public Class ClassConfig
End Property End Property
' === Simple/Actual Config Properties === ' === Simple/Actual Config Properties ===
' === Service Configuration ===
Public Property ServiceIP As String = String.Empty Public Property ServiceIP As String = String.Empty
Public Property ServicePort As Integer = -1 Public Property ServicePort As Integer = -1
Public Property HeartbeatInterval As Integer = 5000
' === Logging Configuration
Public Property LogDebug As Boolean = False Public Property LogDebug As Boolean = False
' === User Configuration ===
Public Property UserLanguage As String = "de-DE" Public Property UserLanguage As String = "de-DE"
End Class End Class

View File

@@ -1,7 +1,21 @@
Imports System.IO Imports System.IO
''' <summary>
''' Helper Class to save DevExpress layouts
'''
''' Example:
'''
''' Layout 1 (for frmMain)
''' ----------------------------------------------
''' | Component 1 Component 2 |
''' | |-------------| |----------------| |
''' | | MainGrid | | DocumentGrid | |
''' | |-------------| |----------------| |
''' | |
''' |---------------------------------------------
''' </summary>
Public Class ClassLayout Public Class ClassLayout
Public Enum LayoutName Public Enum GroupName
LayoutMain LayoutMain
End Enum End Enum
@@ -10,9 +24,19 @@ Public Class ClassLayout
DocumentManager DocumentManager
End Enum End Enum
Public Shared Function GetLayoutPath(LayoutName As LayoutName, Component As LayoutComponent) As String ''' <summary>
Dim oFileName As String = $"{LayoutName.ToString}-{Component.ToString}.xml" ''' Returns a path for the chosen Devexpress layout file
Return IO.Path.Combine(GetAppDataFolder(), ClassConstants.FOLDER_NAME_LAYOUT, oFileName) ''' </summary>
''' <param name="Group">The Group to which the the component belongs to. For example, a form could be a Layout</param>
''' <param name="Component">The component to which the layout belongs to</param>
''' <returns></returns>
Public Shared Function GetLayoutPath(Group As GroupName, Component As LayoutComponent) As String
Dim oFileName As String = $"{Group.ToString}-{Component.ToString}.xml"
Return Path.Combine(GetLayoutDirectory(), oFileName)
End Function
Public Shared Function GetLayoutDirectory() As String
Return Path.Combine(GetAppDataFolder(), ClassConstants.FOLDER_NAME_LAYOUT)
End Function End Function
Private Shared Function GetAppDataFolder() As String Private Shared Function GetAppDataFolder() As String

View File

@@ -18,6 +18,32 @@ Public Class ClassService
_Logger = _LogConfig.GetLogger() _Logger = _LogConfig.GetLogger()
End Sub End Sub
Public Function TestConnection() As ConnectionTestResult
Return TestConnection(My.Config.ServiceConnection)
End Function
Public Function TestConnection(EndpointURL As String) As ConnectionTestResult
Try
Dim oChannelFactory = GetChannelFactory(EndpointURL)
Dim oChannel = oChannelFactory.CreateChannel()
oChannel.OperationTimeout = New TimeSpan(0, 0, ClassConstants.SERVICE_OPEN_TIMEOUT)
oChannel.Open()
oChannel.Close()
Return ConnectionTestResult.Successful
Catch ex As EndpointNotFoundException
_Logger.Error(ex)
Return ConnectionTestResult.NotFound
Catch ex As Exception
_Logger.Error(ex)
Return ConnectionTestResult.Unknown
End Try
End Function
Public Async Function TestConnectionAsync() As Task(Of ConnectionTestResult)
Return Await TestConnectionAsync(My.Config.ServiceConnection)
End Function
Public Async Function TestConnectionAsync(EndpointURL As String) As Task(Of ConnectionTestResult) Public Async Function TestConnectionAsync(EndpointURL As String) As Task(Of ConnectionTestResult)
Return Await Task.Factory.StartNew(Function() Return Await Task.Factory.StartNew(Function()
Try Try

View File

@@ -1,4 +1,5 @@
Imports System.Threading Imports System.ServiceModel
Imports System.Threading
Imports System.Timers Imports System.Timers
Imports DigitalData.Modules.EDMIFileOps.EDMIServiceReference Imports DigitalData.Modules.EDMIFileOps.EDMIServiceReference
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
@@ -10,28 +11,56 @@ Public Class ClassTimer
Private _Timer As Timers.Timer Private _Timer As Timers.Timer
Private _Channel As IEDMServiceChannel Private _Channel As IEDMServiceChannel
Private Const TIMER_START_TIME = 1000 Public Event OnlineChanged As OnlineChangedEventHandler
Private Const TIMER_INTERVAL = 5000 Public Delegate Sub OnlineChangedEventHandler(sender As Object, Online As Boolean)
Public Sub Callback(sender As Object, e As ElapsedEventArgs) Public Sub New(LogConfig As LogConfig, SynchronizingObject As frmMain, HeartbeatInterval As Integer)
_Logger.Info("Checking if Service is up...") Try
_LogConfig = LogConfig
_Logger = LogConfig.GetLogger()
' Connect to service and send hearbeat request _Channel = My.ChannelFactory.CreateChannel()
_Channel.Open()
My.Application.Service.Online = True _Timer = New Timers.Timer(HeartbeatInterval) With {
My.Application.Service.LastChecked = DateTime.Now .SynchronizingObject = SynchronizingObject,
.Enabled = True
}
AddHandler _Timer.Elapsed, AddressOf Callback
Catch ex As Exception
_Logger.Error(ex)
End Try
End Sub End Sub
Public Sub New(LogConfig As LogConfig) Public Async Sub Callback(sender As Object, e As ElapsedEventArgs)
_LogConfig = LogConfig Try
_Logger = LogConfig.GetLogger() _Logger.Debug("Checking if Service is up...")
_Channel = My.ChannelFactory.CreateChannel() If _Channel.State = ServiceModel.CommunicationState.Faulted Then
_Channel.Open() _Channel = My.ChannelFactory.CreateChannel()
End If
_Timer = New Timers.Timer(TIMER_INTERVAL) ' Connect to service and send hearbeat request
_Timer.SynchronizingObject = My.MainForm Dim oResult = Await _Channel.HeartbeatAsync()
AddHandler _Timer.Elapsed, AddressOf Callback
_Timer.Enabled = True
_Logger.Debug("Service is online")
SetOnlineState(True)
Catch ex As Exception
_Logger.Debug("Service is offline!")
SetOnlineState(False)
Finally
My.Application.Service.LastChecked = DateTime.Now
End Try
End Sub
Private Sub SetOnlineState(NewState As Boolean)
If My.Application.Service.Online <> NewState Then
My.Application.Service.Online = NewState
RaiseEvent OnlineChanged(Me, NewState)
End If
End Sub End Sub
End Class End Class

View File

@@ -207,8 +207,8 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile> </Compile>
<Compile Include="MyApplication.vb" /> <Compile Include="MyApplication.vb" />
<Compile Include="State\ServiceState.vb" /> <Compile Include="State\ClassServiceState.vb" />
<Compile Include="State\UserState.vb" /> <Compile Include="State\ClassUserState.vb" />
<Compile Include="Strings\ControlProperties.Designer.vb"> <Compile Include="Strings\ControlProperties.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>

View File

@@ -29,8 +29,8 @@ Namespace My
''' </summary> ''' </summary>
Partial Class MyApplication Partial Class MyApplication
' User Config ' User Config
Public User As New UserState() Public User As New ClassUserState()
Public Service As New ServiceState() Public Service As New ClassServiceState()
End Class End Class
End Namespace End Namespace

View File

@@ -0,0 +1,4 @@
Public Class ClassServiceState
Public Property Online As Boolean = True
Public Property LastChecked As DateTime = DateTime.Now
End Class

View File

@@ -3,7 +3,7 @@
''' <summary> ''' <summary>
''' Helper Class to hold User State ''' Helper Class to hold User State
''' </summary> ''' </summary>
Public Class UserState Public Class ClassUserState
Public UserName As String Public UserName As String
Public MachineName As String Public MachineName As String
Public Language As String Public Language As String

View File

@@ -1,9 +0,0 @@
Public Class ServiceState
Public Online As Boolean
Public LastChecked As DateTime
Public Sub New()
Online = True
LastChecked = DateTime.Now
End Sub
End Class

View File

@@ -22,7 +22,7 @@
My.Config.ServicePort = Integer.Parse(oPort) My.Config.ServicePort = Integer.Parse(oPort)
lblStatus.Text = "Verbindung wird hergestellt..." lblStatus.Text = "Verbindung wird hergestellt..."
oResult = Await _Service.TestConnectionAsync(My.ConfigManager.Config.ServiceConnection) oResult = Await _Service.TestConnectionAsync()
If oResult = ClassService.ConnectionTestResult.Successful Then If oResult = ClassService.ConnectionTestResult.Successful Then
My.ConfigManager.Save() My.ConfigManager.Save()

View File

@@ -19,10 +19,11 @@ Partial Class frmMain
'Do not modify it using the code editor. 'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> <System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent() Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmMain)) Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmMain))
Dim PushTransition1 As DevExpress.Utils.Animation.PushTransition = New DevExpress.Utils.Animation.PushTransition() Dim PushTransition1 As DevExpress.Utils.Animation.PushTransition = New DevExpress.Utils.Animation.PushTransition()
Me.RibbonControl = New DevExpress.XtraBars.Ribbon.RibbonControl() Me.RibbonControl = New DevExpress.XtraBars.Ribbon.RibbonControl()
Me.MainMenu = New DevExpress.XtraBars.Ribbon.ApplicationMenu() Me.MainMenu = New DevExpress.XtraBars.Ribbon.ApplicationMenu(Me.components)
Me.BarButtonExit = New DevExpress.XtraBars.BarButtonItem() Me.BarButtonExit = New DevExpress.XtraBars.BarButtonItem()
Me.BarButtonUserSettings = New DevExpress.XtraBars.BarButtonItem() Me.BarButtonUserSettings = New DevExpress.XtraBars.BarButtonItem()
Me.BarButtonConnectionSettings = New DevExpress.XtraBars.BarButtonItem() Me.BarButtonConnectionSettings = New DevExpress.XtraBars.BarButtonItem()
@@ -39,6 +40,7 @@ Partial Class frmMain
Me.BarButtonItem2 = New DevExpress.XtraBars.BarButtonItem() Me.BarButtonItem2 = New DevExpress.XtraBars.BarButtonItem()
Me.BarWorkspaceMenuItem1 = New DevExpress.XtraBars.BarWorkspaceMenuItem() Me.BarWorkspaceMenuItem1 = New DevExpress.XtraBars.BarWorkspaceMenuItem()
Me.WorkspaceManager1 = New DevExpress.Utils.WorkspaceManager() Me.WorkspaceManager1 = New DevExpress.Utils.WorkspaceManager()
Me.LabelServiceOnline = New DevExpress.XtraBars.BarStaticItem()
Me.RibbonPageCategoryEntityDesigner = New DevExpress.XtraBars.Ribbon.RibbonPageCategory() Me.RibbonPageCategoryEntityDesigner = New DevExpress.XtraBars.Ribbon.RibbonPageCategory()
Me.RibbonPageControlActions = New DevExpress.XtraBars.Ribbon.RibbonPage() Me.RibbonPageControlActions = New DevExpress.XtraBars.Ribbon.RibbonPage()
Me.RibbonPageGroup5 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup() Me.RibbonPageGroup5 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
@@ -50,16 +52,16 @@ Partial Class frmMain
Me.RibbonPageWorkflow = New DevExpress.XtraBars.Ribbon.RibbonPage() Me.RibbonPageWorkflow = New DevExpress.XtraBars.Ribbon.RibbonPage()
Me.RibbonPageGroup4 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup() Me.RibbonPageGroup4 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
Me.RibbonStatusBar = New DevExpress.XtraBars.Ribbon.RibbonStatusBar() Me.RibbonStatusBar = New DevExpress.XtraBars.Ribbon.RibbonStatusBar()
Me.DocumentManager = New DevExpress.XtraBars.Docking2010.DocumentManager() Me.DocumentManager = New DevExpress.XtraBars.Docking2010.DocumentManager(Me.components)
Me.TabbedView1 = New DevExpress.XtraBars.Docking2010.Views.Tabbed.TabbedView() Me.TabbedView1 = New DevExpress.XtraBars.Docking2010.Views.Tabbed.TabbedView(Me.components)
Me.DockManager = New DevExpress.XtraBars.Docking.DockManager() Me.DockManager = New DevExpress.XtraBars.Docking.DockManager(Me.components)
Me.panelContainer1 = New DevExpress.XtraBars.Docking.DockPanel() Me.panelContainer1 = New DevExpress.XtraBars.Docking.DockPanel()
Me.DockPanelGlobix = New DevExpress.XtraBars.Docking.DockPanel() Me.DockPanelGlobix = New DevExpress.XtraBars.Docking.DockPanel()
Me.DockPanel1_Container = New DevExpress.XtraBars.Docking.ControlContainer() Me.DockPanel1_Container = New DevExpress.XtraBars.Docking.ControlContainer()
Me.Label1 = New System.Windows.Forms.Label() Me.Label1 = New System.Windows.Forms.Label()
Me.DockPanelProcessManager = New DevExpress.XtraBars.Docking.DockPanel() Me.DockPanelProcessManager = New DevExpress.XtraBars.Docking.DockPanel()
Me.DockPanel2_Container = New DevExpress.XtraBars.Docking.ControlContainer() Me.DockPanel2_Container = New DevExpress.XtraBars.Docking.ControlContainer()
Me.ProcessManagerWidget = New ClientSuite.ProcessManagerWidget() Me.ProcessManagerWidget = New DigitalData.GUIs.ClientSuite.ProcessManagerWidget()
CType(Me.RibbonControl, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.RibbonControl, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.MainMenu, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.MainMenu, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.DocumentManager, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.DocumentManager, System.ComponentModel.ISupportInitialize).BeginInit()
@@ -76,9 +78,9 @@ Partial Class frmMain
' '
Me.RibbonControl.ApplicationButtonDropDownControl = Me.MainMenu Me.RibbonControl.ApplicationButtonDropDownControl = Me.MainMenu
Me.RibbonControl.ExpandCollapseItem.Id = 0 Me.RibbonControl.ExpandCollapseItem.Id = 0
Me.RibbonControl.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl.ExpandCollapseItem, Me.BarButtonExit, Me.BarButtonUserSettings, Me.LabelCurrentUser, Me.LabelCurrentMachine, Me.LabelCurrentVersion, Me.BarButtonItem1, Me.BarButtonDock1, Me.SkinDropDownButtonItem1, Me.BarButtonDashboard, Me.BarButtonEntityDesigner, Me.BarButtonDeleteControl, Me.BarButtonConnectionSettings, Me.LabelCurrentLanguage, Me.BarButtonItem2, Me.BarWorkspaceMenuItem1}) Me.RibbonControl.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl.ExpandCollapseItem, Me.BarButtonExit, Me.BarButtonUserSettings, Me.LabelCurrentUser, Me.LabelCurrentMachine, Me.LabelCurrentVersion, Me.BarButtonItem1, Me.BarButtonDock1, Me.SkinDropDownButtonItem1, Me.BarButtonDashboard, Me.BarButtonEntityDesigner, Me.BarButtonDeleteControl, Me.BarButtonConnectionSettings, Me.LabelCurrentLanguage, Me.BarButtonItem2, Me.BarWorkspaceMenuItem1, Me.LabelServiceOnline})
Me.RibbonControl.Location = New System.Drawing.Point(0, 0) Me.RibbonControl.Location = New System.Drawing.Point(0, 0)
Me.RibbonControl.MaxItemId = 18 Me.RibbonControl.MaxItemId = 19
Me.RibbonControl.Name = "RibbonControl" Me.RibbonControl.Name = "RibbonControl"
Me.RibbonControl.PageCategories.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageCategory() {Me.RibbonPageCategoryEntityDesigner}) Me.RibbonControl.PageCategories.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageCategory() {Me.RibbonPageCategoryEntityDesigner})
Me.RibbonControl.PageHeaderItemLinks.Add(Me.SkinDropDownButtonItem1) Me.RibbonControl.PageHeaderItemLinks.Add(Me.SkinDropDownButtonItem1)
@@ -200,6 +202,12 @@ Partial Class frmMain
Me.WorkspaceManager1.TargetControl = Me Me.WorkspaceManager1.TargetControl = Me
Me.WorkspaceManager1.TransitionType = PushTransition1 Me.WorkspaceManager1.TransitionType = PushTransition1
' '
'LabelServiceOnline
'
Me.LabelServiceOnline.Caption = "BarStaticItem1"
Me.LabelServiceOnline.Id = 18
Me.LabelServiceOnline.Name = "LabelServiceOnline"
'
'RibbonPageCategoryEntityDesigner 'RibbonPageCategoryEntityDesigner
' '
Me.RibbonPageCategoryEntityDesigner.AutoStretchPageHeaders = True Me.RibbonPageCategoryEntityDesigner.AutoStretchPageHeaders = True
@@ -271,6 +279,7 @@ Partial Class frmMain
Me.RibbonStatusBar.ItemLinks.Add(Me.LabelCurrentMachine) Me.RibbonStatusBar.ItemLinks.Add(Me.LabelCurrentMachine)
Me.RibbonStatusBar.ItemLinks.Add(Me.LabelCurrentVersion) Me.RibbonStatusBar.ItemLinks.Add(Me.LabelCurrentVersion)
Me.RibbonStatusBar.ItemLinks.Add(Me.LabelCurrentLanguage) Me.RibbonStatusBar.ItemLinks.Add(Me.LabelCurrentLanguage)
Me.RibbonStatusBar.ItemLinks.Add(Me.LabelServiceOnline)
Me.RibbonStatusBar.Location = New System.Drawing.Point(0, 556) Me.RibbonStatusBar.Location = New System.Drawing.Point(0, 556)
Me.RibbonStatusBar.Name = "RibbonStatusBar" Me.RibbonStatusBar.Name = "RibbonStatusBar"
Me.RibbonStatusBar.Ribbon = Me.RibbonControl Me.RibbonStatusBar.Ribbon = Me.RibbonControl
@@ -436,4 +445,5 @@ Partial Class frmMain
Friend WithEvents BarButtonItem2 As DevExpress.XtraBars.BarButtonItem Friend WithEvents BarButtonItem2 As DevExpress.XtraBars.BarButtonItem
Friend WithEvents BarWorkspaceMenuItem1 As DevExpress.XtraBars.BarWorkspaceMenuItem Friend WithEvents BarWorkspaceMenuItem1 As DevExpress.XtraBars.BarWorkspaceMenuItem
Friend WithEvents WorkspaceManager1 As DevExpress.Utils.WorkspaceManager Friend WithEvents WorkspaceManager1 As DevExpress.Utils.WorkspaceManager
Friend WithEvents LabelServiceOnline As DevExpress.XtraBars.BarStaticItem
End Class End Class

View File

@@ -13,17 +13,33 @@ Public Class frmMain
' Dieser Aufruf ist für den Designer erforderlich. ' Dieser Aufruf ist für den Designer erforderlich.
InitializeComponent() InitializeComponent()
' Assign My.MainForm before everything else
My.MainForm = Me
' Initialize Main Timer
_Timer = New ClassTimer(My.LogConfig)
' Show splashscreen ' Show splashscreen
frmSplash.ShowDialog() frmSplash.ShowDialog()
' Initialize Form Related Variables
My.MainForm = Me
End Sub
Private Sub SetOnlineLabel()
If My.Application.Service.Online Then
LabelServiceOnline.Caption = "Service Online"
LabelServiceOnline.ItemAppearance.Normal.ForeColor = Color.Green
Else
LabelServiceOnline.Caption = "Service Offline"
LabelServiceOnline.ItemAppearance.Normal.ForeColor = Color.Red
End If
End Sub
Private Sub HandleOnlineChanged(sender As Object, Online As Boolean)
SetOnlineLabel()
End Sub End Sub
Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles Me.Load Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
' Initialize Main Timer
_Timer = New ClassTimer(My.LogConfig, Me, My.Config.HeartbeatInterval)
AddHandler _Timer.OnlineChanged, AddressOf HandleOnlineChanged
SetOnlineLabel()
LabelCurrentUser.Caption = My.Application.User.UserName LabelCurrentUser.Caption = My.Application.User.UserName
LabelCurrentMachine.Caption = My.Application.User.MachineName LabelCurrentMachine.Caption = My.Application.User.MachineName
LabelCurrentVersion.Caption = My.Application.Info.Version.ToString LabelCurrentVersion.Caption = My.Application.Info.Version.ToString
@@ -48,7 +64,6 @@ Public Class frmMain
MsgBox($"Clicked on Document {RowView.Row.Item("DocName")}") MsgBox($"Clicked on Document {RowView.Row.Item("DocName")}")
End Sub End Sub
LoadLayout() LoadLayout()
End Sub End Sub
@@ -57,21 +72,21 @@ Public Class frmMain
End Sub End Sub
Private Sub LoadLayout() Private Sub LoadLayout()
Dim oLayoutPathForDockManager As String = GetLayoutPath(LayoutName.LayoutMain, LayoutComponent.DockManager) Dim oLayoutPathForDockManager As String = GetLayoutPath(GroupName.LayoutMain, LayoutComponent.DockManager)
Dim oLayoutPathForDocumentManager As String = GetLayoutPath(LayoutName.LayoutMain, LayoutComponent.DocumentManager) Dim oLayoutPathForDocumentManager As String = GetLayoutPath(GroupName.LayoutMain, LayoutComponent.DocumentManager)
If IO.File.Exists(oLayoutPathForDockManager) Then If File.Exists(oLayoutPathForDockManager) Then
DockManager.RestoreLayoutFromXml(oLayoutPathForDockManager) DockManager.RestoreLayoutFromXml(oLayoutPathForDockManager)
End If End If
If IO.File.Exists(oLayoutPathForDocumentManager) Then If File.Exists(oLayoutPathForDocumentManager) Then
DocumentManager.View.RestoreLayoutFromXml(oLayoutPathForDocumentManager) DocumentManager.View.RestoreLayoutFromXml(oLayoutPathForDocumentManager)
End If End If
End Sub End Sub
Private Sub SaveLayout() Private Sub SaveLayout()
Dim oLayoutPathForDockManager As String = GetLayoutPath(LayoutName.LayoutMain, LayoutComponent.DockManager) Dim oLayoutPathForDockManager As String = GetLayoutPath(GroupName.LayoutMain, LayoutComponent.DockManager)
Dim oLayoutPathForDocumentManager As String = GetLayoutPath(LayoutName.LayoutMain, LayoutComponent.DocumentManager) Dim oLayoutPathForDocumentManager As String = GetLayoutPath(GroupName.LayoutMain, LayoutComponent.DocumentManager)
Dim oDirectory As String = Path.GetDirectoryName(oLayoutPathForDockManager) Dim oDirectory As String = GetLayoutDirectory()
If Not Directory.Exists(oDirectory) Then If Not Directory.Exists(oDirectory) Then
Directory.CreateDirectory(oDirectory) Directory.CreateDirectory(oDirectory)

View File

@@ -49,6 +49,12 @@ Public NotInheritable Class frmSplash
End Function End Function
#Region "Worker" #Region "Worker"
Private Enum WorkerResult
AllGood
ServiceOffline
End Enum
Private Sub StartWorker() Private Sub StartWorker()
AddHandler _Worker.DoWork, AddressOf bw_DoWork AddHandler _Worker.DoWork, AddressOf bw_DoWork
AddHandler _Worker.ProgressChanged, AddressOf bw_ProgressChanged AddHandler _Worker.ProgressChanged, AddressOf bw_ProgressChanged
@@ -58,17 +64,25 @@ Public NotInheritable Class frmSplash
_Worker.RunWorkerAsync() _Worker.RunWorkerAsync()
End Sub End Sub
Private Sub bw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Private Async Sub bw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
Dim oService As New ClassService(My.LogConfig) Dim oService As New ClassService(My.LogConfig)
_Worker.ReportProgress(SetProgress(1), "Connecting to service..") _Worker.ReportProgress(SetProgress(1), "Connecting to service..")
Dim oChannelFactory As ChannelFactory(Of IEDMServiceChannel)
Dim oChannel As IEDMServiceChannel
Dim oConnectionSuccessful = False Dim oConnectionSuccessful = False
oChannelFactory = oService.GetChannelFactory() e.Result = WorkerResult.AllGood
oChannel = oChannelFactory.CreateChannel()
_ChannelFactory = oService.GetChannelFactory()
_Channel = _ChannelFactory.CreateChannel()
'Dim oServiceOnline = Await oService.TestConnectionAsync()
Dim oServiceState = oService.TestConnection()
If oServiceState <> ClassService.ConnectionTestResult.Successful Then
e.Result = WorkerResult.ServiceOffline
Return
End If
Thread.Sleep(SLEEP_TIME) Thread.Sleep(SLEEP_TIME)
@@ -92,11 +106,25 @@ Public NotInheritable Class frmSplash
Private Sub bw_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Private Sub bw_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs)
' Bei Fehler MsgBox anzeigen und Programm beenden ' Bei Fehler MsgBox anzeigen und Programm beenden
If e.Error IsNot Nothing Then If e.Error IsNot Nothing Then
'ClassLogger.Add("Unexpected error in Initializing application....") MsgBox(e.Error.Message, MsgBoxStyle.Critical, "Unhandled Error")
MsgBox(e.Error.Message, MsgBoxStyle.Critical, "Critical Error") Application.Exit()
ElseIf e.Result <> WorkerResult.AllGood Then
Dim oErrorMessage
Select Case e.Result
Case WorkerResult.ServiceOffline
oErrorMessage = "Service is offline!"
Case Else
oErrorMessage = "Unknown Error"
End Select
MsgBox($"Application could not be started{vbNewLine}Reason: {oErrorMessage}", MsgBoxStyle.Critical, "Critical Error")
Application.Exit() Application.Exit()
End If End If
My.ChannelFactory = _ChannelFactory
My.Channel = _Channel
' Wenn kein Fehler, Splashscreen schließen ' Wenn kein Fehler, Splashscreen schließen
Me.Close() Me.Close()
End Sub End Sub

View File

@@ -6,5 +6,5 @@
cause the file to be unrecognizable by the program. cause the file to be unrecognizable by the program.
--> -->
<GenericObjectDataSource DisplayName="ContainerResult" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource"> <GenericObjectDataSource DisplayName="ContainerResult" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>DigitalData.Modules.EDMIFileOps.EDMIServiceReference.ContainerResult</TypeInfo> <TypeInfo>DigitalData.Modules.EDMIFileOps.EDMIServiceReference.ContainerResult, Connected Services.EDMIServiceReference.Reference.vb.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource> </GenericObjectDataSource>

View File

@@ -6,5 +6,5 @@
cause the file to be unrecognizable by the program. cause the file to be unrecognizable by the program.
--> -->
<GenericObjectDataSource DisplayName="NonQueryResult" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource"> <GenericObjectDataSource DisplayName="NonQueryResult" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>DigitalData.Modules.EDMIFileOps.EDMIServiceReference.NonQueryResult</TypeInfo> <TypeInfo>DigitalData.Modules.EDMIFileOps.EDMIServiceReference.NonQueryResult, Connected Services.EDMIServiceReference.Reference.vb.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource> </GenericObjectDataSource>

View File

@@ -6,5 +6,5 @@
cause the file to be unrecognizable by the program. cause the file to be unrecognizable by the program.
--> -->
<GenericObjectDataSource DisplayName="ScalarResult" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource"> <GenericObjectDataSource DisplayName="ScalarResult" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>DigitalData.Modules.EDMIFileOps.EDMIServiceReference.ScalarResult</TypeInfo> <TypeInfo>DigitalData.Modules.EDMIFileOps.EDMIServiceReference.ScalarResult, Connected Services.EDMIServiceReference.Reference.vb.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource> </GenericObjectDataSource>

View File

@@ -6,5 +6,5 @@
cause the file to be unrecognizable by the program. cause the file to be unrecognizable by the program.
--> -->
<GenericObjectDataSource DisplayName="TableResult" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource"> <GenericObjectDataSource DisplayName="TableResult" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>DigitalData.Modules.EDMIFileOps.EDMIServiceReference.TableResult</TypeInfo> <TypeInfo>DigitalData.Modules.EDMIFileOps.EDMIServiceReference.TableResult, Connected Services.EDMIServiceReference.Reference.vb.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource> </GenericObjectDataSource>

View File

@@ -9,6 +9,12 @@
<xsd:import namespace="http://schemas.datacontract.org/2004/07/DigitalData.Modules.Filesystem" /> <xsd:import namespace="http://schemas.datacontract.org/2004/07/DigitalData.Modules.Filesystem" />
</xsd:schema> </xsd:schema>
</wsdl:types> </wsdl:types>
<wsdl:message name="IEDMService_Heartbeat_InputMessage">
<wsdl:part name="parameters" element="tns:Heartbeat" />
</wsdl:message>
<wsdl:message name="IEDMService_Heartbeat_OutputMessage">
<wsdl:part name="parameters" element="tns:HeartbeatResponse" />
</wsdl:message>
<wsdl:message name="IEDMService_CreateDatabaseRequest_InputMessage"> <wsdl:message name="IEDMService_CreateDatabaseRequest_InputMessage">
<wsdl:part name="parameters" element="tns:CreateDatabaseRequest" /> <wsdl:part name="parameters" element="tns:CreateDatabaseRequest" />
</wsdl:message> </wsdl:message>
@@ -64,6 +70,10 @@
<wsdl:part name="parameters" element="tns:DeleteFileResponse" /> <wsdl:part name="parameters" element="tns:DeleteFileResponse" />
</wsdl:message> </wsdl:message>
<wsdl:portType name="IEDMService"> <wsdl:portType name="IEDMService">
<wsdl:operation name="Heartbeat">
<wsdl:input wsaw:Action="http://DigitalData.Services.EDMService/IEDMService/Heartbeat" message="tns:IEDMService_Heartbeat_InputMessage" />
<wsdl:output wsaw:Action="http://DigitalData.Services.EDMService/IEDMService/HeartbeatResponse" message="tns:IEDMService_Heartbeat_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="CreateDatabaseRequest"> <wsdl:operation name="CreateDatabaseRequest">
<wsdl:input wsaw:Action="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequest" message="tns:IEDMService_CreateDatabaseRequest_InputMessage" /> <wsdl:input wsaw:Action="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequest" message="tns:IEDMService_CreateDatabaseRequest_InputMessage" />
<wsdl:output wsaw:Action="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequestResponse" message="tns:IEDMService_CreateDatabaseRequest_OutputMessage" /> <wsdl:output wsaw:Action="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequestResponse" message="tns:IEDMService_CreateDatabaseRequest_OutputMessage" />

View File

@@ -1,6 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://DigitalData.Services.EDMService" elementFormDefault="qualified" targetNamespace="http://DigitalData.Services.EDMService" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:schema xmlns:tns="http://DigitalData.Services.EDMService" elementFormDefault="qualified" targetNamespace="http://DigitalData.Services.EDMService" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://schemas.datacontract.org/2004/07/DigitalData.Services.EDMService" /> <xs:import namespace="http://schemas.datacontract.org/2004/07/DigitalData.Services.EDMService" />
<xs:element name="Heartbeat">
<xs:complexType>
<xs:sequence />
</xs:complexType>
</xs:element>
<xs:element name="HeartbeatResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="HeartbeatResult" type="xs:boolean" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CreateDatabaseRequest"> <xs:element name="CreateDatabaseRequest">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>

View File

@@ -427,6 +427,12 @@ Namespace EDMIServiceReference
System.ServiceModel.ServiceContractAttribute([Namespace]:="http://DigitalData.Services.EDMService", ConfigurationName:="EDMIServiceReference.IEDMService")> _ System.ServiceModel.ServiceContractAttribute([Namespace]:="http://DigitalData.Services.EDMService", ConfigurationName:="EDMIServiceReference.IEDMService")> _
Public Interface IEDMService Public Interface IEDMService
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMService/IEDMService/Heartbeat", ReplyAction:="http://DigitalData.Services.EDMService/IEDMService/HeartbeatResponse")> _
Function Heartbeat() As Boolean
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMService/IEDMService/Heartbeat", ReplyAction:="http://DigitalData.Services.EDMService/IEDMService/HeartbeatResponse")> _
Function HeartbeatAsync() As System.Threading.Tasks.Task(Of Boolean)
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequest", ReplyAction:="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequestResponse")> _ <System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequest", ReplyAction:="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequestResponse")> _
Function CreateDatabaseRequest(ByVal Name As String, ByVal Debug As Boolean) As String Function CreateDatabaseRequest(ByVal Name As String, ByVal Debug As Boolean) As String
@@ -513,6 +519,14 @@ Namespace EDMIServiceReference
MyBase.New(binding, remoteAddress) MyBase.New(binding, remoteAddress)
End Sub End Sub
Public Function Heartbeat() As Boolean Implements EDMIServiceReference.IEDMService.Heartbeat
Return MyBase.Channel.Heartbeat
End Function
Public Function HeartbeatAsync() As System.Threading.Tasks.Task(Of Boolean) Implements EDMIServiceReference.IEDMService.HeartbeatAsync
Return MyBase.Channel.HeartbeatAsync
End Function
Public Function CreateDatabaseRequest(ByVal Name As String, ByVal Debug As Boolean) As String Implements EDMIServiceReference.IEDMService.CreateDatabaseRequest Public Function CreateDatabaseRequest(ByVal Name As String, ByVal Debug As Boolean) As String Implements EDMIServiceReference.IEDMService.CreateDatabaseRequest
Return MyBase.Channel.CreateDatabaseRequest(Name, Debug) Return MyBase.Channel.CreateDatabaseRequest(Name, Debug)
End Function End Function

View File

@@ -39,6 +39,15 @@
<wsp:PolicyReference URI="#tcpBinding_policy"> <wsp:PolicyReference URI="#tcpBinding_policy">
</wsp:PolicyReference> </wsp:PolicyReference>
<soap12:binding transport="http://schemas.microsoft.com/soap/tcp" /> <soap12:binding transport="http://schemas.microsoft.com/soap/tcp" />
<wsdl:operation name="Heartbeat">
<soap12:operation soapAction="http://DigitalData.Services.EDMService/IEDMService/Heartbeat" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CreateDatabaseRequest"> <wsdl:operation name="CreateDatabaseRequest">
<soap12:operation soapAction="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequest" style="document" /> <soap12:operation soapAction="http://DigitalData.Services.EDMService/IEDMService/CreateDatabaseRequest" style="document" />
<wsdl:input> <wsdl:input>

View File

@@ -17,18 +17,25 @@ Public Class EDMService
Private _request As Request = Nothing Private _request As Request = Nothing
Private _debug As Boolean = False Private _debug As Boolean = False
Private _username As String
Public Sub New() Public Sub New()
Dim oOperationContext As OperationContext = OperationContext.Current Dim oOperationContext As OperationContext = OperationContext.Current
Dim oInstanceContext As InstanceContext = oOperationContext.InstanceContext Dim oInstanceContext As InstanceContext = oOperationContext.InstanceContext
Dim oUsername = oOperationContext.ServiceSecurityContext.WindowsIdentity.Name Dim oUsername = oOperationContext.ServiceSecurityContext.WindowsIdentity.Name
_username = oUsername
_logger = LogConfig.GetLogger() _logger = LogConfig.GetLogger()
End Sub End Sub
#Region "Heartbeat"
Public Function Heartbeat() As Boolean Implements IEDMService.Heartbeat
Return True
End Function
#End Region
#Region "Request" #Region "Request"
Public Function CreateDatabaseRequest(Name As String, Optional Debug As Boolean = False) As String Implements IEDMService.CreateDatabaseRequest Public Function CreateDatabaseRequest(Name As String, Optional Debug As Boolean = False) As String Implements IEDMService.CreateDatabaseRequest
_request = New Request(Name, _session.Username, Database, Debug) _request = New Request(Name, _username, Database, Debug)
_debug = Debug _debug = Debug
_logger.Info("Creating request {0}/{1}", _request.Name, _request.RequestId) _logger.Info("Creating request {0}/{1}", _request.Name, _request.RequestId)

View File

@@ -4,6 +4,11 @@ Imports DigitalData.Modules.Filesystem
<ServiceContract([Namespace]:="http://DigitalData.Services.EDMService")> <ServiceContract([Namespace]:="http://DigitalData.Services.EDMService")>
Interface IEDMService Interface IEDMService
#Region "Heartbeat"
<OperationContract>
Function Heartbeat() As Boolean
#End Region
#Region "Database" #Region "Database"
<OperationContract> <OperationContract>
Function CreateDatabaseRequest(Name As String, Optional Debug As Boolean = False) As String Function CreateDatabaseRequest(Name As String, Optional Debug As Boolean = False) As String

View File

@@ -15,7 +15,6 @@ Public Class WindowsService
Private _logger As Logger Private _logger As Logger
Private _db As Firebird Private _db As Firebird
Private _clientsConnected As Integer = 0 Private _clientsConnected As Integer = 0
Private _clients As New List(Of Session)
Private _config As AppConfig Private _config As AppConfig
Public Sub New() Public Sub New()
@@ -46,9 +45,6 @@ Public Class WindowsService
_logger.Info("Successfully connected to database!") _logger.Info("Successfully connected to database!")
AddHandler EDMService.ClientConnectedEvent, AddressOf EDMService_ClientConnected
AddHandler EDMService.ClientDisconnectedEvent, AddressOf EDMService_ClientDisonnected
EDMService.Database = _db EDMService.Database = _db
EDMService.LogConfig = _logConfig EDMService.LogConfig = _logConfig
EDMService.AppConfig = _config EDMService.AppConfig = _config
@@ -66,18 +62,6 @@ Public Class WindowsService
End Try End Try
End Sub End Sub
Private Sub EDMService_ClientDisonnected(sender As Object, e As Session)
_clientsConnected -= 1
_clients.Remove(e)
_logger.Info("Client {0}/{1} disconnected! Total {2}", e.Username, e.SessionId, _clientsConnected)
End Sub
Private Sub EDMService_ClientConnected(sender As Object, e As Session)
_clientsConnected += 1
_clients.Add(e)
_logger.Info("Client {0}/{1} connected! Total {2}", e.Username, e.SessionId, _clientsConnected)
End Sub
Protected Overrides Sub OnStop() Protected Overrides Sub OnStop()
If _serviceHost IsNot Nothing Then If _serviceHost IsNot Nothing Then
_serviceHost.Close() _serviceHost.Close()