Skip to content

Commit

Permalink
patch: update example application using step (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
kuju63 authored Jul 25, 2023
1 parent bc48a8c commit 5241b22
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 140 deletions.
13 changes: 5 additions & 8 deletions BatchSharp.Example/ExampleBatchApplication.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using BatchSharp.Processor;
using BatchSharp.Reader;
using BatchSharp.Step;
using BatchSharp.Writer;

using Microsoft.Extensions.Logging;
Expand All @@ -9,21 +10,17 @@ namespace BatchSharp.Example;
/// <summary>
/// Class of example batch application.
/// </summary>
public class ExampleBatchApplication : DefaultBatchApplication<string, int>
public class ExampleBatchApplication : DefaultBatchApplication
{
/// <summary>
/// Initializes a new instance of the <see cref="ExampleBatchApplication"/> class.
/// </summary>
/// <param name="logger">Logger.</param>
/// <param name="reader">Reader.</param>
/// <param name="processor">Processor.</param>
/// <param name="writer">Writer.</param>
/// <param name="step">Step.</param>
public ExampleBatchApplication(
ILogger<ExampleBatchApplication> logger,
IReader<string> reader,
IProcessor<string, int> processor,
IWriter<int> writer)
: base(logger, reader, processor, writer)
IStep step)
: base(logger, step)
{
}
}
3 changes: 3 additions & 0 deletions BatchSharp.Example/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using BatchSharp.Example.Writer;
using BatchSharp.Processor;
using BatchSharp.Reader;
using BatchSharp.Step;
using BatchSharp.Writer;

using Microsoft.Extensions.DependencyInjection;
Expand All @@ -22,6 +23,8 @@
.AddScoped<IReader<string>, ExampleReader>();
services.AddScoped<IProcessor<string, int>, ExampleProcessor>();
services.AddScoped<IWriter<int>, ExampleWriter>();
services.AddScoped<IStep, SimpleStep<string, int>>();
services.AddScoped<IStepState, StepState>();
});

var app = builder.Build();
Expand Down
104 changes: 13 additions & 91 deletions BatchSharp.Tests/DefaultBatchApplicationTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using BatchSharp.Processor;
using BatchSharp.Reader;
using BatchSharp.Step;
using BatchSharp.Writer;

using Microsoft.Extensions.Logging;
Expand All @@ -13,95 +14,22 @@ namespace BatchSharp.Tests;
/// </summary>
public class DefaultBatchApplicationTest
{
private readonly Mock<IReader<string>> _reader = new();
private readonly Mock<IProcessor<string, int>> _processor = new();
private readonly Mock<IWriter<int>> _writer = new();
private readonly Mock<ILogger<DefaultBatchApplication>> _logger = new();
private readonly Mock<IStep> _step = new();

/// <summary>
/// Test for <see cref="DefaultBatchApplication{TRead,TResult}.RunAsync()"/>.
/// If reader returns single element list, should return completed.
/// </summary>
/// <returns>Asynchronous task.</returns>
[Fact]
public async Task ShouldReturnCompletedWhenReadSingleAsync()
public async Task ShouldReturnCompletedWhenExecutionSuccess()
{
var logger = new Mock<ILogger<DefaultBatchApplication<string, int>>>();
_reader.SetupSequence(x => x.ReadAsync())
.Returns(new[] { "test" }.ToAsyncEnumerable())
.Returns(AsyncEnumerable.Empty<string>());

_processor.SetupSequence(x => x.Process("test"))
.Returns(4);
_writer.SetupSequence(x => x.WriteAsync(It.IsIn(4), It.IsAny<CancellationToken>()))
.Returns(Task.CompletedTask);
var application =
new DefaultBatchApplication<string, int>(
logger.Object,
_reader.Object,
_processor.Object,
_writer.Object);

await application.RunAsync();

_reader.Verify((r) => r.ReadAsync(), Times.Once());
_processor.Verify(p => p.Process("test"), Times.Once());
_writer.Verify(x => x.WriteAsync(It.IsIn(4), It.IsAny<CancellationToken>()), Times.Once());
}

/// <summary>
/// Test for <see cref="DefaultBatchApplication{TRead,TResult}.RunAsync()"/>.
/// Should return completed when reader returns empty list.
/// </summary>
/// <returns>Asynchronous task.</returns>
[Fact]
public async Task ShouldReturnCompletedWhenReadEmptyAsync()
{
var logger = new Mock<ILogger<DefaultBatchApplication<string, int>>>();
_reader.SetupSequence(x => x.ReadAsync())
.Returns(AsyncEnumerable.Empty<string>());
_processor.SetupSequence(x => x.Process(It.IsAny<string>()));
_writer.SetupSequence(x => x.WriteAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()));
var application =
new DefaultBatchApplication<string, int>(
logger.Object,
_reader.Object,
_processor.Object,
_writer.Object);
_step.Setup(x => x.ExecuteAsync(default));
var application = new DefaultBatchApplication(_logger.Object, _step.Object);

await application.RunAsync();

_reader.Verify(r => r.ReadAsync(), Times.Once());
_processor.Verify(x => x.Process(It.IsAny<string>()), Times.Never());
_writer.Verify(x => x.WriteAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()), Times.Never());
}

