09-12-2022

This commit is contained in:
Jonathan Jenne 2022-12-09 17:29:08 +01:00
parent 0a25b0925c
commit 8d6d81f488
30 changed files with 640 additions and 91 deletions

View File

@ -33,10 +33,34 @@
<xs:element minOccurs="0" name="ErrorMessage" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="JobName" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="Message" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="Steps" nillable="true" type="tns:ArrayOfHistoryItem.HistoryStep" />
<xs:element minOccurs="0" name="Successful" type="xs:boolean" />
</xs:sequence>
</xs:complexType>
<xs:element name="HistoryItem" nillable="true" type="tns:HistoryItem" />
<xs:complexType name="ArrayOfHistoryItem.HistoryStep">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="HistoryItem.HistoryStep" nillable="true" type="tns:HistoryItem.HistoryStep" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfHistoryItem.HistoryStep" nillable="true" type="tns:ArrayOfHistoryItem.HistoryStep" />
<xs:complexType name="HistoryItem.HistoryStep">
<xs:sequence>
<xs:element minOccurs="0" name="Created" type="xs:dateTime" />
<xs:element minOccurs="0" name="Level" type="tns:HistoryItem.StepLevel" />
<xs:element minOccurs="0" name="Message" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="HistoryItem.HistoryStep" nillable="true" type="tns:HistoryItem.HistoryStep" />
<xs:simpleType name="HistoryItem.StepLevel">
<xs:restriction base="xs:string">
<xs:enumeration value="Debug" />
<xs:enumeration value="Info" />
<xs:enumeration value="Warning" />
<xs:enumeration value="Error" />
</xs:restriction>
</xs:simpleType>
<xs:element name="HistoryItem.StepLevel" nillable="true" type="tns:HistoryItem.StepLevel" />
<xs:complexType name="ArrayOfStatusItem">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="StatusItem" nillable="true" type="tns:StatusItem" />

View File

