Skip to content

Instantly share code, notes, and snippets.

@PawelHaracz
Created April 6, 2020 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PawelHaracz/334b13fd33dcaf12a4773d42605c548c to your computer and use it in GitHub Desktop.
Save PawelHaracz/334b13fd33dcaf12a4773d42605c548c to your computer and use it in GitHub Desktop.
using Microsoft.Extensions.Options;
using Structurizr;
using Structurizr.Api;
namespace model.c4
{
public class C4Generator
{
private readonly Options.Structurizr _options;
private const string MicroserviceTag = "Microservice";
private const string MessageBusTag = "Message Bus";
private const string DataStoreTag = "Database";
public C4Generator(IOptions<Options.Structurizr> options)
{
_options = options.Value;
}
public void Generate()
{
var workspace = new Workspace("The Grundfos", "Grundfos Industry");
var model = workspace.Model;
var views = workspace.Views;
model.Enterprise = new Enterprise("The Mixit Grundfos Enterpise");
#region Context
var customer = model.AddPerson(Location.External, "Customer", "a person who uses a mixit platform");
var mixitServiceSoftwareSystem =
model.AddSoftwareSystem(Location.Internal, "Mixit System", "Managing mixit devices via portal");
var deviceDiscoverySoftwareSystem = model.AddSoftwareSystem("Device Discovery system",
"Manges traffic between devices and Systems");
var deviceSoftwareSystem = model.AddSoftwareSystem(Location.External, "Devices", "Connected devices to the Internet");
customer.Uses(mixitServiceSoftwareSystem, "Uses");
deviceDiscoverySoftwareSystem.Uses(deviceSoftwareSystem, "Reads and writes");
mixitServiceSoftwareSystem.Uses(deviceDiscoverySoftwareSystem, "Reads");
var systemContextView = views.CreateSystemContextView(mixitServiceSoftwareSystem, "System Context","Diagram of system context");
systemContextView.AddNearestNeighbours(mixitServiceSoftwareSystem);
systemContextView.AddAnimation(mixitServiceSoftwareSystem);
systemContextView.AddAnimation(customer);
systemContextView.AddAnimation(deviceDiscoverySoftwareSystem);
#endregion
#region Container
var frontend = mixitServiceSoftwareSystem.AddContainer("Frontend",
"Deliver mixit freemium version web portal for customers","React and Redux");
var proxyApi = mixitServiceSoftwareSystem.AddContainer("ProxyApi", "Aggregate data from all microservices", "NodeJs");
proxyApi.AddTags(MicroserviceTag);
var assetService =
mixitServiceSoftwareSystem.AddContainer("Asset Service", "Information about location and devices", "GRPC Asp.Net");
var assetServiceDb = mixitServiceSoftwareSystem.AddContainer("Asset service Database",
"store asset, location and user access", "Postgres SQL");
assetServiceDb.AddTags(MicroserviceTag);
var alarmService = mixitServiceSoftwareSystem.AddContainer("Alarm service", "processed alarms from devices", "GRPC Asp.Net");
var alarmServiceDb = mixitServiceSoftwareSystem.AddContainer("Alarm service database","store alarms", "Postgres SQL");
alarmService.AddTags(MicroserviceTag);
var dataPointService = mixitServiceSoftwareSystem.AddContainer("Datapoint service", "processed datapoints from devices and generate trend curves", "GRPC Asp.Net");
var dataPointServiceDb = mixitServiceSoftwareSystem.AddContainer("Datapoint service database","store all datapoints", "Postgres SQL/TimeScale");
dataPointService.AddTags(MicroserviceTag);
var telemetryService = mixitServiceSoftwareSystem.AddContainer("Telemetry service ",
"takes all telemetries and send do event hub", "Iot hubs and .net core console");
telemetryService.AddTags(MicroserviceTag);
var discoveryService =
deviceDiscoverySoftwareSystem.AddContainer("discovery service", "Manage access to devices, create SaS token based on deviceId",
"GRPC asp.net");
var deviceDiscoverySubscriber = deviceDiscoverySoftwareSystem.AddContainer("Device discovery subscriber",
"Store Iot Hub connections when was created new one",
"Azure Service Bus");
var deviceDiscoveryStorage =
deviceDiscoverySoftwareSystem.AddContainer("Device discovery table storage", "Store all IoT Hubs connection strings", "azure table storage");
var deviceDiscoveryDeviceImporter = deviceDiscoverySoftwareSystem.AddContainer("Device Discovery Device Importer", "Checks all IoT Hubs and save new devices", ".net core console app");
var deviceDiscoveryCache = deviceDiscoverySoftwareSystem.AddContainer("Device discovery Redis cache",
"Store information which device uses which IotHub", "Redis Cache");
discoveryService.AddTags(MicroserviceTag);
discoveryService.Uses(deviceDiscoveryCache, "Reads", "Rest API");
discoveryService.Uses(deviceDiscoveryStorage, "Reads", "Rest API");
deviceDiscoverySubscriber.Uses(deviceDiscoveryStorage, "Writes", "Rest API");
deviceDiscoveryDeviceImporter.Uses(deviceDiscoveryStorage, "Reads", "Rest API");
deviceDiscoveryDeviceImporter.Uses(deviceDiscoveryCache, "Writes", "Rest API");
customer.Uses(frontend, "Uses");
assetService.Uses(assetServiceDb, "Reads", "Npsql");
alarmService.Uses(alarmServiceDb, "Reads", "Npsql");
dataPointService.Uses(dataPointServiceDb, "Reads", "Npsql");
proxyApi.Uses(assetService, "Uses", "GRPC");
proxyApi.Uses(alarmService, "Uses", "GRPC");
proxyApi.Uses(dataPointService, "Uses", "GRPC");
frontend.Uses(proxyApi, "Uses", "GraphQL");
alarmService.Uses(telemetryService, "Reads", "Azure Event Hub");
assetService.Uses(telemetryService, "Reads", "Azure Event Hub");
var containerMixitView = views.CreateContainerView(mixitServiceSoftwareSystem, "Mixit Container", "Diagram of mixit Container");
containerMixitView.Add(customer);
containerMixitView.AddAllContainers();
containerMixitView.AddAnimation(customer,deviceSoftwareSystem);
containerMixitView.AddAnimation(proxyApi,assetService, alarmService, telemetryService, alarmServiceDb, assetServiceDb);
#endregion
#region Component
var locationController =
assetService.AddComponent("Location", "Gets all locations", "asp.net grpc controller");
var deviceController = assetService.AddComponent("Devices", "Gets all devices under locations", "asp.net grpc controller");
var alarmController = alarmService.AddComponent("Alarms", "Check if the device has an alarm");
var datapointController = dataPointService.AddComponent("Datapoints", "Get generated materialized view",
"asp.net grpc controller");
var materialziedView =
dataPointServiceDb.AddComponent("Materialize view", "Generate Materialize view", "Postgres SQL");
assetService.Uses(locationController, "Uses");
assetService.Uses(deviceController, "Uses");
deviceController.Uses(assetServiceDb, "Reads", "Postgres SQL");
locationController.Uses(assetServiceDb, "Reads", "Postgres SQL");
proxyApi.Uses(locationController, "Uses", "GRPC");
proxyApi.Uses(deviceController, "Uses", "GRPC");
alarmService.Uses(alarmController, "Uese");
alarmController.Uses(alarmServiceDb, "Reads", "Postgres SQL");
proxyApi.Uses(alarmController, "Uses", "GRPC");
dataPointService.Uses(datapointController, "Uses");
datapointController.Uses(dataPointServiceDb, "Uses", "Postgres SQL");
dataPointServiceDb.Uses(materialziedView, "Uses");
proxyApi.Uses(datapointController, "Uses", "GRPC");
var assetComponentView = views.CreateComponentView(assetService, "Asset components", "Diagram of Assets components");
assetComponentView.Add(locationController);
assetComponentView.Add(deviceController);
assetComponentView.Add(proxyApi);
assetComponentView.Add(assetService);
assetComponentView.Add(assetServiceDb);
assetComponentView.AddAnimation(locationController);
assetComponentView.AddAnimation(deviceController);
assetComponentView.AddAnimation(proxyApi);
assetComponentView.AddAnimation(assetServiceDb);
var alarmComponentView = views.CreateComponentView(alarmService, "Alarm components", "Diagram of Alarms components");
alarmComponentView.Add(alarmController);
alarmComponentView.Add(proxyApi);
alarmComponentView.Add(alarmService);
alarmComponentView.Add(alarmServiceDb);
alarmComponentView.AddAnimation(alarmController);
alarmComponentView.AddAnimation(proxyApi);
alarmComponentView.AddAnimation(alarmServiceDb);
var datapointComponentView = views.CreateComponentView(dataPointService, "Datapoint components", "Diagram of Datapoints components");
datapointComponentView.Add(datapointController);
datapointComponentView.Add(proxyApi);
datapointComponentView.Add(dataPointService);
datapointComponentView.Add(dataPointServiceDb);
datapointComponentView.AddAnimation(datapointController);
datapointComponentView.AddAnimation(proxyApi);
datapointComponentView.AddAnimation(dataPointServiceDb);
#endregion
model.AddImplicitRelationships();
var structurizrClient = new StructurizrClient(_options.ClientId, _options.ClientSecret);
structurizrClient.PutWorkspace(_options.Workspace, workspace);
}
}
}
@PawelHaracz
Copy link
Author

PawelHaracz commented Apr 6, 2020

Images show how looks a generated c4 model via above code in structurizr

image
image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment