diff --git a/GUIs.Common/DocumentResultList/frmDocumentResultList.vb b/GUIs.Common/DocumentResultList/frmDocumentResultList.vb index cd5d169f..17ec85b7 100644 --- a/GUIs.Common/DocumentResultList/frmDocumentResultList.vb +++ b/GUIs.Common/DocumentResultList/frmDocumentResultList.vb @@ -54,10 +54,10 @@ Public Class frmDocumentResultList _Params = Params _ResultLists = Params.Results - InitIDB() + MaybeInitIDB() End Sub - Private Sub InitIDB() + Private Sub MaybeInitIDB() _IsLegacy = Not _Environment.Service.IsActive If _Environment.Service.IsActive Then Dim oSplit As List(Of String) = _Environment.Service.Address.Split(";").ToList() @@ -218,6 +218,7 @@ Public Class frmDocumentResultList If e.FocusedRowHandle >= 0 Then Dim oRow = sender.GetDataRow(e.FocusedRowHandle) Dim oFullPath = oRow.Item(COLUMN_FILEPATH) + DocumentViewer1.LoadFile(oFullPath) End If End Sub diff --git a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.Results.xsd b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.Messages.xsd similarity index 90% rename from Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.Results.xsd rename to Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.Messages.xsd index 4c749748..943f1763 100644 --- a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.Results.xsd +++ b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.Messages.xsd @@ -1,5 +1,5 @@  - + diff --git a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.wsdl b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.wsdl index 58a4896e..49a6e750 100644 --- a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.wsdl +++ b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.wsdl @@ -4,7 +4,7 @@ - + diff --git a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.xsd b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.xsd index 7724ddb4..333e0f84 100644 --- a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.xsd +++ b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/DigitalData.Services.EDMIService.xsd @@ -1,6 +1,6 @@  - + @@ -26,7 +26,7 @@ - + @@ -40,7 +40,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -68,7 +68,7 @@ - + @@ -82,7 +82,7 @@ - + @@ -96,7 +96,7 @@ - + @@ -110,7 +110,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -138,7 +138,7 @@ - + @@ -152,7 +152,7 @@ - + diff --git a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/Reference.svcmap b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/Reference.svcmap index 778a5cea..8b05869e 100644 --- a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/Reference.svcmap +++ b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/Reference.svcmap @@ -26,7 +26,7 @@ - + diff --git a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/Reference.vb b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/Reference.vb index 9b5a77a5..e1e3d13a 100644 --- a/Modules.EDMIAPI/Connected Services/EDMIServiceReference/Reference.vb +++ b/Modules.EDMIAPI/Connected Services/EDMIServiceReference/Reference.vb @@ -18,7 +18,8 @@ Namespace EDMIServiceReference _ Partial Public Class NonQueryResult Inherits EDMIServiceReference.BaseResult @@ -120,7 +123,8 @@ Namespace EDMIServiceReference _ Partial Public Class TableResult Inherits EDMIServiceReference.BaseResult diff --git a/Modules.EDMIAPI/EDMI.API.vbproj b/Modules.EDMIAPI/EDMI.API.vbproj index e11f662b..cfec58bb 100644 --- a/Modules.EDMIAPI/EDMI.API.vbproj +++ b/Modules.EDMIAPI/EDMI.API.vbproj @@ -72,6 +72,7 @@ + True @@ -123,7 +124,7 @@ Reference.svcmap - + Designer diff --git a/Modules.EDMIAPI/My Project/AssemblyInfo.vb b/Modules.EDMIAPI/My Project/AssemblyInfo.vb index f7b314a3..4373aa8d 100644 --- a/Modules.EDMIAPI/My Project/AssemblyInfo.vb +++ b/Modules.EDMIAPI/My Project/AssemblyInfo.vb @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' übernehmen, indem Sie "*" eingeben: ' - + diff --git a/Modules.EDMIAPI/Rights.vb b/Modules.EDMIAPI/Rights.vb new file mode 100644 index 00000000..dc6ce6bf --- /dev/null +++ b/Modules.EDMIAPI/Rights.vb @@ -0,0 +1,7 @@ +Public Class Rights + Public Enum AccessRight + VIEW_ONLY = 1 + VIEW_EXPORT = 2 + FULL = 4 + End Enum +End Class diff --git a/Modules.Language/Utils.vb b/Modules.Language/Utils.vb index c7cda3b6..d619ef7f 100644 --- a/Modules.Language/Utils.vb +++ b/Modules.Language/Utils.vb @@ -22,6 +22,24 @@ Public Class Utils Return [Enum].Parse(GetType(T), value) End Function + ''' + ''' Converts an Integer value to the given Enum + ''' + ''' The Enum Type + ''' The integer value to convert + Public Shared Function ToEnum(Of T)(value As Integer) As T + Return [Enum].ToObject(GetType(T), value) + End Function + + ''' + ''' Converts a Long value to the given Enum + ''' + ''' The Enum Type + ''' The long value to convert + Public Shared Function ToEnum(Of T)(value As Long) As T + Return [Enum].ToObject(GetType(T), value) + End Function + Public Shared Function ToBoolean(input As String) As Boolean If String.IsNullOrEmpty(input) Then Return False Return (input.Trim().ToLower() = "true") OrElse (input.Trim() = "1") diff --git a/Service.EDMIService/EDMIService.vb b/Service.EDMIService/EDMIService.vb index 6ab1d49f..9302901b 100644 --- a/Service.EDMIService/EDMIService.vb +++ b/Service.EDMIService/EDMIService.vb @@ -1,14 +1,13 @@ Imports DigitalData.Modules.Database Imports DigitalData.Modules.Logging -Imports DigitalData.Modules.Filesystem Imports DigitalData.Modules.Language Imports DigitalData.Modules Imports System.IO Imports System.ServiceModel Imports System.Data.SqlClient -Imports DigitalData.Services.EDMIService.Results Imports System.ServiceModel.Description -Imports System.ServiceModel.Channels +Imports DigitalData.Services.EDMIService.Messages +Imports DigitalData.Modules.EDMI.API.Rights Public Class EDMIService @@ -24,10 +23,9 @@ Public Class EDMIService Public Shared GlobalState As GlobalState Public Shared Scheduler As Scheduler - Private ReadOnly _logger As Logger - - Private ReadOnly _debug As Boolean = False - Private ReadOnly _username As String + Private ReadOnly _Logger As Logger + Private ReadOnly _Debug As Boolean = False + Private ReadOnly _Username As String Public Shared Sub Configure(Config As ServiceConfiguration) Dim oBaseAddress = Config.BaseAddresses.Item(0) @@ -37,8 +35,6 @@ Public Class EDMIService 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}) End Sub @@ -48,12 +44,12 @@ Public Class EDMIService Dim oInstanceContext As InstanceContext = oOperationContext.InstanceContext Dim oUsername = StripDomainFromUsername(oOperationContext.ServiceSecurityContext.WindowsIdentity.Name) - _username = oUsername - _logger = LogConfig.GetLogger() - _logger.Debug("New Request by User [{0}]", _username) + _Username = oUsername + _Logger = LogConfig.GetLogger() + _Logger.Debug("New Request by User [{0}]", _Username) End Sub - Public Function StripDomainFromUsername(UserName As String) + Private Function StripDomainFromUsername(UserName As String) If UserName.Contains("\") Then Return UserName.Split("\")(1) ElseIf UserName.Contains("@") Then @@ -63,34 +59,21 @@ Public Class EDMIService End If End Function -#Region "=== Authorization ===" - Private Function TestUserAuth() As Boolean - Try - 'Dim oSQL As String = $"SELECT FNIDB_AUTH_USER('{_username}') FROM RDB$DATABASE;" - 'Dim oResult As Boolean = Database.GetScalarValue(oSQL) - 'Return oResult - Return True - Catch ex As Exception - _logger.Error(ex) - Return False - End Try - End Function -#End Region #Region "=== Heartbeat ===" Public Function Heartbeat() As Boolean Implements IEDMIService.Heartbeat Return True End Function #End Region -#Region "Database" +#Region "=== Database ===" Public Function ReturnDatatableFromCache(Name As String, FilterExpression As String, SortByColumn As String) As TableResult Implements IEDMIService.ReturnDatatableFromCache Try - _logger.Info($"ReturnDatatableFromCache, Datatable: {Name}") + _Logger.Info($"ReturnDatatableFromCache, Datatable: {Name}") - Dim oDataset As DataSet = Scheduler.DataSet + Dim oDataset As DataSet = GlobalState.TableStore Dim oDataTable As DataTable = Nothing - _logger.Debug("DataSet contains [{0}] datatables", oDataset.Tables.Count) + _Logger.Debug("DataSet contains [{0}] datatables", oDataset.Tables.Count) If oDataset.Tables.Contains(Name) Then oDataTable = oDataset.Tables.Item(Name).Copy() @@ -111,16 +94,16 @@ Public Class EDMIService oFilteredTable.TableName = Name End If - _logger.Debug("Datatable Stats for [{0}]:", Name) - _logger.Debug("Unfiltered: [{0}] rows", oDataTable.Rows.Count) - _logger.Debug("Filtered: [{0}] rows", oFilteredTable.Rows.Count) + _Logger.Debug("Datatable Stats for [{0}]:", Name) + _Logger.Debug("Unfiltered: [{0}] rows", oDataTable.Rows.Count) + _Logger.Debug("Filtered: [{0}] rows", oFilteredTable.Rows.Count) Return New TableResult(oFilteredTable) Else Throw New ApplicationException($"DataTable {Name} does not exist") End If Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New TableResult(ex.Message) End Try End Function @@ -129,33 +112,33 @@ Public Class EDMIService #Region "=== Database (MSSQL IDB) ===" Public Function ReturnDatatable_MSSQL_IDB(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_MSSQL_IDB Try - _logger.Info($"ReturnDatatable_MSSQL_IDB, SQL: {SQL}") + _Logger.Info($"ReturnDatatable_MSSQL_IDB, SQL: {SQL}") Dim oResult As DataTable = MSSQL_IDB.GetDatatable(SQL) Return New TableResult(oResult) Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New TableResult(ex.Message) 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}") + _Logger.Info($"ReturnScalar_MSSQL_IDB, SQL: {SQL}") Dim oResult As Object = MSSQL_IDB.GetScalarValue(SQL) Return New ScalarResult(oResult) Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New ScalarResult(ex.Message) 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}") + _Logger.Info($"ExecuteNonQuery_MSSQL_IDB, SQL: {SQL}") Dim oResult As Boolean = MSSQL_IDB.ExecuteNonQuery(SQL) Return New NonQueryResult() Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New NonQueryResult(ex.Message) End Try End Function @@ -164,33 +147,33 @@ Public Class EDMIService #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}") + _Logger.Info($"ReturnDatatable_MSSQL_ECM, SQL: {SQL}") Dim oResult As DataTable = MSSQL_ECM.GetDatatable(SQL) Return New TableResult(oResult) Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New TableResult(ex.Message) 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}") + _Logger.Info($"ReturnScalar_MSSQL_ECM, SQL: {SQL}") Dim oResult As Object = MSSQL_ECM.GetScalarValue(SQL) Return New ScalarResult(oResult) Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New ScalarResult(ex.Message) 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}") + _Logger.Info($"ExecuteNonQuery_MSSQL_ECM, SQL: {SQL}") Dim oResult As Boolean = MSSQL_ECM.ExecuteNonQuery(SQL) Return New NonQueryResult() Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New NonQueryResult(ex.Message) End Try End Function @@ -199,45 +182,44 @@ Public Class EDMIService #Region "=== Database (Firebird) ===" Public Function ReturnDatatable_Firebird(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_Firebird Try - _logger.Info($"ReturnDatatable, SQL: {SQL}") + _Logger.Info($"ReturnDatatable, SQL: {SQL}") Dim oResult As DataTable = Firebird.GetDatatable(SQL) Return New TableResult(oResult) Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New TableResult(ex.Message) End Try End Function Public Function ReturnScalar_Firebird(SQL As String) As ScalarResult Implements IEDMIService.ReturnScalar_Firebird Try - _logger.Info($"ReturnScalar, SQL: {SQL}") + _Logger.Info($"ReturnScalar, SQL: {SQL}") Dim oResult As Object = Firebird.GetScalarValue(SQL) Return New ScalarResult(oResult) Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New ScalarResult(ex.Message) End Try End Function Public Function ExecuteNonQuery_Firebird(SQL As String) As NonQueryResult Implements IEDMIService.ExecuteNonQuery_Firebird Try - _logger.Info($"ExecuteNonQuery, SQL: {SQL}") + _Logger.Info($"ExecuteNonQuery, SQL: {SQL}") Dim oResult As Boolean = Firebird.ExecuteNonQuery(SQL) Return New NonQueryResult() Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Return New NonQueryResult(ex.Message) End Try End Function #End Region - #Region "=== Document ===" ''' ''' Imports a file according to ObjectStoreId ''' ''' - Public Function ImportFile(Data As Messages.DocumentImportRequest) As Messages.DocumentImportResponse Implements IEDMIService.ImportFile + Public Function ImportFile(Data As DocumentImportRequest) As DocumentImportResponse Implements IEDMIService.ImportFile Dim oObjectStore = GlobalState.ObjectStores. Where(Function(s) s.Id = Data.ObjectStoreId). FirstOrDefault() @@ -263,14 +245,14 @@ Public Class EDMIService Try Directory.CreateDirectory(oDirectoryPath) Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Throw New FaultException(ex.Message) End Try Try Dim oVersionedFileName As String = Filesystem.GetVersionedFilename(oAbsolutePath) - _logger.Info("ImportFile: Saving file [{0}] to path [{1}]", Data.FileName, oVersionedFileName) + _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) @@ -281,7 +263,7 @@ Public Class EDMIService 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("@WHO", _Username) oCommand.Parameters.AddWithValue("@REF_DOCID", 0) oCommand.Parameters.Add(New SqlParameter("@IDB_OBJ_ID", SqlDbType.BigInt)) @@ -289,12 +271,12 @@ Public Class EDMIService Return New Messages.DocumentImportResponse() With {.ObjectId = oObjectId} Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Throw New FaultException(ex.Message) End Try End Function - Public Function GetFileByObjectId(Data As Messages.DocumentStreamRequest) As Messages.DocumentStreamResponse Implements IEDMIService.GetFileByObjectId + Public Function GetFileByObjectId(Data As DocumentStreamRequest) As DocumentStreamResponse Implements IEDMIService.GetFileByObjectId Try Dim oSQL As String = $"SELECT ObjectStoreId FROM VWIDB_DOC_DATA WHERE IDB_OBJ_ID = {Data.ObjectId}" Dim oObjectStoreId = MSSQL_IDB.GetScalarValue(oSQL) @@ -306,7 +288,6 @@ Public Class EDMIService Dim oSQL2 As String = $"SELECT DocRelativePath FROM VWIDB_DOC_DATA WHERE IDB_OBJ_ID = {Data.ObjectId}" Dim oPath As String = MSSQL_IDB.GetScalarValue(oSQL2) - If IsNothing(oPath) Then Throw New FaultException($"Object [{Data.ObjectId}] does not exist in database!") End If @@ -314,7 +295,7 @@ Public Class EDMIService Dim EDMIPath As New EDMI.File.Path(LogConfig, oObjectStore.Path) Dim oFullPath = EDMIPath.GetFullPathFromRelativePath(oPath) - _logger.Debug("GetFileByObjectId: Loading file [{0}]", oFullPath) + _Logger.Debug("GetFileByObjectId: Loading file [{0}]", oFullPath) Dim oFileInfo As New FileInfo(oFullPath) @@ -335,27 +316,64 @@ Public Class EDMIService Return oMessage Catch ex As IOException - _logger.Error(ex) + _Logger.Error(ex) Throw New FaultException($"Object [{Data.ObjectId}] could not be streamed!") Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Throw New FaultException(ex.Message) End Try End Function - Public Function ListFilesForUser() As Messages.DocumentListResponse Implements IEDMIService.ListFilesForUser + Public Function ListFilesForUser() As DocumentListResponse Implements IEDMIService.ListFilesForUser Try Dim oSQL = $"SELECT * FROM VWIDB_DOC_DATA" Dim oDatatable As DataTable = MSSQL_IDB.GetDatatable(oSQL) oDatatable.TableName = "DocumentList" - Return New Messages.DocumentListResponse() With { + Return New DocumentListResponse() With { .Datatable = oDatatable } Catch ex As Exception - _logger.Error(ex) + _Logger.Error(ex) Throw New FaultException(ex.Message) End Try End Function #End Region + +#Region "=== Access Rights ===" + Public Function GetAccessRight(UserId As Long, ObjectId As Long) As AccessRightResult Implements IEDMIService.GetAccessRight + Try + Dim oTableName As String = "TBIDB_ACCESSRIGHT" + + If Not GlobalState.TableStore.Tables.Contains(oTableName) Then + _Logger.Warn("GetAccessRight: Access right table does not exist!") + Return New AccessRightResult(AccessRight.VIEW_ONLY) + End If + + Dim oTable As DataTable = GlobalState.TableStore.Tables.Item(oTableName) + Dim oRows As List(Of DataRow) = oTable.Select($"IDB_OBJ_ID = {ObjectId} AND USR_ID = {UserId}").ToList() + Dim oRight As AccessRight = AccessRight.VIEW_ONLY + + If oRows.Count = 0 Then + _Logger.Warn("GetAccessRight: Access right assignment does not exist for user [{0}] on object [{1}]", UserId, ObjectId) + Return New AccessRightResult(AccessRight.VIEW_ONLY) + Else + If oRows.Count > 1 Then + _Logger.Warn("GetAccessRight: 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") + + oRight = Utils.ToEnum(Of AccessRight)(oRightAsInt) + End If + + Return New AccessRightResult(oRight) + Catch ex As Exception + _Logger.Warn("GetAccessRight: Exception while getting access right for user [{0}] on object [{1}]", UserId, ObjectId) + _Logger.Error(ex) + Return New AccessRightResult(ex) + End Try + End Function +#End Region End Class \ No newline at end of file diff --git a/Service.EDMIService/EDMIService.vbproj b/Service.EDMIService/EDMIService.vbproj index 0a905b4a..b77d578f 100644 --- a/Service.EDMIService/EDMIService.vbproj +++ b/Service.EDMIService/EDMIService.vbproj @@ -126,7 +126,9 @@ - + + + diff --git a/Service.EDMIService/GlobalState.vb b/Service.EDMIService/GlobalState.vb index adaf8feb..225e1ea0 100644 --- a/Service.EDMIService/GlobalState.vb +++ b/Service.EDMIService/GlobalState.vb @@ -9,6 +9,8 @@ Public Class GlobalState Public Property ObjectStores As New List(Of ObjectStore) + Public Property TableStore As New DataSet + Public Sub New(LogConfig As LogConfig, MSSQL_IDB As MSSQLServer, MSSQL_ECM As MSSQLServer) _LogConfig = LogConfig _Logger = LogConfig.GetLogger() diff --git a/Service.EDMIService/IEDMIService.vb b/Service.EDMIService/IEDMIService.vb index fa04259e..0431c6fe 100644 --- a/Service.EDMIService/IEDMIService.vb +++ b/Service.EDMIService/IEDMIService.vb @@ -1,6 +1,7 @@ Imports System.IO Imports System.ServiceModel Imports DigitalData.Modules.Filesystem +Imports DigitalData.Services.EDMIService.Messages Imports DigitalData.Services.EDMIService.Results @@ -49,16 +50,19 @@ Interface IEDMIService Function ExecuteNonQuery_MSSQL_ECM(SQL As String) As NonQueryResult #End Region +#Region "Access Rights" + Function GetAccessRight(UserId As Long, ObjectId As Long) As AccessRightResult +#End Region + #Region "Document (New)" - Function ImportFile(Data As Messages.DocumentImportRequest) As Messages.DocumentImportResponse - 'Function ImportFile(FileName As String, Contents As Byte(), ObjectStoreId As Int64, DocumentType As String, Optional RetentionDays As Int64 = Nothing) As Messages.DocumentImportResponse + Function ImportFile(Data As DocumentImportRequest) As DocumentImportResponse - Function GetFileByObjectId(Data As Messages.DocumentStreamRequest) As Messages.DocumentStreamResponse + Function GetFileByObjectId(Data As DocumentStreamRequest) As DocumentStreamResponse - Function ListFilesForUser() As Messages.DocumentListResponse + Function ListFilesForUser() As DocumentListResponse #End Region End Interface \ No newline at end of file diff --git a/Service.EDMIService/Results.vb b/Service.EDMIService/Results.vb new file mode 100644 index 00000000..12c058df --- /dev/null +++ b/Service.EDMIService/Results.vb @@ -0,0 +1,2 @@ +Friend Class Results +End Class diff --git a/Service.EDMIService/Results/AccessRightResult.vb b/Service.EDMIService/Results/AccessRightResult.vb new file mode 100644 index 00000000..d8640d49 --- /dev/null +++ b/Service.EDMIService/Results/AccessRightResult.vb @@ -0,0 +1,23 @@ +Imports System.Runtime.Serialization +Imports DigitalData.Modules.Language +Imports DigitalData.Modules.EDMI.API.Rights + +Namespace Messages + Public Class AccessRightResult + Inherits BaseResult + + Public Property Right As AccessRight = AccessRight.VIEW_ONLY + + Public Sub New(AccessRight As AccessRight) + MyBase.New() + Right = AccessRight + End Sub + + Public Sub New(Exception As Exception) + MyBase.New() + OK = False + ErrorMessage = Exception.Message + End Sub + End Class + +End Namespace \ No newline at end of file diff --git a/Service.EDMIService/Results/BaseResult.vb b/Service.EDMIService/Results/BaseResult.vb index 788ade61..72cfd738 100644 --- a/Service.EDMIService/Results/BaseResult.vb +++ b/Service.EDMIService/Results/BaseResult.vb @@ -1,6 +1,6 @@ Imports System.Runtime.Serialization -Namespace Results +Namespace Messages @@ -14,9 +14,14 @@ Namespace Results OK = True End Sub - Public Sub New(ErrorMessage As String) + Public Sub New(Message As String) OK = False - Me.ErrorMessage = ErrorMessage + ErrorMessage = Message + End Sub + + Public Sub New(Exception As Exception) + OK = False + ErrorMessage = Exception.Message End Sub End Class End Namespace diff --git a/Service.EDMIService/Results/DatabaseResult.vb b/Service.EDMIService/Results/DatabaseResult.vb index a303b47d..63e006d0 100644 --- a/Service.EDMIService/Results/DatabaseResult.vb +++ b/Service.EDMIService/Results/DatabaseResult.vb @@ -1,6 +1,6 @@ Imports System.Runtime.Serialization -Namespace Results +Namespace Messages diff --git a/Service.EDMIService/Messages.vb b/Service.EDMIService/Results/Messages.vb similarity index 100% rename from Service.EDMIService/Messages.vb rename to Service.EDMIService/Results/Messages.vb diff --git a/Service.EDMIService/Scheduler.vb b/Service.EDMIService/Scheduler.vb index 102b15d7..795cd335 100644 --- a/Service.EDMIService/Scheduler.vb +++ b/Service.EDMIService/Scheduler.vb @@ -20,20 +20,12 @@ Public Class Scheduler Private Const JOB_GROUP As String = "DatatableJobs" - Public ReadOnly Property DataSet As DataSet - Get - Return _JobListener.Dataset - End Get - End Property - - Public Sub New(LogConfig As LogConfig, MSSQL_ECM As MSSQLServer) + Public Sub New(LogConfig As LogConfig, MSSQL_ECM As MSSQLServer, TableStore As DataSet) _LogConfig = LogConfig _Logger = LogConfig.GetLogger() _Factory = New StdSchedulerFactory(_Props) _MSSQL = MSSQL_ECM - - Dim oDataSet As New DataSet() - _JobListener = New JobListener(LogConfig, _MSSQL, oDataSet) + _JobListener = New JobListener(LogConfig, _MSSQL, TableStore) Logging.LogProvider.SetCurrentLogProvider(New LogProvider(_Logger)) End Sub @@ -59,48 +51,28 @@ Public Class Scheduler Dim oDefinition As String = oRow.Item("CRON_DEFINITION") Dim oTitle As String = oRow.Item("TITLE") Dim oGuid As Integer = oRow.Item("GUID") - Dim oCronDetails As DataTable = Await GetCronJobDetails(oGuid) - If oCronDetails IsNot Nothing Then - _Logger.Debug("Loaded job [{0}]", oTitle) - _Logger.Debug("Job details: {0}", oCronDetails.Rows.Count) - _Logger.Debug("Job definition: {0}", oDefinition) + Dim oTrigger As ITrigger + Dim oJob As IJobDetail + Dim oIdentity As String = $"CRON-JOB-{oGuid}" - For Each oRowDetail As DataRow In oCronDetails.Rows - Dim oTrigger As ITrigger - Dim oJob As IJobDetail - Dim oDataTableName As String = oRowDetail.Item("DT_NAME") - Dim oRunOnStartup As Boolean = oRowDetail.Item("RUN_ON_STARTUP") - Dim oJobIdentity As String = $"{oGuid}~{oDataTableName}" + oTrigger = TriggerBuilder.Create(). + WithIdentity(oIdentity, JOB_GROUP). + WithCronSchedule(oDefinition). + Build() - Dim oBaseTrigger = TriggerBuilder.Create(). - WithIdentity(oJobIdentity, JOB_GROUP). - WithCronSchedule(oDefinition) + oJob = JobBuilder.Create(Of DatatableJob)(). + WithIdentity(oIdentity, JOB_GROUP). + UsingJobData(New JobDataMap From { + {"LogConfig", _LogConfig}, + {"MSSQL", _MSSQL}, + {"CronJobId", oGuid}, + {"CronJobTitle", oTitle} + }). + Build() - ' Run directly at startup if configured - If oRunOnStartup Then - oBaseTrigger = oBaseTrigger.StartNow() - End If - - oTrigger = oBaseTrigger.Build() - - oJob = JobBuilder.Create(Of DatatableJob)(). - WithIdentity(oJobIdentity, JOB_GROUP). - UsingJobData(New JobDataMap() From { - {"LogConfig", _LogConfig}, - {"MSSQL", _MSSQL}, - {"CronJobId", oGuid}, - {"CronJobTitle", oTitle}, - {"CronJobDetails", oRowDetail} - }). - Build() - - Await _Scheduler.ScheduleJob(oJob, oTrigger) - _Logger.Debug("Scheduled a new job for Cron Job Id [{0}]", oGuid) - Next - Else - _Logger.Warn("CronJob Details for CronJob [{0}] could not be fetched!", oGuid) - End If + Await _Scheduler.ScheduleJob(oJob, oTrigger) + _Logger.Debug("Scheduled a new job for Cron Job [{0}]", oTitle) Next Else _Logger.Warn("CronJobs could not be fetched!") diff --git a/Service.EDMIService/Scheduler/DatatableJob.vb b/Service.EDMIService/Scheduler/DatatableJob.vb index ebf7d330..b705daf5 100644 --- a/Service.EDMIService/Scheduler/DatatableJob.vb +++ b/Service.EDMIService/Scheduler/DatatableJob.vb @@ -9,58 +9,127 @@ Imports Quartz Public Class DatatableJob Implements IJob + Private _MSSQL As MSSQLServer + Public Function Execute(context As IJobExecutionContext) As Task Implements IJob.Execute Dim oJobData = context.MergedJobDataMap Dim oLogConfig As LogConfig = oJobData.Item("LogConfig") + Dim oCronJobId As Integer = oJobData.Item("CronJobId") + Dim oCronJobTitle As String = oJobData.Item("CronJobTitle") Dim oLogger As Logger = oLogConfig.GetLogger() - Dim oDetailRow As DataRow = oJobData.Item("CronJobDetails") - Dim oDatatableName As String = NotNull(oDetailRow.Item("DT_NAME"), String.Empty) + + Dim oResult As New JobResult() + + oLogger.Info("Running Datatable Job [{0}]/[{1}]", context.JobDetail.Key, oCronJobTitle) Try - Dim oCronJobTitle As String = oJobData.Item("CronJobTitle") Dim oMSSQL As MSSQLServer = oJobData.Item("MSSQL") + Dim oCronSQL As String = $"SELECT * FROM TBAPPSERV_CRON_DETAIL WHERE CRON_ID = {oCronJobId}" + Dim oCronDetails As DataTable = oMSSQL.GetDatatable(oCronSQL) - Dim oConnectionId As Integer = NotNull(oDetailRow.Item("CON_ID"), String.Empty) - Dim oTitle As String = NotNull(oDetailRow.Item("TITLE"), String.Empty) - Dim oSQL As String = NotNull(oDetailRow.Item("COMMAND"), String.Empty) + For Each oRow As DataRow In oCronDetails.Rows + Dim oConnectionId As Integer = NotNull(oRow.Item("CON_ID"), String.Empty) + Dim oTitle As String = NotNull(oRow.Item("TITLE"), String.Empty) + Dim oSQL As String = NotNull(oRow.Item("COMMAND"), String.Empty) + Dim oDatatableName As String = NotNull(oRow.Item("DT_NAME"), String.Empty) - oLogger.Debug("Running Command-Job [{0}]", oTitle) - oLogger.Debug("Datatable Name: {0}", oDatatableName) - oLogger.Debug("Connection Id: {0}", oConnectionId) + oLogger.Debug("Running Command-Job [{0}]", oTitle) + oLogger.Debug("Datatable Name: {0}", oDatatableName) + oLogger.Debug("Connection Id: {0}", oConnectionId) - Dim oConnectionString = oMSSQL.Get_ConnectionStringforID(oConnectionId) + Dim oConnectionString = oMSSQL.Get_ConnectionStringforID(oConnectionId) + Dim oTable = oMSSQL.GetDatatableWithConnection(oSQL, oConnectionString) + oTable.TableName = oDatatableName + oLogger.Debug("Result Datatable [{0}] contains [{1}] rows", oTable.TableName, oTable.Rows.Count) - Dim oTable = oMSSQL.GetDatatableWithConnection(oSQL, oConnectionString) - oTable.TableName = oDatatableName - oLogger.Debug("Result Datatable [{0}] contains [{1}] rows", oTable.TableName, oTable.Rows.Count) + Dim oResultTable = New JobResult.ResultTable() With { + .Table = oTable, + .DetailRow = oRow + } - Dim oResult = New JobResult() With { - .Table = oTable - } + Dim oChildTableNAme As String = NotNull(oRow.Item("CHILD_DT_NAME"), String.Empty) - Dim oChildTableNAme As String = NotNull(oDetailRow.Item("CHILD_DT_NAME"), String.Empty) + If oChildTableNAme <> String.Empty Then + Dim oParentColumn As String = NotNull(oRow.Item("DT_COLUMN"), String.Empty) + Dim oChildColumn As String = NotNull(oRow.Item("CHILD_DT_COLUMN"), String.Empty) + oLogger.Debug("Child Datatable [{0}] defined, Relation: Parent [{1}] -> Child [{2}]", oChildTableNAme, oParentColumn, oChildColumn) - If oChildTableNAme <> String.Empty Then - Dim oParentColumn As String = NotNull(oDetailRow.Item("DT_COLUMN"), String.Empty) - Dim oChildColumn As String = NotNull(oDetailRow.Item("CHILD_DT_COLUMN"), String.Empty) - oLogger.Debug("Child Datatable [{0}] defined, Relation: Parent [{1}] -> Child [{2}]", oChildTableName, oParentColumn, oChildColumn) + Dim oChildTable As DataTable = oMSSQL.GetDatatableWithConnection($"SELECT * FROM {oChildTableNAme}", oConnectionString) + oChildTable.TableName = oChildTableNAme + oLogger.Debug("Child Datatable [{0}] contains [{1}] rows", oChildTable.TableName, oChildTable.Rows.Count) - Dim oChildTable As DataTable = oMSSQL.GetDatatableWithConnection($"SELECT * FROM {oChildTableName}", oConnectionString) - oChildTable.TableName = oChildTableName - oLogger.Debug("Child Datatable [{0}] contains [{1}] rows", oChildTable.TableName, oChildTable.Rows.Count) + oResultTable.ChildTable = oChildTable + oResultTable.ChildRelationColumn = oChildColumn + oResultTable.TableRelationColumn = oParentColumn + End If - oResult.ChildTable = oChildTable - oResult.ChildRelationColumn = oChildColumn - oResult.TableRelationColumn = oParentColumn - End If + oLogger.Info("Fetched Datatable [{0}]", oDatatableName) + oResult.Tables.Add(oResultTable) + Next - ' Das Ergebnis speichern + ' Das Ergebnis speichern context.Result = oResult + Catch ex As Exception oLogger.Error(ex) - oLogger.Warn("Unhandled exception while executing SQL for Datatable {0}", oDatatableName) + oLogger.Warn("Unhandled exception while executing SQL for Datatable {0}", oCronJobTitle) End Try Return Task.FromResult(True) + +#Region "OLD" + 'Dim oJobData = context.MergedJobDataMap + 'Dim oLogConfig As LogConfig = oJobData.Item("LogConfig") + 'Dim oLogger As Logger = oLogConfig.GetLogger() + 'Dim oDetailRow As DataRow = oJobData.Item("CronJobDetails") + 'Dim oDatatableName As String = NotNull(oDetailRow.Item("DT_NAME"), String.Empty) + + 'Try + ' Dim oCronJobTitle As String = oJobData.Item("CronJobTitle") + ' Dim oMSSQL As MSSQLServer = oJobData.Item("MSSQL") + + ' Dim oConnectionId As Integer = NotNull(oDetailRow.Item("CON_ID"), String.Empty) + ' Dim oTitle As String = NotNull(oDetailRow.Item("TITLE"), String.Empty) + ' Dim oSQL As String = NotNull(oDetailRow.Item("COMMAND"), String.Empty) + + ' oLogger.Debug("Running Command-Job [{0}]", oTitle) + ' oLogger.Debug("Datatable Name: {0}", oDatatableName) + ' oLogger.Debug("Connection Id: {0}", oConnectionId) + + ' Dim oConnectionString = oMSSQL.Get_ConnectionStringforID(oConnectionId) + + ' Dim oTable = oMSSQL.GetDatatableWithConnection(oSQL, oConnectionString) + ' oTable.TableName = oDatatableName + ' oLogger.Debug("Result Datatable [{0}] contains [{1}] rows", oTable.TableName, oTable.Rows.Count) + + ' Dim oResult = New JobResult() With { + ' .Table = oTable + ' } + + ' Dim oChildTableNAme As String = NotNull(oDetailRow.Item("CHILD_DT_NAME"), String.Empty) + + ' If oChildTableNAme <> String.Empty Then + ' Dim oParentColumn As String = NotNull(oDetailRow.Item("DT_COLUMN"), String.Empty) + ' Dim oChildColumn As String = NotNull(oDetailRow.Item("CHILD_DT_COLUMN"), String.Empty) + ' oLogger.Debug("Child Datatable [{0}] defined, Relation: Parent [{1}] -> Child [{2}]", oChildTableName, oParentColumn, oChildColumn) + + ' Dim oChildTable As DataTable = oMSSQL.GetDatatableWithConnection($"SELECT * FROM {oChildTableName}", oConnectionString) + ' oChildTable.TableName = oChildTableName + ' oLogger.Debug("Child Datatable [{0}] contains [{1}] rows", oChildTable.TableName, oChildTable.Rows.Count) + + ' oResult.ChildTable = oChildTable + ' oResult.ChildRelationColumn = oChildColumn + ' oResult.TableRelationColumn = oParentColumn + ' End If + + ' ' Das Ergebnis speichern + ' context.Result = oResult + 'Catch ex As Exception + ' oLogger.Error(ex) + ' oLogger.Warn("Unhandled exception while executing SQL for Datatable {0}", oDatatableName) + 'End Try + + 'Return Task.FromResult(True) +#End Region End Function End Class diff --git a/Service.EDMIService/Scheduler/JobListener.vb b/Service.EDMIService/Scheduler/JobListener.vb index d969cc47..50714c6b 100644 --- a/Service.EDMIService/Scheduler/JobListener.vb +++ b/Service.EDMIService/Scheduler/JobListener.vb @@ -26,6 +26,24 @@ Public Class JobListener Dataset = ResultDataSet End Sub + Public Overrides Function JobWasExecuted(context As IJobExecutionContext, jobException As JobExecutionException, Optional cancellationToken As CancellationToken = Nothing) As Task + _Logger.Info("Job [{0}] was executed successfully. Saving Data.", context.JobDetail.Key) + + Dim oResult As JobResult = context.Result + + For Each oTableResult As JobResult.ResultTable In oResult.Tables + Try + _Logger.Debug("Saving Datatable [{0}]", oTableResult.Table) + SaveDataTables(oTableResult) + + Catch ex As Exception + _Logger.Error("Error while executing SaveDataTables for {0}", oTableResult.Table.TableName) + End Try + Next + + Return MyBase.JobWasExecuted(context, jobException, cancellationToken) + End Function + Public Sub ReplaceExistingTable(Name As String, Table As DataTable, DataSet As DataSet, Optional ChildTable As DataTable = Nothing) Try Dim oDatatableNameTemp As String = Name & "-TEMP" @@ -140,16 +158,17 @@ Public Class JobListener End Try End Sub - Public Sub SaveDataTables(Result As JobResult, DetailRow As DataRow) + Public Sub SaveDataTables(Result As JobResult.ResultTable) Try Dim oTable As DataTable = Result.Table - Dim oName As String = DetailRow.Item("DT_NAME") - Dim oDetailId As Integer = DetailRow.Item("GUID") + Dim oName As String = Result.DetailRow.Item("DT_NAME") + Dim oDetailId As Integer = Result.DetailRow.Item("GUID") Dim oDatatableNameTemp As String = oName & "-TEMP" ' Used for debugging relations and constraints - 'ListTables(Dataset) + _Logger.Debug("Dataset BEFORE saving datatables") + ListTables(Dataset) If Dataset.Tables.Contains(oName) Then ' Replace existing table @@ -179,6 +198,10 @@ Public Class JobListener _Logger.Debug(oRelation.RelationName) Next + ' Used for debugging relations and constraints + _Logger.Debug("Dataset AFTER saving datatables") + ListTables(Dataset) + _MSSQL.ExecuteNonQuery($"INSERT INTO TBAPPSERV_CRON_DETAIL_HISTORY (DETAIL_ID) VALUES ({oDetailId})") Catch ex As Exception _Logger.Warn("Unexpected error in JobListener: {0}", ex.Message) @@ -205,11 +228,4 @@ Public Class JobListener oIndex += 1 Next End Sub - - Public Overrides Function JobWasExecuted(context As IJobExecutionContext, jobException As JobExecutionException, Optional cancellationToken As CancellationToken = Nothing) As Task - Dim oDetailRow As DataRow = context.MergedJobDataMap.Item("CronJobDetails") - SaveDataTables(context.Result, oDetailRow) - - Return MyBase.JobWasExecuted(context, jobException, cancellationToken) - End Function End Class diff --git a/Service.EDMIService/Scheduler/JobResult.vb b/Service.EDMIService/Scheduler/JobResult.vb index dfdfaf10..a9736f69 100644 --- a/Service.EDMIService/Scheduler/JobResult.vb +++ b/Service.EDMIService/Scheduler/JobResult.vb @@ -1,6 +1,12 @@ Public Class JobResult - Public Table As DataTable - Public ChildTable As DataTable - Public TableRelationColumn As String - Public ChildRelationColumn As String + Public Tables As New List(Of ResultTable) + + Public Class ResultTable + Public Table As DataTable + Public ChildTable As DataTable + Public TableRelationColumn As String + Public ChildRelationColumn As String + + Public DetailRow As DataRow + End Class End Class diff --git a/Service.EDMIService/WindowsService.vb b/Service.EDMIService/WindowsService.vb index 6aa602d4..efacfb70 100644 --- a/Service.EDMIService/WindowsService.vb +++ b/Service.EDMIService/WindowsService.vb @@ -39,7 +39,6 @@ Public Class WindowsService Dim oServicePath As String = AppDomain.CurrentDomain.BaseDirectory _LogConfig = New LogConfig(LogConfig.PathType.CustomPath, IO.Path.Combine(oServicePath, "Log")) - _LogConfig.Debug = True _Logger = _LogConfig.GetLogger() _Logger.Info("Service {0} is starting...", SERVICE_DISPLAY_NAME) _Logger.Info("ServiceDirectory: {0}", oServicePath) @@ -60,7 +59,7 @@ Public Class WindowsService _Archive = New EDMI.File.Archive(_LogConfig) _Filesystem = New Filesystem.File(_LogConfig) _Global = New GlobalState(_LogConfig, _MSSQL_IDB, _MSSQL_ECM) - _Scheduler = New Scheduler(_LogConfig, _MSSQL_ECM) + _Scheduler = New Scheduler(_LogConfig, _MSSQL_ECM, _Global.TableStore) _Logger.Debug("Loading Objectstores") _Global.LoadObjectStores() @@ -107,15 +106,28 @@ Public Class WindowsService Private Function StartFirebird() As Firebird _Logger.Debug("Connecting to Firebird") - Dim oFirebird = New Firebird( - _LogConfig, - _Config.Firebird_Datasource, - _Config.Firebird_DatabaseName, - _Config.Firebird_DatabaseUser, - _Config.Firebird_DatabasePassword - ) - _Logger.Info("Database connection established.") - Return oFirebird + + If _Config.Firebird_Datasource = String.Empty Then + _Logger.Info("Firebird database not configured. Skipping.") + Return Nothing + End If + + Try + Dim oFirebird = New Firebird( + _LogConfig, + _Config.Firebird_Datasource, + _Config.Firebird_DatabaseName, + _Config.Firebird_DatabaseUser, + _Config.Firebird_DatabasePassword + ) + + _Logger.Info("Database connection established.") + Return oFirebird + Catch ex As Exception + _Logger.Warn("StartFirebird: Could not connect to firebird database.") + _Logger.Error(ex) + Return Nothing + End Try End Function Private Function StartMSSQL_ECM() As MSSQLServer diff --git a/Service.JobRunner/App.config b/Service.JobRunner/App.config index fa6bbc22..fc4472ab 100644 --- a/Service.JobRunner/App.config +++ b/Service.JobRunner/App.config @@ -29,7 +29,7 @@ False - False|0 0 0/1 * * ?|RootPath::LDAP://DIGITALDATA,UserFilter::(&(samaccountname=@SAMACCOUNTNAME)),GroupFilter(&(samaccountname=*)) + False|0 0 0/1 * * ?|RootPath::LDAP://DIGITALDATA,UserFilter::(&(samaccountname=@SAMACCOUNTNAME)),GroupFilter::(&(samaccountname=*)) True|10/0 * * * * ?|Foo::Bar