Add dotnet activities for train interface.

This commit is contained in:
Rob Holland
2025-02-14 11:51:57 +00:00
parent 39462955eb
commit e085f02128
12 changed files with 157 additions and 23 deletions

2
enterprise/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
obj
bin

View File

@@ -0,0 +1,40 @@
using System.Net.Http.Json;
using Temporalio.Activities;
using TrainSearchWorker.Models;
namespace TrainSearchWorker.Activities;
public class TrainActivities
{
private readonly HttpClient _client;
public TrainActivities(IHttpClientFactory clientFactory)
{
_client = clientFactory.CreateClient("TrainApi");
}
[Activity]
public async Task<List<Journey>> SearchTrains(SearchTrainsRequest request)
{
var response = await _client.GetAsync(
$"api/search?from={Uri.EscapeDataString(request.From)}" +
$"&to={Uri.EscapeDataString(request.To)}" +
$"&outbound_time={Uri.EscapeDataString(request.OutboundTime)}" +
$"&return_time={Uri.EscapeDataString(request.ReturnTime)}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<List<Journey>>()
?? throw new InvalidOperationException("Received null response from API");
}
[Activity]
public async Task<List<Journey>> BookTrains(BookTrainsRequest request)
{
var response = await _client.PostAsJsonAsync("api/book", request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<List<Journey>>()
?? throw new InvalidOperationException("Received null response from API");
}
}

View File

@@ -0,0 +1,6 @@
namespace TrainSearchWorker.Models;
public record BookTrainsRequest
{
public required string TrainIds { get; init; }
}

View File

@@ -0,0 +1,12 @@
namespace TrainSearchWorker.Models;
public record Journey
{
public required string Id { get; init; }
public required string Type { get; init; }
public required string Departure { get; init; }
public required string Arrival { get; init; }
public required string DepartureTime { get; init; }
public required string ArrivalTime { get; init; }
public required decimal Price { get; init; }
}

View File

@@ -0,0 +1,9 @@
namespace TrainSearchWorker.Models;
public record SearchTrainsRequest
{
public required string From { get; init; }
public required string To { get; init; }
public required string OutboundTime { get; init; }
public required string ReturnTime { get; init; }
}

52
enterprise/Program.cs Normal file
View File

@@ -0,0 +1,52 @@
using Microsoft.Extensions.DependencyInjection;
using Temporalio.Client;
using Temporalio.Worker;
using TrainSearchWorker.Activities;
var services = new ServiceCollection();
// Add HTTP client
services.AddHttpClient("TrainApi", client =>
{
client.BaseAddress = new Uri("http://localhost:8080/");
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
// Add activities
services.AddScoped<TrainActivities>();
var serviceProvider = services.BuildServiceProvider();
// Create client
var client = await TemporalClient.ConnectAsync(new()
{
TargetHost = "localhost:7233",
});
// Create worker options
var options = new TemporalWorkerOptions("agent-task-queue-legacy");
// Register activities
var activities = serviceProvider.GetRequiredService<TrainActivities>();
options.AddActivity(activities.SearchTrains);
options.AddActivity(activities.BookTrains);
// Create and run worker
var worker = new TemporalWorker(client, options);
Console.WriteLine("Starting worker...");
using var tokenSource = new CancellationTokenSource();
Console.CancelKeyPress += (_, eventArgs) =>
{
eventArgs.Cancel = true;
tokenSource.Cancel();
};
try
{
await worker.ExecuteAsync(tokenSource.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Worker shutting down...");
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Temporalio" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
</ItemGroup>
</Project>