06-12-2022

This commit is contained in:
Jonathan Jenne 2022-12-06 14:08:20 +01:00
parent c867e4e3a6
commit 248be23804
47 changed files with 1521 additions and 355 deletions

View File

@ -14,11 +14,17 @@
<wsdl:message name="IEDMIService_GetHeartbeat_OutputMessage"> <wsdl:message name="IEDMIService_GetHeartbeat_OutputMessage">
<wsdl:part name="parameters" element="tns:GetHeartbeatResponse" /> <wsdl:part name="parameters" element="tns:GetHeartbeatResponse" />
</wsdl:message> </wsdl:message>
<wsdl:message name="IEDMIService_GetJobHistory_InputMessage"> <wsdl:message name="IEDMIService_GetJobStatus_InputMessage">
<wsdl:part name="parameters" element="tns:GetJobHistory" /> <wsdl:part name="parameters" element="tns:GetJobStatus" />
</wsdl:message> </wsdl:message>
<wsdl:message name="IEDMIService_GetJobHistory_OutputMessage"> <wsdl:message name="IEDMIService_GetJobStatus_OutputMessage">
<wsdl:part name="parameters" element="tns:GetJobHistoryResponse" /> <wsdl:part name="parameters" element="tns:GetJobStatusResponse" />
</wsdl:message>
<wsdl:message name="IEDMIService_UpdateJob_InputMessage">
<wsdl:part name="parameters" element="tns:UpdateJob" />
</wsdl:message>
<wsdl:message name="IEDMIService_UpdateJob_OutputMessage">
<wsdl:part name="parameters" element="tns:UpdateJobResponse" />
</wsdl:message> </wsdl:message>
<wsdl:message name="IEDMIService_GetJobConfig_InputMessage"> <wsdl:message name="IEDMIService_GetJobConfig_InputMessage">
<wsdl:part name="parameters" element="tns:GetJobConfig" /> <wsdl:part name="parameters" element="tns:GetJobConfig" />
@ -31,9 +37,13 @@
<wsdl:input wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetHeartbeat" message="tns:IEDMIService_GetHeartbeat_InputMessage" /> <wsdl:input wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetHeartbeat" message="tns:IEDMIService_GetHeartbeat_InputMessage" />
<wsdl:output wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetHeartbeatResponse" message="tns:IEDMIService_GetHeartbeat_OutputMessage" /> <wsdl:output wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetHeartbeatResponse" message="tns:IEDMIService_GetHeartbeat_OutputMessage" />
</wsdl:operation> </wsdl:operation>
<wsdl:operation name="GetJobHistory"> <wsdl:operation name="GetJobStatus">
<wsdl:input wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetJobHistory" message="tns:IEDMIService_GetJobHistory_InputMessage" /> <wsdl:input wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetJobStatus" message="tns:IEDMIService_GetJobStatus_InputMessage" />
<wsdl:output wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetJobHistoryResponse" message="tns:IEDMIService_GetJobHistory_OutputMessage" /> <wsdl:output wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetJobStatusResponse" message="tns:IEDMIService_GetJobStatus_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="UpdateJob">
<wsdl:input wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/UpdateJob" message="tns:IEDMIService_UpdateJob_InputMessage" />
<wsdl:output wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/UpdateJobResponse" message="tns:IEDMIService_UpdateJob_OutputMessage" />
</wsdl:operation> </wsdl:operation>
<wsdl:operation name="GetJobConfig"> <wsdl:operation name="GetJobConfig">
<wsdl:input wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetJobConfig" message="tns:IEDMIService_GetJobConfig_InputMessage" /> <wsdl:input wsaw:Action="http://DigitalData.Services.EDMIService/IEDMIService/GetJobConfig" message="tns:IEDMIService_GetJobConfig_InputMessage" />

View File

@ -13,15 +13,29 @@
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
<xs:element name="GetJobHistory"> <xs:element name="GetJobStatus">
<xs:complexType> <xs:complexType>
<xs:sequence /> <xs:sequence />
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
<xs:element name="GetJobHistoryResponse"> <xs:element name="GetJobStatusResponse">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" minOccurs="0" name="GetJobHistoryResult" nillable="true" type="q1:GetJobHistory.GetJobHistoryResponse" /> <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" minOccurs="0" name="GetJobStatusResult" nillable="true" type="q1:GetJobStatus.GetJobStatusResponse" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="UpdateJob">
<xs:complexType>
<xs:sequence>
<xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" minOccurs="0" name="pData" nillable="true" type="q2:UpdateJob.UpdateJobRequest" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="UpdateJobResponse">
<xs:complexType>
<xs:sequence>
<xs:element xmlns:q3="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" minOccurs="0" name="UpdateJobResult" nillable="true" type="q3:UpdateJob.UpdateJobResponse" />
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -33,7 +47,7 @@
<xs:element name="GetJobConfigResponse"> <xs:element name="GetJobConfigResponse">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" minOccurs="0" name="GetJobConfigResult" nillable="true" type="q2:GetJobConfig.GetJobConfigResponse" /> <xs:element xmlns:q4="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" minOccurs="0" name="GetJobConfigResult" nillable="true" type="q4:GetJobConfig.GetJobConfigResponse" />
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="GetJobHistoryGetJobHistoryResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>ECM.JobRunner.Common.JobRunnerReference.GetJobHistoryGetJobHistoryResponse, Connected Services.JobRunnerReference.Reference.vb.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="GetJobStatusGetJobStatusResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>ECM.JobRunner.Common.JobRunnerReference.GetJobStatusGetJobStatusResponse, Connected Services.JobRunnerReference.Reference.vb.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="UpdateJobUpdateJobResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>ECM.JobRunner.Common.JobRunnerReference.UpdateJobUpdateJobResponse, Connected Services.JobRunnerReference.Reference.vb.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xs:complexType name="ArrayOfHistoryItem"> <xs:complexType name="ArrayOfHistoryItem">
<xs:sequence> <xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="HistoryItem" nillable="true" type="tns:HistoryItem" /> <xs:element minOccurs="0" maxOccurs="unbounded" name="HistoryItem" nillable="true" type="tns:HistoryItem" />
@ -16,12 +17,25 @@
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
<xs:element name="HistoryItem" nillable="true" type="tns:HistoryItem" /> <xs:element name="HistoryItem" nillable="true" type="tns:HistoryItem" />
<xs:complexType name="ArrayOfJobDefinition"> <xs:complexType name="ArrayOfStatusItem">
<xs:sequence> <xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="JobDefinition" nillable="true" type="tns:JobDefinition" /> <xs:element minOccurs="0" maxOccurs="unbounded" name="StatusItem" nillable="true" type="tns:StatusItem" />
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
<xs:element name="ArrayOfJobDefinition" nillable="true" type="tns:ArrayOfJobDefinition" /> <xs:element name="ArrayOfStatusItem" nillable="true" type="tns:ArrayOfStatusItem" />
<xs:complexType name="StatusItem">
<xs:sequence>
<xs:element minOccurs="0" name="CompleteTime" type="xs:dateTime" />
<xs:element minOccurs="0" name="Executing" type="xs:boolean" />
<xs:element minOccurs="0" name="ExecutionTime" type="ser:duration" />
<xs:element minOccurs="0" name="Id" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="ProgressCurrent" type="xs:int" />
<xs:element minOccurs="0" name="ProgressTotal" type="xs:int" />
<xs:element minOccurs="0" name="StartTime" type="xs:dateTime" />
</xs:sequence>
</xs:complexType>
<xs:element name="StatusItem" nillable="true" type="tns:StatusItem" />
<xs:complexType name="JobDefinition"> <xs:complexType name="JobDefinition">
<xs:sequence> <xs:sequence>
<xs:element minOccurs="0" name="Active" type="xs:boolean" /> <xs:element minOccurs="0" name="Active" type="xs:boolean" />
@ -41,6 +55,12 @@
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
<xs:element name="JobType" nillable="true" type="tns:JobType" /> <xs:element name="JobType" nillable="true" type="tns:JobType" />
<xs:complexType name="ArrayOfJobDefinition">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="JobDefinition" nillable="true" type="tns:JobDefinition" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfJobDefinition" nillable="true" type="tns:ArrayOfJobDefinition" />
<xs:complexType name="ArrayOfJobType"> <xs:complexType name="ArrayOfJobType">
<xs:sequence> <xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="JobType" nillable="true" type="tns:JobType" /> <xs:element minOccurs="0" maxOccurs="unbounded" name="JobType" nillable="true" type="tns:JobType" />

View File

@ -1,16 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" /> <xs:import namespace="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" />
<xs:complexType name="GetJobHistory.GetJobHistoryResponse"> <xs:complexType name="GetJobStatus.GetJobStatusResponse">
<xs:complexContent mixed="false"> <xs:complexContent mixed="false">
<xs:extension base="tns:Base.BaseResponse"> <xs:extension base="tns:Base.BaseResponse">
<xs:sequence> <xs:sequence>
<xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" minOccurs="0" name="Items" nillable="true" type="q1:ArrayOfHistoryItem" /> <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" minOccurs="0" name="HistoryItems" nillable="true" type="q1:ArrayOfHistoryItem" />
<xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" minOccurs="0" name="StatusItems" nillable="true" type="q2:ArrayOfStatusItem" />
</xs:sequence> </xs:sequence>
</xs:extension> </xs:extension>
</xs:complexContent> </xs:complexContent>
</xs:complexType> </xs:complexType>
<xs:element name="GetJobHistory.GetJobHistoryResponse" nillable="true" type="tns:GetJobHistory.GetJobHistoryResponse" /> <xs:element name="GetJobStatus.GetJobStatusResponse" nillable="true" type="tns:GetJobStatus.GetJobStatusResponse" />
<xs:complexType name="Base.BaseResponse"> <xs:complexType name="Base.BaseResponse">
<xs:sequence> <xs:sequence>
<xs:element minOccurs="0" name="ErrorDetails" nillable="true" type="xs:string" /> <xs:element minOccurs="0" name="ErrorDetails" nillable="true" type="xs:string" />
@ -19,12 +20,35 @@
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
<xs:element name="Base.BaseResponse" nillable="true" type="tns:Base.BaseResponse" /> <xs:element name="Base.BaseResponse" nillable="true" type="tns:Base.BaseResponse" />
<xs:complexType name="UpdateJob.UpdateJobRequest">
<xs:sequence>
<xs:element minOccurs="0" name="Action" type="tns:UpdateJob.UpdateJobRequest.UpdateJobAction" />
<xs:element xmlns:q3="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" minOccurs="0" name="Job" nillable="true" type="q3:JobDefinition" />
</xs:sequence>
</xs:complexType>
<xs:element name="UpdateJob.UpdateJobRequest" nillable="true" type="tns:UpdateJob.UpdateJobRequest" />
<xs:simpleType name="UpdateJob.UpdateJobRequest.UpdateJobAction">
<xs:restriction base="xs:string">
<xs:enumeration value="Create" />
<xs:enumeration value="Update" />
<xs:enumeration value="Delete" />
</xs:restriction>
</xs:simpleType>
<xs:element name="UpdateJob.UpdateJobRequest.UpdateJobAction" nillable="true" type="tns:UpdateJob.UpdateJobRequest.UpdateJobAction" />
<xs:complexType name="UpdateJob.UpdateJobResponse">
<xs:complexContent mixed="false">
<xs:extension base="tns:Base.BaseResponse">
<xs:sequence />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="UpdateJob.UpdateJobResponse" nillable="true" type="tns:UpdateJob.UpdateJobResponse" />
<xs:complexType name="GetJobConfig.GetJobConfigResponse"> <xs:complexType name="GetJobConfig.GetJobConfigResponse">
<xs:complexContent mixed="false"> <xs:complexContent mixed="false">
<xs:extension base="tns:Base.BaseResponse"> <xs:extension base="tns:Base.BaseResponse">
<xs:sequence> <xs:sequence>
<xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" minOccurs="0" name="JobDefinitions" nillable="true" type="q2:ArrayOfJobDefinition" /> <xs:element xmlns:q4="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" minOccurs="0" name="JobDefinitions" nillable="true" type="q4:ArrayOfJobDefinition" />
<xs:element xmlns:q3="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" minOccurs="0" name="JobTypes" nillable="true" type="q3:ArrayOfJobType" /> <xs:element xmlns:q5="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common" minOccurs="0" name="JobTypes" nillable="true" type="q5:ArrayOfJobType" />
</xs:sequence> </xs:sequence>
</xs:extension> </xs:extension>
</xs:complexContent> </xs:complexContent>

