From b5559955a3040069f5a8ef47f2b1f1c65175ae91 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Tue, 23 Apr 2019 14:36:08 +0200 Subject: [PATCH] finish adsync for now, add test job --- GUIs.Test.ADSyncTest/Form1.Designer.vb | 66 ++++++++++++++++ GUIs.Test.ADSyncTest/Form1.vb | 5 +- Jobs/JobConfig.vb | 7 ++ Jobs/JobConfigParser.vb | 51 ++++++++++++ Jobs/Jobs.vbproj | 2 + .../SyncUsers.MSSQL.vb | 2 +- Service.JobRunner/App.config | 12 ++- Service.JobRunner/JobRunner.vb | 79 +++++++++++++------ Service.JobRunner/JobRunnerService.vb | 5 +- .../My Project/Settings.Designer.vb | 36 ++++++--- .../My Project/Settings.settings | 12 ++- 11 files changed, 235 insertions(+), 42 deletions(-) create mode 100644 Jobs/JobConfig.vb create mode 100644 Jobs/JobConfigParser.vb diff --git a/GUIs.Test.ADSyncTest/Form1.Designer.vb b/GUIs.Test.ADSyncTest/Form1.Designer.vb index 309bfed9..51609d9d 100644 --- a/GUIs.Test.ADSyncTest/Form1.Designer.vb +++ b/GUIs.Test.ADSyncTest/Form1.Designer.vb @@ -27,6 +27,12 @@ Partial Class Form1 Me.ListBox2 = New System.Windows.Forms.ListBox() Me.Button2 = New System.Windows.Forms.Button() Me.Button3 = New System.Windows.Forms.Button() + Me.txtJobConfigString = New System.Windows.Forms.TextBox() + Me.TextBox2 = New System.Windows.Forms.TextBox() + Me.TextBox3 = New System.Windows.Forms.TextBox() + Me.TextBox4 = New System.Windows.Forms.TextBox() + Me.btnParseConfig = New System.Windows.Forms.Button() + Me.Label1 = New System.Windows.Forms.Label() Me.SuspendLayout() ' 'Button1 @@ -72,11 +78,64 @@ Partial Class Form1 Me.Button3.Text = "List Users for selected Group" Me.Button3.UseVisualStyleBackColor = True ' + 'txtJobConfigString + ' + Me.txtJobConfigString.Location = New System.Drawing.Point(12, 250) + Me.txtJobConfigString.Name = "txtJobConfigString" + Me.txtJobConfigString.Size = New System.Drawing.Size(227, 20) + Me.txtJobConfigString.TabIndex = 5 + Me.txtJobConfigString.Text = "True|* 0/5 * * * ?|Arg1::Foo,Arg2::Bar" + ' + 'TextBox2 + ' + Me.TextBox2.Location = New System.Drawing.Point(12, 321) + Me.TextBox2.Name = "TextBox2" + Me.TextBox2.Size = New System.Drawing.Size(227, 20) + Me.TextBox2.TabIndex = 6 + ' + 'TextBox3 + ' + Me.TextBox3.Location = New System.Drawing.Point(12, 347) + Me.TextBox3.Name = "TextBox3" + Me.TextBox3.Size = New System.Drawing.Size(227, 20) + Me.TextBox3.TabIndex = 7 + ' + 'TextBox4 + ' + Me.TextBox4.Location = New System.Drawing.Point(12, 373) + Me.TextBox4.Name = "TextBox4" + Me.TextBox4.Size = New System.Drawing.Size(227, 20) + Me.TextBox4.TabIndex = 8 + ' + 'btnParseConfig + ' + Me.btnParseConfig.Location = New System.Drawing.Point(12, 399) + Me.btnParseConfig.Name = "btnParseConfig" + Me.btnParseConfig.Size = New System.Drawing.Size(227, 33) + Me.btnParseConfig.TabIndex = 9 + Me.btnParseConfig.Text = "Parse Config" + Me.btnParseConfig.UseVisualStyleBackColor = True + ' + 'Label1 + ' + Me.Label1.AutoSize = True + Me.Label1.Location = New System.Drawing.Point(9, 234) + Me.Label1.Name = "Label1" + Me.Label1.Size = New System.Drawing.Size(67, 13) + Me.Label1.TabIndex = 10 + Me.Label1.Text = "ConfigString:" + ' 'Form1 ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(800, 450) + Me.Controls.Add(Me.Label1) + Me.Controls.Add(Me.btnParseConfig) + Me.Controls.Add(Me.TextBox4) + Me.Controls.Add(Me.TextBox3) + Me.Controls.Add(Me.TextBox2) + Me.Controls.Add(Me.txtJobConfigString) Me.Controls.Add(Me.Button3) Me.Controls.Add(Me.Button2) Me.Controls.Add(Me.ListBox2) @@ -85,6 +144,7 @@ Partial Class Form1 Me.Name = "Form1" Me.Text = "Form1" Me.ResumeLayout(False) + Me.PerformLayout() End Sub @@ -93,4 +153,10 @@ Partial Class Form1 Friend WithEvents ListBox2 As ListBox Friend WithEvents Button2 As Button Friend WithEvents Button3 As Button + Friend WithEvents txtJobConfigString As TextBox + Friend WithEvents TextBox2 As TextBox + Friend WithEvents TextBox3 As TextBox + Friend WithEvents TextBox4 As TextBox + Friend WithEvents btnParseConfig As Button + Friend WithEvents Label1 As Label End Class diff --git a/GUIs.Test.ADSyncTest/Form1.vb b/GUIs.Test.ADSyncTest/Form1.vb index 079f5f27..79686b2f 100644 --- a/GUIs.Test.ADSyncTest/Form1.vb +++ b/GUIs.Test.ADSyncTest/Form1.vb @@ -2,6 +2,7 @@ Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Database Imports DigitalData.Modules.Config +Imports DigitalData.Modules.Jobs Public Class Form1 Private _sync As ActiveDirectoryInterface @@ -68,5 +69,7 @@ Public Class Form1 Return oAttributeMappings End Function - + Private Sub btnParseConfig_Click(sender As Object, e As EventArgs) Handles btnParseConfig.Click + Dim oConfig = JobConfigParser.ParseConfig(txtJobConfigString.Text) + End Sub End Class diff --git a/Jobs/JobConfig.vb b/Jobs/JobConfig.vb new file mode 100644 index 00000000..9b086bd2 --- /dev/null +++ b/Jobs/JobConfig.vb @@ -0,0 +1,7 @@ +Imports System.Collections.Generic + +Public Class JobConfig + Public Enabled As Boolean + Public CronExpression As String + Public Arguments As Dictionary(Of String, String) +End Class \ No newline at end of file diff --git a/Jobs/JobConfigParser.vb b/Jobs/JobConfigParser.vb new file mode 100644 index 00000000..ad089da0 --- /dev/null +++ b/Jobs/JobConfigParser.vb @@ -0,0 +1,51 @@ +Imports System.Collections.Generic +Imports System.Text.RegularExpressions + +Public Class JobConfigParser + Private Shared JobOptionsRegex As New Regex("(?True|False)\|(?[\w\d\s,\?*-/]*)(?:\|(?(?:\w*::\w*,?)*))?") + Private Shared JobArgumentsRegex As New Regex("(?:(?:\w+::\w+,?)?)+") + Private Const ARGS_ITEM_DELIMITER As String = "," + Private Const ARGS_KEYVALUE_DELIMITER As String = "::" + + Public Shared Function ParseConfig(ConfigString As String) As JobConfig + If JobOptionsRegex.IsMatch(ConfigString) Then + Dim oMatches = JobOptionsRegex.Matches(ConfigString) + Dim oOptions As New JobConfig + + If oMatches.Count = 1 Then + Dim oMatch = oMatches.Item(0) + + oOptions.Enabled = CBool(oMatch.Groups("enabled").Value) + oOptions.CronExpression = oMatch.Groups("cron").Value + oOptions.Arguments = ParseOptionalArguments(oMatch.Groups("args").Value) + Else + Throw New ArgumentException("Config Malformed") + End If + + Return oOptions + Else + Throw New ArgumentException("Config Malformed") + End If + End Function + + Private Shared Function ParseOptionalArguments(ArgsString As String) As Dictionary(Of String, String) + Dim oArgsDictionary As New Dictionary(Of String, String) + + If JobArgumentsRegex.IsMatch(ArgsString) Then + Dim oArgs As String() = ArgsString.Split(ARGS_ITEM_DELIMITER) + + For Each oArg In oArgs + Dim oDelimiter As String() = New String() {ARGS_KEYVALUE_DELIMITER} + Dim oArgSplit = oArg.Split(oDelimiter, StringSplitOptions.RemoveEmptyEntries) + + If oArgSplit.Length = 2 Then + oArgsDictionary.Add(oArgSplit(0), oArgSplit(1)) + Else + Throw New ArgumentException("Config Malformed") + End If + Next + End If + + Return oArgsDictionary + End Function +End Class diff --git a/Jobs/Jobs.vbproj b/Jobs/Jobs.vbproj index 59acde28..ba1b63e1 100644 --- a/Jobs/Jobs.vbproj +++ b/Jobs/Jobs.vbproj @@ -93,6 +93,8 @@ + + True diff --git a/Modules.Interfaces/ActiveDirectoryInterface/SyncUsers.MSSQL.vb b/Modules.Interfaces/ActiveDirectoryInterface/SyncUsers.MSSQL.vb index 6dcd32e9..7035828d 100644 --- a/Modules.Interfaces/ActiveDirectoryInterface/SyncUsers.MSSQL.vb +++ b/Modules.Interfaces/ActiveDirectoryInterface/SyncUsers.MSSQL.vb @@ -43,7 +43,7 @@ Namespace SyncUsers _logger.Debug("Checking if user {0} exists", oUser) oUserId = GetUserId(oUser.samAccountName) oUserExists = oUserId > 0 - _logger.Debug("User {0} exists in database: ", oUser, oUserExists) + _logger.Debug("User {0} exists in database: {1}", oUser, oUserExists) Catch ex As Exception _logger.Error(ex) _logger.Warn("Could not get UserId for user. Skipping") diff --git a/Service.JobRunner/App.config b/Service.JobRunner/App.config index 3c284e0b..7f837fee 100644 --- a/Service.JobRunner/App.config +++ b/Service.JobRunner/App.config @@ -7,9 +7,6 @@ - - - @@ -28,6 +25,15 @@ + + False + + + + + + False|10/0 * * * * ?|Foo:Bar + \ No newline at end of file diff --git a/Service.JobRunner/JobRunner.vb b/Service.JobRunner/JobRunner.vb index 6908bf59..29d17192 100644 --- a/Service.JobRunner/JobRunner.vb +++ b/Service.JobRunner/JobRunner.vb @@ -1,4 +1,5 @@ Imports System.Collections.Specialized +Imports System.Text.RegularExpressions Imports DigitalData.Modules.Database Imports DigitalData.Modules.Jobs Imports DigitalData.Modules.Logging @@ -39,34 +40,50 @@ Public Class JobRunner _Logger.Info("Starting Scheduler..") Await _scheduler.Start() - _Logger.Info("Done") - Dim oJobData As New JobDataMap From { - {"LogConfig", _LogConfig}, - {"Firebird", _firebird}, - {"MSSQL", _mssql}, - {"RootPath", My.Settings.JOB_ADSYNC_ROOT_PATH} - } - - Dim oJobDetail = JobBuilder.Create(Of ADJob)(). - WithIdentity("activedirectory-sync"). - UsingJobData(oJobData). - Build() - - Dim oTrigger = TriggerBuilder.Create(). - WithIdentity("activedirectory-sync-trigger"). - StartNow(). - WithCronSchedule("0 0/1 * * * ?"). - Build() + ' [START] Job Scheduling + ' ADSync + Await ScheduleJob(Of ADJob)("ADSync", My.Settings.ADSYNC_CONFIG) + ' Test Job + Await ScheduleJob(Of TestJob)("TestJob", My.Settings.TEST_CONFIG) + ' [END] Job Scheduling - _Logger.Info("Starting ADSync Job..") - Await _scheduler.ScheduleJob(oJobDetail, oTrigger) - _Logger.Info("Done") Catch ex As Exception + _Logger.Warn("Job Failed.") _Logger.Error(ex) End Try End Sub + Public Async Function ScheduleJob(Of T As Quartz.IJob)(JobName As String, JobConfigString As String) As Task + Dim oJobIdentity As String = JobName + Dim oTriggerIdentity As String = JobName & "-Trigger" + Dim oJobConfig As JobConfig = JobConfigParser.ParseConfig(JobConfigString) + Dim oJobData As New JobDataMap From { + {"LogConfig", _LogConfig}, + {"Firebird", _firebird}, + {"MSSQL", _mssql}, + {"Args", oJobConfig.Arguments} + } + + Dim oJobDetail = JobBuilder.Create(Of T)(). + WithIdentity(oJobIdentity). + UsingJobData(oJobData). + Build() + + Dim oTrigger = TriggerBuilder.Create(). + WithIdentity(oTriggerIdentity). + StartNow(). + WithCronSchedule(oJobConfig.CronExpression). + Build() + + If oJobConfig.Enabled Then + Await _scheduler.ScheduleJob(oJobDetail, oTrigger) + _Logger.Info("Job {0} started.", JobName) + Else + _Logger.Info("Job {0} is disabled.", JobName) + End If + End Function + Public Async Sub [Stop]() _Logger.Info("Stopping JobRunner") Await _scheduler.Shutdown() @@ -80,7 +97,9 @@ Public Class JobRunner Dim oLogConfig As LogConfig = oJobData.Item("LogConfig") Dim oFirebird As Firebird = oJobData.Item("Firebird") Dim oMSSQL As MSSQLServer = oJobData.Item("MSSQL") - Dim oRootPath As String = oJobData.Item("RootPath") + Dim oArgs As Dictionary(Of String, String) = oJobData.Item("Args") + Dim oRootPath As String = oArgs.Item("RootPath") + Dim oADJobArgs = New ADSyncArgs() With { .RootPath = oRootPath } @@ -91,6 +110,21 @@ Public Class JobRunner Return Task.FromResult(True) End Function End Class + Public Class TestJob + Implements Quartz.IJob + + Public Function Execute(context As IJobExecutionContext) As Task Implements Quartz.IJob.Execute + Dim oJobData = context.MergedJobDataMap + Dim oLogConfig As LogConfig = oJobData.Item("LogConfig") + Dim oArgs As Dictionary(Of String, String) = oJobData.Item("Args") + Dim oArg1 As String = oArgs.Item("Arg1") + Dim oLogger = oLogConfig.GetLogger() + + oLogger.Info("Running Test Job With Arg1: {0}", oArg1) + + Return Task.FromResult(True) + End Function + End Class Private Class LogProvider Implements ILogProvider @@ -126,5 +160,4 @@ Public Class JobRunner Throw New NotImplementedException() End Function End Class - End Class diff --git a/Service.JobRunner/JobRunnerService.vb b/Service.JobRunner/JobRunnerService.vb index fef04489..24106e2a 100644 --- a/Service.JobRunner/JobRunnerService.vb +++ b/Service.JobRunner/JobRunnerService.vb @@ -11,8 +11,9 @@ Public Class JobRunnerService Private _jobrunner As JobRunner Protected Overrides Sub OnStart(ByVal args() As String) - _logConfig = New LogConfig(PathType.CustomPath, My.Settings.LOG_PATH) - _logConfig.Debug = True + _logConfig = New LogConfig(PathType.CustomPath, My.Settings.LOG_PATH) With { + .Debug = My.Settings.LOG_DEBUG + } _logger = _logConfig.GetLogger() _logger.Info("Starting Service {0}", ServiceName) diff --git a/Service.JobRunner/My Project/Settings.Designer.vb b/Service.JobRunner/My Project/Settings.Designer.vb index edc05f59..da4d8c38 100644 --- a/Service.JobRunner/My Project/Settings.Designer.vb +++ b/Service.JobRunner/My Project/Settings.Designer.vb @@ -54,15 +54,6 @@ Namespace My End Get End Property - _ - Public ReadOnly Property JOB_ADSYNC_ROOT_PATH() As String - Get - Return CType(Me("JOB_ADSYNC_ROOT_PATH"),String) - End Get - End Property - _ @@ -116,6 +107,33 @@ Namespace My Return CType(Me("FIREBIRD_PASSWORD"),String) End Get End Property + + _ + Public ReadOnly Property LOG_DEBUG() As Boolean + Get + Return CType(Me("LOG_DEBUG"),Boolean) + End Get + End Property + + _ + Public ReadOnly Property ADSYNC_CONFIG() As String + Get + Return CType(Me("ADSYNC_CONFIG"),String) + End Get + End Property + + _ + Public ReadOnly Property TEST_CONFIG() As String + Get + Return CType(Me("TEST_CONFIG"),String) + End Get + End Property End Class End Namespace diff --git a/Service.JobRunner/My Project/Settings.settings b/Service.JobRunner/My Project/Settings.settings index 7291f536..61a6220d 100644 --- a/Service.JobRunner/My Project/Settings.settings +++ b/Service.JobRunner/My Project/Settings.settings @@ -2,9 +2,6 @@ - - - @@ -23,5 +20,14 @@ + + False + + + + + + False|10/0 * * * * ?|Foo:Bar + \ No newline at end of file