@ -296,6 +296,9 @@ Namespace JobRunnerReference
<System.Runtime.Serialization.OptionalFieldAttribute()> _
Private MessageField As String
<System.Runtime.Serialization.OptionalFieldAttribute()> _
Private StepsField() As JobRunnerReference.HistoryItem.HistoryStep
<System.Runtime.Serialization.OptionalFieldAttribute()> _
Private SuccessfulField As Boolean
@ -361,6 +364,19 @@ Namespace JobRunnerReference
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property Steps() As JobRunnerReference.HistoryItem.HistoryStep()
Get
Return Me.StepsField
End Get
Set
If (Object.ReferenceEquals(Me.StepsField, value) <> true) Then
Me.StepsField = value
Me.RaisePropertyChanged("Steps")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property Successful() As Boolean
Get
@ -382,6 +398,101 @@ Namespace JobRunnerReference
propertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(propertyName))
End If
End Sub
<System.Diagnostics.DebuggerStepThroughAttribute(), _
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), _
System.Runtime.Serialization.DataContractAttribute(Name:="HistoryItem.HistoryStep", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"), _
System.SerializableAttribute()> _
Partial Public Class HistoryStep
Inherits Object
Implements System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
<System.NonSerializedAttribute()> _
Private extensionDataField As System.Runtime.Serialization.ExtensionDataObject
<System.Runtime.Serialization.OptionalFieldAttribute()> _
Private CreatedField As Date
<System.Runtime.Serialization.OptionalFieldAttribute()> _
Private LevelField As JobRunnerReference.HistoryItem.StepLevel
<System.Runtime.Serialization.OptionalFieldAttribute()> _
Private MessageField As String
Public Property ExtensionData() As System.Runtime.Serialization.ExtensionDataObject Implements System.Runtime.Serialization.IExtensibleDataObject.ExtensionData
Get
Return Me.extensionDataField
End Get
Set
Me.extensionDataField = value
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property Created() As Date
Get
Return Me.CreatedField
End Get
Set
If (Me.CreatedField.Equals(value) <> true) Then
Me.CreatedField = value
Me.RaisePropertyChanged("Created")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property Level() As JobRunnerReference.HistoryItem.StepLevel
Get
Return Me.LevelField
End Get
Set
If (Me.LevelField.Equals(value) <> true) Then
Me.LevelField = value
Me.RaisePropertyChanged("Level")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property Message() As String
Get
Return Me.MessageField
End Get
Set
If (Object.ReferenceEquals(Me.MessageField, value) <> true) Then
Me.MessageField = value
Me.RaisePropertyChanged("Message")
End If
End Set
End Property
Public Event PropertyChanged As System.ComponentModel.PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Protected Sub RaisePropertyChanged(ByVal propertyName As String)
Dim propertyChanged As System.ComponentModel.PropertyChangedEventHandler = Me.PropertyChangedEvent
If (Not (propertyChanged) Is Nothing) Then
propertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(propertyName))
End If
End Sub
End Class
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), _
System.Runtime.Serialization.DataContractAttribute(Name:="HistoryItem.StepLevel", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows")> _
Public Enum StepLevel As Integer
<System.Runtime.Serialization.EnumMemberAttribute()> _
Debug = 0
<System.Runtime.Serialization.EnumMemberAttribute()> _
Info = 1
<System.Runtime.Serialization.EnumMemberAttribute()> _
Warning = 2
<System.Runtime.Serialization.EnumMemberAttribute()> _
[Error] = 3
End Enum
End Class
<System.Diagnostics.DebuggerStepThroughAttribute(), _

View File

@ -5,6 +5,6 @@
<binding digest="System.ServiceModel.Configuration.NetTcpBindingElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data name=&quot;NetTcpBinding_IEDMIService&quot; transferMode=&quot;Streamed&quot;&gt;&lt;security&gt;&lt;transport sslProtocols=&quot;None&quot; /&gt;&lt;/security&gt;&lt;/Data&gt;" bindingType="netTcpBinding" name="NetTcpBinding_IEDMIService" />
</bindings>
<endpoints>
<endpoint normalizedDigest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;net.tcp://localhost:9001/DigitalData/Services/JobRunner&quot; binding=&quot;netTcpBinding&quot; bindingConfiguration=&quot;NetTcpBinding_IEDMIService&quot; contract=&quot;JobRunnerReference.IEDMIService&quot; name=&quot;NetTcpBinding_IEDMIService&quot;&gt;&lt;identity&gt;&lt;userPrincipalName value=&quot;Administrator@dd-san01.dd-gan.local.digitaldata.works&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" digest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;net.tcp://localhost:9001/DigitalData/Services/JobRunner&quot; binding=&quot;netTcpBinding&quot; bindingConfiguration=&quot;NetTcpBinding_IEDMIService&quot; contract=&quot;JobRunnerReference.IEDMIService&quot; name=&quot;NetTcpBinding_IEDMIService&quot;&gt;&lt;identity&gt;&lt;userPrincipalName value=&quot;Administrator@dd-san01.dd-gan.local.digitaldata.works&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" contractName="JobRunnerReference.IEDMIService" name="NetTcpBinding_IEDMIService" />
<endpoint normalizedDigest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;net.tcp://localhost:9001/DigitalData/Services/JobRunner&quot; binding=&quot;netTcpBinding&quot; bindingConfiguration=&quot;NetTcpBinding_IEDMIService&quot; contract=&quot;JobRunnerReference.IEDMIService&quot; name=&quot;NetTcpBinding_IEDMIService&quot;&gt;&lt;identity&gt;&lt;servicePrincipalName value=&quot;host/sDD-VMP03-VM09.dd-san01.dd-gan.local.digitaldata.works&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" digest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;net.tcp://localhost:9001/DigitalData/Services/JobRunner&quot; binding=&quot;netTcpBinding&quot; bindingConfiguration=&quot;NetTcpBinding_IEDMIService&quot; contract=&quot;JobRunnerReference.IEDMIService&quot; name=&quot;NetTcpBinding_IEDMIService&quot;&gt;&lt;identity&gt;&lt;servicePrincipalName value=&quot;host/sDD-VMP03-VM09.dd-san01.dd-gan.local.digitaldata.works&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" contractName="JobRunnerReference.IEDMIService" name="NetTcpBinding_IEDMIService" />
</endpoints>
</configurationSnapshot>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<SavedWcfConfigurationInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="9.1" CheckSum="DoUniskVeDbP1hRdgocMLRvIRWWXBsyF6LnDt8ZDNTI=">
<SavedWcfConfigurationInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="9.1" CheckSum="ho0oZcIegSOp+ZGeQ1YrB58dDQqmy97E7VQqQI8HV80=">
<bindingConfigurations>
<bindingConfiguration bindingType="netTcpBinding" name="NetTcpBinding_IEDMIService">
<properties>
@ -150,14 +150,14 @@
<property path="/identity/userPrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.UserPrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.UserPrincipalNameElement</serializedValue>
</property>
<property path="/identity/userPrincipalName/value" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Administrator@dd-san01.dd-gan.local.digitaldata.works</serializedValue>
<property path="/identity/userPrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/servicePrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.ServicePrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.ServicePrincipalNameElement</serializedValue>
</property>
<property path="/identity/servicePrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
<property path="/identity/servicePrincipalName/value" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>host/sDD-VMP03-VM09.dd-san01.dd-gan.local.digitaldata.works</serializedValue>
</property>
<property path="/identity/dns" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.DnsElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.DnsElement</serializedValue>

View File

@ -93,7 +93,7 @@
<wsa10:EndpointReference>
<wsa10:Address>net.tcp://localhost:9001/DigitalData/Services/JobRunner</wsa10:Address>
<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<Upn>Administrator@dd-san01.dd-gan.local.digitaldata.works</Upn>
<Spn>host/sDD-VMP03-VM09.dd-san01.dd-gan.local.digitaldata.works</Spn>
</Identity>
</wsa10:EndpointReference>
</wsdl:port>

View File

@ -39,7 +39,7 @@
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IEDMIService"
contract="JobRunnerReference.IEDMIService" name="NetTcpBinding_IEDMIService">
<identity>
<userPrincipalName value="Administrator@dd-san01.dd-gan.local.digitaldata.works" />
<servicePrincipalName value="host/sDD-VMP03-VM09.dd-san01.dd-gan.local.digitaldata.works" />
</identity>
</endpoint>
</client>

View File

@ -0,0 +1,5 @@
<h3>StatusIcon</h3>
@code {
}

View File

@ -13,12 +13,18 @@
<li class="list-group-item">Loading Job History..</li>
</ul>
}
else
else if (historyEntries.Count == 0)
{
<ul class="list-group">
<li class="list-group-item">No Job History yet.</li>
</ul>
}
else
{
@foreach (var entry in historyEntries)
{
<li class="list-group-item d-flex justify-content-between align-items-start">
<ul class="list-group mb-3">
<li class="list-group-item bg-light bg-gradient d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle text-success" viewBox="0 0 16 16">
@ -28,10 +34,26 @@ else
<span>@entry.JobName</span>
</div>
</div>
<span class="badge bg-primary rounded-pill">@entry.CreatedAt.ToShortTimeString()</span>
</li>
@foreach (var step in entry.Steps)
{
<li class="list-group-item">
<strong>@step.Created.ToString("HH:mm")</strong> @step.Message
</li>
}
<li class="list-group-item">
<strong>@entry.CreatedAt.ToString("HH:mm")</strong> @entry.Message
</li>
@if (entry.Successful == false)
{
<li class="list-group-item text-danger">Job Failed</li>
}
else
{
<li class="list-group-item text-success">Job Succeeded</li>
}
</ul>
}
}
@code {

View File

@ -19,9 +19,14 @@
}
else if (executingEntries.Count == 0)
{
<h4>Executing</h4>
<h4>Executing (0)</h4>
<ul class="list-group">
<li class="list-group-item">No jobs currently executing</li>
<li class="list-group-item">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cup-hot" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M.5 6a.5.5 0 0 0-.488.608l1.652 7.434A2.5 2.5 0 0 0 4.104 16h5.792a2.5 2.5 0 0 0 2.44-1.958l.131-.59a3 3 0 0 0 1.3-5.854l.221-.99A.5.5 0 0 0 13.5 6H.5ZM13 12.5a2.01 2.01 0 0 1-.316-.025l.867-3.898A2.001 2.001 0 0 1 13 12.5ZM2.64 13.825 1.123 7h11.754l-1.517 6.825A1.5 1.5 0 0 1 9.896 15H4.104a1.5 1.5 0 0 1-1.464-1.175Z" />
<path d="m4.4.8-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 3.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 3.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 3 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 4.4.8Zm3 0-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 6.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 6.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 6 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 7.4.8Zm3 0-.003.004-.014.019a4.077 4.077 0 0 0-.204.31 2.337 2.337 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.198 3.198 0 0 1-.202.388 5.385 5.385 0 0 1-.252.382l-.019.025-.005.008-.002.002A.5.5 0 0 1 9.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 9.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 9 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 10.4.8Z" />
</svg> No jobs currently executing.
</li>
</ul>
}
else
@ -62,10 +67,15 @@
}
else if (completedEntries.Count == 0)
{
<h4>Completed</h4>
<h4>Completed (0)</h4>
<ul class="list-group">
<li class="list-group-item">No jobs currently executing</li>
<li class="list-group-item">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cup-hot" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M.5 6a.5.5 0 0 0-.488.608l1.652 7.434A2.5 2.5 0 0 0 4.104 16h5.792a2.5 2.5 0 0 0 2.44-1.958l.131-.59a3 3 0 0 0 1.3-5.854l.221-.99A.5.5 0 0 0 13.5 6H.5ZM13 12.5a2.01 2.01 0 0 1-.316-.025l.867-3.898A2.001 2.001 0 0 1 13 12.5ZM2.64 13.825 1.123 7h11.754l-1.517 6.825A1.5 1.5 0 0 1 9.896 15H4.104a1.5 1.5 0 0 1-1.464-1.175Z" />
<path d="m4.4.8-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 3.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 3.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 3 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 4.4.8Zm3 0-.003.004-.014.019a4.167 4.167 0 0 0-.204.31 2.327 2.327 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.31 3.31 0 0 1-.202.388 5.444 5.444 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 6.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 6.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 6 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 7.4.8Zm3 0-.003.004-.014.019a4.077 4.077 0 0 0-.204.31 2.337 2.337 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.593.593 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3.198 3.198 0 0 1-.202.388 5.385 5.385 0 0 1-.252.382l-.019.025-.005.008-.002.002A.5.5 0 0 1 9.6 4.2l.003-.004.014-.019a4.149 4.149 0 0 0 .204-.31 2.06 2.06 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.593.593 0 0 0-.09-.252A4.334 4.334 0 0 0 9.6 2.8l-.01-.012a5.099 5.099 0 0 1-.37-.543A1.53 1.53 0 0 1 9 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a5.446 5.446 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 10.4.8Z" />
</svg> No completed jobs yet.
</li>
</ul>
}
else
@ -126,7 +136,7 @@ else
completedEntries = response.jobStatus.
Where(s => !s.Executing).
Where(s => s.StartTime.AddMinutes(1) > DateTime.Now).
Where(s => s.StartTime.AddMinutes(10) > DateTime.Now).
ToList();
InvokeAsync(StateHasChanged);

