Imports DigitalData.Modules.Database Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Patterns Imports DigitalData.Modules.Language Imports DigitalData.Services.EDMIService.Methods.GetDatatableFromCache Imports System.IO Imports DigitalData.Modules.ZooFlow.State Namespace Methods.GlobalIndexer.ImportFile Public Class ImportFileMethod Inherits BaseMethod Private ReadOnly Patterns As Patterns2 Private ReadOnly GetDatatable As GetDatatableFromCacheMethod Private ReadOnly Connection As SqlClient.SqlConnection Private ReadOnly Transaction As SqlClient.SqlTransaction Private User As UserState Private Profile As DataRow Private Const VIEW_PROFILE = "VWGI_DOCTYPE_IDB" Private Const VIEW_INDEX_MANUAL = "VWDDINDEX_MAN" Private Const VIEW_INDEX_AUTOMATIC = "VWDDINDEX_AUTOM" Private Const TABLE_POST_PROCESSING = "TBDD_INDEX_MAN_POSTPROCESSING" Public Sub New(pLogConfig As LogConfig, pMSSQLServer As MSSQLServer, pGlobalState As GlobalState) MyBase.New(pLogConfig, pMSSQLServer, pGlobalState) Patterns = New Patterns2(pLogConfig) GetDatatable = New GetDatatableFromCacheMethod(LogConfig, Database, GlobalState) Connection = Database.GetConnection() Transaction = Connection.BeginTransaction() End Sub ''' ''' ''' ''' ''' ''' ''' ''' Public Function Run(pData As ImportFileRequest) Try User = pData.User ' TODO: Add missing user properties in UserState from TBDD_USER 'pData.User = ResolveUserFromUserName(pData.User.UserName) Dim oManualIndexes = LoadManualIndexes(pData.ProfileId) Dim oAutomaticIndexes = LoadAutomaticIndexes(pData.ProfileId) Dim oPostProcessingSteps As DataTable = LoadPostProcessingSteps(oManualIndexes) LoadProfile(pData.ProfileId) Dim oUserAttributes = pData.AttributeValues Dim oAutoAttributes As List(Of UserAttributeValue) = Nothing ' Apply post processing Dim oPostProcessing = New Steps.PostProcessing(LogConfig, oPostProcessingSteps) oUserAttributes = oPostProcessing.ApplyManualPostprocessing(oUserAttributes) ' Apply automatic attributes Dim oAutomaticIndexing = New Steps.AutomaticIndexing(LogConfig, Database, oAutomaticIndexes, GlobalState) oAutoAttributes = oAutomaticIndexing.ApplyAutomaticeAttributes(oUserAttributes, pData.File.FileInfoRaw, User) ' Import the file Dim oNewFile As New NewFileMethod(LogConfig, Database, GlobalState) Dim oResponse = oNewFile.Run(New NewFile.NewFileRequest With { .File = pData.File, .BusinessEntity = pData.BusinessEntity, .KindType = pData.KindType, .StoreName = pData.StoreName, .User = User }) If oResponse.OK Then Logger.Info("Import of file [{0}] under ObjectId [{1}] successful!", pData.File.FileName, oResponse.ObjectId) Else Throw New ApplicationException(oResponse.ErrorMessage) End If Logger.Info("Generating display filename for file [{0}]", pData.File.FileName) Dim oNameconvention As String = Profile.ItemEx(Of String)("NAMENKONVENTION") Dim oDisplayFilename = GetFilenameByNameconvention(pData.File.FileInfoRaw, oNameconvention, User, oUserAttributes, oAutoAttributes) Logger.Info("Collecting Attributes for ObjectId [{0}]", oResponse.ObjectId) Dim oFinalAttributes As New Dictionary(Of String, List(Of String)) From { {"DisplayFileName", New List(Of String) From {oDisplayFilename}} } oFinalAttributes = oFinalAttributes. Concat(Helpers.UserAttributesToDictionary(oUserAttributes)). Concat(Helpers.UserAttributesToDictionary(oAutoAttributes)). ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value) Logger.Info("Writing [{0}] Attributes for ObjectId [{0}] ", oResponse.ObjectId) WriteAttributeValues(oResponse.ObjectId, oFinalAttributes) ' Finally, commit the transaction Transaction?.Commit() Return New ImportFileResponse(oResponse.ObjectId) Catch ex As Exception Logger.Warn("Error occurred while importing file!") Logger.Error(ex) Logger.Info("Rolling back transaction.") Transaction?.Rollback() Return New ImportFileResponse(ex) End Try End Function Private Function GetFilenameByNameconvention(pFileInfo As FileInfo, pNameconvention As String, pUser As UserState, pAttributes As List(Of UserAttributeValue), pAutoAttributes As List(Of UserAttributeValue)) As String Dim oAttributeDict = Helpers.UserAttributesToDictionary(pAttributes) Dim oAutoAttributeDict = Helpers.UserAttributesToDictionary(pAutoAttributes) If pNameconvention Is Nothing OrElse pNameconvention = String.Empty Then Logger.Warn("Nameconvention for File [{0}] was empty. Returning original filename.", pFileInfo.Name) Return pFileInfo.Name End If Dim oFileName As String = Helpers.GetPlaceholderValue(pNameconvention, pFileInfo, pUser, oAttributeDict, oAutoAttributeDict) Return oFileName & pFileInfo.Extension End Function Private Sub WriteAttributeValues(pObjectId As Long, pAttributes As Dictionary(Of String, List(Of String))) For Each oAttribute As KeyValuePair(Of String, List(Of String)) In pAttributes Try ' TODO: This works only for simple attributes for now!!! Dim oValue = oAttribute.Value.FirstOrDefault() ' Dont write empty attributes If oValue Is Nothing Then Continue For End If ' Now make the call to the database Dim oSuccess = Helpers.SetAttributeValue(Connection, Transaction, pObjectId, oAttribute.Key, oValue, User.Language, User.UserName) If oSuccess Then Logger.Info("Attribute [{0}] written with value [{1}]", oAttribute.Key, oAttribute.Value) Else Logger.Warn("Attribute value could not be written") End If Catch ex As Exception LogAndThrow(ex, $"Attribute [{oAttribute.Key}] could not be written!") End Try Next End Sub ''' ''' Load Profiles for this Import ''' Private Sub LoadProfile(pProfileId As Integer) Logger.Debug("Start of Method [LoadAutomaticIndexes]") Try Dim oProfile = GetDatatable.Run( New GetDatatableFromCacheRequest With { .DataTable = VIEW_PROFILE, .FilterExpression = $"DOCTYPE_ID = {pProfileId}" }) If oProfile.OK = False Then LogAndThrow(oProfile.ErrorMessage) End If Profile = oProfile.Table.Rows.Item(0) Catch ex As Exception LogAndThrow(ex, "Error while automatic loading indexes!") End Try End Sub ''' ''' Load automatic indexes for this Import ''' Private Function LoadAutomaticIndexes(pProfileId As Integer) As List(Of AutomaticIndex) Logger.Debug("Start of Method [LoadAutomaticIndexes]") Try ' Load automatic Indexes for this Import Dim oAutomaticIndexes = GetDatatable.Run( New GetDatatableFromCacheRequest With { .DataTable = VIEW_INDEX_AUTOMATIC, .FilterExpression = $"DOCTYPE_ID = {pProfileId}" }) If oAutomaticIndexes.OK = False Then LogAndThrow(oAutomaticIndexes.ErrorMessage) End If Dim oIndexes As New List(Of AutomaticIndex) For Each oRow As DataRow In oAutomaticIndexes.Table.Rows Dim oAutomaticIndex As New AutomaticIndex With { .Id = oRow.ItemEx(Of Integer)("GUID"), .Name = oRow.ItemEx(Of String)("INDEXNAME"), .ProfileId = oRow.ItemEx(Of Integer)("DOCTYPE_ID"), .SQLCommand = oRow.ItemEx(Of String)("SQL_RESULT"), .SQLConnectionId = oRow.ItemEx(Of Integer)("CONNECTION_ID"), .Sequence = oRow.ItemEx(Of String)("SEQUENCE"), .Value = oRow.ItemEx(Of String)("VALUE") } oIndexes.Add(oAutomaticIndex) Next Logger.Info("Automatic indexes loaded: [{0}]", oIndexes.Count) Return oIndexes Catch ex As Exception LogAndThrow(ex, "Error while automatic loading indexes!") End Try End Function ''' ''' Load manual indexes for this Import ''' Private Function LoadManualIndexes(pProfileId As Integer) As List(Of ManualIndex) Logger.Debug("Start of Method [LoadManualIndexes]") Try ' Load manual Indexes for this Import Dim oManualIndexes = GetDatatable.Run( New GetDatatableFromCacheRequest With { .DataTable = VIEW_INDEX_MANUAL, .FilterExpression = $"DOK_ID = {pProfileId}" }) If oManualIndexes.OK = False Then LogAndThrow(oManualIndexes.ErrorMessage) End If Dim oIndexes As New List(Of ManualIndex) For Each oRow As DataRow In oManualIndexes.Table.Rows Dim oManualIndex As New ManualIndex With { .Id = oRow.ItemEx(Of Integer)("GUID"), .Name = oRow.ItemEx(Of String)("INDEXNAME"), .ProfileId = oRow.ItemEx(Of Integer)("DOCTYPE_ID"), .IsOptional = oRow.ItemEx(Of Boolean)("OPTIONAL"), .IsMultiselect = oRow.ItemEx(Of String)("MULTISELECT"), .SQLCommand = oRow.ItemEx(Of String)("SQL_RESULT"), .SQLConnectionId = oRow.ItemEx(Of Integer)("CONNECTION_ID"), .DefaultValue = oRow.ItemEx(Of String)("DEFAULT_VALUE"), .DataType = oRow.ItemEx(Of String)("DATA_TYPE") } oIndexes.Add(oManualIndex) Next Logger.Info("Manual indexes loaded: [{0}]", oIndexes.Count) Return oIndexes Catch ex As Exception LogAndThrow(ex, "Error while loading indexes!") End Try End Function Private Function LoadPostProcessingSteps(pManualIndexes As List(Of ManualIndex)) As DataTable Logger.Debug("Start of Method [LoadPostProcessingSteps]") Try ' Generate a string containing all index ids joined into a string Dim oIndexIdList As List(Of Integer) = pManualIndexes. Select(Function(index) index.Id). ToList() Dim oIndexIds As String = String.Join(",", oIndexIdList) If oIndexIdList.Count = 0 Then Logger.Debug("No Postprocessing steps found for this profile. Exiting.") Return Nothing End If ' Load all relevant postprocessing steps Dim oPostProcessingSteps = GetDatatable.Run( New GetDatatableFromCacheRequest With { .DataTable = TABLE_POST_PROCESSING, .FilterExpression = $"IDXMAN_ID IN ({oIndexIds})" }) If oPostProcessingSteps.OK = False Then LogAndThrow(oPostProcessingSteps.ErrorMessage) End If Return oPostProcessingSteps.Table Catch ex As Exception LogAndThrow(ex, "Error while loading post processing steps!") End Try End Function End Class End Namespace