View File

@ -16,72 +16,73 @@ Imports System.Runtime.Serialization
Namespace JobRunnerReference Namespace JobRunnerReference
<System.Diagnostics.DebuggerStepThroughAttribute(), _ <System.Diagnostics.DebuggerStepThroughAttribute(),
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), _ System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"),
System.Runtime.Serialization.DataContractAttribute(Name:="Base.BaseResponse", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"), _ System.Runtime.Serialization.DataContractAttribute(Name:="Base.BaseResponse", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"),
System.SerializableAttribute(), _ System.SerializableAttribute(),
System.Runtime.Serialization.KnownTypeAttribute(GetType(JobRunnerReference.GetJobConfigGetJobConfigResponse)), _ System.Runtime.Serialization.KnownTypeAttribute(GetType(JobRunnerReference.UpdateJobUpdateJobResponse)),
System.Runtime.Serialization.KnownTypeAttribute(GetType(JobRunnerReference.GetJobHistoryGetJobHistoryResponse))> _ System.Runtime.Serialization.KnownTypeAttribute(GetType(JobRunnerReference.GetJobConfigGetJobConfigResponse)),
System.Runtime.Serialization.KnownTypeAttribute(GetType(JobRunnerReference.GetJobStatusGetJobStatusResponse))>
Partial Public Class BaseBaseResponse Partial Public Class BaseBaseResponse
Inherits Object Inherits Object
Implements System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged Implements System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
<System.NonSerializedAttribute()> _ <System.NonSerializedAttribute()>
Private extensionDataField As System.Runtime.Serialization.ExtensionDataObject Private extensionDataField As System.Runtime.Serialization.ExtensionDataObject
<System.Runtime.Serialization.OptionalFieldAttribute()> _ <System.Runtime.Serialization.OptionalFieldAttribute()>
Private ErrorDetailsField As String Private ErrorDetailsField As String
<System.Runtime.Serialization.OptionalFieldAttribute()> _ <System.Runtime.Serialization.OptionalFieldAttribute()>
Private ErrorMessageField As String Private ErrorMessageField As String
<System.Runtime.Serialization.OptionalFieldAttribute()> _ <System.Runtime.Serialization.OptionalFieldAttribute()>
Private OKField As Boolean Private OKField As Boolean
<Global.System.ComponentModel.BrowsableAttribute(false)> _ <Global.System.ComponentModel.BrowsableAttribute(False)>
Public Property ExtensionData() As System.Runtime.Serialization.ExtensionDataObject Implements System.Runtime.Serialization.IExtensibleDataObject.ExtensionData Public Property ExtensionData() As System.Runtime.Serialization.ExtensionDataObject Implements System.Runtime.Serialization.IExtensibleDataObject.ExtensionData
Get Get
Return Me.extensionDataField Return Me.extensionDataField
End Get End Get
Set Set
Me.extensionDataField = value Me.extensionDataField = Value
End Set End Set
End Property End Property
<System.Runtime.Serialization.DataMemberAttribute()> _ <System.Runtime.Serialization.DataMemberAttribute()>
Public Property ErrorDetails() As String Public Property ErrorDetails() As String
Get Get
Return Me.ErrorDetailsField Return Me.ErrorDetailsField
End Get End Get
Set Set
If (Object.ReferenceEquals(Me.ErrorDetailsField, value) <> true) Then If (Object.ReferenceEquals(Me.ErrorDetailsField, Value) <> True) Then
Me.ErrorDetailsField = value Me.ErrorDetailsField = Value
Me.RaisePropertyChanged("ErrorDetails") Me.RaisePropertyChanged("ErrorDetails")
End If End If
End Set End Set
End Property End Property
<System.Runtime.Serialization.DataMemberAttribute()> _ <System.Runtime.Serialization.DataMemberAttribute()>
Public Property ErrorMessage() As String Public Property ErrorMessage() As String
Get Get
Return Me.ErrorMessageField Return Me.ErrorMessageField
End Get End Get
Set Set
If (Object.ReferenceEquals(Me.ErrorMessageField, value) <> true) Then If (Object.ReferenceEquals(Me.ErrorMessageField, Value) <> True) Then
Me.ErrorMessageField = value Me.ErrorMessageField = Value
Me.RaisePropertyChanged("ErrorMessage") Me.RaisePropertyChanged("ErrorMessage")
End If End If
End Set End Set
End Property End Property
<System.Runtime.Serialization.DataMemberAttribute()> _ <System.Runtime.Serialization.DataMemberAttribute()>
Public Property OK() As Boolean Public Property OK() As Boolean
Get Get
Return Me.OKField Return Me.OKField
End Get End Get
Set Set
If (Me.OKField.Equals(value) <> true) Then If (Me.OKField.Equals(Value) <> True) Then
Me.OKField = value Me.OKField = Value
Me.RaisePropertyChanged("OK") Me.RaisePropertyChanged("OK")
End If End If
End Set End Set
@ -97,6 +98,14 @@ Namespace JobRunnerReference
End Sub End Sub
End Class End Class
<System.Diagnostics.DebuggerStepThroughAttribute(),
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"),
System.Runtime.Serialization.DataContractAttribute(Name:="UpdateJob.UpdateJobResponse", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"),
System.SerializableAttribute()>
Partial Public Class UpdateJobUpdateJobResponse
Inherits JobRunnerReference.BaseBaseResponse
End Class
<System.Diagnostics.DebuggerStepThroughAttribute(), <System.Diagnostics.DebuggerStepThroughAttribute(),
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"),
System.Runtime.Serialization.DataContractAttribute(Name:="GetJobConfig.GetJobConfigResponse", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"), System.Runtime.Serialization.DataContractAttribute(Name:="GetJobConfig.GetJobConfigResponse", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"),
@ -139,23 +148,39 @@ Namespace JobRunnerReference
<System.Diagnostics.DebuggerStepThroughAttribute(), <System.Diagnostics.DebuggerStepThroughAttribute(),
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"),
System.Runtime.Serialization.DataContractAttribute(Name:="GetJobHistory.GetJobHistoryResponse", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"), System.Runtime.Serialization.DataContractAttribute(Name:="GetJobStatus.GetJobStatusResponse", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"),
System.SerializableAttribute()> System.SerializableAttribute()>
Partial Public Class GetJobHistoryGetJobHistoryResponse Partial Public Class GetJobStatusGetJobStatusResponse
Inherits JobRunnerReference.BaseBaseResponse Inherits JobRunnerReference.BaseBaseResponse
<System.Runtime.Serialization.OptionalFieldAttribute()> <System.Runtime.Serialization.OptionalFieldAttribute()>
Private ItemsField() As JobRunnerReference.HistoryItem Private HistoryItemsField() As JobRunnerReference.HistoryItem
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private StatusItemsField() As JobRunnerReference.StatusItem
<System.Runtime.Serialization.DataMemberAttribute()> <System.Runtime.Serialization.DataMemberAttribute()>
Public Property Items() As JobRunnerReference.HistoryItem() Public Property HistoryItems() As JobRunnerReference.HistoryItem()
Get Get
Return Me.ItemsField Return Me.HistoryItemsField
End Get End Get
Set Set
If (Object.ReferenceEquals(Me.ItemsField, Value) <> True) Then If (Object.ReferenceEquals(Me.HistoryItemsField, Value) <> True) Then
Me.ItemsField = Value Me.HistoryItemsField = Value
Me.RaisePropertyChanged("Items") Me.RaisePropertyChanged("HistoryItems")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property StatusItems() As JobRunnerReference.StatusItem()
Get
Return Me.StatusItemsField
End Get
Set
If (Object.ReferenceEquals(Me.StatusItemsField, Value) <> True) Then
Me.StatusItemsField = Value
Me.RaisePropertyChanged("StatusItems")
End If End If
End Set End Set
End Property End Property
@ -272,6 +297,165 @@ Namespace JobRunnerReference
End Sub End Sub
End Class End Class
<System.Diagnostics.DebuggerStepThroughAttribute(),
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"),
System.Runtime.Serialization.DataContractAttribute(Name:="StatusItem", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common"),
System.SerializableAttribute()>
Partial Public Class StatusItem
Inherits Object
Implements System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
<System.NonSerializedAttribute()>
Private extensionDataField As System.Runtime.Serialization.ExtensionDataObject
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private CompleteTimeField As Date
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private ExecutingField As Boolean
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private ExecutionTimeField As System.TimeSpan
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private IdField As String
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private NameField As String
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private ProgressCurrentField As Integer
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private ProgressTotalField As Integer
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private StartTimeField As Date
<Global.System.ComponentModel.BrowsableAttribute(False)>
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 CompleteTime() As Date
Get
Return Me.CompleteTimeField
End Get
Set
If (Me.CompleteTimeField.Equals(Value) <> True) Then
Me.CompleteTimeField = Value
Me.RaisePropertyChanged("CompleteTime")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property Executing() As Boolean
Get
Return Me.ExecutingField
End Get
Set
If (Me.ExecutingField.Equals(Value) <> True) Then
Me.ExecutingField = Value
Me.RaisePropertyChanged("Executing")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property ExecutionTime() As System.TimeSpan
Get
Return Me.ExecutionTimeField
End Get
Set
If (Me.ExecutionTimeField.Equals(Value) <> True) Then
Me.ExecutionTimeField = Value
Me.RaisePropertyChanged("ExecutionTime")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property Id() As String
Get
Return Me.IdField
End Get
Set
If (Object.ReferenceEquals(Me.IdField, Value) <> True) Then
Me.IdField = Value
Me.RaisePropertyChanged("Id")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property Name() As String
Get
Return Me.NameField
End Get
Set
If (Object.ReferenceEquals(Me.NameField, Value) <> True) Then
Me.NameField = Value
Me.RaisePropertyChanged("Name")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property ProgressCurrent() As Integer
Get
Return Me.ProgressCurrentField
End Get
Set
If (Me.ProgressCurrentField.Equals(Value) <> True) Then
Me.ProgressCurrentField = Value
Me.RaisePropertyChanged("ProgressCurrent")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property ProgressTotal() As Integer
Get
Return Me.ProgressTotalField
End Get
Set
If (Me.ProgressTotalField.Equals(Value) <> True) Then
Me.ProgressTotalField = Value
Me.RaisePropertyChanged("ProgressTotal")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property StartTime() As Date
Get
Return Me.StartTimeField
End Get
Set
If (Me.StartTimeField.Equals(Value) <> True) Then
Me.StartTimeField = Value
Me.RaisePropertyChanged("StartTime")
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.Diagnostics.DebuggerStepThroughAttribute(), <System.Diagnostics.DebuggerStepThroughAttribute(),
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"),
System.Runtime.Serialization.DataContractAttribute(Name:="JobDefinition", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common"), System.Runtime.Serialization.DataContractAttribute(Name:="JobDefinition", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Common"),
@ -478,6 +662,83 @@ Namespace JobRunnerReference
End Sub End Sub
End Class End Class
<System.Diagnostics.DebuggerStepThroughAttribute(),
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"),
System.Runtime.Serialization.DataContractAttribute(Name:="UpdateJob.UpdateJobRequest", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows"),
System.SerializableAttribute()>
Partial Public Class UpdateJobUpdateJobRequest
Inherits Object
Implements System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
<System.NonSerializedAttribute()>
Private extensionDataField As System.Runtime.Serialization.ExtensionDataObject
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private ActionField As JobRunnerReference.UpdateJobUpdateJobRequest.UpdateJobAction
<System.Runtime.Serialization.OptionalFieldAttribute()>
Private JobField As JobRunnerReference.JobDefinition
<Global.System.ComponentModel.BrowsableAttribute(False)>
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 Action() As JobRunnerReference.UpdateJobUpdateJobRequest.UpdateJobAction
Get
Return Me.ActionField
End Get
Set
If (Me.ActionField.Equals(Value) <> True) Then
Me.ActionField = Value
Me.RaisePropertyChanged("Action")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()>
Public Property Job() As JobRunnerReference.JobDefinition
Get
Return Me.JobField
End Get
Set
If (Object.ReferenceEquals(Me.JobField, Value) <> True) Then
Me.JobField = Value
Me.RaisePropertyChanged("Job")
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
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"),
System.Runtime.Serialization.DataContractAttribute(Name:="UpdateJob.UpdateJobRequest.UpdateJobAction", [Namespace]:="http://schemas.datacontract.org/2004/07/ECM.JobRunner.Windows")>
Public Enum UpdateJobAction As Integer
<System.Runtime.Serialization.EnumMemberAttribute()>
Create = 0
<System.Runtime.Serialization.EnumMemberAttribute()>
Update = 1
<System.Runtime.Serialization.EnumMemberAttribute()>
Delete = 2
End Enum
End Class
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0"), <System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0"),
System.ServiceModel.ServiceContractAttribute([Namespace]:="http://DigitalData.Services.EDMIService", ConfigurationName:="JobRunnerReference.IEDMIService")> System.ServiceModel.ServiceContractAttribute([Namespace]:="http://DigitalData.Services.EDMIService", ConfigurationName:="JobRunnerReference.IEDMIService")>
Public Interface IEDMIService Public Interface IEDMIService
@ -488,11 +749,17 @@ Namespace JobRunnerReference
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/GetHeartbeat", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/GetHeartbeatResponse")> <System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/GetHeartbeat", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/GetHeartbeatResponse")>
Function GetHeartbeatAsync() As System.Threading.Tasks.Task(Of Date) Function GetHeartbeatAsync() As System.Threading.Tasks.Task(Of Date)
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobHistory", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobHistoryResponse")> <System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobStatus", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobStatusResponse")>
Function GetJobHistory() As JobRunnerReference.GetJobHistoryGetJobHistoryResponse Function GetJobStatus() As JobRunnerReference.GetJobStatusGetJobStatusResponse
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobHistory", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobHistoryResponse")> <System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobStatus", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobStatusResponse")>
Function GetJobHistoryAsync() As System.Threading.Tasks.Task(Of JobRunnerReference.GetJobHistoryGetJobHistoryResponse) Function GetJobStatusAsync() As System.Threading.Tasks.Task(Of JobRunnerReference.GetJobStatusGetJobStatusResponse)
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/UpdateJob", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/UpdateJobResponse")>
Function UpdateJob(ByVal pData As JobRunnerReference.UpdateJobUpdateJobRequest) As JobRunnerReference.UpdateJobUpdateJobResponse
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/UpdateJob", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/UpdateJobResponse")>
Function UpdateJobAsync(ByVal pData As JobRunnerReference.UpdateJobUpdateJobRequest) As System.Threading.Tasks.Task(Of JobRunnerReference.UpdateJobUpdateJobResponse)
<System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobConfig", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobConfigResponse")> <System.ServiceModel.OperationContractAttribute(Action:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobConfig", ReplyAction:="http://DigitalData.Services.EDMIService/IEDMIService/GetJobConfigResponse")>
Function GetJobConfig() As JobRunnerReference.GetJobConfigGetJobConfigResponse Function GetJobConfig() As JobRunnerReference.GetJobConfigGetJobConfigResponse
@ -501,13 +768,13 @@ Namespace JobRunnerReference
Function GetJobConfigAsync() As System.Threading.Tasks.Task(Of JobRunnerReference.GetJobConfigGetJobConfigResponse) Function GetJobConfigAsync() As System.Threading.Tasks.Task(Of JobRunnerReference.GetJobConfigGetJobConfigResponse)
End Interface End Interface
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")> _ <System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")>
Public Interface IEDMIServiceChannel Public Interface IEDMIServiceChannel
Inherits JobRunnerReference.IEDMIService, System.ServiceModel.IClientChannel Inherits JobRunnerReference.IEDMIService, System.ServiceModel.IClientChannel
End Interface End Interface
<System.Diagnostics.DebuggerStepThroughAttribute(), _ <System.Diagnostics.DebuggerStepThroughAttribute(),
System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")> _ System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")>
Partial Public Class EDMIServiceClient Partial Public Class EDMIServiceClient
Inherits System.ServiceModel.ClientBase(Of JobRunnerReference.IEDMIService) Inherits System.ServiceModel.ClientBase(Of JobRunnerReference.IEDMIService)
Implements JobRunnerReference.IEDMIService Implements JobRunnerReference.IEDMIService
@ -540,12 +807,20 @@ Namespace JobRunnerReference
Return MyBase.Channel.GetHeartbeatAsync Return MyBase.Channel.GetHeartbeatAsync
End Function End Function
Public Function GetJobHistory() As JobRunnerReference.GetJobHistoryGetJobHistoryResponse Implements JobRunnerReference.IEDMIService.GetJobHistory Public Function GetJobStatus() As JobRunnerReference.GetJobStatusGetJobStatusResponse Implements JobRunnerReference.IEDMIService.GetJobStatus
Return MyBase.Channel.GetJobHistory Return MyBase.Channel.GetJobStatus
End Function End Function
Public Function GetJobHistoryAsync() As System.Threading.Tasks.Task(Of JobRunnerReference.GetJobHistoryGetJobHistoryResponse) Implements JobRunnerReference.IEDMIService.GetJobHistoryAsync Public Function GetJobStatusAsync() As System.Threading.Tasks.Task(Of JobRunnerReference.GetJobStatusGetJobStatusResponse) Implements JobRunnerReference.IEDMIService.GetJobStatusAsync
Return MyBase.Channel.GetJobHistoryAsync Return MyBase.Channel.GetJobStatusAsync
End Function
Public Function UpdateJob(ByVal pData As JobRunnerReference.UpdateJobUpdateJobRequest) As JobRunnerReference.UpdateJobUpdateJobResponse Implements JobRunnerReference.IEDMIService.UpdateJob
Return MyBase.Channel.UpdateJob(pData)
End Function
Public Function UpdateJobAsync(ByVal pData As JobRunnerReference.UpdateJobUpdateJobRequest) As System.Threading.Tasks.Task(Of JobRunnerReference.UpdateJobUpdateJobResponse) Implements JobRunnerReference.IEDMIService.UpdateJobAsync
Return MyBase.Channel.UpdateJobAsync(pData)
End Function End Function
Public Function GetJobConfig() As JobRunnerReference.GetJobConfigGetJobConfigResponse Implements JobRunnerReference.IEDMIService.GetJobConfig Public Function GetJobConfig() As JobRunnerReference.GetJobConfigGetJobConfigResponse Implements JobRunnerReference.IEDMIService.GetJobConfig