View File

@ -10,14 +10,14 @@
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<NavLink class="nav-link px-3" href="" Match="NavLinkMatch.All">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-house" viewBox="0 0 16 16">
<path d="M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.708L2 8.207V13.5A1.5 1.5 0 0 0 3.5 15h9a1.5 1.5 0 0 0 1.5-1.5V8.207l.646.647a.5.5 0 0 0 .708-.708L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.707 1.5ZM13 7.207V13.5a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5V7.207l5-5 5 5Z" />
</svg> Start
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="profiles">
<NavLink class="nav-link px-3" href="profiles">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-rocket" viewBox="0 0 16 16">
<path d="M8 8c.828 0 1.5-.895 1.5-2S8.828 4 8 4s-1.5.895-1.5 2S7.172 8 8 8Z" />
<path d="M11.953 8.81c-.195-3.388-.968-5.507-1.777-6.819C9.707 1.233 9.23.751 8.857.454a3.495 3.495 0 0 0-.463-.315A2.19 2.19 0 0 0 8.25.064.546.546 0 0 0 8 0a.549.549 0 0 0-.266.073 2.312 2.312 0 0 0-.142.08 3.67 3.67 0 0 0-.459.33c-.37.308-.844.803-1.31 1.57-.805 1.322-1.577 3.433-1.774 6.756l-1.497 1.826-.004.005A2.5 2.5 0 0 0 2 12.202V15.5a.5.5 0 0 0 .9.3l1.125-1.5c.166-.222.42-.4.752-.57.214-.108.414-.192.625-.281l.198-.084c.7.428 1.55.635 2.4.635.85 0 1.7-.207 2.4-.635.067.03.132.056.196.083.213.09.413.174.627.282.332.17.586.348.752.57l1.125 1.5a.5.5 0 0 0 .9-.3v-3.298a2.5 2.5 0 0 0-.548-1.562l-1.499-1.83ZM12 10.445v.055c0 .866-.284 1.585-.75 2.14.146.064.292.13.425.199.39.197.8.46 1.1.86L13 14v-1.798a1.5 1.5 0 0 0-.327-.935L12 10.445ZM4.75 12.64C4.284 12.085 4 11.366 4 10.5v-.054l-.673.82a1.5 1.5 0 0 0-.327.936V14l.225-.3c.3-.4.71-.664 1.1-.861.133-.068.279-.135.425-.199ZM8.009 1.073c.063.04.14.094.226.163.284.226.683.621 1.09 1.28C10.137 3.836 11 6.237 11 10.5c0 .858-.374 1.48-.943 1.893C9.517 12.786 8.781 13 8 13c-.781 0-1.517-.214-2.057-.607C5.373 11.979 5 11.358 5 10.5c0-4.182.86-6.586 1.677-7.928.409-.67.81-1.082 1.096-1.32.09-.076.17-.135.236-.18Z" />
@ -26,7 +26,7 @@
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="status">
<NavLink class="nav-link px-3" href="status">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-speedometer" viewBox="0 0 16 16">
<path d="M8 2a.5.5 0 0 1 .5.5V4a.5.5 0 0 1-1 0V2.5A.5.5 0 0 1 8 2zM3.732 3.732a.5.5 0 0 1 .707 0l.915.914a.5.5 0 1 1-.708.708l-.914-.915a.5.5 0 0 1 0-.707zM2 8a.5.5 0 0 1 .5-.5h1.586a.5.5 0 0 1 0 1H2.5A.5.5 0 0 1 2 8zm9.5 0a.5.5 0 0 1 .5-.5h1.5a.5.5 0 0 1 0 1H12a.5.5 0 0 1-.5-.5zm.754-4.246a.389.389 0 0 0-.527-.02L7.547 7.31A.91.91 0 1 0 8.85 8.569l3.434-4.297a.389.389 0 0 0-.029-.518z" />
<path fill-rule="evenodd" d="M6.664 15.889A8 8 0 1 1 9.336.11a8 8 0 0 1-2.672 15.78zm-4.665-4.283A11.945 11.945 0 0 1 8 10c2.186 0 4.236.585 6.001 1.606a7 7 0 1 0-12.002 0z" />
@ -34,7 +34,7 @@
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="history">
<NavLink class="nav-link px-3" href="history">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clock-history" viewBox="0 0 16 16">
<path d="M8.515 1.019A7 7 0 0 0 8 1V0a8 8 0 0 1 .589.022l-.074.997zm2.004.45a7.003 7.003 0 0 0-.985-.299l.219-.976c.383.086.76.2 1.126.342l-.36.933zm1.37.71a7.01 7.01 0 0 0-.439-.27l.493-.87a8.025 8.025 0 0 1 .979.654l-.615.789a6.996 6.996 0 0 0-.418-.302zm1.834 1.79a6.99 6.99 0 0 0-.653-.796l.724-.69c.27.285.52.59.747.91l-.818.576zm.744 1.352a7.08 7.08 0 0 0-.214-.468l.893-.45a7.976 7.976 0 0 1 .45 1.088l-.95.313a7.023 7.023 0 0 0-.179-.483zm.53 2.507a6.991 6.991 0 0 0-.1-1.025l.985-.17c.067.386.106.778.116 1.17l-1 .025zm-.131 1.538c.033-.17.06-.339.081-.51l.993.123a7.957 7.957 0 0 1-.23 1.155l-.964-.267c.046-.165.086-.332.12-.501zm-.952 2.379c.184-.29.346-.594.486-.908l.914.405c-.16.36-.345.706-.555 1.038l-.845-.535zm-.964 1.205c.122-.122.239-.248.35-.378l.758.653a8.073 8.073 0 0 1-.401.432l-.707-.707z" />
<path d="M8 1a7 7 0 1 0 4.95 11.95l.707.707A8.001 8.001 0 1 1 8 0v1z" />

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -7,6 +7,7 @@
Public Const JOB_CONFIG_ARGUMENTS = "__Arguments"
Public Const JOB_CONFIG_DATABASE = "__Database"
Public Const JOB_CONFIG_STATE = "__State"
Public Const JOB_CONFIG_WINDREAM = "__Windream"
End Class
Public Class Jobs

