Skip to content
Tutorial2/4

2. Create the System and run it

Create the system host and run two orders through it.

From the distribution-workspace root:

Terminal window
intropy sys create -n OrderNotifications
using cached integrio-intropy/intropy-templates@v2.0.0
created order-notifications from integrio-intropy/intropy-templates@v2.0.0 (template system-host)
assembled system "order-notifications": 2 component(s), 1 topic(s), 2 port(s), contracts from Contracts

This reads the scaffold records and creates order-notifications/, the system host. Messages.cs declares the message and the topic it travels on:

order-notifications/Messages.cs
public static class Messages
{
/// <summary>OrderPlaced messages, published on the orders topic.</summary>
public static readonly MessageRef<OrderPlaced> OrderPlaced =
MessageRef<OrderPlaced>.Define("order-placed", topic: "orders");
}

The system definition connects the Components through that message:

order-notifications/OrderNotificationsSystem.cs
public sealed class OrderNotificationsSystem : ISystemDefinition
{
public string SystemName => "order-notifications";
public void Define(SystemBuilder builder)
{
builder.AddExtractor("erp-extractor")
.From(Ports.ErpExtractorSource)
.Publishes(Messages.OrderPlaced)
.Calls(Services.Idempotency)
.Calls(Services.BusinessIncidents);
// Rendered as a declarative Dapr Subscription: one routing rule per route, in order,
// and a default route for the rest of the topic. The subscription's first message
// anchors it; the rest are also handled on the same channel.
builder.AddLoader("wms-loader")
.Subscribes(Messages.OrderPlaced,
configure: sub => sub
.IgnoreOthers())
.To(Ports.WmsLoaderDestination)
.Calls(Services.Idempotency)
.Calls(Services.BusinessIncidents);
}
}

Subscribes declares the loader’s subscription: the messages it takes from the orders topic. Chapter 3 extends it.

Skim Ports.cs and OrderNotificationsDevelopment.cs. Chapter 4 edits those files.

The scaffolded host ships a Taskfile.yml. Its seed task copies two sample orders into the extractor’s source folder; its run task starts the host. The extractor sweeps its source folder at host start, so seed before running. From order-notifications/:

Terminal window
cd order-notifications
task seed
task run

Docker must be running and dapr init must have completed; without the installed Dapr runtime, each sidecar starts and exits immediately.

Wait for the dashboard line and open the login URL it prints:

Login to the dashboard at http://localhost:15170/login?t=<token>

Stop any previous host first. The dashboard ports are fixed.

In a second terminal, from order-notifications/, list the WMS output:

Terminal window
ls test/wms-loader-destination
cat test/wms-loader-destination/ORD-1001.order-placed.json
ORD-1001.order-placed.json
ORD-1002.order-placed.json
{"OrderId":"ORD-1001","CustomerId":"CUST-42","LoadedAt":"2026-10-08T14:05:39.870689+00:00","Status":"0"}

The loader names each file <orderId>.<message>.json. The two sample orders differ in Status: ORD-1001 has "0" and ORD-1002 has "1". Both are published as order-placed for now. Chapter 3 publishes the status "1" order as a cancellation.

Stop the host with Ctrl+C before chapter 3.