View File

@ -50,8 +50,17 @@
<soap12:body use="literal" /> <soap12:body use="literal" />
</wsdl:output> </wsdl:output>
</wsdl:operation> </wsdl:operation>
<wsdl:operation name="GetJobHistory"> <wsdl:operation name="GetJobStatus">
<soap12:operation soapAction="http://DigitalData.Services.EDMIService/IEDMIService/GetJobHistory" style="document" /> <soap12:operation soapAction="http://DigitalData.Services.EDMIService/IEDMIService/GetJobStatus" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="UpdateJob">
<soap12:operation soapAction="http://DigitalData.Services.EDMIService/IEDMIService/UpdateJob" style="document" />
<wsdl:input> <wsdl:input>
<soap12:body use="literal" /> <soap12:body use="literal" />
</wsdl:input> </wsdl:input>

View File

@ -74,6 +74,7 @@
<Compile Include="JobConfig\JobDefinition.vb" /> <Compile Include="JobConfig\JobDefinition.vb" />
<Compile Include="JobConfig\JobType.vb" /> <Compile Include="JobConfig\JobType.vb" />
<Compile Include="JobHistory\HistoryItem.vb" /> <Compile Include="JobHistory\HistoryItem.vb" />
<Compile Include="JobStatus\StatusItem.vb" />
<Compile Include="My Project\AssemblyInfo.vb" /> <Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@ -107,7 +108,10 @@
<None Include="Connected Services\JobRunnerReference\ECM.JobRunner.Common.JobRunnerReference.GetJobConfigGetJobConfigResponse.datasource"> <None Include="Connected Services\JobRunnerReference\ECM.JobRunner.Common.JobRunnerReference.GetJobConfigGetJobConfigResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon> <DependentUpon>Reference.svcmap</DependentUpon>
</None> </None>
<None Include="Connected Services\JobRunnerReference\ECM.JobRunner.Common.JobRunnerReference.GetJobHistoryGetJobHistoryResponse.datasource"> <None Include="Connected Services\JobRunnerReference\ECM.JobRunner.Common.JobRunnerReference.GetJobStatusGetJobStatusResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</None>
<None Include="Connected Services\JobRunnerReference\ECM.JobRunner.Common.JobRunnerReference.UpdateJobUpdateJobResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon> <DependentUpon>Reference.svcmap</DependentUpon>
</None> </None>
<None Include="Connected Services\JobRunnerReference\ECM.JobRunner.Common.xsd"> <None Include="Connected Services\JobRunnerReference\ECM.JobRunner.Common.xsd">