View File

@ -57,6 +57,10 @@
<Reference Include="DigitalData.Modules.Database">
<HintPath>..\..\DDModules\Database\bin\Debug\DigitalData.Modules.Database.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Modules.Filesystem, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\DDModules\Filesystem\bin\Debug\DigitalData.Modules.Filesystem.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Modules.Language, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\DDModules\Language\bin\Debug\DigitalData.Modules.Language.dll</HintPath>
@ -123,6 +127,7 @@
<Compile Include="Models\Jobs\HistoryItem.vb" />
<Compile Include="Models\Jobs\StatusItem.vb" />
<Compile Include="Models\Profiles\BaseProfile.vb" />
<Compile Include="Models\Profiles\ImportFile.vb" />
<Compile Include="Models\Profiles\ImportProfile.vb" />
<Compile Include="Models\Profiles\ImportProfileStep.vb" />
<Compile Include="Models\Windream\ObjectType.vb" />
@ -168,6 +173,7 @@
<Compile Include="WCF\JobRunner.vb" />
<Compile Include="WCF\Methods\Base.vb" />
<Compile Include="WCF\Methods\GetJobConfig.vb" />
<Compile Include="WCF\Methods\RunJob.vb" />
<Compile Include="WCF\Methods\UpdateJob.vb" />
<Compile Include="WCF\Methods\UpdateProfile.vb" />
<Compile Include="WCF\Methods\GetJobStatus.vb" />

View File

@ -4,4 +4,19 @@
Public Property Successful As Boolean
Public Property ErrorMessage As String
Public Property Message As String
Public Property Steps As List(Of HistoryStep)
Public Class HistoryStep
Public Property Created As Date = Now
Public Property Message As String
Public Property Level As StepLevel
End Class
Public Enum StepLevel
Debug
Info
Warning
[Error]
End Enum
End Class

View File

@ -0,0 +1,19 @@
Public Class ImportFile
Public Property FilePath As String
Public Property FilePathOriginal As String
Public Property FilePathWindream As String
Public Property FileInfo As IO.FileInfo
Public Property IndexValues As New List(Of IndexItem)
Public Class IndexItem
Public Value As String
Public IndexName As String
End Class
Public Sub New(pFilePath As String)
_FilePathOriginal = pFilePath
_FilePath = pFilePath
_FileInfo = New IO.FileInfo(pFilePath)
End Sub
End Class

View File

@ -12,23 +12,25 @@ Namespace Scheduler
MyBase.New(pLogConfig)
End Sub
Public Sub AddSuccess(pName As String, pMessage As String)
Public Sub AddSuccess(pName As String, pMessage As String, pSteps As List(Of HistoryItem.HistoryStep))
Entries.Add(New HistoryItem With {
.CreatedAt = Now,
.JobName = pName,
.Successful = True,
.ErrorMessage = Nothing,
.Message = pMessage
.Message = pMessage,
.Steps = pSteps
})
End Sub
Public Sub AddError(pName As String, ErrorMessage As String)
Public Sub AddError(pName As String, ErrorMessage As String, pSteps As List(Of HistoryItem.HistoryStep))
Entries.Add(New HistoryItem With {
.CreatedAt = Now,
.JobName = pName,
.Successful = False,
.ErrorMessage = ErrorMessage,
.Message = ""
.Message = "",
.Steps = pSteps
})
End Sub
End Class