/// <summary>
/// Test for <see cref="DefaultBatchApplication{TRead,TResult}.RunAsync(CancellationToken)"/>.
/// </summary>
/// <returns>Asynchronous task.</returns>
[Fact]
public async Task ShouldReturnCompletedWhenReadSingleWithCancellationTokenAsync()
{
var logger = new Mock<ILogger<DefaultBatchApplication<string, int>>>();
_reader.SetupSequence(x => x.ReadAsync())
.Returns(new[] { "test" }.ToAsyncEnumerable())
.Returns(AsyncEnumerable.Empty<string>());
_processor.SetupSequence(x => x.Process(It.IsIn("test")))
.Returns(4);
_writer.SetupSequence(x => x.WriteAsync(It.IsIn(4), It.IsAny<CancellationToken>()))
.Returns(Task.CompletedTask);
var application =
new DefaultBatchApplication<string, int>(
logger.Object,
_reader.Object,
_processor.Object,
_writer.Object);
using var cancellationTokenSource = new CancellationTokenSource();
await application.RunAsync(cancellationTokenSource.Token);

_reader.Verify((r) => r.ReadAsync(), Times.Once());
_processor.Verify(p => p.Process(It.IsIn("test")), Times.Once());
_writer.Verify(x => x.WriteAsync(It.IsIn(4), It.IsAny<CancellationToken>()), Times.Once());
_step.Verify(x => x.ExecuteAsync(default), Times.Once());
}

/// <summary>
Expand All @@ -111,22 +39,16 @@ public async Task ShouldReturnCompletedWhenReadSingleWithCancellationTokenAsync(
[Fact]
public async Task ShouldReturnCancelledAsync()
{
var logger = new Mock<ILogger<DefaultBatchApplication<string, int>>>();
_reader.Setup(x => x.ReadAsync());
_processor.Setup(x => x.Process(It.IsAny<string>()));
_writer.Setup(x => x.WriteAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()));
_step.Setup(x => x.ExecuteAsync(It.IsAny<CancellationToken>()));
var application =
new DefaultBatchApplication<string, int>(
logger.Object,
_reader.Object,
_processor.Object,
_writer.Object);
new DefaultBatchApplication(
_logger.Object,
_step.Object);

using var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.Cancel();
await Assert.ThrowsAsync<TaskCanceledException>(() => application.RunAsync(cancellationTokenSource.Token));

_reader.Verify(r => r.ReadAsync(), Times.Never());
_processor.Verify(x => x.Process(It.IsAny<string>()), Times.Never());
_writer.Verify(x => x.WriteAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()), Times.Never());
_step.Verify(x => x.ExecuteAsync(It.IsAny<CancellationToken>()), Times.Never());
}
}
41 changes: 14 additions & 27 deletions BatchSharp/DefaultBatchApplication.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Runtime.CompilerServices;

using BatchSharp.Processor;
using BatchSharp.Reader;
using BatchSharp.Step;
using BatchSharp.Writer;

using Microsoft.Extensions.Logging;
Expand All @@ -9,34 +12,22 @@ namespace BatchSharp;
/// <summary>
/// Class for running a batch application.
/// </summary>
/// <typeparam name="TRead">DataBinding class of datasource.</typeparam>
/// <typeparam name="TResult">Processing result type.</typeparam>
public class DefaultBatchApplication<TRead, TResult> : IBatchApplication
where TRead : notnull
where TResult : notnull
public class DefaultBatchApplication : IBatchApplication
{
private readonly ILogger<DefaultBatchApplication<TRead, TResult>> _logger;
private readonly IReader<TRead> _reader;
private readonly IProcessor<TRead, TResult> _processor;
private readonly IWriter<TResult> _writer;
private readonly ILogger<DefaultBatchApplication> _logger;
private readonly IStep _step;

/// <summary>
/// Initializes a new instance of the <see cref="DefaultBatchApplication{TRead, TResult}"/> class.
/// Initializes a new instance of the <see cref="DefaultBatchApplication"/> class.
/// </summary>
/// <param name="logger">Logger.</param>
/// <param name="reader">Reader instance.</param>
/// <param name="processor">Processor instance.</param>
/// <param name="writer">Writer instance.</param>
/// <param name="step">Step.</param>
public DefaultBatchApplication(
ILogger<DefaultBatchApplication<TRead, TResult>> logger,
IReader<TRead> reader,
IProcessor<TRead, TResult> processor,
IWriter<TResult> writer)
ILogger<DefaultBatchApplication> logger,
IStep step)
{
_logger = logger;
_reader = reader;
_processor = processor;
_writer = writer;
_step = step;
}

/// <inheritdoc/>
Expand All @@ -50,13 +41,9 @@ public async Task RunAsync(CancellationToken cancellationToken)
{
if (!cancellationToken.IsCancellationRequested)
{
await foreach (var readData in _reader.ReadAsync().WithCancellation(cancellationToken))
{
_logger.LogInformation("Read data: {Item}", readData);
var processingResult = _processor.Process(readData);
_logger.LogInformation("Processed data: {Item}", processingResult);
await _writer.WriteAsync(processingResult, cancellationToken);
}
_logger.LogDebug("Start batch application.");
await _step.ExecuteAsync(cancellationToken);
_logger.LogDebug("End batch application.");
}
else
{
Expand Down
18 changes: 4 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ BatchSharp can be installed using the Nuget package manager or the `dotnet` CLI.
.AddScoped<IReader<string>, ExampleReader>();
services.AddScoped<IProcessor<string, int>, ExampleProcessor>();
services.AddScoped<IWriter<int>, ExampleWriter>();
services.AddScoped<IStep, SimpleStep<string, int>>();
services.AddScoped<IStepState, StepState>();
});
var app = builder.Build();
Expand All @@ -69,24 +71,12 @@ BatchSharp can be installed using the Nuget package manager or the `dotnet` CLI.
`IReader` is used to read input data. `IProcessor` is used to process input data. `IWriter` is used to write output data. These class are injected by DI container.
```csharp
/// <summary>
/// Class of example batch application.
/// </summary>
public class ExampleBatchApplication : DefaultBatchApplication<string, int>
{
/// <summary>
/// Initializes a new instance of the <see cref="ExampleBatchApplication"/> class.
/// </summary>
/// <param name="logger">Logger.</param>
/// <param name="reader">Reader.</param>
/// <param name="processor">Processor.</param>
/// <param name="writer">Writer.</param>
public ExampleBatchApplication(
ILogger<ExampleBatchApplication> logger,
IReader<string> reader,
IProcessor<string, int> processor,
IWriter<int> writer)
: base(logger, reader, processor, writer)
IStep step)
: base(logger, step)
{
}
}
Expand Down
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to wri
services.AddScoped<IFileWriterSetting, FileWriterSetting>(c => new FileWriterSetting("output.txt"));
// Register writer class
services.AddScoped<IWriter<int>, ExampleWriter>();
services.AddScoped<IStep, SimpleStep<string, int>>();
services.AddScoped<IStepState, StepState>();
});

var app = builder.Build();
Expand Down

0 comments on commit 5241b22

Please sign in to comment.