337 lines
13 KiB
VB.net
337 lines
13 KiB
VB.net
Imports System.Net.Http
|
|
Imports Newtonsoft.Json
|
|
Imports DigitalData.Modules.Base
|
|
Imports DigitalData.Modules.Base.ModuleExtensions
|
|
Imports DigitalData.Modules.Database
|
|
Imports DigitalData.Modules.Logging
|
|
Imports Connectors.Common.slt.Constants
|
|
Imports Connectors.Common.slt.Responses
|
|
Imports Connectors.Common.slt.Entities
|
|
Imports System.Threading.Tasks
|
|
Imports System.IO
|
|
|
|
Namespace slt
|
|
Public Class sltSync
|
|
Inherits BaseModule
|
|
Implements ISync
|
|
|
|
Private ReadOnly MimeEx As MimeEx
|
|
|
|
Public Overrides Property Name As String = "slt Sync"
|
|
Public Overrides Property IsLoggedIn As Boolean = False
|
|
Public SessionId As String = Nothing
|
|
Public AvailableSystems As New List(Of sltAvailableSystem)
|
|
|
|
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer, pConfig As Config)
|
|
MyBase.New(pLogConfig, pDatabase, pConfig)
|
|
MimeEx = New MimeEx(pLogConfig)
|
|
End Sub
|
|
|
|
Public Overrides Async Function Run() As Threading.Tasks.Task Implements ISync.Run
|
|
Try
|
|
AddInfoEntry("Starting sltSync.")
|
|
AddDivider()
|
|
|
|
EnsureOutputDirectoryExists()
|
|
RefreshDirectoryGuid()
|
|
|
|
Dim oExtDocIds = Await FetchDocIds()
|
|
If oExtDocIds Is Nothing Then
|
|
Throw New ApplicationException($"Document Ids could not be fetched!")
|
|
End If
|
|
|
|
AddInfoEntry("Logging in..")
|
|
Await GetAvailableSystems()
|
|
Await Login(Config.sltConfiguration.SystemId)
|
|
|
|
For Each oDocId As String In oExtDocIds
|
|
Try
|
|
Logger.Debug("Fetching document from API..")
|
|
Dim oDocument As sltDocument = Await GetDocumentContent(oDocId)
|
|
oDocument = Await GetDocumentDetails(oDocument)
|
|
Logger.Debug("Document fetched!")
|
|
|
|
AddInfoEntry("Document: [{0}]", oDocument.Name)
|
|
Logger.Info("ExtDocId: [{0}]", oDocument.ExtDocId)
|
|
|
|
Dim oFileName = oDocument.GetUniqueFilename()
|
|
|
|
If oFileName Is Nothing Then
|
|
Throw New ApplicationException($"Filename or extension for ExDocId [{oDocId}] could not be determined!")
|
|
End If
|
|
|
|
Dim oFilePath = GetFinalFilePath(oFileName)
|
|
|
|
If CopyFileToOutputPath(oDocument.Data, oFilePath) = False Then
|
|
Throw New ApplicationException("File could not be created in output path!")
|
|
End If
|
|
|
|
Dim oSQL = String.Format(Config.SQLQueryExport, oDocument.ExtDocId, oFileName)
|
|
If Await Database.ExecuteNonQueryAsync(oSQL) = True Then
|
|
RaiseFileProcessed(oFilePath)
|
|
Else
|
|
Throw New ApplicationException("Database entry could not be written!")
|
|
End If
|
|
|
|
Catch ex As Exception
|
|
RaiseFileError(oDocId)
|
|
|
|
Logger.Error(ex)
|
|
AddWarnEntry("Error while running Sync: " & ex.Message)
|
|
End Try
|
|
Next
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
AddWarnEntry("Error while running Sync: " & ex.Message)
|
|
|
|
End Try
|
|
|
|
Try
|
|
AddInfoEntry("Finished Sync.")
|
|
AddInfoEntry("Logging Out..")
|
|
Await Logout()
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
AddWarnEntry("Error while logging out: " & ex.Message)
|
|
Finally
|
|
AddDivider()
|
|
End Try
|
|
End Function
|
|
|
|
Public Overrides Async Function Cleanup() As Task Implements ISync.Cleanup
|
|
Await Logout()
|
|
End Function
|
|
|
|
Public Overrides Function TestConfigIsComplete() As Boolean Implements ISync.TestConfigIsComplete
|
|
Dim oComplete = TestConfigIsCompleteBase()
|
|
|
|
If Config.sltConfiguration.Hostname = String.Empty Then
|
|
AddWarnEntry("Configuration for 'Hostname' is empty.")
|
|
oComplete = False
|
|
End If
|
|
|
|
If Config.sltConfiguration.Port = String.Empty Then
|
|
AddWarnEntry("Configuration for 'Port' is empty.")
|
|
oComplete = False
|
|
End If
|
|
|
|
If Config.sltConfiguration.Username = String.Empty Then
|
|
AddWarnEntry("Configuration for 'Username' is empty.")
|
|
oComplete = False
|
|
End If
|
|
|
|
If Config.sltConfiguration.Password = String.Empty Then
|
|
AddWarnEntry("Configuration for 'Password' is empty.")
|
|
oComplete = False
|
|
End If
|
|
|
|
If Config.sltConfiguration.sltDatabase = String.Empty Then
|
|
AddWarnEntry("Configuration for 'sltDatabase' is empty.")
|
|
oComplete = False
|
|
End If
|
|
|
|
Return oComplete
|
|
End Function
|
|
|
|
Private Function GetFilenameWithExtensionFromMimeType(pFilename As String, pMimetype As String) As String
|
|
Try
|
|
If pMimetype = "application/outlook" Then
|
|
pMimetype = "application/vnd.ms-outlook"
|
|
End If
|
|
|
|
Dim oExtension = MimeEx.GetExtension(pMimetype)
|
|
Return StringEx.ConvertTextToSlug(pFilename) & oExtension
|
|
|
|
Catch ex As ArgumentException
|
|
Logger.Error(ex)
|
|
Logger.Warn("File [{0}] does not have a valid mimetype [{1}]. Returning null.", pFilename, pMimetype)
|
|
Return Nothing
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
AddWarnEntry("Unexpected error while getting extension. Returning original filename.", pFilename, pMimetype)
|
|
|
|
Return pFilename
|
|
End Try
|
|
End Function
|
|
|
|
Private Async Function GetAvailableSystems() As Threading.Tasks.Task
|
|
Try
|
|
Logger.Debug("Fetching available systems..")
|
|
|
|
Dim oUrl = "/slt/External/System/Authentication/Json/AvailableSystems"
|
|
Dim oJson As String = Await SendRequest(oUrl)
|
|
Dim oResponse = JsonConvert.DeserializeObject(Of sltAvailableSystemResponse)(oJson)
|
|
|
|
TestRequestSuccessful(oUrl, oResponse, ErrorType.AvailableSystemError)
|
|
|
|
AvailableSystems = oResponse.Value
|
|
|
|
Logger.Debug("Fetched [{0}] available systems!", oResponse.Value.Count)
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Throw New sltException(ErrorType.AvailableSystemError, ex.Message)
|
|
End Try
|
|
End Function
|
|
|
|
Private Async Function Login(pSystemId As String) As Threading.Tasks.Task
|
|
Try
|
|
Logger.Debug("Logging in..")
|
|
|
|
If AvailableSystems.Any(Function(s) s.SystemId = pSystemId) = False Then
|
|
Dim oMessage = String.Format("SystemId [{0}] does not match any System returned from API.", pSystemId)
|
|
Logger.Warn(oMessage)
|
|
Throw New sltException(ErrorType.LoginError, oMessage)
|
|
End If
|
|
|
|
Dim oUrl = "/slt/External/System/Authentication/Json/Login"
|
|
Dim oParams = New Dictionary(Of String, String) From {
|
|
{"systemid", pSystemId},
|
|
{"user", Config.sltConfiguration.Username},
|
|
{"password", Config.sltConfiguration.Password}
|
|
}
|
|
|
|
Logger.Debug("Username: [{0}]", Config.sltConfiguration.Username)
|
|
Logger.Debug("SystemId: [{0}]", pSystemId)
|
|
|
|
Dim oJson As String = Await SendRequest(oUrl, oParams)
|
|
Dim oResponse = JsonConvert.DeserializeObject(Of sltLoginResponse)(oJson)
|
|
|
|
TestRequestSuccessful(oUrl, oResponse, ErrorType.LoginError)
|
|
|
|
SessionId = oResponse.Value
|
|
IsLoggedIn = True
|
|
|
|
Logger.Debug("Login successful!")
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Throw New sltException(ErrorType.LoginError, ex.Message)
|
|
End Try
|
|
End Function
|
|
|
|
Private Async Function Logout() As Threading.Tasks.Task
|
|
If Not IsLoggedIn Then
|
|
Throw New sltException(ErrorType.NotLoggedInError, "No session found")
|
|
End If
|
|
|
|
Logger.Debug("Logging out..")
|
|
|
|
Try
|
|
Dim oUrl = "/slt/External/System/Authentication/Json/Logout"
|
|
Dim oParams = New Dictionary(Of String, String) From {
|
|
{"SessionId", SessionId}
|
|
}
|
|
Dim oJson As String = Await SendRequest(oUrl, oParams)
|
|
Dim oResponse = JsonConvert.DeserializeObject(Of sltLogoutResponse)(oJson)
|
|
|
|
TestRequestSuccessful(oUrl, oResponse, ErrorType.LogoutError)
|
|
|
|
SessionId = Nothing
|
|
IsLoggedIn = False
|
|
|
|
Logger.Debug("Login successful!")
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Throw New sltException(ErrorType.LogoutError, ex.Message)
|
|
End Try
|
|
End Function
|
|
|
|
Private Async Function GetDocumentDetails(pDocument As sltDocument) As Task(Of sltDocument)
|
|
If Not IsLoggedIn Then
|
|
Throw New sltException(ErrorType.NotLoggedInError, "No session found")
|
|
End If
|
|
|
|
Try
|
|
Logger.Debug("Fetching document details with ExtDocId [{0}]", pDocument.ExtDocId)
|
|
|
|
Dim oSQL = $"SELECT DOCORIGINALNAME
|
|
FROM {Config.sltConfiguration.sltDatabase}.[EXTDOCS]
|
|
WHERE EXTDOCID = '{pDocument.ExtDocId}'"
|
|
Dim oResult As Object = Await Database.GetScalarValueAsync(oSQL)
|
|
Dim oFileNameOriginal As String = ObjectEx.NotNull(Of String)(oResult.ToString, "")
|
|
|
|
If Not String.IsNullOrEmpty(oFileNameOriginal) Then
|
|
pDocument.DocOriginalFilename = oFileNameOriginal
|
|
End If
|
|
|
|
Return pDocument
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Return pDocument
|
|
End Try
|
|
End Function
|
|
|
|
Private Async Function GetDocumentContent(pExternalDocumentId As String) As Threading.Tasks.Task(Of slt.Entities.sltDocument)
|
|
If Not IsLoggedIn Then
|
|
Throw New sltException(ErrorType.NotLoggedInError, "No session found")
|
|
End If
|
|
|
|
Try
|
|
Logger.Debug("Fetching document with ExtDocId [{0}]", pExternalDocumentId)
|
|
|
|
Dim oUrl = "/slt/External/Services/Allgemein/ExtDocs/JSon/GetDocument"
|
|
Dim oParams As New Dictionary(Of String, String) From {
|
|
{"extdocid", pExternalDocumentId},
|
|
{"sessionid", SessionId}
|
|
}
|
|
|
|
Dim oJson = Await SendRequest(oUrl, oParams)
|
|
Dim oResponse = JsonConvert.DeserializeObject(Of sltDocumentResponse)(oJson)
|
|
|
|
Logger.Debug("Document Fetched!")
|
|
|
|
Return oResponse.Value
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Throw New sltException(ErrorType.GetDocumentError, ex.Message)
|
|
End Try
|
|
End Function
|
|
|
|
Private Async Function SendRequest(pUrl As String) As Threading.Tasks.Task(Of String)
|
|
Return Await SendRequest(pUrl, New Dictionary(Of String, String))
|
|
End Function
|
|
|
|
Private Async Function SendRequest(pUrl As String, pQueryParams As Dictionary(Of String, String)) As Threading.Tasks.Task(Of String)
|
|
Try
|
|
Dim oUrl = GetUrl(pUrl, pQueryParams)
|
|
Logger.Debug("Preparing request to: [{0}]", oUrl)
|
|
|
|
Using oClient As New HttpClient()
|
|
oClient.DefaultRequestHeaders.Accept.Clear()
|
|
oClient.DefaultRequestHeaders.Accept.Add(New Headers.MediaTypeWithQualityHeaderValue("application/json"))
|
|
oClient.DefaultRequestHeaders.Add("User-Agent", "Digital Data sltSync")
|
|
|
|
Logger.Debug("Sending request.")
|
|
Return Await oClient.GetStringAsync(oUrl)
|
|
End Using
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Return Nothing
|
|
End Try
|
|
End Function
|
|
|
|
Private Function GetUrl(pPath As String, pQueryParams As Dictionary(Of String, String)) As String
|
|
Dim oUrl As String = $"http://{Config.sltConfiguration.Hostname}:{Config.sltConfiguration.Port}"
|
|
If Not pPath.StartsWith("/") Then pPath &= "/"
|
|
|
|
Dim queryString = pQueryParams.ToURLQueryString()
|
|
|
|
Return $"{oUrl}{pPath}?{queryString}"
|
|
End Function
|
|
|
|
Private Sub TestRequestSuccessful(pUrl As String, pResponse As Responses.sltResponse, pErrorType As Constants.ErrorType)
|
|
If pResponse.State = False Then
|
|
Logger.Warn("Request to Url [{0}] returned error.", pUrl)
|
|
Logger.Error(pResponse.Message)
|
|
Throw New sltException(pErrorType, pResponse.Message)
|
|
End If
|
|
End Sub
|
|
End Class
|
|
End Namespace
|