View File

@ -25,13 +25,13 @@ Namespace Scheduler
If jobException Is Nothing Then
If TypeOf context.Result Is JobResult Then
Dim oResult As JobResult = context.Result
History.AddSuccess(context.JobDetail.Key.Name, oResult.Description)
History.AddSuccess(context.JobDetail.Key.Name, oResult.Description, oResult.Steps)
Else
History.AddSuccess(context.JobDetail.Key.Name, "Job Successful!")
History.AddSuccess(context.JobDetail.Key.Name, "Job Successful!", New List(Of HistoryItem.HistoryStep))
End If
Else
History.AddError(context.JobDetail.Key.Name, jobException.Message)
History.AddError(context.JobDetail.Key.Name, jobException.Message, New List(Of HistoryItem.HistoryStep))
End If
Return MyBase.JobWasExecuted(context, jobException, cancellationToken)

View File

@ -1,3 +1,5 @@
Public Class JobResult
Public Property Successful As Boolean
Public Property Description As String
Public Property Steps As List(Of HistoryItem.HistoryStep)
End Class

View File

@ -1,8 +1,10 @@
Imports System.Collections.Specialized
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Windream
Imports ECM.JobRunner.Common
Imports Quartz
Imports Quartz.Logging.OperationName
Namespace Scheduler
Public Class JobScheduler
@ -16,20 +18,32 @@ Namespace Scheduler
Private ReadOnly Database As MSSQLServer
Private ReadOnly Factory As Quartz.Impl.StdSchedulerFactory
Private ReadOnly State As State
Private ReadOnly Windream As Windream
Private Scheduler As IScheduler
Private Const JOB_TYPE_IMPORT As Integer = 1
Private Const JOB_TYPE_INDEX As Integer = 2
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer, pState As State)
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer, pState As State, pWindream As Windream)
LogConfig = pLogConfig
Logger = pLogConfig.GetLogger()
Factory = New Impl.StdSchedulerFactory(Settings)
Database = pDatabase
Windream = pWindream
State = pState
End Sub
Private Function BuildJobData(pJobConfig As JobConfig) As JobDataMap
Return New JobDataMap From {
{Constants.Scheduler.JOB_CONFIG_LOGCONFIG, LogConfig},
{Constants.Scheduler.JOB_CONFIG_ARGUMENTS, pJobConfig.Arguments},
{Constants.Scheduler.JOB_CONFIG_DATABASE, Database},
{Constants.Scheduler.JOB_CONFIG_STATE, State},
{Constants.Scheduler.JOB_CONFIG_WINDREAM, Windream}
}
End Function
Public Async Function Start() As Task(Of Boolean)
Try
' Log all quartz events into our standard log files
@ -69,26 +83,39 @@ Namespace Scheduler
Return Await Scheduler.GetCurrentlyExecutingJobs()
End Function
Public Async Function ScheduleJob(pJobId As Integer) As Task
Dim oJob = State.JobDefinitions.Where(Function(j) j.Id = pJobId).SingleOrDefault()
If oJob IsNot Nothing Then
Logger.Info("Scheduling Job [{0}] manually!", oJob.Name)
Await PrepareScheduleJob(oJob)
End If
End Function
Private Async Function PrepareScheduleJob(pJob As JobDefinition) As Task
Logger.Debug("Loading Job Definition [{0}]", pJob.Name)
Logger.Debug("Job Type is [{0}]", pJob.Type.Name)
Select Case pJob.TypeId
Case JOB_TYPE_IMPORT
Dim oJobConfig = BuildJobConfig(Of Jobs.FileImportJob)(pJob)
Await ScheduleJob(Of Jobs.FileImportJob)(oJobConfig)
Case JOB_TYPE_INDEX
Dim oJobConfig = BuildJobConfig(Of Jobs.FileIndexJob)(pJob)
Await ScheduleJob(Of Jobs.FileIndexJob)(oJobConfig)
Case Else
Logger.Warn("Job for TypeId [{0}] is not implemented!", pJob.TypeId)
End Select
End Function
Private Async Sub ScheduleJobs()
Logger.Info("Loading [{0}] Job Definitions..", State.JobDefinitions.Count)
For Each oJob In State.JobDefinitions
Logger.Debug("Loading Job Definition [{0}]", oJob.Name)
Logger.Debug("Job Type is [{0}]", oJob.Type.Name)
Select Case oJob.TypeId
Case JOB_TYPE_IMPORT
Dim oJobConfig = BuildJobConfig(Of Jobs.FileImportJob)(oJob)
Await ScheduleJob(Of Jobs.FileImportJob)(oJobConfig)
Case JOB_TYPE_INDEX
Dim oJobConfig = BuildJobConfig(Of Jobs.FileIndexJob)(oJob)
Await ScheduleJob(Of Jobs.FileIndexJob)(oJobConfig)
Case Else
Logger.Warn("Job for TypeId [{0}] is not implemented!", oJob.TypeId)
End Select
Await PrepareScheduleJob(oJob)
Next
End Sub
@ -155,15 +182,6 @@ Namespace Scheduler
End If
End Function
Private Function BuildJobData(pJobConfig As JobConfig) As JobDataMap
Return New JobDataMap From {
{Constants.Scheduler.JOB_CONFIG_LOGCONFIG, LogConfig},
{Constants.Scheduler.JOB_CONFIG_ARGUMENTS, pJobConfig.Arguments},
{Constants.Scheduler.JOB_CONFIG_DATABASE, Database},
{Constants.Scheduler.JOB_CONFIG_STATE, State}
}
End Function
Private Function BuildJob(Of T As IJob)(pJobConfig As JobConfig, pJobData As JobDataMap) As IJobDetail
Dim oJobName = GetJobName(pJobConfig)
Return JobBuilder.Create(Of T)().

View File

@ -1,5 +1,6 @@
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Windream
Imports ECM.JobRunner.Common
Imports Quartz
@ -8,11 +9,14 @@ Namespace Scheduler.Jobs
Friend LogConfig As LogConfig
Friend Logger As Logger
Friend Database As MSSQLServer
Friend Windream As Windream
Friend State As State
Friend Id As Integer
Friend Name As String
Friend ResultItems As New List(Of HistoryItem.HistoryStep)
Private ctx As IJobExecutionContext
Public Function InitializeJob(context As IJobExecutionContext) As Dictionary(Of String, String)
@ -23,6 +27,7 @@ Namespace Scheduler.Jobs
LogConfig = oJobData.Item(Constants.Scheduler.JOB_CONFIG_LOGCONFIG)
Database = oJobData.Item(Constants.Scheduler.JOB_CONFIG_DATABASE)
State = oJobData.Item(Constants.Scheduler.JOB_CONFIG_STATE)
Windream = oJobData.Item(Constants.Scheduler.JOB_CONFIG_WINDREAM)
Logger = LogConfig.GetLogger()
Id = Integer.Parse(oArgs.Item("Id"))
@ -36,9 +41,45 @@ Namespace Scheduler.Jobs
State.JobStatus.Update(ctx, pCurrentValue, pTotalValue)
End Sub
Public Sub CompleteJob()
State.JobStatus.Complete(ctx)
Public Sub LogStep(pLevel As HistoryItem.StepLevel, pMessage As String, ParamArray pArgs As String())
ResultItems.Add(New HistoryItem.HistoryStep With {
.Message = String.Format(pMessage, pArgs),
.Level = pLevel
})
End Sub
Public Function CompleteJob() As Task(Of Boolean)
ctx.Result = New JobResult With {
.Successful = True,
.Steps = ResultItems,
.Description = "Job completed."
}
State.JobStatus.Complete(ctx)
Return Task.FromResult(True)
End Function
Public Function CompleteJob(pCompletionMessage As String) As Task(Of Boolean)
ctx.Result = New JobResult With {
.Successful = True,
.Steps = ResultItems,
.Description = pCompletionMessage
}
State.JobStatus.Complete(ctx)
Return Task.FromResult(True)
End Function
Public Function CompleteJob(pException As Exception) As Task(Of Boolean)
ctx.Result = New JobResult With {
.Successful = False,
.Steps = ResultItems,
.Description = pException.Message
}
State.JobStatus.Complete(ctx)
Return Task.FromResult(False)
End Function
End Class
End Namespace

View File

@ -18,7 +18,7 @@ Namespace Scheduler.Jobs
context.Result = oResult
CompleteJob()
CompleteJob("Done!")
Return Task.FromResult(True)
End Function
End Class

View File