View File

@ -0,0 +1,14 @@
Public Class StatusItem
Public Const PROGRESS_CURRENT = "__Progress_Current"
Public Const PROGRESS_TOTAL = "__Progress_Total"
Public Id As String
Public Name As String
Public ExecutionTime As TimeSpan
Public ProgressCurrent As Integer
Public ProgressTotal As Integer
Public Executing As Boolean = False
Public StartTime As Date
Public CompleteTime As Date
End Class

View File

@ -0,0 +1,89 @@
@using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data;
@inject JobService Jobs;
@if (job == null)
{
<p>Form loading..</p>
}
else
{
<EditForm Model="job" OnValidSubmit="OnValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="mb-3">
<label for="id" class="form-label">Id</label>
<input type="email" class="form-control" id="id" aria-describedby="nameHelp" @bind="job.Id" readonly="readonly">
<div id="nameHelp" class="form-text">Die Datenbank Id des Jobs.</div>
</div>
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" aria-describedby="nameHelp" @bind="job.Name">
<div id="nameHelp" class="form-text">Der Name des Jobs. Wird in der Übersicht angezeigt.</div>
</div>
<div class="mb-3">
<label for="cronExpression" class="form-label">Cron Expression</label>
<input type="text" class="form-control" id="cronExpression" @bind="job.CronSchedule" aria-describedby="cronHelp">
<div id="cronHelp" class="form-text">Die Zeitplan des Jobs. Erwartet eine <a href="https://www.quartz-scheduler.net/documentation/quartz-3.x/how-tos/crontrigger.html#examples" target="_blank">Quartz.NET Cron Expression.</a></div>
</div>
<div class="mb-3">
<label for="jobType" class="form-label">Job Typ</label>
<select class="form-select" aria-label="Job type selection" id="jobType" @bind="job.TypeId">
<option selected>Auswählen..</option>
@if (types != null)
{
@foreach (JobType type in types)
{
<option value="@type.Id">@type.Name</option>
}
}
</select>
<div id="cronHelp" class="form-text">Der Typ des Jobs.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enabled" @bind="job.Active">
<label class="form-check-label" for="enabled">Aktiv</label>
</div>
<div class="btn-group mt-3" role="group" aria-label="Basic example">
<a class="btn btn-secondary" href="jobs/@job.Id">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z" />
</svg> Back
</a>
<button type="submit" class="btn btn-primary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-save" viewBox="0 0 16 16">
<path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H9.5a1 1 0 0 0-1 1v7.293l2.646-2.647a.5.5 0 0 1 .708.708l-3.5 3.5a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L7.5 9.293V2a2 2 0 0 1 2-2H14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h2.5a.5.5 0 0 1 0 1H2z" />
</svg> Save
</button>
</div>
</EditForm>
}
@code {
[Parameter]
public int JobId { get; set; }
[Parameter]
public EventCallback<EditContext> OnValidSubmit { get; set; }
private JobDefinition? job = new();
private List<JobType>? types;
protected override async Task OnInitializedAsync()
{
types = await Jobs.GetJobTypes();
if (JobId == Constants.ENTITY_ID_NEW)
{
job = new JobDefinition() { Id = Constants.ENTITY_ID_NEW };
}
else
{
job = await Jobs.GetJob(JobId);
}
}
}

View File

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

View File

@ -0,0 +1,29 @@
@using ECM.JobRunner.Common.JobRunnerReference;
<div class="progress">
<div class="progress-bar"
role="progressbar"
style="width: @getCompletedPercent(jobStatus)%"
aria-label="Job Status in %"
aria-valuenow="@getCompletedPercent(jobStatus)"
aria-valuemin="0"
aria-valuemax="100"
></div>
</div>
@code {
[Parameter]
public StatusItem? jobStatus { get; set; }
protected float getCompletedPercent(StatusItem? entry)
{
if (entry != null && entry.ProgressCurrent > 0 && entry.ProgressTotal > 0)
{
return ((float)entry.ProgressCurrent / (float)entry.ProgressTotal) * 100;
}
else
{
return 0;
}
}
}

View File

@ -0,0 +1,7 @@
namespace ECM.JobRunner.Web
{
public class Constants
{
public const int ENTITY_ID_NEW = -1;
}
}

View File

@ -1,92 +0,0 @@
using DigitalData.Modules.Messaging.WCF;
using ECM.JobRunner.Common;
namespace ECM.JobRunner.Web.Data
{
public class ApiService
{
private readonly Channel<Common.JobRunnerReference.IEDMIServiceChannel> channelManager;
private readonly Common.JobRunnerReference.IEDMIServiceChannel channel;
private ServerAddress address;
private System.Timers.Timer pollingTimer = new();
public event EventHandler<ApiStatusResponse> DataUpdated;
public ApiService(LoggingService Logging, WcfService Wcf)
{
channel = Wcf.Channel;
pollingTimer.Elapsed += PollingTimer_Elapsed;
pollingTimer.Interval = 1000;
pollingTimer.Start();
}
protected virtual void OnDataUpdated(ApiStatusResponse e)
{
EventHandler<ApiStatusResponse> handler = DataUpdated;
if (handler != null)
{
handler(this, e);
}
}
private async void PollingTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
OnDataUpdated(await GetData());
}
public async Task<List<Common.JobRunnerReference.JobDefinition>?> GetJobList()
{
var resp = await channel.GetJobConfigAsync();
if (resp != null && resp.OK)
{
return resp.JobDefinitions.ToList();
}
else
{
return null;
}
}
public async Task<ApiStatusResponse> GetData()
{
DateTime heartbeat = await GetHeartbeat();
List<Common.JobRunnerReference.HistoryItem> jobHistory = await GetHistoryEntries();
return new ApiStatusResponse()
{
heartbeat = heartbeat,
jobHistory = jobHistory.OrderByDescending(e => e.CreatedAt).Take(10).ToList()
};
}
private async Task<DateTime> GetHeartbeat()
{
return await channel.GetHeartbeatAsync();
}
private async Task<List<Common.JobRunnerReference.HistoryItem>> GetHistoryEntries()
{
try
{
var oResponse = await channel.GetJobHistoryAsync();
if (oResponse.OK)
{
return oResponse.Items.ToList();
}
else
{
return new();
}
}
catch (Exception)
{
throw;
}
}
}
}

View File

@ -2,9 +2,10 @@
namespace ECM.JobRunner.Web.Data namespace ECM.JobRunner.Web.Data
{ {
public class ApiStatusResponse public class DashboardResponse
{ {
public DateTime heartbeat = DateTime.MinValue; public DateTime heartbeat = DateTime.MinValue;
public List<HistoryItem> jobHistory = new(); public List<HistoryItem> jobHistory = new();
public List<StatusItem> jobStatus = new();
} }
} }

View File

@ -0,0 +1,107 @@
using DigitalData.Modules.Logging;
using DigitalData.Modules.Messaging.WCF;
using ECM.JobRunner.Common;
namespace ECM.JobRunner.Web.Data
{
public class DashboardService
{
private readonly Common.JobRunnerReference.IEDMIServiceChannel channel;
private Logger logger;
private System.Timers.Timer pollingTimer = new();
public event EventHandler<DashboardResponse> DataUpdated;
public DashboardService(LoggingService Logging, WcfService Wcf)
{
logger = Logging.LogConfig.GetLogger();
channel = Wcf.Channel;
pollingTimer.Elapsed += PollingTimer_Elapsed;
pollingTimer.Interval = 1000;
pollingTimer.Start();
}
protected virtual void OnDataUpdated(DashboardResponse e)
{
EventHandler<DashboardResponse> handler = DataUpdated;
if (handler != null)
{
handler(this, e);
}
}
private async void PollingTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
OnDataUpdated(await GetData());
}
public async Task<DashboardResponse> GetData()
{
DateTime heartbeat = await GetHeartbeat();
List<Common.JobRunnerReference.HistoryItem> jobHistory = await GetHistoryItems();
List<Common.JobRunnerReference.StatusItem> jobStatus = await GetStatusItems();
return new DashboardResponse()
{
heartbeat = heartbeat,
jobHistory = jobHistory.OrderByDescending(e => e.CreatedAt).Take(10).ToList(),
jobStatus = jobStatus.OrderByDescending(e => e.StartTime).Take(10).ToList()
};
}
private async Task<DateTime> GetHeartbeat()
{
return await channel.GetHeartbeatAsync();
}
private async Task<List<Common.JobRunnerReference.HistoryItem>> GetHistoryItems()
{
try
{
var oResponse = await channel.GetJobStatusAsync();
if (oResponse.OK)
{
return oResponse.HistoryItems.ToList();
}
else
{
return new();
}
}
catch (Exception e)
{
logger.Error(e);
return new();
}
}
private async Task<List<Common.JobRunnerReference.StatusItem>> GetStatusItems()
{
try
{
var oResponse = await channel.GetJobStatusAsync();
if (oResponse.OK)
{
return oResponse.StatusItems.ToList();
}
else
{
return new();
}
}
catch (Exception e)
{
logger.Error(e);
return new();
}
}
}
}

View File

