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.
759 lines
32 KiB
VB.net
759 lines
32 KiB
VB.net
Imports System.Diagnostics
|
||
Imports System.IO
|
||
Imports System.ServiceModel
|
||
Imports System.ServiceModel.Description
|
||
Imports System.Threading
|
||
Imports DigitalData.Modules.Database
|
||
Imports DigitalData.Modules.EDMI
|
||
Imports DigitalData.Modules.EDMI.API.Rights
|
||
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,
|
||
ConcurrencyMode:=ConcurrencyMode.Multiple)>
|
||
Public Class EDMIService
|
||
Implements IEDMIService
|
||
|
||
Public Shared LogConfig As LogConfig
|
||
Public Shared MSSQL_ECM As MSSQLServer
|
||
Public Shared MSSQL_IDB As MSSQLServer
|
||
Public Shared Firebird As Firebird
|
||
Public Shared AppConfig As Config
|
||
Public Shared GlobalState As GlobalState
|
||
Public Shared Scheduler As Scheduler
|
||
|
||
Public Const TBIDB_DOC_INFO = "TBIDB_DOC_INFO"
|
||
Public Const TBIDB_ACCESSRIGHT = "TBIDB_ACCESSRIGHT"
|
||
' ── Aktive Sessions: SessionId → Username (thread-safe) ──────────────────
|
||
Private Shared ReadOnly _ActiveSessions As New Collections.Concurrent.ConcurrentDictionary(Of String, String)
|
||
|
||
Public Shared ReadOnly Property ActiveSessions As Integer
|
||
Get
|
||
Return _ActiveSessions.Count
|
||
End Get
|
||
End Property
|
||
|
||
Public Shared ReadOnly Property ActiveSessionUsers As IReadOnlyCollection(Of String)
|
||
Get
|
||
Return _ActiveSessions.Values.Distinct().OrderBy(Function(u) u).ToList().AsReadOnly()
|
||
End Get
|
||
End Property
|
||
' ─────────────────────────────────────────────────────────────────────────
|
||
|
||
Private ReadOnly _Logger As Logger
|
||
Private ReadOnly _Debug As Boolean = False
|
||
Private ReadOnly _Username As String
|
||
Private ReadOnly _IDBHelpers As IDB.Helpers
|
||
' ── Konfigurationswerte für späteres Logging in New() ────────────────────
|
||
Private Shared _ConfiguredEndpoint As String = String.Empty
|
||
Private Shared _ConfiguredMaxCalls As Integer = 0
|
||
Private Shared _ConfiguredMaxSessions As Integer = 0
|
||
' ─────────────────────────────────────────────────────────────────────────
|
||
|
||
|
||
Public Shared Sub Configure(Config As ServiceConfiguration)
|
||
Dim oBaseAddress = Config.BaseAddresses.Item(0)
|
||
Dim oBinding = API.Channel.GetBinding()
|
||
Dim oAddress = New EndpointAddress(oBaseAddress)
|
||
Dim oDescription = ContractDescription.GetContract(GetType(IEDMIService), GetType(EDMIService))
|
||
Dim oEndpoint As New ServiceEndpoint(oDescription, oBinding, oAddress)
|
||
|
||
Config.AddServiceEndpoint(oEndpoint)
|
||
Config.Description.Behaviors.Add(New ServiceDebugBehavior With {.IncludeExceptionDetailInFaults = True})
|
||
|
||
Dim oThrottling = Config.Description.Behaviors.Find(Of ServiceThrottlingBehavior)()
|
||
If oThrottling Is Nothing Then
|
||
oThrottling = New ServiceThrottlingBehavior()
|
||
Config.Description.Behaviors.Add(oThrottling)
|
||
End If
|
||
Dim oCpuCores As Integer = Environment.ProcessorCount
|
||
oThrottling.MaxConcurrentCalls = Math.Max(200, 32 * oCpuCores) ' war 16×
|
||
oThrottling.MaxConcurrentSessions = Math.Max(400, 150 * oCpuCores) ' war 100×
|
||
oThrottling.MaxConcurrentInstances = Integer.MaxValue
|
||
|
||
' ── Werte für späteres Logging speichern ─────────────────────────────
|
||
_ConfiguredEndpoint = oBaseAddress.ToString()
|
||
_ConfiguredMaxCalls = oThrottling.MaxConcurrentCalls
|
||
_ConfiguredMaxSessions = oThrottling.MaxConcurrentSessions
|
||
' ─────────────────────────────────────────────────────────────────────
|
||
End Sub
|
||
|
||
Public Sub New()
|
||
Dim oOperationContext As OperationContext = OperationContext.Current
|
||
Dim oInstanceContext As InstanceContext = oOperationContext.InstanceContext
|
||
Dim oUsername = StripDomainFromUsername(oOperationContext.ServiceSecurityContext.WindowsIdentity.Name)
|
||
Dim oSessionId As String = If(oOperationContext.SessionId, $"no-session_{Guid.NewGuid().ToString("N").Substring(0, 8)}")
|
||
|
||
_Username = If(String.IsNullOrWhiteSpace(oUsername), "unknown", oUsername)
|
||
_Logger = LogConfig.GetLogger()
|
||
_IDBHelpers = New IDB.Helpers(LogConfig, MSSQL_IDB)
|
||
|
||
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}]",
|
||
oEndpointSnapshot, _ConfiguredMaxCalls, _ConfiguredMaxSessions, Environment.ProcessorCount)
|
||
End If
|
||
|
||
_ActiveSessions(oSessionId) = _Username
|
||
' ← 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)
|
||
_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}] | SessionId=[{1}] | ActiveSessions=[{2}]",
|
||
_Username, oSessionId, _ActiveSessions.Count)
|
||
End Sub
|
||
|
||
End Sub
|
||
''' <summary>
|
||
''' Erstellt die User-Liste nur wenn nötig (Debug-Guard vorher prüfen).
|
||
''' </summary>
|
||
Private Shared Function BuildUserList() As String
|
||
Return String.Join(", ", _ActiveSessions.Values.Distinct().OrderBy(Function(u) u))
|
||
End Function
|
||
#Region "=== Base ==="
|
||
Public Function Heartbeat() As Boolean Implements IEDMIService.Heartbeat
|
||
Return True
|
||
End Function
|
||
|
||
Public Function GetClientConfig() As Base.GetClientConfig.GetClientConfigResponse Implements IEDMIService.GetClientConfig
|
||
_Logger.Debug("Start of Method [GetClientConfig]")
|
||
Dim oGetClientConfig As New Base.GetClientConfig.GetClientConfigMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oGetClientConfig.Run()
|
||
End Function
|
||
''' <summary>
|
||
''' Returns a snapshot of all currently active sessions for monitoring purposes
|
||
''' </summary>
|
||
Public Function GetServiceStatus() As Messages.ServiceStatusResponse Implements IEDMIService.GetServiceStatus
|
||
_Logger.Debug("GetServiceStatus called by User=[{0}]", _Username)
|
||
' Snapshot nur einmal erstellen, nicht zweimal iterieren:
|
||
Dim oSnapshot = _ActiveSessions.ToArray()
|
||
Return New Messages.ServiceStatusResponse With {
|
||
.ActiveSessionCount = oSnapshot.Length,
|
||
.ActiveUsers = oSnapshot.Select(Function(p) p.Value).Distinct().OrderBy(Function(u) u).ToList(),
|
||
.ActiveSessions = oSnapshot.ToDictionary(Function(p) p.Key, Function(p) p.Value),
|
||
.Timestamp = DateTime.Now
|
||
}
|
||
End Function
|
||
#End Region
|
||
|
||
Public Function NewFile(Data As NewFile.NewFileRequest) As NewFile.NewFileResponse Implements IEDMIService.NewFile
|
||
_Logger.Debug("Start of Method [NewFile]")
|
||
Dim oNewFile As New NewFile.NewFileMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oNewFile.Run(Data)
|
||
End Function
|
||
|
||
Public Function UpdateFile(Data As UpdateFile.UpdateFileRequest) As UpdateFile.UpdateFileResponse Implements IEDMIService.UpdateFile
|
||
_Logger.Debug("Start of Method [VersionFile]")
|
||
Dim oVersionFile As New UpdateFile.UpdateFileMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oVersionFile.Run(Data)
|
||
End Function
|
||
|
||
Public Function SetAttributeValue(Data As SetAttributeValue.SetAttributeValueRequest) As SetAttributeValue.SetAttributeValueResponse Implements IEDMIService.SetAttributeValue
|
||
_Logger.Debug("Start of Method [SetAttributeValue]")
|
||
Dim oSetAttributeValue As New SetAttributeValue.SetAttributeValueMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oSetAttributeValue.Run(Data)
|
||
End Function
|
||
|
||
Public Function GetAttributeValue(Data As GetAttributeValue.GetAttributeValueRequest) As GetAttributeValue.GetAttributeValueResponse Implements IEDMIService.GetAttributeValue
|
||
_Logger.Debug("Start of Method [GetAttributeValue]")
|
||
Dim oGetAttributeValue As New GetAttributeValue.GetAttributeValueMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oGetAttributeValue.Run(Data)
|
||
End Function
|
||
|
||
Public Function GetFileObject(pData As GetFileObject.GetFileObjectRequest) As GetFileObject.GetFileObjectResponse Implements IEDMIService.GetFileObject
|
||
_Logger.Debug("Start of Method [GetFileObject]")
|
||
Dim oGetFileObject As New GetFileObject.GetFileObjectMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oGetFileObject.Run(pData)
|
||
End Function
|
||
|
||
Public Function CheckInOutFile(pData As CheckInOutFile.CheckInOutFileRequest) As CheckInOutFile.CheckInOutFileResponse Implements IEDMIService.CheckInOutFile
|
||
_Logger.Debug("Start of Method [CheckInOutFile]")
|
||
Dim oCheckInOutFile As New CheckInOutFile.CheckInOutFileMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oCheckInOutFile.Run(pData)
|
||
End Function
|
||
|
||
Public Function ImportFile(pData As ImportFile.ImportFileRequest) As ImportFile.ImportFileResponse Implements IEDMIService.ImportFile
|
||
_Logger.Debug("Start of Method [IDB.ImportFile]")
|
||
Dim oImportFile As New ImportFile.ImportFileMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oImportFile.Run(pData)
|
||
End Function
|
||
|
||
Public Function Globix_ImportFile(pData As GlobalIndexer.ImportFile.Globix_ImportFileRequest) As GlobalIndexer.ImportFile.Globix_ImportFileResponse Implements IEDMIService.Globix_ImportFile
|
||
_Logger.Debug("Start of Method [Globix.ImportFile]")
|
||
Dim oImportFile As New GlobalIndexer.ImportFile.ImportFileMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Return oImportFile.Run(pData)
|
||
End Function
|
||
|
||
|
||
#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
|
||
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
|
||
End Function
|
||
|
||
Public Function ReturnDatatableFromCache(Name As String, FilterExpression As String, SortByColumn As String) As TableResult Implements IEDMIService.ReturnDatatableFromCache
|
||
Dim oReturnDatatableFromCache As New GetDatatableFromCache.GetDatatableFromCacheMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
|
||
Dim oResult = oReturnDatatableFromCache.Run(New GetDatatableFromCache.GetDatatableFromCacheRequest With {
|
||
.DataTable = Name,
|
||
.FilterExpression = FilterExpression,
|
||
.SortByColumn = SortByColumn
|
||
})
|
||
|
||
If oResult.OK Then
|
||
Return New TableResult(oResult.Table)
|
||
Else
|
||
Return New TableResult(oResult.ErrorMessage)
|
||
End If
|
||
End Function
|
||
|
||
Public Function ReturnDatatable(pData As GetDatatable.GetDatatableRequest) As GetDatatable.GetDatatableResponse Implements IEDMIService.ReturnDatatable
|
||
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
|
||
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
|
||
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
|
||
|
||
#Region "=== Database (MSSQL IDB) ==="
|
||
Public Function ReturnDatatable_MSSQL_IDB(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_MSSQL_IDB
|
||
Try
|
||
_Logger.Debug($"ReturnDatatable_MSSQL_IDB, SQL: {SQL}")
|
||
Dim oResult As DataTable = MSSQL_IDB.GetDatatable(SQL)
|
||
oResult.TableName = "DD_RESULT"
|
||
Return New TableResult(oResult)
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function ReturnScalar_MSSQL_IDB(SQL As String) As ScalarResult Implements IEDMIService.ReturnScalar_MSSQL_IDB
|
||
Try
|
||
_Logger.Info($"ReturnScalar_MSSQL_IDB, SQL: {SQL}")
|
||
Dim oResult As Object = MSSQL_IDB.GetScalarValue(SQL)
|
||
Return New ScalarResult(oResult)
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function ExecuteNonQuery_MSSQL_IDB(SQL As String) As NonQueryResult Implements IEDMIService.ExecuteNonQuery_MSSQL_IDB
|
||
Try
|
||
_Logger.Info($"ExecuteNonQuery_MSSQL_IDB, SQL: {SQL}")
|
||
Dim oResult As Boolean = MSSQL_IDB.ExecuteNonQuery(SQL)
|
||
Return New NonQueryResult()
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
#End Region
|
||
|
||
#Region "=== Database (MSSQL ECM) ==="
|
||
Public Function ReturnDatatable_MSSQL_ECM(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_MSSQL_ECM
|
||
Try
|
||
_Logger.Info($"ReturnDatatable_MSSQL_ECM, SQL: {SQL}")
|
||
Dim oResult As DataTable = MSSQL_ECM.GetDatatable(SQL)
|
||
oResult.TableName = "DD_RESULT"
|
||
Return New TableResult(oResult)
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function ReturnScalar_MSSQL_ECM(SQL As String) As ScalarResult Implements IEDMIService.ReturnScalar_MSSQL_ECM
|
||
Try
|
||
_Logger.Info($"ReturnScalar_MSSQL_ECM, SQL: {SQL}")
|
||
Dim oResult As Object = MSSQL_ECM.GetScalarValue(SQL)
|
||
Return New ScalarResult(oResult)
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function ExecuteNonQuery_MSSQL_ECM(SQL As String) As NonQueryResult Implements IEDMIService.ExecuteNonQuery_MSSQL_ECM
|
||
Try
|
||
_Logger.Info($"ExecuteNonQuery_MSSQL_ECM, SQL: {SQL}")
|
||
Dim oResult As Boolean = MSSQL_ECM.ExecuteNonQuery(SQL)
|
||
Return New NonQueryResult()
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
#End Region
|
||
|
||
#Region "=== Database (Firebird) ==="
|
||
Public Function ReturnDatatable_Firebird(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_Firebird
|
||
Try
|
||
_Logger.Info($"ReturnDatatable, SQL: {SQL}")
|
||
Dim oResult As DataTable = Firebird.GetDatatable(SQL)
|
||
oResult.TableName = "DD_RESULT"
|
||
Return New TableResult(oResult)
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function ReturnScalar_Firebird(SQL As String) As ScalarResult Implements IEDMIService.ReturnScalar_Firebird
|
||
Try
|
||
_Logger.Info($"ReturnScalar, SQL: {SQL}")
|
||
Dim oResult As Object = Firebird.GetScalarValue(SQL)
|
||
Return New ScalarResult(oResult)
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function ExecuteNonQuery_Firebird(SQL As String) As NonQueryResult Implements IEDMIService.ExecuteNonQuery_Firebird
|
||
Try
|
||
_Logger.Info($"ExecuteNonQuery, SQL: {SQL}")
|
||
Dim oResult As Boolean = Firebird.ExecuteNonQuery(SQL)
|
||
Return New NonQueryResult()
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
#End Region
|
||
|
||
#Region "=== Document ==="
|
||
''' <summary>
|
||
''' Imports a file according to ObjectStoreId
|
||
''' </summary>
|
||
''' <returns></returns>
|
||
'Public Function ImportFile(Data As DocumentImportRequest) As DocumentImportResponse Implements IEDMIService.ImportFile
|
||
' Dim oObjectStore = GlobalState.ObjectStores.First()
|
||
' Dim EDMIPath = New EDMI.File.Path(LogConfig, oObjectStore.Path)
|
||
|
||
' ' TODO:
|
||
' ' - Get Object Store -> Object Catalog -> Catalog Path
|
||
' ' - If IS_ARCHIVE = True And RetentionDays <> Nothing:
|
||
' ' DoArchive!
|
||
' ' - Refactor EDMIPath to get ObjectStore at service start up
|
||
' ' and return ObjectStore Path from ObjectStoreId + RelativePath
|
||
' ' VWIDB_OBJECTSTORE
|
||
|
||
' Dim oRelativePath As String = EDMIPath.GetRelativePath(Data.DocumentType, Data.FileName)
|
||
' Dim oAbsolutePath As String = EDMIPath.GetFullPath(Data.DocumentType, Data.FileName)
|
||
' Dim oDirectoryPath = EDMIPath.GetFullPath(Data.DocumentType)
|
||
|
||
' Try
|
||
' Directory.CreateDirectory(oDirectoryPath)
|
||
|
||
' Dim oVersionedFileName As String = Filesystem.GetVersionedFilename(oAbsolutePath)
|
||
|
||
' _Logger.Info("ImportFile: Saving file [{0}] to path [{1}]", Data.FileName, oVersionedFileName)
|
||
' Using oStream = New FileStream(oVersionedFileName, FileMode.CreateNew)
|
||
' oStream.Write(Data.Contents, 0, Data.Contents.Length)
|
||
' oStream.Flush(True)
|
||
' oStream.Close()
|
||
' End Using
|
||
|
||
' ' insert into db
|
||
' Dim oCommand As New SqlCommand("PRIDB_NEW_DOCUMENT")
|
||
' oCommand.Parameters.AddWithValue("@OBJ_ST_ID", 1)
|
||
' oCommand.Parameters.AddWithValue("@REL_PATH", oRelativePath)
|
||
' oCommand.Parameters.AddWithValue("@WHO", _Username)
|
||
' oCommand.Parameters.AddWithValue("@REF_DOCID", 0)
|
||
' oCommand.Parameters.Add(New SqlParameter("@IDB_OBJ_ID", SqlDbType.BigInt))
|
||
|
||
' Dim oObjectId = MSSQL_IDB.GetScalarValue(oCommand, "@IDB_OBJ_ID")
|
||
|
||
' Return New DocumentImportResponse() With {.ObjectId = oObjectId}
|
||
|
||
' Catch ex As FaultException
|
||
' _Logger.Error(ex)
|
||
' Throw ex
|
||
|
||
' Catch ex As Exception
|
||
' _Logger.Error(ex)
|
||
' Throw GetFault(ex)
|
||
|
||
' End Try
|
||
'End Function
|
||
|
||
Public Function GetFileByObjectId(Data As DocumentStreamRequest) As DocumentStreamResponse Implements IEDMIService.GetFileByObjectId
|
||
Try
|
||
Dim oFullPath = GetFullPathForObjectId(Data.ObjectId)
|
||
|
||
If oFullPath = String.Empty Then
|
||
Dim oDetails As New ObjectDoesNotExistFault(Data.ObjectId)
|
||
_Logger.Warn("⚠ GetFileByObjectId: " & oDetails.ErrorMessage)
|
||
Throw New FaultException(Of ObjectDoesNotExistFault)(oDetails, oDetails.ErrorMessage)
|
||
End If
|
||
|
||
_Logger.Debug("GetFileByObjectId: Loading file [{0}]", oFullPath)
|
||
|
||
Dim oFileInfo As New FileInfo(oFullPath)
|
||
|
||
If Not oFileInfo.Exists Then
|
||
Dim oDetails As New ObjectDoesNotExistFault(Data.ObjectId)
|
||
_Logger.Warn("⚠ GetFileByObjectId: " & oDetails.ErrorMessage)
|
||
Throw New FaultException(Of ObjectDoesNotExistFault)(oDetails, oDetails.ErrorMessage)
|
||
End If
|
||
|
||
Dim oDestination As New MemoryStream()
|
||
Using oSource As FileStream = IO.File.OpenRead(oFullPath)
|
||
oSource.CopyTo(oDestination)
|
||
End Using
|
||
oDestination.Seek(0, SeekOrigin.Begin)
|
||
|
||
Dim oMessage As New DocumentStreamResponse() With {
|
||
.FileName = oFileInfo.Name,
|
||
.FileContents = oDestination
|
||
}
|
||
|
||
Return oMessage
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function GetFileInfoByObjectId(Data As DocumentInfoRequest) As DocumentInfoResponse Implements IEDMIService.GetFileInfoByObjectId
|
||
Try
|
||
_Logger.Debug("GetFileInfoByObjectId...")
|
||
Dim oAccessRight = GetAccessRightForObjectId(Data.UserId, Data.ObjectId)
|
||
Dim oFullPath = GetFullPathForObjectId(Data.ObjectId)
|
||
|
||
If oFullPath = String.Empty Then
|
||
Dim oFault As New ObjectDoesNotExistFault(Data.ObjectId)
|
||
Throw New FaultException(Of ObjectDoesNotExistFault)(oFault, oFault.ErrorMessage)
|
||
End If
|
||
|
||
Dim oResult = New DocumentInfoResponse With {
|
||
.FileRight = oAccessRight,
|
||
.FullPath = oFullPath
|
||
}
|
||
_Logger.Debug("End GetFileInfoByObjectId!") ' ← jetzt erreichbar
|
||
Return oResult
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Warn("⚠ GetFileInfoByObjectId: " & ex.Message)
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Warn("⚠ GetFileInfoByObjectId: " & ex.Message)
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function ListFilesForUser() As DocumentListResponse Implements IEDMIService.ListFilesForUser
|
||
Try
|
||
Dim oDatatable = GetFileList()
|
||
|
||
Return New DocumentListResponse() With {
|
||
.Datatable = oDatatable
|
||
}
|
||
|
||
Catch ex As FaultException
|
||
_Logger.Error(ex)
|
||
Throw
|
||
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Throw GetFault(ex)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
Public Function GetFileList() As DataTable
|
||
Try
|
||
If Not GlobalState.TableStore.Tables.Contains(TBIDB_DOC_INFO) Then
|
||
_Logger.Warn("⚠ GetFileList: Document info table does not exist!")
|
||
Return Nothing
|
||
End If
|
||
|
||
Dim oTable As DataTable = GlobalState.TableStore.Tables.Item(TBIDB_DOC_INFO)
|
||
Return oTable
|
||
Catch ex As Exception
|
||
_Logger.Warn("⚠ GetFileList: Unexpected Error while getting file list.")
|
||
_Logger.Error(ex)
|
||
Return Nothing
|
||
End Try
|
||
End Function
|
||
|
||
Public Function TestObjectIdExists(Data As TestObjectIdExistsRequest) As TestObjectIdExistsResponse Implements IEDMIService.TestObjectIdExists
|
||
Try
|
||
Dim oDeleted As Boolean = False
|
||
Dim oActive As Boolean = False
|
||
|
||
If _IDBHelpers.TestObjectIdExists(Data.ObjectId, oDeleted, oActive) = False Then
|
||
Return New TestObjectIdExistsResponse(False)
|
||
End If
|
||
|
||
Return New TestObjectIdExistsResponse(True) With {
|
||
.Deleted = oDeleted,
|
||
.Inactive = Not oActive
|
||
}
|
||
Catch ex As Exception
|
||
_Logger.Error(ex)
|
||
Return New TestObjectIdExistsResponse(False)
|
||
|
||
End Try
|
||
End Function
|
||
|
||
|
||
|
||
|
||
#End Region
|
||
|
||
#Region "=== Private ==="
|
||
|
||
|
||
|
||
|
||
|
||
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)
|
||
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(ErrorMessage))
|
||
End Function
|
||
|
||
Private Function GetFullPathForObjectId(ObjectId As Long) As String
|
||
Try
|
||
If Not GlobalState.TableStore.Tables.Contains(TBIDB_DOC_INFO) Then
|
||
_Logger.Warn("⚠ GetFullPathForObjectId: Document info table does not exist!")
|
||
Return String.Empty
|
||
End If
|
||
|
||
Dim oTable As DataTable = GlobalState.TableStore.Tables.Item(TBIDB_DOC_INFO)
|
||
Dim oRows As List(Of DataRow) = oTable.Select($"IDB_OBJ_ID = {ObjectId}").ToList()
|
||
|
||
Dim oFullPath As String
|
||
|
||
If oRows.Count = 0 Then
|
||
_Logger.Warn("⚠ GetFullPathForObjectId: Full path does not exist for object [{0}]", ObjectId)
|
||
oFullPath = String.Empty
|
||
Else
|
||
Dim oRow As DataRow = oRows.First()
|
||
oFullPath = oRow.Item("FULL_PATH")
|
||
End If
|
||
|
||
Return oFullPath
|
||
Catch ex As Exception
|
||
_Logger.Warn("⚠ GetFullPathForObjectId: Unexpected Error while getting full path for object [{0}].", ObjectId)
|
||
_Logger.Error(ex)
|
||
Return String.Empty
|
||
End Try
|
||
End Function
|
||
|
||
Private Function GetAccessRightForObjectId(UserId As Long, ObjectId As Long) As AccessRight
|
||
Try
|
||
If Not GlobalState.TableStore.Tables.Contains(TBIDB_ACCESSRIGHT) Then
|
||
_Logger.Warn("⚠ GetAccessRightForObjectId: Access right table does not exist!")
|
||
Return AccessRight.VIEW_ONLY
|
||
End If
|
||
|
||
_Logger.Debug("Getting AccessRights for ObjectId [{0}]", ObjectId)
|
||
Dim oTable As DataTable = GlobalState.TableStore.Tables.Item(TBIDB_ACCESSRIGHT)
|
||
Dim oRows As List(Of DataRow) = oTable.Select($"IDB_OBJ_ID = {ObjectId} AND USR_ID = {UserId}").ToList()
|
||
Dim oRight As AccessRight
|
||
|
||
_Logger.Debug("Successfully got AccessRights for ObjectId [{0}]", ObjectId)
|
||
_Logger.Debug("Parsing AccessRights for ObjectId [{0}]", ObjectId)
|
||
|
||
If oRows.Count = 0 Then
|
||
_Logger.Warn("⚠ GetAccessRightForObjectId: Access right assignment does not exist for user [{0}] on object [{1}]", UserId, ObjectId)
|
||
Return AccessRight.VIEW_ONLY
|
||
Else
|
||
If oRows.Count > 1 Then
|
||
_Logger.Warn("⚠ GetAccessRightForObjectId: More than one access right assignment found for user [{0}] on object [{1}]", UserId, ObjectId)
|
||
End If
|
||
|
||
Dim oRow As DataRow = oRows.First()
|
||
Dim oRightAsInt = oRow.Item("ACCESSRIGHT")
|
||
|
||
Select Case oRightAsInt
|
||
Case 1
|
||
oRight = AccessRight.VIEW_ONLY
|
||
Case 2
|
||
oRight = AccessRight.VIEW_EXPORT
|
||
Case 4
|
||
oRight = AccessRight.FULL
|
||
Case Else
|
||
_Logger.Warn("⚠ GetAccessRightForObjectId: Unknown access right [{0}] for user [{1}] on object [{2}]", oRightAsInt, UserId, ObjectId)
|
||
oRight = AccessRight.VIEW_ONLY
|
||
End Select
|
||
End If
|
||
|
||
_Logger.Debug("Successfully parsed AccessRights for ObjectId [{0}]", ObjectId)
|
||
_Logger.Debug("AccessRight for ObjectId [{0}] is [{1}]", ObjectId, oRight.ToString)
|
||
|
||
Return oRight
|
||
Catch ex As Exception
|
||
_Logger.Warn("⚠ GetAccessRightForObjectId: Unexpected Error while getting access right for object [{0}].", ObjectId)
|
||
_Logger.Error(ex)
|
||
Return AccessRight.VIEW_ONLY
|
||
End Try
|
||
End Function
|
||
|
||
Private Function StripDomainFromUsername(UserName As String)
|
||
If UserName.Contains("\") Then
|
||
Return UserName.Split("\")(1)
|
||
ElseIf UserName.Contains("@") Then
|
||
Return UserName.Split("@")(0)
|
||
Else
|
||
Return UserName
|
||
End If
|
||
End Function
|
||
|
||
|
||
#End Region
|
||
|
||
|
||
End Class |