@ -1,7 +1,7 @@
Imports ECM.JobRunner.Windows.Scheduler.Jobs
Imports Quartz
Imports System.Text.RegularExpressions
Imports DigitalData.Modules.Filesystem
Namespace Scheduler.Jobs
@ -50,47 +50,271 @@ Namespace Scheduler.Jobs
Inherits BaseJob
Implements IJob
Private FileEx As File
Public Function Execute(context As IJobExecutionContext) As Task Implements IJob.Execute
Dim oArgs = MyBase.InitializeJob(context)
Try
Logger.Info("Running File Import [{0}]", Name)
FileEx = New File(LogConfig)
Dim oProfile = State.ProfileDefintions.ImportProfiles.Where(Function(p) p.JobId = Id).SingleOrDefault()
Dim oSourceDirectory As String = oProfile.SourceFolder
Dim oRecursive As Boolean = oProfile.IncludeSubfolders
Dim oFiles = GetFiles(oSourceDirectory, oRecursive)
Logger.Info("Running File Import [{0}]", Name)
Logger.Info("Source directory: [{0}]", oProfile.SourceFolder)
Logger.Info("Target directory: [{0}]", oProfile.TargetFolder)
Logger.Info("Backup directory: [{0}]", oProfile.BackupFolder)
If oFiles.Count = 0 Then
Logger.Info("No Files for Profile [{0}]", Name)
Return Task.FromResult(True)
Dim oObjectType = State.ObjectTypes.Where(Function(o) o.Name = oProfile.ObjectTypeName).SingleOrDefault()
If IO.Directory.Exists(oProfile.SourceFolder) = False Then
LogStep(HistoryItem.StepLevel.Error, "Source directory [{0}] does not exist!", oProfile.SourceFolder)
Return Task.FromResult(False)
End If
Logger.Info("[0] files found in source directory [{1}]", oFiles.Count, oSourceDirectory)
Dim oRecursive As Boolean = oProfile.IncludeSubfolders
Dim oFileNames = GetFiles(oProfile.SourceFolder, oRecursive)
Dim oRegexList As List(Of Regex) = GetRegexList(oProfile.FileExcludeRegex)
'Dim oMax = 100
'For index = 1 To oMax
' UpdateProgress(index, oMax)
' Threading.Thread.Sleep(100)
'Next
Logger.Debug("[{0}] Regexes loaded", oRegexList.Count)
Dim oResult = New JobResult() With {
.Description = $"File Import Job [{Name}] completed!"
}
If oFileNames.Count = 0 Then
Logger.Info("No Files for Profile [{0}]", Name)
Return CompleteJob("No files for profile")
End If
context.Result = oResult
Logger.Info("[{0}] files found in source directory [{1}]", oFileNames.Count, oProfile.SourceFolder)
LogStep(HistoryItem.StepLevel.Info, "{0} files found in source directory {1}", oFileNames.Count, oProfile.SourceFolder)
Return Task.FromResult(True)
' - [ ] Process Rules, build list of files and indexes
' - [x] Process Regex to filter out files
' - [x] Check time to filter out files
' - [ ] (Check if files can be accessed)
' - [ ] Check if backup is needed and backup files
' - [ ] Import into windream
' - [ ] Create original subfolder structure
' - [ ] Create DateTime Subfolders
' - [x] Check if file exists and version
' - [x] Do import
' - [ ] Check for filesize 0
' - [ ] Write indexes (using data from getimportfile)
' - [ ] Check if orig file should be deleted
' - [ ] (delete subdirectories in source path)
Dim oFiles = oFileNames.
Select(Function(f) New ImportFile(f)).
ToList()
Dim oFilteredFiles = oFiles
' Check time to filter out files
Dim oDateFilteredFiles = oFilteredFiles.Where(Function(f) FileIsOlderThan(f, pMinutes:=1)).ToList()
Dim oDateFilteredCount = oFilteredFiles.Except(oDateFilteredFiles).Count()
Logger.Debug("[{0}] Files filtered out for being too new.", oDateFilteredCount)
LogStep(HistoryItem.StepLevel.Debug, "{0} Files filtered out for being too new.", oDateFilteredCount)
oFilteredFiles = oDateFilteredFiles
' Process Regex to filter out files
Dim oRegexFilteredFiles = oFilteredFiles.Where(Function(f) Not FileMatchesRegex(f, oRegexList))
Dim oRegexFilteredCount = oFilteredFiles.Except(oRegexFilteredFiles).Count()
Logger.Debug("[{0}] Files filtered out for matching exclusion Regex.", oRegexFilteredCount)
LogStep(HistoryItem.StepLevel.Debug, "{0} Files filtered out for matching exclusion Regex.", oRegexFilteredCount)
oFilteredFiles = oDateFilteredFiles
Logger.Info("Importing files..")
Dim oImportedFiles As New List(Of ImportFile)
For Each oFile In oFilteredFiles
Dim oImportedPath = ImportFile(oFile, oProfile)
If oImportedPath Is Nothing Then
Logger.Warn("File [{0}] could not be imported!", oFile.FilePath)
Continue For
End If
oFile.FilePathWindream = oImportedPath
oImportedFiles.Add(oFile)
Next
Logger.Info("[{0}] files successfully Imported!", oImportedFiles.Count)
LogStep(HistoryItem.StepLevel.Info, "{0} files successfully Imported!", oImportedFiles.Count)
Dim oIndexedFiles As New List(Of ImportFile)
For Each oFile In oImportedFiles
Logger.Info("Indexing file [{0}]", oFile.FilePathWindream)
Dim oIndexResult = IndexFile(oFile, oProfile)
If oIndexResult = True Then
oIndexedFiles.Add(oFile)
End If
Logger.Info("Indexing of file [{0}] done!", oFile.FilePathWindream)
Next
Logger.Info("[{0}] files successfully Indexed!", oIndexedFiles.Count)
LogStep(HistoryItem.StepLevel.Info, "{0} files successfully Indexed!", oIndexedFiles.Count)
Return CompleteJob($"{oImportedFiles.Count} files successfully Processed!")
Catch ex As Exception
Logger.Error(ex)
LogStep(HistoryItem.StepLevel.Error, "Unexpected Error: [{0}]", ex.Message)
Return Task.FromResult(False)
Finally
CompleteJob()
Return CompleteJob(ex)
End Try
End Function
Private Function FileIsOlderThan(pFile As ImportFile, pMinutes As Integer)
Return pFile.FileInfo.CreationTime.AddMinutes(pMinutes) < Now
End Function
Private Function FileMatchesRegex(pFile As ImportFile, pRegexList As List(Of Regex))
Return pRegexList.Any(Function(r) r.IsMatch(pFile.FilePath))
End Function
Private Function GetRegexList(pRegexString As String) As List(Of Regex)
Return pRegexString.
Split(vbNewLine).
ToList().
Where(Function(r) String.IsNullOrWhiteSpace(r) = False).
Select(Function(s)
Logger.Debug("Regex loaded: [{0}]", s)
Return New Regex(s)
End Function).ToList()
End Function
Private Function ImportFile(pFile As ImportFile, pProfile As ImportProfile) As String
'Check if target folder exists
If Windream.TestFolderExists(pProfile.TargetFolder) = False Then
If Windream.NewFolder(pProfile.TargetFolder) = False Then
Logger.Warn("Folder [{0}] could not be created!", pProfile.TargetFolder)
Return Nothing
End If
End If
' Generate new filepath and stream file
Dim oFileName = IO.Path.GetFileName(pFile.FilePath)
Dim oNewFilePath As String = IO.Path.Combine(pProfile.TargetFolder, oFileName)
Dim oVersionedFilePath = GetVersionedWindreamPath(oNewFilePath)
If Windream.NewFileStream(pFile.FilePathOriginal, oVersionedFilePath, pProfile.ObjectTypeName) = False Then
Logger.Warn("File [{0}] could not be streamed to path [{1}]!", pFile.FilePathOriginal, oNewFilePath)
Return Nothing
End If
Return oVersionedFilePath
End Function
Private Function GetVersionedWindreamPath(pWindreamFilePath As String) As String
Dim oAbsolutePath = Windream.GetAbsolutePath(pWindreamFilePath)
' This versions the filename but does not rely on access though the filesystem.
' Instead the check for file existence is made through the windream sdk.
Dim oVersionedPath = FileEx.GetVersionedFilenameWithFilecheck(oAbsolutePath, Function(pPath As String) Windream.TestFileExists(pPath))
Dim oVersionedAndNormalizedPath = Windream.GetNormalizedPath(oVersionedPath, False)
Return oVersionedAndNormalizedPath
End Function
Private Function GetImportFile(pFilename As String, pProfile As ImportProfile) As ImportFile
Dim oImportFile = New ImportFile(pFilename)
Return oImportFile
End Function
Private Function ProcessSteps(pFile As ImportFile, pProfile As ImportProfile) As List(Of ImportFile.IndexItem)
Dim oIndexItems = New List(Of ImportFile.IndexItem)
' Process Steps on Filename
For Each oStep In pProfile.Steps
Dim oValue As String
' Get the base value by checking scope
Select Case oStep.Scope
Case ImportProfileStep.StepScope.FILE
oValue = pFile.FileInfo.Name
Case ImportProfileStep.StepScope.FOLDER
oValue = pFile.FileInfo.DirectoryName
Case Else
oValue = pFile.FilePath
End Select
' TODO: Error handling!
Select Case oStep.Method
Case ImportProfileStep.StepMethod.SUBSTRING
Try
Dim oIndex1 = Integer.Parse(oStep.Argument1)
Dim oLength = Integer.Parse(oStep.Argument2)
oValue = oValue.Substring(oIndex1, oLength)
Catch ex As Exception
LogStep(HistoryItem.StepLevel.Error, "Method SUBSTRING could not be applied to Index '{0}'. Error: '{1}'", oStep.IndexName, ex.Message)
Logger.Error(ex)
End Try
Case ImportProfileStep.StepMethod.SPLIT
Try
Dim oSeparator = oStep.Argument1.Substring(0, 1)
Dim oIndex = Integer.Parse(oStep.Argument2)
Dim oSplit = oValue.Split(oSeparator)
oValue = oSplit(oIndex)
Catch ex As Exception
LogStep(HistoryItem.StepLevel.Error, "Method SPLIT could not be applied to Index '{0}'. Error: '{1}'", oStep.IndexName, ex.Message)
Logger.Error(ex)
End Try
Case ImportProfileStep.StepMethod.REGEX
Try
Dim oRegex = New Regex(oStep.Argument1)
Dim oTrueValue = oStep.Argument2
Dim oFalseValue = oStep.Argument3
If oRegex.IsMatch(oValue) Then
oValue = oTrueValue
Else
oValue = oFalseValue
End If
Catch ex As Exception
LogStep(HistoryItem.StepLevel.Error, "Method REGEX could not be applied to Index '{0}'. Error: '{1}'", oStep.IndexName, ex.Message)
Logger.Error(ex)
End Try
Case ImportProfileStep.StepMethod.VALUE
oValue = oStep.Argument1
Case ImportProfileStep.StepMethod.ALL
'noop
Case Else
'noop
End Select
oIndexItems.Add(New ImportFile.IndexItem With {
.IndexName = oStep.IndexName,
.Value = oValue
})
Next
Return oIndexItems
End Function
Private Function IndexFile(pFile As ImportFile, pProfile As ImportProfile) As Boolean
Logger.Debug("Writing [{0}] indexes for File [{1}]", pFile.IndexValues.Count, pFile.FilePathWindream)
Dim oIndexItems = ProcessSteps(pFile, pProfile)
Dim oResults = oIndexItems.
Select(Function(v)
Dim oIndexResult = False
Logger.Info("Writing Index [{0}] with value [{1}]", v.IndexName, v.Value)
If Windream.TestIndexNameIsVectorIndex(v.IndexName) Then
oIndexResult = Windream.SetFileIndex(pFile.FilePathWindream, v.IndexName, New List(Of String) From {v.Value}, pProfile.ObjectTypeName)
Else
oIndexResult = Windream.SetFileIndex(pFile.FilePathWindream, v.IndexName, v.Value, pProfile.ObjectTypeName)
End If
Return oIndexResult
End Function).
ToList()
' Return True if all Indexes were set correctly
Return oResults.All(Function(r) r = True)
End Function
Private Function GetFiles(pDirectory As String, pRecursive As Boolean) As String()