@ -0,0 +1,138 @@
using DigitalData.Modules.Logging;
using ECM.JobRunner.Common.JobRunnerReference;
using System.Threading.Channels;
namespace ECM.JobRunner.Web.Data
{
public class JobService
{
private readonly Logger logger;
private readonly Common.JobRunnerReference.IEDMIServiceChannel channel;
public JobService(LoggingService Logging, WcfService Wcf)
{
logger = Logging.LogConfig.GetLogger();
channel = Wcf.Channel;
}
public async Task<List<Common.JobRunnerReference.JobDefinition>> GetJobs()
{
var resp = await channel.GetJobConfigAsync();
if (resp != null && resp.OK)
{
return resp.JobDefinitions.ToList();
}
else
{
return new();
}
}
public async Task<List<Common.JobRunnerReference.JobType>> GetJobTypes()
{
var resp = await channel.GetJobConfigAsync();
if (resp != null && resp.OK)
{
return resp.JobTypes.ToList();
}
else
{
return new();
}
}
public async Task<Common.JobRunnerReference.JobDefinition?> GetJob(int pJobId)
{
var resp = await channel.GetJobConfigAsync();
if (resp != null && resp.OK)
{
return resp.JobDefinitions.
Where(j => j.Id == pJobId).
FirstOrDefault();
}
else
{
return null;
}
}
public async Task<bool> UpdateJob(JobDefinition job)
{
var resp = await channel.UpdateJobAsync(new UpdateJobUpdateJobRequest {
Job = job,
Action = UpdateJobUpdateJobRequest.UpdateJobAction.Update
});
if (resp != null && resp.OK)
{
return true;
}
else
{
return false;
}
}
public async Task<bool> CreateJob(JobDefinition job)
{
var resp = await channel.UpdateJobAsync(new UpdateJobUpdateJobRequest
{
Job = job,
Action = UpdateJobUpdateJobRequest.UpdateJobAction.Create
});
if (resp != null && resp.OK)
{
return true;
}
else
{
return false;
}
}
public async Task<bool> DeleteJob(JobDefinition job)
{
var resp = await channel.UpdateJobAsync(new UpdateJobUpdateJobRequest
{
Job = job,
Action = UpdateJobUpdateJobRequest.UpdateJobAction.Delete
});
if (resp != null && resp.OK)
{
return true;
}
else
{
return false;
}
}
public DateTime GetNextExecutionTime(string pCronExpression)
{
Quartz.CronExpression expression = new(pCronExpression);
if (expression != null)
{
var next = expression.GetNextValidTimeAfter(DateTimeOffset.Now);
if (next != null)
{
return ((DateTimeOffset)next).DateTime;
}
else
{
return DateTime.MinValue;
}
}
else
{
return DateTime.MinValue;
}
}
}
}

View File

@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="NLog" Version="5.1.0" /> <PackageReference Include="NLog" Version="5.1.0" />
<PackageReference Include="Quartz" Version="3.5.0" />
<PackageReference Include="System.ServiceModel.Duplex" Version="4.10.*" /> <PackageReference Include="System.ServiceModel.Duplex" Version="4.10.*" />
<PackageReference Include="System.ServiceModel.Federation" Version="4.10.*" /> <PackageReference Include="System.ServiceModel.Federation" Version="4.10.*" />
<PackageReference Include="System.ServiceModel.Http" Version="4.10.*" /> <PackageReference Include="System.ServiceModel.Http" Version="4.10.*" />

View File

@ -1,7 +1,7 @@
@page "/history" @page "/history"
@using ECM.JobRunner.Common.JobRunnerReference; @using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@inject ApiService Api @inject DashboardService Api
<PageTitle>History</PageTitle> <PageTitle>History</PageTitle>
@ -41,18 +41,18 @@ else
protected async override void OnInitialized() protected async override void OnInitialized()
{ {
ApiStatusResponse data = await Api.GetData(); DashboardResponse data = await Api.GetData();
UpdateData(data); UpdateData(data);
Api.DataUpdated += Api_DataUpdated; Api.DataUpdated += Api_DataUpdated;
} }
protected void Api_DataUpdated(object sender, ApiStatusResponse e) protected void Api_DataUpdated(object sender, DashboardResponse e)
{ {
UpdateData(e); UpdateData(e);
} }
protected void UpdateData(ApiStatusResponse response) protected void UpdateData(DashboardResponse response)
{ {
today = response.heartbeat; today = response.heartbeat;
historyEntries = response.jobHistory; historyEntries = response.jobHistory;

View File

@ -0,0 +1,28 @@
@page "/jobs/{jobId:int}/edit"
@using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data;
@using ECM.JobRunner.Web.Components.Job;
@inject NavigationManager Navigation;
@inject JobService Jobs;
<PageTitle>Job bearbeiten</PageTitle>
<h3>Job bearbeiten</h3>
<JobForm JobId="JobId" OnValidSubmit="OnFormSubmit" />
@code {
[Parameter]
public int JobId { get; set; }
private async void OnFormSubmit(EditContext ctx)
{
JobDefinition job = (JobDefinition)ctx.Model;
bool result = await Jobs.UpdateJob(job);
if (result == true)
{
Navigation.NavigateTo($"/jobs/{job.Id}");
}
}
}

View File

@ -0,0 +1,76 @@
@page "/jobs"
@using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data;
@inject JobService Jobs
<PageTitle>Jobs</PageTitle>
<h3>Jobs</h3>
@if (jobs == null)
{
<ul class="list-group">
<li class="list-group-item">Loading Jobs..</li>
</ul>
}
else
{
<div class="list-group">
@foreach (var job in jobs)
{
<a class="list-group-item list-group-item-action d-flex justify-content-between align-items-start" href="/jobs/@job.Id">
<div class="ms-2 me-auto">
<div class="fw-bold">
<span>
@if (job.Active)
{
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play-circle text-success" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M6.271 5.055a.5.5 0 0 1 .52.038l3.5 2.5a.5.5 0 0 1 0 .814l-3.5 2.5A.5.5 0 0 1 6 10.5v-5a.5.5 0 0 1 .271-.445z" />
</svg>
}
else
{
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-stop-circle text-danger" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M5 6.5A1.5 1.5 0 0 1 6.5 5h3A1.5 1.5 0 0 1 11 6.5v3A1.5 1.5 0 0 1 9.5 11h-3A1.5 1.5 0 0 1 5 9.5v-3z" />
</svg>
}
</span>
<span>@job.Name</span>
</div>
@job.Type.Name
</div>
@if (job.Active)
{
<span class="badge bg-primary rounded-pill">Running</span>
}
else
{
<span class="badge bg-danger rounded-pill">Stopped</span>
}
</a>
}
</div>
<div class="btn-group mt-3" role="group" aria-label="Basic example">
<a class="btn btn-primary" href="jobs/new">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z" />
</svg> New
</a>
</div>
}
@code {
private List<JobDefinition>? jobs;
protected async override void OnInitialized()
{
jobs = await Jobs.GetJobs();
StateHasChanged();
}
}

View File

@ -1,7 +1,10 @@
@page "/jobs/{jobId:int}" @page "/jobs/{jobId:int}"
@using ECM.JobRunner.Common.JobRunnerReference; @using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@inject ApiService Api
@inject NavigationManager Navigation;
@inject IJSRuntime JsRuntime
@inject JobService Jobs
<PageTitle>Job</PageTitle> <PageTitle>Job</PageTitle>
@ -49,7 +52,7 @@ else
<path d="M2 1.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1h-11a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1-.5-.5zm2.5.5v1a3.5 3.5 0 0 0 1.989 3.158c.533.256 1.011.791 1.011 1.491v.702c0 .7-.478 1.235-1.011 1.491A3.5 3.5 0 0 0 4.5 13v1h7v-1a3.5 3.5 0 0 0-1.989-3.158C8.978 9.586 8.5 9.052 8.5 8.351v-.702c0-.7.478-1.235 1.011-1.491A3.5 3.5 0 0 0 11.5 3V2h-7z" /> <path d="M2 1.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1h-11a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1-.5-.5zm2.5.5v1a3.5 3.5 0 0 0 1.989 3.158c.533.256 1.011.791 1.011 1.491v.702c0 .7-.478 1.235-1.011 1.491A3.5 3.5 0 0 0 4.5 13v1h7v-1a3.5 3.5 0 0 0-1.989-3.158C8.978 9.586 8.5 9.052 8.5 8.351v-.702c0-.7.478-1.235 1.011-1.491A3.5 3.5 0 0 0 11.5 3V2h-7z" />
</svg> Next Run at </svg> Next Run at
</div> </div>
@DateTime.Now.AddMinutes(5) @nextExecution
</div> </div>
</li> </li>
</ul> </ul>
@ -66,7 +69,7 @@ else
<path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z" /> <path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z" />
</svg> Edit </svg> Edit
</a> </a>
<a class="btn btn-danger"> <a class="btn btn-danger" @onclick="DeleteJob">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash3" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash3" viewBox="0 0 16 16">
<path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5ZM11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3A1.5 1.5 0 0 0 5 1.5v1H2.506a.58.58 0 0 0-.01 0H1.5a.5.5 0 0 0 0 1h.538l.853 10.66A2 2 0 0 0 4.885 16h6.23a2 2 0 0 0 1.994-1.84l.853-10.66h.538a.5.5 0 0 0 0-1h-.995a.59.59 0 0 0-.01 0H11Zm1.958 1-.846 10.58a1 1 0 0 1-.997.92h-6.23a1 1 0 0 1-.997-.92L3.042 3.5h9.916Zm-7.487 1a.5.5 0 0 1 .528.47l.5 8.5a.5.5 0 0 1-.998.06L5 5.03a.5.5 0 0 1 .47-.53Zm5.058 0a.5.5 0 0 1 .47.53l-.5 8.5a.5.5 0 1 1-.998-.06l.5-8.5a.5.5 0 0 1 .528-.47ZM8 4.5a.5.5 0 0 1 .5.5v8.5a.5.5 0 0 1-1 0V5a.5.5 0 0 1 .5-.5Z" /> <path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5ZM11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3A1.5 1.5 0 0 0 5 1.5v1H2.506a.58.58 0 0 0-.01 0H1.5a.5.5 0 0 0 0 1h.538l.853 10.66A2 2 0 0 0 4.885 16h6.23a2 2 0 0 0 1.994-1.84l.853-10.66h.538a.5.5 0 0 0 0-1h-.995a.59.59 0 0 0-.01 0H11Zm1.958 1-.846 10.58a1 1 0 0 1-.997.92h-6.23a1 1 0 0 1-.997-.92L3.042 3.5h9.916Zm-7.487 1a.5.5 0 0 1 .528.47l.5 8.5a.5.5 0 0 1-.998.06L5 5.03a.5.5 0 0 1 .47-.53Zm5.058 0a.5.5 0 0 1 .47.53l-.5 8.5a.5.5 0 1 1-.998-.06l.5-8.5a.5.5 0 0 1 .528-.47ZM8 4.5a.5.5 0 0 1 .5.5v8.5a.5.5 0 0 1-1 0V5a.5.5 0 0 1 .5-.5Z" />
</svg> Delete </svg> Delete
@ -79,15 +82,31 @@ else
public int JobId { get; set; } public int JobId { get; set; }
private JobDefinition? job; private JobDefinition? job;
private DateTime nextExecution;
protected async override void OnInitialized() protected async override void OnInitialized()
{ {
var jobs = await Api.GetJobList(); job = await Jobs.GetJob(JobId);
if (jobs != null) if (job != null)
{ {
job = jobs.Where(j => j.Id == JobId).SingleOrDefault(); nextExecution = Jobs.GetNextExecutionTime(job.CronSchedule);
StateHasChanged(); StateHasChanged();
} }
} }
protected async void DeleteJob()
{
if (job != null)
{
bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Are you sure?");
if (confirmed)
{
await Jobs.DeleteJob(job);
Navigation.NavigateTo($"/jobs");
}
}
}
} }

