diff --git a/Directory.Packages.props b/Directory.Packages.props
index eee086797..f09712445 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -4,51 +4,53 @@
true
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/src/Dapr.Extensions.Configuration/DaprConfigurationStoreProvider.cs b/src/Dapr.Extensions.Configuration/DaprConfigurationStoreProvider.cs
index b5f2900d8..3e859b8d0 100644
--- a/src/Dapr.Extensions.Configuration/DaprConfigurationStoreProvider.cs
+++ b/src/Dapr.Extensions.Configuration/DaprConfigurationStoreProvider.cs
@@ -89,7 +89,7 @@ private async Task LoadAsync()
var subscribeConfigurationResponse = await daprClient.SubscribeConfiguration(store, keys, metadata, cts.Token);
await foreach (var items in subscribeConfigurationResponse.Source.WithCancellation(cts.Token))
{
- var data = new Dictionary(Data, StringComparer.OrdinalIgnoreCase);
+ var data = new Dictionary(Data, StringComparer.OrdinalIgnoreCase);
foreach (var item in items)
{
id = subscribeConfigurationResponse.Id;
@@ -121,4 +121,4 @@ private async Task LoadAsync()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationProvider.cs b/src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationProvider.cs
index b2d4dc417..31aa5b1fc 100644
--- a/src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationProvider.cs
+++ b/src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationProvider.cs
@@ -189,7 +189,7 @@ private string NormalizeKey(string key)
private async Task LoadAsync()
{
- var data = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
+ var data = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
// Wait for the Dapr Sidecar to report healthy before attempting to fetch secrets.
using (var tokenSource = new CancellationTokenSource(sidecarWaitTimeout))
@@ -259,4 +259,4 @@ private async Task LoadAsync()
Data = data;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Dapr.Jobs/DaprJobsClient.cs b/src/Dapr.Jobs/DaprJobsClient.cs
index 2aecf816a..c30c34ba3 100644
--- a/src/Dapr.Jobs/DaprJobsClient.cs
+++ b/src/Dapr.Jobs/DaprJobsClient.cs
@@ -70,12 +70,15 @@ public abstract class DaprJobsClient(Autogenerated.DaprClient client, HttpClient
/// The optional point-in-time from which the job schedule should start.
/// The optional number of times the job should be triggered.
/// Represents when the job should expire. If both this and DueTime are set, TTL needs to represent a later point in time.
+ /// A flag indicating whether the job should be overwritten when submitted (true); otherwise false to require
+ /// to require that an existing job with the same name be deleted first.
+ /// The characteristics of the policy to apply when a job fails to trigger.
/// Cancellation token.
[Obsolete(
"The API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")]
public abstract Task ScheduleJobAsync(string jobName, DaprJobSchedule schedule,
ReadOnlyMemory? payload = null, DateTimeOffset? startingFrom = null, int? repeats = null,
- DateTimeOffset? ttl = null,
+ DateTimeOffset? ttl = null, bool overwrite = false, IJobFailurePolicyOptions? failurePolicyOptions = null,
CancellationToken cancellationToken = default);
///
diff --git a/src/Dapr.Jobs/DaprJobsGrpcClient.cs b/src/Dapr.Jobs/DaprJobsGrpcClient.cs
index 182db48cf..31811ee82 100644
--- a/src/Dapr.Jobs/DaprJobsGrpcClient.cs
+++ b/src/Dapr.Jobs/DaprJobsGrpcClient.cs
@@ -35,17 +35,19 @@ internal sealed class DaprJobsGrpcClient(Autogenerated.Dapr.DaprClient client, H
/// The optional point-in-time from which the job schedule should start.
/// The optional number of times the job should be triggered.
/// Represents when the job should expire. If both this and DueTime are set, TTL needs to represent a later point in time.
+ /// A flag indicating whether the job should be overwritten when submitted (true); otherwise false to require that an existing job with the same name be deleted first.
+ /// The characteristics of the policy to apply when a job fails to trigger.
/// Cancellation token.
[Obsolete("The API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")]
public override async Task ScheduleJobAsync(string jobName, DaprJobSchedule schedule,
ReadOnlyMemory? payload = null, DateTimeOffset? startingFrom = null, int? repeats = null,
- DateTimeOffset? ttl = null,
+ DateTimeOffset? ttl = null, bool overwrite = false, IJobFailurePolicyOptions? failurePolicyOptions = null,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(jobName, nameof(jobName));
ArgumentNullException.ThrowIfNull(schedule, nameof(schedule));
- var job = new Autogenerated.Job { Name = jobName };
+ var job = new Autogenerated.Job { Name = jobName, Overwrite = overwrite };
//Set up the schedule (recurring or point in time)
if (schedule.IsPointInTimeExpression)
@@ -88,6 +90,43 @@ public override async Task ScheduleJobAsync(string jobName, DaprJobSchedule sche
job.Ttl = ((DateTimeOffset)ttl).ToString("O");
}
+ if (failurePolicyOptions is not null)
+ {
+ switch (failurePolicyOptions.Policy)
+ {
+ case JobFailurePolicy.Drop:
+ job.FailurePolicy = new Autogenerated.JobFailurePolicy
+ {
+ Drop = new Autogenerated.JobFailurePolicyDrop()
+ };
+ break;
+ case JobFailurePolicy.Constant:
+ var constantOptions = (JobFailurePolicyConstantOptions)failurePolicyOptions;
+ if (constantOptions.MaxRetries is null)
+ {
+ job.FailurePolicy = new Autogenerated.JobFailurePolicy
+ {
+ Constant = new Autogenerated.JobFailurePolicyConstant
+ {
+ Interval = constantOptions.Interval.ToDuration()
+ }
+ };
+ }
+ else
+ {
+ job.FailurePolicy = new Autogenerated.JobFailurePolicy
+ {
+ Constant = new Autogenerated.JobFailurePolicyConstant
+ {
+ Interval = constantOptions.Interval.ToDuration(),
+ MaxRetries = (uint)constantOptions.MaxRetries
+ }
+ };
+ }
+ break;
+ }
+ }
+
var envelope = new Autogenerated.ScheduleJobRequest { Job = job };
var grpcCallOptions = DaprClientUtilities.ConfigureGrpcCallOptions(typeof(DaprJobsClient).Assembly, this.DaprApiToken, cancellationToken);
diff --git a/src/Dapr.Jobs/Extensions/DaprSerializationExtensions.cs b/src/Dapr.Jobs/Extensions/DaprSerializationExtensions.cs
index 0a612e3a9..2fd278002 100644
--- a/src/Dapr.Jobs/Extensions/DaprSerializationExtensions.cs
+++ b/src/Dapr.Jobs/Extensions/DaprSerializationExtensions.cs
@@ -38,10 +38,14 @@ public static class DaprJobsSerializationExtensions
/// The optional number of times the job should be triggered.
/// Optional JSON serialization options.
/// Represents when the job should expire. If both this and DueTime are set, TTL needs to represent a later point in time.
+ /// A flag indicating whether the job should be overwritten when submitted (true); otherwise false to require that an existing job with the same name be deleted first.
+ /// The characteristics of the policy to apply when a job fails to trigger.
/// Cancellation token.
[Obsolete("The API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")]
public static async Task ScheduleJobWithPayloadAsync(this DaprJobsClient client, string jobName, DaprJobSchedule schedule,
- object payload, DateTime? startingFrom = null, int? repeats = null, JsonSerializerOptions? jsonSerializerOptions = null, DateTimeOffset? ttl = null,
+ object payload, DateTime? startingFrom = null, int? repeats = null,
+ JsonSerializerOptions? jsonSerializerOptions = null, DateTimeOffset? ttl = null,
+ bool overwrite = false, IJobFailurePolicyOptions? failurePolicyOptions = null,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(payload, nameof(payload));
@@ -50,7 +54,8 @@ public static async Task ScheduleJobWithPayloadAsync(this DaprJobsClient client,
var payloadBytes =
JsonSerializer.SerializeToUtf8Bytes(payload, serializerOptions);
- await client.ScheduleJobAsync(jobName, schedule, payloadBytes, startingFrom, repeats, ttl, cancellationToken);
+ await client.ScheduleJobAsync(jobName, schedule, payloadBytes, startingFrom, repeats, ttl, overwrite,
+ failurePolicyOptions, cancellationToken);
}
///
@@ -63,16 +68,20 @@ public static async Task ScheduleJobWithPayloadAsync(this DaprJobsClient client,
/// The optional point-in-time from which the job schedule should start.
/// The optional number of times the job should be triggered.
/// Represents when the job should expire. If both this and DueTime are set, TTL needs to represent a later point in time.
+ /// A flag indicating whether the job should be overwritten when submitted (true); otherwise false to require that an existing job with the same name be deleted first.
+ /// The characteristics of the policy to apply when a job fails to trigger.
/// Cancellation token.
[Obsolete("The API is currently not stable as it is in the Alpha stage. This attribute will be removed once it is stable.")]
public static async Task ScheduleJobWithPayloadAsync(this DaprJobsClient client, string jobName, DaprJobSchedule schedule,
string payload, DateTime? startingFrom = null, int? repeats = null, DateTimeOffset? ttl = null,
+ bool overwrite = false, IJobFailurePolicyOptions? failurePolicyOptions = null,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(payload, nameof(payload));
var payloadBytes = Encoding.UTF8.GetBytes(payload);
- await client.ScheduleJobAsync(jobName, schedule, payloadBytes, startingFrom, repeats, ttl, cancellationToken);
+ await client.ScheduleJobAsync(jobName, schedule, payloadBytes, startingFrom, repeats, ttl, overwrite,
+ failurePolicyOptions, cancellationToken);
}
}
diff --git a/src/Dapr.Jobs/Models/DaprJobSchedule.cs b/src/Dapr.Jobs/Models/DaprJobSchedule.cs
index f897bd6b3..06663b11d 100644
--- a/src/Dapr.Jobs/Models/DaprJobSchedule.cs
+++ b/src/Dapr.Jobs/Models/DaprJobSchedule.cs
@@ -71,13 +71,7 @@ public static DaprJobSchedule FromCronExpression(CronExpressionBuilder builder)
/// Specifies a schedule using a Cron-like expression or '@' prefixed period strings.
///
/// The systemd Cron-like expression indicating when the job should be triggered.
- public static DaprJobSchedule FromExpression(string expression)
- {
-#if NET6_0
- ArgumentNullException.ThrowIfNull(expression, nameof(expression));
-#endif
- return new DaprJobSchedule(expression);
- }
+ public static DaprJobSchedule FromExpression(string expression) => new(expression);
///
/// Specifies a schedule using a duration interval articulated via a .
diff --git a/src/Dapr.Jobs/Models/IJobFailurePolicyOptions.cs b/src/Dapr.Jobs/Models/IJobFailurePolicyOptions.cs
new file mode 100644
index 000000000..5f45b0f09
--- /dev/null
+++ b/src/Dapr.Jobs/Models/IJobFailurePolicyOptions.cs
@@ -0,0 +1,25 @@
+// ------------------------------------------------------------------------
+// Copyright 2025 The Dapr Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ------------------------------------------------------------------------
+
+namespace Dapr.Jobs.Models;
+
+///
+/// Interface for specifying job failure policy options.
+///
+public interface IJobFailurePolicyOptions
+{
+ ///
+ /// The type of policy to apply.
+ ///
+ public JobFailurePolicy Policy { get; }
+}
diff --git a/src/Dapr.Jobs/Models/JobFailurePolicy.cs b/src/Dapr.Jobs/Models/JobFailurePolicy.cs
new file mode 100644
index 000000000..fff575c01
--- /dev/null
+++ b/src/Dapr.Jobs/Models/JobFailurePolicy.cs
@@ -0,0 +1,29 @@
+// ------------------------------------------------------------------------
+// Copyright 2025 The Dapr Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ------------------------------------------------------------------------
+
+namespace Dapr.Jobs.Models;
+
+///
+/// Specifies the policy the apply when a job fails to trigger.
+///
+public enum JobFailurePolicy
+{
+ ///
+ /// Drops the job tick with the job fails to trigger.
+ ///
+ Drop,
+ ///
+ /// Retries the job at a consistent interval when the job fails to trigger.
+ ///
+ Constant
+}
diff --git a/src/Dapr.Jobs/Models/JobFailurePolicyConstantOptions.cs b/src/Dapr.Jobs/Models/JobFailurePolicyConstantOptions.cs
new file mode 100644
index 000000000..df0b33aea
--- /dev/null
+++ b/src/Dapr.Jobs/Models/JobFailurePolicyConstantOptions.cs
@@ -0,0 +1,33 @@
+// ------------------------------------------------------------------------
+// Copyright 2025 The Dapr Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ------------------------------------------------------------------------
+
+namespace Dapr.Jobs.Models;
+
+///
+/// A policy which retries the job at a consistent interval when the job
+/// fails to trigger.
+///
+/// The constant delay to wait before trying the job.
+public sealed record JobFailurePolicyConstantOptions(TimeSpan Interval) : IJobFailurePolicyOptions
+{
+ ///
+ /// An optional maximum number of retries to attempt before giving up. If unset,
+ /// the Job will be retried indefinitely.
+ ///
+ public uint? MaxRetries { get; init; } = null;
+
+ ///
+ /// The type of policy to apply.
+ ///
+ public JobFailurePolicy Policy => JobFailurePolicy.Constant;
+}
diff --git a/src/Dapr.Jobs/Models/JobFailurePolicyDropOptions.cs b/src/Dapr.Jobs/Models/JobFailurePolicyDropOptions.cs
new file mode 100644
index 000000000..562c09c85
--- /dev/null
+++ b/src/Dapr.Jobs/Models/JobFailurePolicyDropOptions.cs
@@ -0,0 +1,25 @@
+// ------------------------------------------------------------------------
+// Copyright 2025 The Dapr Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ------------------------------------------------------------------------
+
+namespace Dapr.Jobs.Models;
+
+///
+/// A policy which drops the job tick when the job fails to trigger.
+///
+public sealed record JobFailurePolicyDropOptions : IJobFailurePolicyOptions
+{
+ ///
+ /// The type of policy to apply.
+ ///
+ public JobFailurePolicy Policy => JobFailurePolicy.Drop;
+}
diff --git a/src/Dapr.Jobs/Models/Responses/DaprJobDetails.cs b/src/Dapr.Jobs/Models/Responses/DaprJobDetails.cs
index 1e53d95e0..77911c7b6 100644
--- a/src/Dapr.Jobs/Models/Responses/DaprJobDetails.cs
+++ b/src/Dapr.Jobs/Models/Responses/DaprJobDetails.cs
@@ -42,4 +42,15 @@ public sealed record DaprJobDetails(DaprJobSchedule Schedule)
/// Stores the main payload of the job which is passed to the trigger function.
///
public byte[]? Payload { get; init; } = null;
+
+ ///
+ /// True if the job should be overwritten when submitted; false to require an existing job with the same name
+ /// to be deleted first.
+ ///
+ public bool Overwrite { get; init; } = false;
+
+ ///
+ /// Defines the characteristics of the policy to apply when a job fails to trigger.
+ ///
+ public JobFailurePolicy? FailurePolicy { get; init; }
}
diff --git a/src/Dapr.Protos/Protos/dapr/proto/common/v1/common.proto b/src/Dapr.Protos/Protos/dapr/proto/common/v1/common.proto
index fc5e99835..c46ad4db7 100644
--- a/src/Dapr.Protos/Protos/dapr/proto/common/v1/common.proto
+++ b/src/Dapr.Protos/Protos/dapr/proto/common/v1/common.proto
@@ -16,6 +16,7 @@ syntax = "proto3";
package dapr.proto.common.v1;
import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
option csharp_namespace = "Dapr.Client.Autogen.Grpc.v1";
option java_outer_classname = "CommonProtos";
@@ -24,10 +25,10 @@ option go_package = "github.com/dapr/dapr/pkg/proto/common/v1;common";
// HTTPExtension includes HTTP verb and querystring
// when Dapr runtime delivers HTTP content.
-//
+//
// For example, when callers calls http invoke api
// `POST http://localhost:3500/v1.0/invoke//method/?query1=value1&query2=value2`
-//
+//
// Dapr runtime will parse POST as a verb and extract querystring to quersytring map.
message HTTPExtension {
// Type of HTTP 1.1 Methods
@@ -158,3 +159,26 @@ message ConfigurationItem {
// the metadata which will be passed to/from configuration store component.
map metadata = 3;
}
+
+// JobFailurePolicy defines the policy to apply when a job fails to trigger.
+message JobFailurePolicy {
+ // policy is the policy to apply when a job fails to trigger.
+ oneof policy {
+ JobFailurePolicyDrop drop = 1;
+ JobFailurePolicyConstant constant = 2;
+ }
+}
+
+// JobFailurePolicyDrop is a policy which drops the job tick when the job fails to trigger.
+message JobFailurePolicyDrop {}
+
+// JobFailurePolicyConstant is a policy which retries the job at a consistent interval when the job fails to trigger.
+message JobFailurePolicyConstant {
+ // interval is the constant delay to wait before retrying the job.
+ google.protobuf.Duration interval = 1;
+
+ // max_retries is the optional maximum number of retries to attempt before giving up.
+ // If unset, the Job will be retried indefinitely.
+ optional uint32 max_retries = 2;
+}
+
diff --git a/src/Dapr.Protos/Protos/dapr/proto/runtime/v1/dapr.proto b/src/Dapr.Protos/Protos/dapr/proto/runtime/v1/dapr.proto
index 0ae51d6b7..a0a7b124a 100644
--- a/src/Dapr.Protos/Protos/dapr/proto/runtime/v1/dapr.proto
+++ b/src/Dapr.Protos/Protos/dapr/proto/runtime/v1/dapr.proto
@@ -694,7 +694,14 @@ message GetMetadataResponse {
string runtime_version = 8 [json_name = "runtimeVersion"];
repeated string enabled_features = 9 [json_name = "enabledFeatures"];
ActorRuntime actor_runtime = 10 [json_name = "actorRuntime"];
- //TODO: Cassie: probably add scheduler runtime status
+ optional MetadataScheduler scheduler = 11 [json_name = "scheduler"];
+}
+
+// MetadataScheduler is a message that contains the list of addresses of the
+// scheduler connections.
+message MetadataScheduler {
+ // connected_addresses the list of addresses of the scheduler connections.
+ repeated string connected_addresses = 1;
}
message ActorRuntime {
@@ -1258,6 +1265,12 @@ message Job {
// payload is the serialized job payload that will be sent to the recipient
// when the job is triggered.
google.protobuf.Any data = 6 [json_name = "data"];
+
+ // If true, allows this job to overwrite an existing job with the same name.
+ bool overwrite = 7 [json_name = "overwrite"];
+
+ // failure_policy is the optional policy for handling job failures.
+ optional common.v1.JobFailurePolicy failure_policy = 8 [json_name = "failurePolicy"];
}
// ScheduleJobRequest is the message to create/schedule the job.
@@ -1344,4 +1357,4 @@ message ConversationResponse {
// An array of results.
repeated ConversationResult outputs = 2;
-}
\ No newline at end of file
+}
diff --git a/test/Dapr.Client.Test/StateApiTest.cs b/test/Dapr.Client.Test/StateApiTest.cs
index 7fcc44a49..5e9b5e240 100644
--- a/test/Dapr.Client.Test/StateApiTest.cs
+++ b/test/Dapr.Client.Test/StateApiTest.cs
@@ -334,15 +334,15 @@ await daprClient.SaveBulkStateAsync("testStore",
envelope.States[0].Key.ShouldBe("testKey1");
envelope.States[0].Value.ShouldBe(ByteString.CopyFromUtf8(JsonSerializer.Serialize("testValue1")));
- envelope.States[0].Metadata.ShouldContainKey("partitionKey1");
+ ((IDictionary)envelope.States[0].Metadata).ShouldContainKey("partitionKey1");
envelope.States[1].Key.ShouldBe("testKey2");
envelope.States[1].Value.ShouldBe(ByteString.CopyFromUtf8(JsonSerializer.Serialize("testValue2")));
- envelope.States[1].Metadata.ShouldContainKey("partitionKey2");
+ ((IDictionary)envelope.States[1].Metadata).ShouldContainKey("partitionKey2");
envelope.States[2].Key.ShouldBe("testKey3");
envelope.States[2].Value.ShouldBe(ByteString.CopyFromUtf8(JsonSerializer.Serialize("testValue3")));
- envelope.States[2].Metadata.ShouldContainKey("partitionKey3");
+ ((IDictionary)envelope.States[2].Metadata).ShouldContainKey("partitionKey3");
}
[Fact]
@@ -1004,7 +1004,7 @@ public async Task DeleteBulkStateAsync_ValidateRequest()
envelope.StoreName.ShouldBe("testStore");
envelope.States.Count.ShouldBe(1);
envelope.States[0].Key.ShouldBe(key);
- envelope.States[0].Metadata.ShouldContainKey("partitionKey");
+ ((IDictionary)envelope.States[0].Metadata).ShouldContainKey("partitionKey");
}
[Fact]
diff --git a/test/Dapr.Jobs.Test/CronExpressionBuilderTests.cs b/test/Dapr.Jobs.Test/CronExpressionBuilderTests.cs
index 38031e0eb..117e5852f 100644
--- a/test/Dapr.Jobs.Test/CronExpressionBuilderTests.cs
+++ b/test/Dapr.Jobs.Test/CronExpressionBuilderTests.cs
@@ -12,7 +12,6 @@
// ------------------------------------------------------------------------
using System;
-using Xunit;
using ArgumentException = System.ArgumentException;
namespace Dapr.Jobs.Test;
diff --git a/test/Dapr.Jobs.Test/DaprJobsClientBuilderTests.cs b/test/Dapr.Jobs.Test/DaprJobsClientBuilderTests.cs
index bdfa2d8d2..1b299a587 100644
--- a/test/Dapr.Jobs.Test/DaprJobsClientBuilderTests.cs
+++ b/test/Dapr.Jobs.Test/DaprJobsClientBuilderTests.cs
@@ -14,7 +14,6 @@
using System;
using System.Text.Json;
using Grpc.Net.Client;
-using Xunit;
namespace Dapr.Jobs.Test;
diff --git a/test/Dapr.Jobs.Test/DaprJobsGrpcClientTests.cs b/test/Dapr.Jobs.Test/DaprJobsGrpcClientTests.cs
index 4f6168830..0e04d1307 100644
--- a/test/Dapr.Jobs.Test/DaprJobsGrpcClientTests.cs
+++ b/test/Dapr.Jobs.Test/DaprJobsGrpcClientTests.cs
@@ -15,7 +15,6 @@
using System.Net.Http;
using Dapr.Jobs.Models;
using Moq;
-using Xunit;
namespace Dapr.Jobs.Test;
diff --git a/test/Dapr.Jobs.Test/Extensions/DaprJobsServiceCollectionExtensionsTests.cs b/test/Dapr.Jobs.Test/Extensions/DaprJobsServiceCollectionExtensionsTests.cs
index 814e52794..dd40287f9 100644
--- a/test/Dapr.Jobs.Test/Extensions/DaprJobsServiceCollectionExtensionsTests.cs
+++ b/test/Dapr.Jobs.Test/Extensions/DaprJobsServiceCollectionExtensionsTests.cs
@@ -11,7 +11,6 @@
// limitations under the License.
// ------------------------------------------------------------------------
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
diff --git a/test/Dapr.Jobs.Test/Extensions/EndpointRouteBuilderExtensionsTests.cs b/test/Dapr.Jobs.Test/Extensions/EndpointRouteBuilderExtensionsTests.cs
index 4220db7bd..77b60fe06 100644
--- a/test/Dapr.Jobs.Test/Extensions/EndpointRouteBuilderExtensionsTests.cs
+++ b/test/Dapr.Jobs.Test/Extensions/EndpointRouteBuilderExtensionsTests.cs
@@ -14,26 +14,17 @@
#nullable enable
using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Dapr.Jobs.Extensions;
-using Dapr.Jobs.Models;
-using Dapr.Jobs.Models.Responses;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using Moq;
-using Xunit;
namespace Dapr.Jobs.Test.Extensions;
diff --git a/test/Dapr.Jobs.Test/Extensions/StringExtensionsTests.cs b/test/Dapr.Jobs.Test/Extensions/StringExtensionsTests.cs
index 8c25de115..2e27025c8 100644
--- a/test/Dapr.Jobs.Test/Extensions/StringExtensionsTests.cs
+++ b/test/Dapr.Jobs.Test/Extensions/StringExtensionsTests.cs
@@ -14,7 +14,6 @@
using System;
using System.Collections.Generic;
using Dapr.Jobs.Extensions;
-using Xunit;
namespace Dapr.Jobs.Test.Extensions;
diff --git a/test/Dapr.Jobs.Test/Extensions/TimeSpanExtensionsTests.cs b/test/Dapr.Jobs.Test/Extensions/TimeSpanExtensionsTests.cs
index 1e888a841..c8aff977f 100644
--- a/test/Dapr.Jobs.Test/Extensions/TimeSpanExtensionsTests.cs
+++ b/test/Dapr.Jobs.Test/Extensions/TimeSpanExtensionsTests.cs
@@ -12,7 +12,6 @@
// ------------------------------------------------------------------------
using System;
-using Xunit;
namespace Dapr.Jobs.Test.Extensions;
diff --git a/test/Dapr.Jobs.Test/Models/DaprJobScheduleTests.cs b/test/Dapr.Jobs.Test/Models/DaprJobScheduleTests.cs
index da0afb438..32f1eef7e 100644
--- a/test/Dapr.Jobs.Test/Models/DaprJobScheduleTests.cs
+++ b/test/Dapr.Jobs.Test/Models/DaprJobScheduleTests.cs
@@ -13,7 +13,6 @@
using System;
using Dapr.Jobs.Models;
-using Xunit;
namespace Dapr.Jobs.Test.Models;