Verbesserung von Logging, Fehlerbehandlung und Caching
Die Änderungen umfassen: - Zusätzliche Prüfung und Fehlermeldung in `ctrlObjectPropertyDialog`, wenn keine Business Entities gefunden werden. - Anpassung der Logik in `frmObjectPropertyDialog` zur besseren Zuordnung von LayoutControlItem und BaseEdit. - Einführung von Thread-Sicherheit für den Cache in `EDMIService` mittels `SyncLock`. - Erweiterung von Methoden wie `ReturnDatatable`, `ReturnScalarValue` und `ExecuteNonQuery` um Performance-Messung mit `Stopwatch`. - Vereinheitlichung der Fehlerbehandlung durch konsistente Nutzung von `FaultException`. - Erweiterung des Loggings für Sessions, Cache-Aktualisierungen und Datenbankoperationen. - Korrektur der Rückgabe in `GetFileInfoByObjectId` und Verbesserung der Fault-Wrapper-Methoden. - Bereinigung von redundanten Codezeilen und Kommentaren.
This commit is contained in:
@@ -85,6 +85,13 @@ Public Class ctrlObjectPropertyDialog
|
||||
End If
|
||||
' Load Business Entities
|
||||
Dim oEntityIds = Await GetBusinessEntitiesForObjectId(pObjectId)
|
||||
|
||||
If oEntityIds.Count = 0 Then
|
||||
_Logger.Warn("Keine Business Entities für ObjectId {0} gefunden.", pObjectId)
|
||||
Helper.ShowErrorMessage(New ApplicationException($"Für das Objekt '{pObjectId}' wurden keine Business Entities gefunden."), "LoadObject")
|
||||
Return False
|
||||
End If
|
||||
|
||||
Dim oActiveEntity = oEntityIds.FirstOrDefault()
|
||||
|
||||
Dim oCombobox As RepositoryItemComboBox = DirectCast(cmbEntityId.Edit, RepositoryItemComboBox)
|
||||
|
||||
@@ -154,7 +154,8 @@ Public Class frmObjectPropertyDialog
|
||||
End Sub
|
||||
|
||||
Private Sub BaseEdit_EditValueChanged(sender As Object, e As EventArgs)
|
||||
Dim oControl As BaseEdit = sender
|
||||
Dim oControlItem As LayoutControlItem = sender
|
||||
Dim oControl As BaseEdit = oControlItem.Control
|
||||
Dim oAttribute As Attribute = oControl.Tag
|
||||
Dim oValue = oControl.EditValue
|
||||
Dim oKey = oAttribute.Title
|
||||
@@ -163,7 +164,6 @@ Public Class frmObjectPropertyDialog
|
||||
Changes.Item(oKey) = oValue
|
||||
Else
|
||||
Changes.Add(oAttribute.Title, oValue)
|
||||
|
||||
End If
|
||||
End Sub
|
||||
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
Imports System.IO
|
||||
Imports System.Diagnostics
|
||||
Imports System.IO
|
||||
Imports System.ServiceModel
|
||||
Imports System.ServiceModel.Description
|
||||
Imports System.Threading
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Logging
|
||||
'Imports DigitalData.Modules.
|
||||
Imports DigitalData.Modules.EDMI
|
||||
Imports DigitalData.Modules.EDMI.API.Rights
|
||||
Imports DigitalData.Services.EDMIService.Messages
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Services.EDMIService.Exceptions
|
||||
Imports DigitalData.Services.EDMIService.Messages
|
||||
Imports DigitalData.Services.EDMIService.Methods
|
||||
Imports DigitalData.Services.EDMIService.Methods.Database
|
||||
Imports DigitalData.Services.EDMIService.Methods.IDB
|
||||
|
||||
|
||||
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession)>
|
||||
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession,
|
||||
ConcurrencyMode:=ConcurrencyMode.Multiple)>
|
||||
Public Class EDMIService
|
||||
Implements IEDMIService
|
||||
|
||||
@@ -91,29 +93,29 @@ Public Class EDMIService
|
||||
_Logger = LogConfig.GetLogger()
|
||||
_IDBHelpers = New IDB.Helpers(LogConfig, MSSQL_IDB)
|
||||
|
||||
' ── Konfiguration beim ersten Aufruf loggen ───────────────────────────
|
||||
If Not String.IsNullOrEmpty(_ConfiguredEndpoint) Then
|
||||
Dim oEndpointSnapshot = Interlocked.Exchange(Of String)(_ConfiguredEndpoint, String.Empty)
|
||||
If Not String.IsNullOrEmpty(oEndpointSnapshot) Then
|
||||
_Logger.Info("✔ EDMIService configured | Endpoint=[{0}] | MaxCalls=[{1}] | MaxSessions=[{2}] | CPUs=[{3}]",
|
||||
_ConfiguredEndpoint, _ConfiguredMaxCalls, _ConfiguredMaxSessions, Environment.ProcessorCount)
|
||||
_ConfiguredEndpoint = String.Empty
|
||||
oEndpointSnapshot, _ConfiguredMaxCalls, _ConfiguredMaxSessions, Environment.ProcessorCount)
|
||||
End If
|
||||
' ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
' ── Session registrieren ──────────────────────────────────────────────
|
||||
_ActiveSessions(oSessionId) = _Username
|
||||
BuildUserList()
|
||||
' ← Neu: Session-Start loggen
|
||||
_Logger.Debug("Session opened | User=[{0}] | SessionId=[{1}] | ActiveSessions=[{2}]",
|
||||
_Username, oSessionId, _ActiveSessions.Count)
|
||||
|
||||
AddHandler oInstanceContext.Closed, Sub()
|
||||
Dim oRemoved As String = Nothing
|
||||
_ActiveSessions.TryRemove(oSessionId, oRemoved)
|
||||
BuildUserList()
|
||||
_Logger.Debug("Session closed | User=[{0}] | SessionId=[{1}] | ActiveSessions=[{2}]",
|
||||
_Username, oSessionId, _ActiveSessions.Count)
|
||||
End Sub
|
||||
|
||||
AddHandler oInstanceContext.Faulted, Sub()
|
||||
Dim oRemoved As String = Nothing
|
||||
_ActiveSessions.TryRemove(oSessionId, oRemoved)
|
||||
_Logger.Warn("⚠ Session faulted | User=[{0}] | ActiveSessions=[{1}]",
|
||||
_Username, _ActiveSessions.Count)
|
||||
_Logger.Warn("⚠ Session faulted | User=[{0}] | SessionId=[{1}] | ActiveSessions=[{2}]",
|
||||
_Username, oSessionId, _ActiveSessions.Count)
|
||||
End Sub
|
||||
|
||||
End Sub
|
||||
@@ -199,17 +201,24 @@ Public Class EDMIService
|
||||
|
||||
|
||||
#Region "=== Database ==="
|
||||
Private Shared ReadOnly _CachedTablesLock As New Object()
|
||||
Private Shared _CachedTablesSnapshot As List(Of String) = Nothing
|
||||
Private Shared _CachedTablesExpiry As DateTime = DateTime.MinValue
|
||||
|
||||
Public Function GetCachedTables() As List(Of String) Implements IEDMIService.GetCachedTables
|
||||
Try
|
||||
If _CachedTablesSnapshot Is Nothing OrElse DateTime.Now > _CachedTablesExpiry Then
|
||||
_CachedTablesSnapshot = GlobalState.GetCachedTables()
|
||||
_CachedTablesExpiry = DateTime.Now.AddSeconds(30)
|
||||
End If
|
||||
Return _CachedTablesSnapshot
|
||||
SyncLock _CachedTablesLock
|
||||
If _CachedTablesSnapshot Is Nothing OrElse DateTime.Now > _CachedTablesExpiry Then
|
||||
_Logger.Debug("GetCachedTables: Refreshing cache...")
|
||||
_CachedTablesSnapshot = GlobalState.GetCachedTables()
|
||||
_CachedTablesExpiry = DateTime.Now.AddSeconds(30)
|
||||
_Logger.Debug("GetCachedTables: Cache refreshed | Count=[{0}] | NextExpiry=[{1}]",
|
||||
_CachedTablesSnapshot.Count, _CachedTablesExpiry.ToString("HH:mm:ss"))
|
||||
End If
|
||||
Return _CachedTablesSnapshot.ToList()
|
||||
End SyncLock
|
||||
Catch ex As Exception
|
||||
_Logger.Error("GetCachedTables failed | User=[{0}] | Error=[{1}]", _Username, ex.Message)
|
||||
_Logger.Error(ex)
|
||||
Return New List(Of String)
|
||||
End Try
|
||||
@@ -231,21 +240,54 @@ Public Class EDMIService
|
||||
End Function
|
||||
|
||||
Public Function ReturnDatatable(pData As GetDatatable.GetDatatableRequest) As GetDatatable.GetDatatableResponse Implements IEDMIService.ReturnDatatable
|
||||
_Logger.Debug("Start of Method [ReturnDatatable]")
|
||||
Dim oGetDatatable As New GetDatatable.GetDatatableMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||||
Return oGetDatatable.Run(pData)
|
||||
Dim oWatch = Stopwatch.StartNew()
|
||||
Try
|
||||
_Logger.Debug("ReturnDatatable | User=[{0}] | DB=[{1}] | SQL=[{2}]",
|
||||
_Username, pData.NamedDatabase, pData.SqlCommand)
|
||||
Dim oGetDatatable As New GetDatatable.GetDatatableMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||||
Dim oResult = oGetDatatable.Run(pData)
|
||||
_Logger.Debug("ReturnDatatable completed | User=[{0}] | Rows=[{1}] | Duration=[{2}ms]",
|
||||
_Username, If(oResult?.Table?.Rows.Count, 0), oWatch.ElapsedMilliseconds)
|
||||
Return oResult
|
||||
Catch ex As Exception
|
||||
_Logger.Error("ReturnDatatable failed | User=[{0}] | Duration=[{1}ms] | Error=[{2}]",
|
||||
_Username, oWatch.ElapsedMilliseconds, ex.Message)
|
||||
Throw
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function ReturnScalarValue(pData As GetScalarValue.GetScalarValueRequest) As GetScalarValue.GetScalarValueResponse Implements IEDMIService.ReturnScalarValue
|
||||
_Logger.Debug("Start of Method [ReturnScalarValue]")
|
||||
Dim oGetScalarValue As New GetScalarValue.GetScalarValueMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||||
Return oGetScalarValue.Run(pData)
|
||||
Dim oWatch = Stopwatch.StartNew()
|
||||
Try
|
||||
_Logger.Debug("ReturnScalarValue | User=[{0}] | DB=[{1}] | SQL=[{2}]",
|
||||
_Username, pData.NamedDatabase, pData.SqlCommand)
|
||||
Dim oGetScalarValue As New GetScalarValue.GetScalarValueMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||||
Dim oResult = oGetScalarValue.Run(pData)
|
||||
_Logger.Debug("ReturnScalarValue completed | User=[{0}] | Duration=[{1}ms]",
|
||||
_Username, oWatch.ElapsedMilliseconds)
|
||||
Return oResult
|
||||
Catch ex As Exception
|
||||
_Logger.Error("ReturnScalarValue failed | User=[{0}] | Duration=[{1}ms] | Error=[{2}]",
|
||||
_Username, oWatch.ElapsedMilliseconds, ex.Message)
|
||||
Throw
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function ExecuteNonQuery(pData As ExecuteNonQuery.ExecuteNonQueryRequest) As ExecuteNonQuery.ExecuteNonQueryResponse Implements IEDMIService.ExecuteNonQuery
|
||||
_Logger.Debug("Start of Method [ExecuteNonQuery]")
|
||||
Dim oExecuteNonQuery As New ExecuteNonQuery.ExecuteNonQueryMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||||
Return oExecuteNonQuery.Run(pData)
|
||||
Dim oWatch = Stopwatch.StartNew()
|
||||
Try
|
||||
_Logger.Debug("ExecuteNonQuery | User=[{0}] | DB=[{1}] | SQL=[{2}]",
|
||||
_Username, pData.NamedDatabase, pData.SqlCommand)
|
||||
Dim oExecuteNonQuery As New ExecuteNonQuery.ExecuteNonQueryMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||||
Dim oResult = oExecuteNonQuery.Run(pData)
|
||||
_Logger.Debug("ExecuteNonQuery completed | User=[{0}] | Duration=[{1}ms]",
|
||||
_Username, oWatch.ElapsedMilliseconds)
|
||||
Return oResult
|
||||
Catch ex As Exception
|
||||
_Logger.Error("ExecuteNonQuery failed | User=[{0}] | Duration=[{1}ms] | Error=[{2}]",
|
||||
_Username, oWatch.ElapsedMilliseconds, ex.Message)
|
||||
Throw
|
||||
End Try
|
||||
End Function
|
||||
#End Region
|
||||
|
||||
@@ -259,7 +301,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -276,7 +318,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -293,7 +335,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -313,7 +355,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -330,7 +372,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -347,7 +389,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -367,7 +409,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -384,7 +426,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -401,7 +443,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -502,7 +544,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -522,15 +564,17 @@ Public Class EDMIService
|
||||
Throw New FaultException(Of ObjectDoesNotExistFault)(oFault, oFault.ErrorMessage)
|
||||
End If
|
||||
|
||||
Return New DocumentInfoResponse With {
|
||||
Dim oResult = New DocumentInfoResponse With {
|
||||
.FileRight = oAccessRight,
|
||||
.FullPath = oFullPath
|
||||
}
|
||||
_Logger.Debug("End GetFileInfoByObjectId!")
|
||||
_Logger.Debug("End GetFileInfoByObjectId!") ' ← jetzt erreichbar
|
||||
Return oResult
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Warn("⚠ GetFileInfoByObjectId: " & ex.Message)
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("⚠ GetFileInfoByObjectId: " & ex.Message)
|
||||
@@ -550,7 +594,7 @@ Public Class EDMIService
|
||||
|
||||
Catch ex As FaultException
|
||||
_Logger.Error(ex)
|
||||
Throw ex
|
||||
Throw
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
@@ -607,13 +651,17 @@ Public Class EDMIService
|
||||
|
||||
|
||||
Private Function GetFault(Exception As Exception) As FaultException
|
||||
Dim oMessage = If(Exception?.Message, "Unknown error")
|
||||
_Logger.Error("Wrapping exception as FaultException | Error=[{0}]", oMessage)
|
||||
Dim oFault As New UnexpectedErrorFault(Exception)
|
||||
Return New FaultException(Of UnexpectedErrorFault)(oFault, New FaultReason(oFault.InnerException.Message))
|
||||
Dim oReason = If(Exception?.InnerException?.Message, oMessage)
|
||||
Return New FaultException(Of UnexpectedErrorFault)(oFault, New FaultReason(oReason))
|
||||
End Function
|
||||
|
||||
Private Function GetFault(ErrorMessage As String) As FaultException
|
||||
_Logger.Error("Wrapping error as FaultException | Error=[{0}]", ErrorMessage)
|
||||
Dim oFault As New UnexpectedErrorFault(New ApplicationException(ErrorMessage))
|
||||
Return New FaultException(Of UnexpectedErrorFault)(oFault, New FaultReason(oFault.InnerException.Message))
|
||||
Return New FaultException(Of UnexpectedErrorFault)(oFault, New FaultReason(ErrorMessage))
|
||||
End Function
|
||||
|
||||
Private Function GetFullPathForObjectId(ObjectId As Long) As String
|
||||
|
||||
Reference in New Issue
Block a user