View File

@ -0,0 +1,28 @@
@page "/jobs/new"
@using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data;
@using ECM.JobRunner.Web.Components.Job;
@inject NavigationManager Navigation;
@inject JobService Jobs;
<PageTitle>Job erstellen</PageTitle>
<h3>Job erstellen</h3>
<JobForm JobId="JobId" OnValidSubmit="OnFormSubmit" />
@code {
public int JobId = -1;
private async void OnFormSubmit(EditContext ctx)
{
JobDefinition job = (JobDefinition)ctx.Model;
bool result = await Jobs.CreateJob(job);
if (result == true)
{
Navigation.NavigateTo($"/jobs");
}
}
}

View File

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

View File

@ -1,42 +0,0 @@
@page "/jobs"
@using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data;
@inject ApiService Api
<PageTitle>Jobs</PageTitle>
<h3>Jobs</h3>
@if (jobList == null)
{
<ul class="list-group">
<li class="list-group-item">Loading Jobs..</li>
</ul>
}
else
{
<div class="list-group">
@foreach (var job in jobList)
{
<a class="list-group-item list-group-item-action d-flex justify-content-between align-items-start" href="/jobs/@job.Id">
<div class="ms-2 me-auto">
<div class="fw-bold">
<span>@job.Name</span>
</div>
@job.Type.Name
</div>
<span class="badge bg-primary rounded-pill">Now</span>
</a>
}
</div>
}
@code {
private List<JobDefinition>? jobList;
protected async override void OnInitialized()
{
jobList = await Api.GetJobList();
StateHasChanged();
}
}

View File

@ -1,7 +0,0 @@
<PageTitle>New Job</PageTitle>
<h3>New Job</h3>
@code {
}

View File

@ -0,0 +1,135 @@
@page "/status"
@using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Components.Status;
@using ECM.JobRunner.Web.Data;
@inject DashboardService Api
<PageTitle>Status</PageTitle>
<h3 class="mb-3">Job Status</h3>
<section class="mb-5">
@if (executingEntries == null)
{
<h4>Executing</h4>
<ul class="list-group">
<li class="list-group-item">Loading Job Status..</li>
</ul>
}
else if (executingEntries.Count == 0)
{
<h4>Executing</h4>
<ul class="list-group">
<li class="list-group-item">No jobs currently executing</li>
</ul>
}
else
{
<h4>Executing (@executingEntries.Count)</h4>
<ul class="list-group">
@foreach (var entry in executingEntries)
{
<li class="list-group-item">
<div class="d-flex justify-content-between align-items-start mb-3">
<div class="ms-2 me-auto w-100">
<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">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z" />
</svg>
<span>@entry.Name</span>
</div>
</div>
<span class="badge bg-primary rounded-pill">Started @entry.StartTime.ToLongTimeString()</span>
</div>
<Progress jobStatus="entry" />
</li>
}
</ul>
}
</section>
@if (completedEntries == null)
{
<h4>Completed</h4>
<ul class="list-group">
<li class="list-group-item">Loading Job Status..</li>
</ul>
}
else if (completedEntries.Count == 0)
{
<h4>Completed</h4>
<ul class="list-group">
<li class="list-group-item">No jobs currently executing</li>
</ul>
}
else
{
<h4>Completed (@completedEntries.Count)</h4>
<ul class="list-group">
@foreach (var entry in completedEntries)
{
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto w-100">
<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">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z" />
</svg>
<span>@entry.Name</span>
</div>
<ul>
<li>Execution Time: @((int)entry.ExecutionTime.TotalSeconds)s</li>
<li>Started: @entry.StartTime.ToLongTimeString()</li>
<li>Completed: @entry.CompleteTime.ToLongTimeString()</li>
</ul>
</div>
<span class="badge bg-primary rounded-pill">Completed @entry.CompleteTime.ToLongTimeString()</span>
</li>
}
</ul>
}
@code {
private DateTime today;
private List<StatusItem>? executingEntries;
private List<StatusItem>? completedEntries;
protected async override void OnInitialized()
{
DashboardResponse data = await Api.GetData();
UpdateData(data);
Api.DataUpdated += Api_DataUpdated;
}
protected void Api_DataUpdated(object sender, DashboardResponse e)
{
UpdateData(e);
}
protected void UpdateData(DashboardResponse response)
{
today = response.heartbeat;
executingEntries = response.jobStatus.
Where(s => s.ProgressTotal > 0).
Where(s => s.Executing).
ToList();
completedEntries = response.jobStatus.
Where(s => !s.Executing).
Where(s => s.StartTime.AddMinutes(1) > DateTime.Now).
ToList();
InvokeAsync(StateHasChanged);
}
}

View File

@ -11,7 +11,8 @@ builder.Services.AddServerSideBlazor();
builder.Services.AddTransient<LoggingService>(); builder.Services.AddTransient<LoggingService>();
builder.Services.AddTransient<DatabaseService>(); builder.Services.AddTransient<DatabaseService>();
builder.Services.AddSingleton<WcfService>(); builder.Services.AddSingleton<WcfService>();
builder.Services.AddTransient<ApiService>(); builder.Services.AddTransient<DashboardService>();
builder.Services.AddTransient<JobService>();
var app = builder.Build(); var app = builder.Build();

View File

@ -24,6 +24,14 @@
</svg> Jobs </svg> Jobs
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3">
<NavLink class="nav-link" 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" />
</svg> Status
</NavLink>
</div>
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="history"> <NavLink class="nav-link" 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"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clock-history" viewBox="0 0 16 16">

View File

@ -3,8 +3,9 @@
Public Const SERVICE_DISPLAY_NAME As String = "Digital Data ECM JobRunner Service" Public Const SERVICE_DISPLAY_NAME As String = "Digital Data ECM JobRunner Service"
Public Class Scheduler Public Class Scheduler
Public Const JOB_CONFIG_LOGCONFIG = "LogConfig" Public Const JOB_CONFIG_LOGCONFIG = "__LogConfig"
Public Const JOB_CONFIG_ARGUMENTS = "Arguments" Public Const JOB_CONFIG_ARGUMENTS = "__Arguments"
Public Const JOB_CONFIG_DATABASE = "Database" Public Const JOB_CONFIG_DATABASE = "__Database"
Public Const JOB_CONFIG_STATE = "__State"
End Class End Class
End Class End Class

View File