View File

@ -17,7 +17,7 @@ Namespace Scheduler.Jobs
context.Result = oResult
CompleteJob()
CompleteJob("Done!")
Return Task.FromResult(True)
End Function
End Class

View File

@ -41,14 +41,14 @@ Public Class Service
' Initialize Windream
Dim oWindream = Config.Windream
Windream = New Windream(LogConfig, True, oWindream.DriveLetter, "/", True,
Windream = New Windream(LogConfig, True, oWindream.DriveLetter, "\\windream\objects\", True,
oWindream.Server, oWindream.Username, oWindream.Password, oWindream.Domain)
' initialize global state
State = New State(LogConfig, Database, Windream)
' start the scheduler
Scheduler = New Scheduler.JobScheduler(LogConfig, Database, State)
Scheduler = New Scheduler.JobScheduler(LogConfig, Database, State, Windream)
If Await Scheduler.Start() Then
Logger.Info("Scheduler started!")
Else

View File

@ -4,6 +4,7 @@ Imports ECM.JobRunner.Windows.UpdateJob
Imports ECM.JobRunner.Windows.UpdateProfile
Imports ECM.JobRunner.Windows.GetJobStatus
Imports ECM.JobRunner.Windows.GetJobConfig
Imports ECM.JobRunner.Windows.RunJob
Namespace WCF
<ServiceContract(Name:="IEDMIService", [Namespace]:="http://DigitalData.Services.EDMIService")>
@ -15,6 +16,9 @@ Namespace WCF
<OperationContract>
Function GetJobStatus() As GetJobStatusResponse
'TODO: implement
Function RunJob() As RunJobResponse
<OperationContract>
Function UpdateJob(pData As UpdateJobRequest) As UpdateJobResponse

View File

@ -4,6 +4,7 @@ Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Messaging.WCF
Imports ECM.JobRunner.Windows.Scheduler
Imports FxResources.System
Namespace WCF
@ -55,6 +56,11 @@ Namespace WCF
Dim oMethod As New UpdateProfile.UpdateProfileMethod(LogConfig, Database, State, Scheduler)
Return oMethod.Run(pData)
End Function
Public Function RunJob() As RunJob.RunJobResponse Implements IJobRunner.RunJob
'Dim oMethod As New RunJob.RunJobMethod(LogConfig, Database, State, Scheduler)
'Return oMethod.Run(pData)
End Function
End Class
End Namespace

View File

@ -0,0 +1,31 @@
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports ECM.JobRunner.Windows.Scheduler
Imports System.Runtime.Serialization
Public Class RunJob
Public Class RunJobMethod
Inherits Base.BaseMethod
Private ReadOnly Scheduler As JobScheduler
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer, pState As State, pScheduler As JobScheduler)
MyBase.New(pLogConfig, pDatabase, pState)
Scheduler = pScheduler
End Sub
Public Async Function Run(pData As RunJobRequest) As Task(Of RunJobResponse)
Await Scheduler.ScheduleJob(pData.JobId)
Return New RunJobResponse()
End Function
End Class
Public Class RunJobRequest
Public Property JobId As Integer
End Class
Public Class RunJobResponse
Inherits Base.BaseResponse
End Class
End Class