@ -129,6 +129,7 @@
<Compile Include="Scheduler\JobListener.vb" /> <Compile Include="Scheduler\JobListener.vb" />
<Compile Include="Scheduler\JobResult.vb" /> <Compile Include="Scheduler\JobResult.vb" />
<Compile Include="Scheduler\JobScheduler.vb" /> <Compile Include="Scheduler\JobScheduler.vb" />
<Compile Include="Scheduler\JobStatus.vb" />
<Compile Include="Scheduler\Jobs\DebugJob.vb" /> <Compile Include="Scheduler\Jobs\DebugJob.vb" />
<Compile Include="Scheduler\Jobs\BaseJob.vb" /> <Compile Include="Scheduler\Jobs\BaseJob.vb" />
<Compile Include="Scheduler\Jobs\FileImportJob.vb" /> <Compile Include="Scheduler\Jobs\FileImportJob.vb" />
@ -155,7 +156,8 @@
<Compile Include="WCF\JobRunner.vb" /> <Compile Include="WCF\JobRunner.vb" />
<Compile Include="WCF\Methods\Base.vb" /> <Compile Include="WCF\Methods\Base.vb" />
<Compile Include="WCF\Methods\GetJobConfig.vb" /> <Compile Include="WCF\Methods\GetJobConfig.vb" />
<Compile Include="WCF\Methods\GetJobHistory.vb" /> <Compile Include="WCF\Methods\UpdateJob.vb" />
<Compile Include="WCF\Methods\GetJobStatus.vb" />
<Compile Include="WCF\ServiceHost.vb" /> <Compile Include="WCF\ServiceHost.vb" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,9 +1,8 @@
Imports System.Collections.Specialized Imports System.Collections.Specialized
Imports System.Threading
Imports DigitalData.Modules.Database Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports ECM.JobRunner.Common
Imports Quartz Imports Quartz
Imports Quartz.Logging.OperationName
Namespace Scheduler Namespace Scheduler
Public Class JobScheduler Public Class JobScheduler
@ -44,44 +43,7 @@ Namespace Scheduler
Await Scheduler.Start() Await Scheduler.Start()
' load job Config and setup job schedules ' load job Config and setup job schedules
ScheduleJobs()
Logger.Info("Loading [{0}] Job Definitions..", State.JobDefinitions.Count)
For Each oJob In State.JobDefinitions
Logger.Debug("Loading Job Definition [{0}]", oJob.Name)
Select Case oJob.TypeId
Case JOB_TYPE_IMPORT
Await ScheduleJob(Of Jobs.FileImportJob)(New JobConfig With {
.Name = oJob.Name,
.Enabled = True,
.Arguments = New Dictionary(Of String, String) From {
{"Name", oJob.Name}
},
.CronSchedule = oJob.CronSchedule
})
Case JOB_TYPE_INDEX
Await ScheduleJob(Of Jobs.FileIndexJob)(New JobConfig With {
.Name = oJob.Name,
.Enabled = True,
.Arguments = New Dictionary(Of String, String) From {
{"Name", oJob.Name}
},
.CronSchedule = oJob.CronSchedule
})
End Select
Next
' setup debug job
Await ScheduleJob(Of Jobs.DebugJob)(New JobConfig With {
.Name = "Debug Job",
.Enabled = True,
.Arguments = New Dictionary(Of String, String) From {{"Arg1", "My awesome argument"}},
.CronSchedule = "0 * * * * ?"
})
Return True Return True
Catch ex As Exception Catch ex As Exception
@ -91,57 +53,141 @@ Namespace Scheduler
End Try End Try
End Function End Function
Public Sub Reload()
' first reload the data from db
State.Reload()
' now reschedule jobs
ScheduleJobs()
End Sub
Public Async Function Shutdown() As Task Public Async Function Shutdown() As Task
Await Scheduler.Shutdown() Await Scheduler.Shutdown()
End Function End Function
Public Async Function ScheduleJob(Of T As IJob)(pJobConfig As JobConfig) As Task Public Async Function GetRunningJobs() As Task(Of IReadOnlyCollection(Of IJobExecutionContext))
Dim oJobName As String = pJobConfig.Name Return Await Scheduler.GetCurrentlyExecutingJobs()
Dim oTriggerName As String = $"{oJobName}-TRIGGER" End Function
pJobConfig.Name = oJobName Private Async Sub ScheduleJobs()
Dim oJobData As New JobDataMap From { Logger.Info("Loading [{0}] Job Definitions..", State.JobDefinitions.Count)
{Constants.Scheduler.JOB_CONFIG_LOGCONFIG, LogConfig},
{Constants.Scheduler.JOB_CONFIG_ARGUMENTS, pJobConfig.Arguments}, For Each oJob In State.JobDefinitions
{Constants.Scheduler.JOB_CONFIG_DATABASE, Database} 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
Next
End Sub
Private Function BuildJobConfig(Of TJob As IJob)(pJob As JobDefinition) As JobConfig
Return New JobConfig With {
.Name = pJob.Name,
.Enabled = pJob.Active,
.Arguments = New Dictionary(Of String, String) From {
{"Name", pJob.Name}
},
.CronSchedule = pJob.CronSchedule
} }
End Function
Dim oJob = JobBuilder.Create(Of T)(). Private Async Function ScheduleJob(Of T As IJob)(pJobConfig As JobConfig) As Task
WithIdentity(oJobName). If Await Scheduler.CheckExists(New JobKey(GetJobName(pJobConfig))) Then
UsingJobData(oJobData). Logger.Debug("Job already exists, rescheduling..")
Build() Await DoRescheduleJob(Of T)(pJobConfig)
Else
Logger.Debug("Job does not exist, scheduling..")
Await DoScheduleJob(Of T)(pJobConfig)
End If
End Function
Dim oTrigger = TriggerBuilder.Create(). ''' <summary>
WithIdentity(oTriggerName). ''' Updates the Trigger and Schedule for a given JobConfig
StartNow(). ''' </summary>
WithCronSchedule(pJobConfig.CronSchedule). ''' <typeparam name="T"></typeparam>
Build() ''' <param name="pJobConfig"></param>
''' <returns></returns>
Private Async Function DoRescheduleJob(Of T As IJob)(pJobConfig As JobConfig) As Task
Dim oJobKey As New JobKey(pJobConfig.Name)
Dim oTriggerKey As New TriggerKey(GetTriggerName(pJobConfig))
Dim oTrigger = BuildTrigger(pJobConfig)
Await Scheduler.RescheduleJob(oTriggerKey, oTrigger)
End Function
Private Async Function DoScheduleJob(Of T As IJob)(pJobConfig As JobConfig) As Task
Dim oJobName As String = GetJobName(pJobConfig)
Dim oTriggerName As String = GetTriggerName(pJobConfig)
Dim oJobData As JobDataMap = BuildJobData(pJobConfig)
Dim oJob As IJobDetail = BuildJob(Of T)(pJobConfig, oJobData)
Dim oTrigger As ITrigger = BuildTrigger(pJobConfig)
If pJobConfig.Enabled Then If pJobConfig.Enabled Then
Await Scheduler.ScheduleJob(oJob, oTrigger) Await Scheduler.ScheduleJob(oJob, oTrigger)
Logger.Info("Job {0} scheduled.", oJobName) Logger.Info("Job [{0}] scheduled.", oJobName)
Else Else
Logger.Info("Job {0} is disabled.", oJobName) Logger.Info("Job [{0}] is disabled.", oJobName)
End If End If
If pJobConfig.StartWithoutDelay Then If pJobConfig.StartWithoutDelay Then
Dim oDebugJob = JobBuilder.Create(Of T)(). Dim oNoDelayTrigger = TriggerBuilder.Create().
WithIdentity(oJobName & "-DEBUG"). WithIdentity(oTriggerName & "-NO-DELAY").
UsingJobData(oJobData).
Build()
Dim oDebugTrigger = TriggerBuilder.Create().
WithIdentity(oTriggerName & "-DEBUG").
StartAt(DateBuilder.FutureDate(10, IntervalUnit.Second)). StartAt(DateBuilder.FutureDate(10, IntervalUnit.Second)).
Build() Build()
Logger.Info("Job {0} will start in 10 Seconds.", oJobName) Logger.Info("Job {0} will start in 10 Seconds.", oJobName)
Await Scheduler.ScheduleJob(oDebugJob, oDebugTrigger) Await Scheduler.ScheduleJob(oJob, oNoDelayTrigger)
End If End If
End Function 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)().
WithIdentity(pJobConfig.Name).
UsingJobData(pJobData).
Build()
End Function
Private Function BuildTrigger(pJobConfig As JobConfig) As ITrigger
Dim oTriggerName As String = GetTriggerName(pJobConfig)
Return TriggerBuilder.Create().
WithIdentity(oTriggerName).
WithCronSchedule(pJobConfig.CronSchedule).
StartNow().
Build()
End Function
Private Function GetJobName(pJobConfig As JobConfig) As String
Return pJobConfig.Name
End Function
Private Function GetTriggerName(pJobConfig As JobConfig) As String
Dim oJobName As String = pJobConfig.Name
Return $"{oJobName}-TRIGGER"
End Function
End Class End Class
End Namespace End Namespace

View File

@ -0,0 +1,65 @@
Imports DigitalData.Modules.Base
Imports DigitalData.Modules.Logging
Imports ECM.JobRunner.Common
Public Class JobStatus
Inherits BaseClass
Public ReadOnly Entries As New List(Of StatusItem)
Public Sub New(pLogConfig As LogConfig)
MyBase.New(pLogConfig)
End Sub
Public Sub Start(pJob As Quartz.IJobExecutionContext)
Dim oStatus = GetJobStatus(pJob)
Logger.Info("Starting Job [{0}]", oStatus.Id)
If oStatus IsNot Nothing Then
oStatus.Name = pJob.JobDetail.Key.Name
oStatus.StartTime = Date.Now
oStatus.Executing = True
End If
End Sub
Public Sub Update(pJob As Quartz.IJobExecutionContext, pCurrent As Integer, pTotal As Integer)
Dim oStatus = GetJobStatus(pJob)
Logger.Debug("Updating Job [{0}] with Status [{1}/{2}]", oStatus.Id, pCurrent, pTotal)
If oStatus IsNot Nothing Then
oStatus.ProgressTotal = pTotal
oStatus.ProgressCurrent = pCurrent
oStatus.ExecutionTime = pJob.JobRunTime
End If
End Sub
Public Sub Complete(pJob As Quartz.IJobExecutionContext)
Dim oStatus = GetJobStatus(pJob)
Logger.Info("Completing Job [{0}]", oStatus.Id)
If oStatus IsNot Nothing Then
oStatus.ProgressCurrent = oStatus.ProgressTotal
oStatus.ExecutionTime = pJob.JobRunTime
oStatus.Executing = False
oStatus.CompleteTime = Date.Now
End If
End Sub
Private Function GetJobStatus(pJob As Quartz.IJobExecutionContext) As StatusItem
Dim oJobId = GetJobId(pJob)
Dim oExists = Entries.Where(Function(e) e.Id = oJobId).Any()
If Not oExists Then
Entries.Add(New StatusItem With {.Id = oJobId})
End If
Return Entries.Where(Function(e) e.Id = oJobId).SingleOrDefault()
End Function
Private Function GetJobId(pJob As Quartz.IJobExecutionContext) As String
Return pJob.JobDetail.Key.ToString() & pJob.FireTimeUtc.ToString("u")
End Function
End Class

View File

@ -1,5 +1,6 @@
Imports DigitalData.Modules.Database Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports ECM.JobRunner.Common
Imports Quartz Imports Quartz
Namespace Scheduler.Jobs Namespace Scheduler.Jobs
@ -7,15 +8,30 @@ Namespace Scheduler.Jobs
Friend LogConfig As LogConfig Friend LogConfig As LogConfig
Friend Logger As Logger Friend Logger As Logger
Friend Database As MSSQLServer Friend Database As MSSQLServer
Friend State As State
Private ctx As IJobExecutionContext
Public Function InitializeJob(context As IJobExecutionContext) As Dictionary(Of String, String) Public Function InitializeJob(context As IJobExecutionContext) As Dictionary(Of String, String)
ctx = context
Dim oJobData = context.MergedJobDataMap Dim oJobData = context.MergedJobDataMap
LogConfig = oJobData.Item(Constants.Scheduler.JOB_CONFIG_LOGCONFIG) LogConfig = oJobData.Item(Constants.Scheduler.JOB_CONFIG_LOGCONFIG)
Database = oJobData.Item(Constants.Scheduler.JOB_CONFIG_DATABASE) Database = oJobData.Item(Constants.Scheduler.JOB_CONFIG_DATABASE)
State = oJobData.Item(Constants.Scheduler.JOB_CONFIG_STATE)
Logger = LogConfig.GetLogger() Logger = LogConfig.GetLogger()
State.JobStatus.Start(ctx)
Return oJobData.Item(Constants.Scheduler.JOB_CONFIG_ARGUMENTS) Return oJobData.Item(Constants.Scheduler.JOB_CONFIG_ARGUMENTS)
End Function End Function
Public Sub UpdateProgress(pCurrentValue As Integer, pTotalValue As Integer)
State.JobStatus.Update(ctx, pCurrentValue, pTotalValue)
End Sub
Public Sub CompleteJob()
State.JobStatus.Complete(ctx)
End Sub
End Class End Class
End Namespace End Namespace

View File

@ -19,6 +19,7 @@ Namespace Scheduler.Jobs
context.Result = oResult context.Result = oResult
CompleteJob()
Return Task.FromResult(True) Return Task.FromResult(True)
End Function End Function
End Class End Class

View File

@ -13,12 +13,19 @@ Namespace Scheduler.Jobs
Logger.Info("Running File Import [{0}]", oName) Logger.Info("Running File Import [{0}]", oName)
Dim oMax = 100
For index = 1 To oMax
UpdateProgress(index, oMax)
Threading.Thread.Sleep(100)
Next
Dim oResult = New JobResult() With { Dim oResult = New JobResult() With {
.Description = $"File Import Job [{oName}] completed!" .Description = $"File Import Job [{oName}] completed!"
} }
context.Result = oResult context.Result = oResult
CompleteJob()
Return Task.FromResult(True) Return Task.FromResult(True)
End Function End Function
End Class End Class

View File

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

View File

@ -52,6 +52,7 @@ Public Class Service
WCF.JobRunner.State = State WCF.JobRunner.State = State
WCF.JobRunner.LogConfig = LogConfig WCF.JobRunner.LogConfig = LogConfig
WCF.JobRunner.Database = Database WCF.JobRunner.Database = Database
WCF.JobRunner.Scheduler = Scheduler
' start the service ' start the service
Dim oAddresses() As Uri = {Binding.GetAddress(Config.Host, Config.Port, Config.Name)} Dim oAddresses() As Uri = {Binding.GetAddress(Config.Host, Config.Port, Config.Name)}

View File

@ -12,6 +12,8 @@ Public Class State
Private ReadOnly Database As MSSQLServer Private ReadOnly Database As MSSQLServer
Public ReadOnly JobHistory As JobHistory Public ReadOnly JobHistory As JobHistory
Public ReadOnly JobStatus As JobStatus
Public ReadOnly Property JobTypes As New List(Of JobType) Public ReadOnly Property JobTypes As New List(Of JobType)
Public ReadOnly Property JobDefinitions As New List(Of JobDefinition) Public ReadOnly Property JobDefinitions As New List(Of JobDefinition)
@ -19,6 +21,7 @@ Public Class State
MyBase.New(pLogConfig) MyBase.New(pLogConfig)
Database = pDatabase Database = pDatabase
JobHistory = New JobHistory(pLogConfig) JobHistory = New JobHistory(pLogConfig)
JobStatus = New JobStatus(pLogConfig)
_JobTypes = GetJobTypes() _JobTypes = GetJobTypes()
_JobDefinitions = GetJobDefinitions(_JobTypes) _JobDefinitions = GetJobDefinitions(_JobTypes)
@ -68,6 +71,8 @@ Public Class State
Dim oJobs As New List(Of JobDefinition) Dim oJobs As New List(Of JobDefinition)
Try Try
Logger.Info("Loading Jobs..")
Dim oSQL As String = "SELECT * FROM TBECM_JR_JOB" Dim oSQL As String = "SELECT * FROM TBECM_JR_JOB"
Dim oTable As DataTable = Database.GetDatatable(oSQL) Dim oTable As DataTable = Database.GetDatatable(oSQL)

View File

@ -1,5 +1,8 @@
Imports System.ServiceModel Imports System.ServiceModel
Imports ECM.JobRunner.Common Imports ECM.JobRunner.Common
Imports ECM.JobRunner.Windows.UpdateJob
Imports ECM.JobRunner.Windows.GetJobStatus
Imports ECM.JobRunner.Windows.GetJobConfig
Namespace WCF Namespace WCF
<ServiceContract(Name:="IEDMIService", [Namespace]:="http://DigitalData.Services.EDMIService")> <ServiceContract(Name:="IEDMIService", [Namespace]:="http://DigitalData.Services.EDMIService")>
@ -9,10 +12,13 @@ Namespace WCF
Function GetHeartbeat() As Date Function GetHeartbeat() As Date
<OperationContract> <OperationContract>
Function GetJobHistory() As GetJobHistory.GetJobHistoryResponse Function GetJobStatus() As GetJobStatusResponse
<OperationContract> <OperationContract>
Function GetJobConfig() As GetJobConfig.GetJobConfigResponse Function UpdateJob(pData As UpdateJobRequest) As UpdateJobResponse
<OperationContract>
Function GetJobConfig() As GetJobConfigResponse
End Interface End Interface
End Namespace End Namespace

View File

@ -3,7 +3,7 @@ Imports System.ServiceModel.Description
Imports DigitalData.Modules.Database Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Messaging.WCF Imports DigitalData.Modules.Messaging.WCF
Imports ECM.JobRunner.Common Imports ECM.JobRunner.Windows.Scheduler
Namespace WCF Namespace WCF
@ -13,6 +13,7 @@ Namespace WCF
Public Shared State As State Public Shared State As State
Public Shared LogConfig As LogConfig Public Shared LogConfig As LogConfig
Public Shared Database As MSSQLServer Public Shared Database As MSSQLServer
Public Shared Scheduler As JobScheduler
''' <summary> ''' <summary>
''' See: https://stackoverflow.com/questions/42327988/addserviceendpoint-throws-key-is-null ''' See: https://stackoverflow.com/questions/42327988/addserviceendpoint-throws-key-is-null
@ -35,8 +36,8 @@ Namespace WCF
Return Now Return Now
End Function End Function
Public Function GetJobHistory() As GetJobHistory.GetJobHistoryResponse Implements IJobRunner.GetJobHistory Public Function GetJobHistory() As GetJobStatus.GetJobStatusResponse Implements IJobRunner.GetJobStatus
Dim oMethod As New GetJobHistory.GetJobHistoryMethod(LogConfig, Database, State) Dim oMethod As New GetJobStatus.GetJobStatusMethod(LogConfig, Database, State, Scheduler)
Return oMethod.Run() Return oMethod.Run()
End Function End Function
@ -44,6 +45,11 @@ Namespace WCF
Dim oMethod As New GetJobConfig.GetJobConfigMethod(LogConfig, Database, State) Dim oMethod As New GetJobConfig.GetJobConfigMethod(LogConfig, Database, State)
Return oMethod.Run() Return oMethod.Run()
End Function End Function
Public Function UpdateJob(pData As UpdateJob.UpdateJobRequest) As UpdateJob.UpdateJobResponse Implements IJobRunner.UpdateJob
Dim oMethod As New UpdateJob.UpdateJobMethod(LogConfig, Database, State, Scheduler)
Return oMethod.Run(pData)
End Function
End Class End Class
End Namespace End Namespace

View File

@ -18,8 +18,6 @@ Public Class GetJobConfig
.JobDefinitions = State.JobDefinitions .JobDefinitions = State.JobDefinitions
} }
End Function End Function
End Class End Class
Public Class GetJobConfigResponse Public Class GetJobConfigResponse

View File

@ -1,25 +0,0 @@
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports ECM.JobRunner.Common
Imports System.Runtime.Serialization
Public Class GetJobHistory
Public Class GetJobHistoryMethod
Inherits Base.BaseMethod
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer, pState As State)
MyBase.New(pLogConfig, pDatabase, pState)
End Sub
Public Function Run() As GetJobHistoryResponse
Return New GetJobHistoryResponse With {.Items = State.JobHistory.Entries}
End Function
End Class
Public Class GetJobHistoryResponse
Inherits Base.BaseResponse
<DataMember>
Public Property Items As List(Of HistoryItem)
End Class
End Class

View File

@ -0,0 +1,37 @@
Imports System.Collections.ObjectModel
Imports System.Runtime.Serialization
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports ECM.JobRunner.Common
Imports ECM.JobRunner.Windows.Scheduler
Public Class GetJobStatus
Public Class GetJobStatusMethod
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 Function Run() As GetJobStatusResponse
Return New GetJobStatusResponse With {
.HistoryItems = State.JobHistory.Entries,
.StatusItems = State.JobStatus.Entries
}
End Function
End Class
Public Class GetJobStatusResponse
Inherits Base.BaseResponse
<DataMember>
Public Property HistoryItems As List(Of HistoryItem)
<DataMember>
Public Property StatusItems As List(Of StatusItem)
End Class
End Class

View File

@ -0,0 +1,93 @@
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports ECM.JobRunner.Common
Imports ECM.JobRunner.Windows.Scheduler
Public Class UpdateJob
Public Class UpdateJobMethod
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 Function Run(pData As UpdateJobRequest) As UpdateJobResponse
Dim oResponse As Boolean = False
Select Case pData.Action
Case UpdateJobRequest.UpdateJobAction.Update
oResponse = DoUpdateJob(pData)
Case UpdateJobRequest.UpdateJobAction.Create
oResponse = DoCreateJob(pData)
Case UpdateJobRequest.UpdateJobAction.Delete
oResponse = DoDeleteJob(pData)
End Select
If oResponse Then
Scheduler.Reload()
End If
Return New UpdateJobResponse With {.OK = oResponse}
End Function
Private Function DoUpdateJob(pData As UpdateJobRequest) As Boolean
Dim oJob = pData.Job
Dim oSQL As String = "UPDATE TBECM_JR_JOB SET TITLE = @TITLE, QUARTZ_DEF = @CRON, JOB_TYPE_ID = @TYPE_ID, ACTIVE = @ACTIVE WHERE GUID = @GUID"
Dim oCommand As New SqlClient.SqlCommand(oSQL)
oCommand.Parameters.Add("TITLE", SqlDbType.NVarChar, 250).Value = oJob.Name
oCommand.Parameters.Add("CRON", SqlDbType.NVarChar, 250).Value = oJob.CronSchedule
oCommand.Parameters.Add("TYPE_ID", SqlDbType.Int).Value = oJob.TypeId
oCommand.Parameters.Add("ACTIVE", SqlDbType.Bit).Value = oJob.Active
oCommand.Parameters.Add("GUID", SqlDbType.Int).Value = oJob.Id
Return Database.ExecuteNonQuery(oCommand)
End Function
Private Function DoCreateJob(pData As UpdateJobRequest) As Boolean
Dim oJob = pData.Job
Dim oSQL As String = "INSERT INTO TBECM_JR_JOB (TITLE, QUARTZ_DEF, JOB_TYPE_ID, ACTIVE) VALUES (@TITLE, @CRON, @TYPE_ID, @ACTIVE)"
Dim oCommand As New SqlClient.SqlCommand(oSQL)
oCommand.Parameters.Add("TITLE", SqlDbType.NVarChar, 250).Value = oJob.Name
oCommand.Parameters.Add("CRON", SqlDbType.NVarChar, 250).Value = oJob.CronSchedule
oCommand.Parameters.Add("TYPE_ID", SqlDbType.Int).Value = oJob.TypeId
oCommand.Parameters.Add("ACTIVE", SqlDbType.Bit).Value = oJob.Active
Return Database.ExecuteNonQuery(oCommand)
End Function
Private Function DoDeleteJob(pData As UpdateJobRequest) As Boolean
Dim oJob = pData.Job
Dim oSQL As String = "DELETE FROM TBECM_JR_JOB WHERE GUID = @GUID"
Dim oCommand As New SqlClient.SqlCommand(oSQL)
oCommand.Parameters.Add("GUID", SqlDbType.Int).Value = oJob.Id
Return Database.ExecuteNonQuery(oCommand)
End Function
End Class
Public Class UpdateJobRequest
Public Enum UpdateJobAction
Create
Update
Delete
End Enum
Public Action As UpdateJobAction
Public Job As JobRunnerReference.JobDefinition
End Class
Public Class UpdateJobResponse
Inherits Base.BaseResponse
End Class
End Class