public void Test_AddNearestNeighbours_AddsNearestNeighbours_WhenThereAreSomeNearestNeighbours() { SoftwareSystem softwareSystemA = Model.AddSoftwareSystem("System A", "Description"); SoftwareSystem softwareSystemB = Model.AddSoftwareSystem("System B", "Description"); Person userA = Model.AddPerson("User A", "Description"); Person userB = Model.AddPerson("User B", "Description"); // userA -> systemA -> system -> systemB -> userB userA.Uses(softwareSystemA, ""); softwareSystemA.Uses(softwareSystem, ""); softwareSystem.Uses(softwareSystemB, ""); softwareSystemB.Delivers(userB, ""); // userA -> systemA -> web application -> systemB -> userB // web application -> database Container webApplication = softwareSystem.AddContainer("Web Application", "", ""); Container database = softwareSystem.AddContainer("Database", "", ""); softwareSystemA.Uses(webApplication, ""); webApplication.Uses(softwareSystemB, ""); webApplication.Uses(database, ""); // userA -> systemA -> controller -> service -> repository -> database Component controller = webApplication.AddComponent("Controller", ""); Component service = webApplication.AddComponent("Service", ""); Component repository = webApplication.AddComponent("Repository", ""); softwareSystemA.Uses(controller, ""); controller.Uses(service, ""); service.Uses(repository, ""); repository.Uses(database, ""); // userA -> systemA -> controller -> service -> systemB -> userB service.Uses(softwareSystemB, ""); view.AddNearestNeighbours(softwareSystem); Assert.Equal(3, view.Elements.Count); Assert.True(view.Elements.Contains(new ElementView(softwareSystemA))); Assert.True(view.Elements.Contains(new ElementView(softwareSystem))); Assert.True(view.Elements.Contains(new ElementView(softwareSystemB))); view = new ContainerView(softwareSystem, "containers", "Description"); view.AddNearestNeighbours(softwareSystemA); Assert.Equal(4, view.Elements.Count); Assert.True(view.Elements.Contains(new ElementView(userA))); Assert.True(view.Elements.Contains(new ElementView(softwareSystemA))); Assert.True(view.Elements.Contains(new ElementView(softwareSystem))); Assert.True(view.Elements.Contains(new ElementView(webApplication))); view = new ContainerView(softwareSystem, "containers", "Description"); view.AddNearestNeighbours(webApplication); Assert.Equal(4, view.Elements.Count); Assert.True(view.Elements.Contains(new ElementView(softwareSystemA))); Assert.True(view.Elements.Contains(new ElementView(webApplication))); Assert.True(view.Elements.Contains(new ElementView(database))); Assert.True(view.Elements.Contains(new ElementView(softwareSystemB))); }
private void PopulateWorkspace() { Model model = _workspace.Model; model.Enterprise = new Enterprise("Some Enterprise"); Person user = model.AddPerson(Location.Internal, "User", ""); SoftwareSystem softwareSystem = model.AddSoftwareSystem(Location.Internal, "Software System", ""); user.Uses(softwareSystem, "Uses"); SoftwareSystem emailSystem = model.AddSoftwareSystem(Location.External, "E-mail System", ""); softwareSystem.Uses(emailSystem, "Sends e-mail using"); emailSystem.Delivers(user, "Delivers e-mails to"); Container webApplication = softwareSystem.AddContainer("Web Application", "", ""); Container database = softwareSystem.AddContainer("Database", "", ""); user.Uses(webApplication, "Uses", "HTTP"); webApplication.Uses(database, "Reads from and writes to", "JDBC"); webApplication.Uses(emailSystem, "Sends e-mail using"); Component controller = webApplication.AddComponent("SomeController", "", "Spring MVC Controller"); Component emailComponent = webApplication.AddComponent("EmailComponent", ""); Component repository = webApplication.AddComponent("SomeRepository", "", "Spring Data"); user.Uses(controller, "Uses", "HTTP"); controller.Uses(repository, "Uses"); controller.Uses(emailComponent, "Sends e-mail using"); repository.Uses(database, "Reads from and writes to", "JDBC"); emailComponent.Uses(emailSystem, "Sends e-mails using", "SMTP"); EnterpriseContextView enterpriseContextView = _workspace.Views.CreateEnterpriseContextView("enterpriseContext", ""); enterpriseContextView.AddAllElements(); SystemContextView systemContextView = _workspace.Views.CreateSystemContextView(softwareSystem, "systemContext", ""); systemContextView.AddAllElements(); ContainerView containerView = _workspace.Views.CreateContainerView(softwareSystem, "containers", ""); containerView.AddAllElements(); ComponentView componentView = _workspace.Views.CreateComponentView(webApplication, "components", ""); componentView.AddAllElements(); DynamicView dynamicView = _workspace.Views.CreateDynamicView(webApplication, "dynamic", ""); dynamicView.Add(user, "Requests /something", controller); dynamicView.Add(controller, repository); dynamicView.Add(repository, "select * from something", database); }
static void Main() { Workspace workspace = new Workspace("Financial Risk System", "This is a simple (incomplete) example C4 model based upon the financial risk system architecture kata, which can be found at http://bit.ly/sa4d-risksystem"); Model model = workspace.Model; SoftwareSystem financialRiskSystem = model.AddSoftwareSystem("Financial Risk System", "Calculates the bank's exposure to risk for product X."); Person businessUser = model.AddPerson("Business User", "A regular business user."); businessUser.Uses(financialRiskSystem, "Views reports using"); Person configurationUser = model.AddPerson("Configuration User", "A regular business user who can also configure the parameters used in the risk calculations."); configurationUser.Uses(financialRiskSystem, "Configures parameters using"); SoftwareSystem tradeDataSystem = model.AddSoftwareSystem("Trade Data System", "The system of record for trades of type X."); financialRiskSystem.Uses(tradeDataSystem, "Gets trade data from"); SoftwareSystem referenceDataSystem = model.AddSoftwareSystem("Reference Data System", "Manages reference data for all counterparties the bank interacts with."); financialRiskSystem.Uses(referenceDataSystem, "Gets counterparty data from"); SoftwareSystem referenceDataSystemV2 = model.AddSoftwareSystem("Reference Data System v2.0", "Manages reference data for all counterparties the bank interacts with."); referenceDataSystemV2.AddTags("Future State"); financialRiskSystem.Uses(referenceDataSystemV2, "Gets counterparty data from").AddTags("Future State"); SoftwareSystem emailSystem = model.AddSoftwareSystem("E-mail system", "The bank's Microsoft Exchange system."); financialRiskSystem.Uses(emailSystem, "Sends a notification that a report is ready to"); emailSystem.Delivers(businessUser, "Sends a notification that a report is ready to", "E-mail message", InteractionStyle.Asynchronous); SoftwareSystem centralMonitoringService = model.AddSoftwareSystem("Central Monitoring Service", "The bank's central monitoring and alerting dashboard."); financialRiskSystem.Uses(centralMonitoringService, "Sends critical failure alerts to", "SNMP", InteractionStyle.Asynchronous).AddTags(AlertTag); SoftwareSystem activeDirectory = model.AddSoftwareSystem("Active Directory", "The bank's authentication and authorisation system."); financialRiskSystem.Uses(activeDirectory, "Uses for user authentication and authorisation"); ViewSet views = workspace.Views; SystemContextView contextView = views.CreateSystemContextView(financialRiskSystem, "Context", "An example System Context diagram for the Financial Risk System architecture kata."); contextView.AddAllSoftwareSystems(); contextView.AddAllPeople(); Styles styles = views.Configuration.Styles; financialRiskSystem.AddTags("Risk System"); styles.Add(new ElementStyle(Tags.Element) { Color = "#ffffff", FontSize = 34 }); styles.Add(new ElementStyle("Risk System") { Background = "#550000", Color = "#ffffff" }); styles.Add(new ElementStyle(Tags.SoftwareSystem) { Width = 650, Height = 400, Background = "#801515", Shape = Shape.RoundedBox }); styles.Add(new ElementStyle(Tags.Person) { Width = 550, Background = "#d46a6a", Shape = Shape.Person }); styles.Add(new RelationshipStyle(Tags.Relationship) { Thickness = 4, Dashed = false, FontSize = 32, Width = 400 }); styles.Add(new RelationshipStyle(Tags.Synchronous) { Dashed = false }); styles.Add(new RelationshipStyle(Tags.Asynchronous) { Dashed = true }); styles.Add(new RelationshipStyle(AlertTag) { Color = "#ff0000" }); styles.Add(new ElementStyle("Future State") { Opacity = 30, Border = Border.Dashed }); styles.Add(new RelationshipStyle("Future State") { Opacity = 30, Dashed = true }); StructurizrDocumentationTemplate template = new StructurizrDocumentationTemplate(workspace); DirectoryInfo documentationRoot = new DirectoryInfo("FinancialRiskSystem"); template.AddContextSection(financialRiskSystem, new FileInfo(Path.Combine(documentationRoot.FullName, "context.adoc"))); template.AddFunctionalOverviewSection(financialRiskSystem, new FileInfo(Path.Combine(documentationRoot.FullName, "functional-overview.md"))); template.AddQualityAttributesSection(financialRiskSystem, new FileInfo(Path.Combine(documentationRoot.FullName, "quality-attributes.md"))); template.AddImages(documentationRoot); StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret); structurizrClient.PutWorkspace(WorkspaceId, workspace); }
public static Workspace Create() { Workspace workspace = new Workspace("Big Bank plc", "This is an example workspace to illustrate the key features of Structurizr, based around a fictional online banking system."); Model model = workspace.Model; ViewSet views = workspace.Views; model.Enterprise = new Enterprise("Big Bank plc"); // people and software systems Person customer = model.AddPerson(Location.External, "Personal Banking Customer", "A customer of the bank, with personal bank accounts."); SoftwareSystem internetBankingSystem = model.AddSoftwareSystem(Location.Internal, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments."); customer.Uses(internetBankingSystem, "Uses"); SoftwareSystem mainframeBankingSystem = model.AddSoftwareSystem(Location.Internal, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc."); mainframeBankingSystem.AddTags(ExistingSystemTag); internetBankingSystem.Uses(mainframeBankingSystem, "Uses"); SoftwareSystem emailSystem = model.AddSoftwareSystem(Location.Internal, "E-mail System", "The internal Microsoft Exchange e-mail system."); internetBankingSystem.Uses(emailSystem, "Sends e-mail using"); emailSystem.AddTags(ExistingSystemTag); emailSystem.Delivers(customer, "Sends e-mails to"); SoftwareSystem atm = model.AddSoftwareSystem(Location.Internal, "ATM", "Allows customers to withdraw cash."); atm.AddTags(ExistingSystemTag); atm.Uses(mainframeBankingSystem, "Uses"); customer.Uses(atm, "Withdraws cash using"); Person customerServiceStaff = model.AddPerson(Location.Internal, "Customer Service Staff", "Customer service staff within the bank."); customerServiceStaff.AddTags(BankStaffTag); customerServiceStaff.Uses(mainframeBankingSystem, "Uses"); customer.InteractsWith(customerServiceStaff, "Asks questions to", "Telephone"); Person backOfficeStaff = model.AddPerson(Location.Internal, "Back Office Staff", "Administration and support staff within the bank."); backOfficeStaff.AddTags(BankStaffTag); backOfficeStaff.Uses(mainframeBankingSystem, "Uses"); // containers Container singlePageApplication = internetBankingSystem.AddContainer("Single-Page Application", "Provides all of the Internet banking functionality to customers via their web browser.", "JavaScript and Angular"); singlePageApplication.AddTags(WebBrowserTag); Container mobileApp = internetBankingSystem.AddContainer("Mobile App", "Provides a limited subset of the Internet banking functionality to customers via their mobile device.", "Xamarin"); mobileApp.AddTags(MobileAppTag); Container webApplication = internetBankingSystem.AddContainer("Web Application", "Delivers the static content and the Internet banking single page application.", "Java and Spring MVC"); Container apiApplication = internetBankingSystem.AddContainer("API Application", "Provides Internet banking functionality via a JSON/HTTPS API.", "Java and Spring MVC"); Container database = internetBankingSystem.AddContainer("Database", "Stores user registration information, hashed authentication credentials, access logs, etc.", "Relational Database Schema"); database.AddTags(DatabaseTag); customer.Uses(webApplication, "Uses", "HTTPS"); customer.Uses(singlePageApplication, "Uses", ""); customer.Uses(mobileApp, "Uses", ""); webApplication.Uses(singlePageApplication, "Delivers to the customer's web browser", ""); apiApplication.Uses(database, "Reads from and writes to", "JDBC"); apiApplication.Uses(mainframeBankingSystem, "Uses", "XML/HTTPS"); apiApplication.Uses(emailSystem, "Sends e-mail using", "SMTP"); // components // - for a real-world software system, you would probably want to extract the components using // - static analysis/reflection rather than manually specifying them all Component signinController = apiApplication.AddComponent("Sign In Controller", "Allows users to sign in to the Internet Banking System.", "Spring MVC Rest Controller"); Component accountsSummaryController = apiApplication.AddComponent("Accounts Summary Controller", "Provides customers with a summary of their bank accounts.", "Spring MVC Rest Controller"); Component resetPasswordController = apiApplication.AddComponent("Reset Password Controller", "Allows users to reset their passwords with a single use URL.", "Spring MVC Rest Controller"); Component securityComponent = apiApplication.AddComponent("Security Component", "Provides functionality related to signing in, changing passwords, etc.", "Spring Bean"); Component mainframeBankingSystemFacade = apiApplication.AddComponent("Mainframe Banking System Facade", "A facade onto the mainframe banking system.", "Spring Bean"); Component emailComponent = apiApplication.AddComponent("E-mail Component", "Sends e-mails to users.", "Spring Bean"); apiApplication.Components.Where(c => "Spring MVC Rest Controller".Equals(c.Technology)).ToList().ForEach(c => singlePageApplication.Uses(c, "Makes API calls to", "JSON/HTTPS")); apiApplication.Components.Where(c => "Spring MVC Rest Controller".Equals(c.Technology)).ToList().ForEach(c => mobileApp.Uses(c, "Makes API calls to", "JSON/HTTPS")); signinController.Uses(securityComponent, "Uses"); accountsSummaryController.Uses(mainframeBankingSystemFacade, "Uses"); resetPasswordController.Uses(securityComponent, "Uses"); resetPasswordController.Uses(emailComponent, "Uses"); securityComponent.Uses(database, "Reads from and writes to", "JDBC"); mainframeBankingSystemFacade.Uses(mainframeBankingSystem, "Uses", "XML/HTTPS"); emailComponent.Uses(emailSystem, "Sends e-mail using"); model.AddImplicitRelationships(); // deployment nodes and container instances DeploymentNode developerLaptop = model.AddDeploymentNode("Development", "Developer Laptop", "A developer laptop.", "Microsoft Windows 10 or Apple macOS"); DeploymentNode apacheTomcat = developerLaptop.AddDeploymentNode("Docker Container - Web Server", "A Docker container.", "Docker") .AddDeploymentNode("Apache Tomcat", "An open source Java EE web server.", "Apache Tomcat 8.x", 1, DictionaryUtils.Create("Xmx=512M", "Xms=1024M", "Java Version=8")); apacheTomcat.Add(webApplication); apacheTomcat.Add(apiApplication); developerLaptop.AddDeploymentNode("Docker Container - Database Server", "A Docker container.", "Docker") .AddDeploymentNode("Database Server", "A development database.", "Oracle 12c") .Add(database); developerLaptop.AddDeploymentNode("Web Browser", "", "Chrome, Firefox, Safari, or Edge").Add(singlePageApplication); DeploymentNode customerMobileDevice = model.AddDeploymentNode("Live", "Customer's mobile device", "", "Apple iOS or Android"); customerMobileDevice.Add(mobileApp); DeploymentNode customerComputer = model.AddDeploymentNode("Live", "Customer's computer", "", "Microsoft Windows or Apple macOS"); customerComputer.AddDeploymentNode("Web Browser", "", "Chrome, Firefox, Safari, or Edge").Add(singlePageApplication); DeploymentNode bigBankDataCenter = model.AddDeploymentNode("Live", "Big Bank plc", "", "Big Bank plc data center"); DeploymentNode liveWebServer = bigBankDataCenter.AddDeploymentNode("bigbank-web***", "A web server residing in the web server farm, accessed via F5 BIG-IP LTMs.", "Ubuntu 16.04 LTS", 4, DictionaryUtils.Create("Location=London and Reading")); liveWebServer.AddDeploymentNode("Apache Tomcat", "An open source Java EE web server.", "Apache Tomcat 8.x", 1, DictionaryUtils.Create("Xmx=512M", "Xms=1024M", "Java Version=8")) .Add(webApplication); DeploymentNode liveApiServer = bigBankDataCenter.AddDeploymentNode("bigbank-api***", "A web server residing in the web server farm, accessed via F5 BIG-IP LTMs.", "Ubuntu 16.04 LTS", 8, DictionaryUtils.Create("Location=London and Reading")); liveApiServer.AddDeploymentNode("Apache Tomcat", "An open source Java EE web server.", "Apache Tomcat 8.x", 1, DictionaryUtils.Create("Xmx=512M", "Xms=1024M", "Java Version=8")) .Add(apiApplication); DeploymentNode primaryDatabaseServer = bigBankDataCenter.AddDeploymentNode("bigbank-db01", "The primary database server.", "Ubuntu 16.04 LTS", 1, DictionaryUtils.Create("Location=London")) .AddDeploymentNode("Oracle - Primary", "The primary, live database server.", "Oracle 12c"); primaryDatabaseServer.Add(database); DeploymentNode bigBankdb02 = bigBankDataCenter.AddDeploymentNode("bigbank-db02", "The secondary database server.", "Ubuntu 16.04 LTS", 1, DictionaryUtils.Create("Location=Reading")); bigBankdb02.AddTags(FailoverTag); DeploymentNode secondaryDatabaseServer = bigBankdb02.AddDeploymentNode("Oracle - Secondary", "A secondary, standby database server, used for failover purposes only.", "Oracle 12c"); secondaryDatabaseServer.AddTags(FailoverTag); ContainerInstance secondaryDatabase = secondaryDatabaseServer.Add(database); model.Relationships.Where(r => r.Destination.Equals(secondaryDatabase)).ToList().ForEach(r => r.AddTags(FailoverTag)); Relationship dataReplicationRelationship = primaryDatabaseServer.Uses(secondaryDatabaseServer, "Replicates data to", ""); secondaryDatabase.AddTags(FailoverTag); // views/diagrams SystemLandscapeView systemLandscapeView = views.CreateSystemLandscapeView("SystemLandscape", "The system landscape diagram for Big Bank plc."); systemLandscapeView.AddAllElements(); systemLandscapeView.PaperSize = PaperSize.A5_Landscape; SystemContextView systemContextView = views.CreateSystemContextView(internetBankingSystem, "SystemContext", "The system context diagram for the Internet Banking System."); systemContextView.EnterpriseBoundaryVisible = false; systemContextView.AddNearestNeighbours(internetBankingSystem); systemContextView.PaperSize = PaperSize.A5_Landscape; ContainerView containerView = views.CreateContainerView(internetBankingSystem, "Containers", "The container diagram for the Internet Banking System."); containerView.Add(customer); containerView.AddAllContainers(); containerView.Add(mainframeBankingSystem); containerView.Add(emailSystem); containerView.PaperSize = PaperSize.A5_Landscape; ComponentView componentView = views.CreateComponentView(apiApplication, "Components", "The component diagram for the API Application."); componentView.Add(mobileApp); componentView.Add(singlePageApplication); componentView.Add(database); componentView.AddAllComponents(); componentView.Add(mainframeBankingSystem); componentView.Add(emailSystem); componentView.PaperSize = PaperSize.A5_Landscape; systemLandscapeView.AddAnimation(internetBankingSystem, customer, mainframeBankingSystem, emailSystem); systemLandscapeView.AddAnimation(atm); systemLandscapeView.AddAnimation(customerServiceStaff, backOfficeStaff); systemContextView.AddAnimation(internetBankingSystem); systemContextView.AddAnimation(customer); systemContextView.AddAnimation(mainframeBankingSystem); systemContextView.AddAnimation(emailSystem); containerView.AddAnimation(customer, mainframeBankingSystem, emailSystem); containerView.AddAnimation(webApplication); containerView.AddAnimation(singlePageApplication); containerView.AddAnimation(mobileApp); containerView.AddAnimation(apiApplication); containerView.AddAnimation(database); componentView.AddAnimation(singlePageApplication, mobileApp); componentView.AddAnimation(signinController, securityComponent, database); componentView.AddAnimation(accountsSummaryController, mainframeBankingSystemFacade, mainframeBankingSystem); componentView.AddAnimation(resetPasswordController, emailComponent, database); // dynamic diagrams and deployment diagrams are not available with the Free Plan DynamicView dynamicView = views.CreateDynamicView(apiApplication, "SignIn", "Summarises how the sign in feature works in the single-page application."); dynamicView.Add(singlePageApplication, "Submits credentials to", signinController); dynamicView.Add(signinController, "Calls isAuthenticated() on", securityComponent); dynamicView.Add(securityComponent, "select * from users where username = ?", database); dynamicView.PaperSize = PaperSize.A5_Landscape; DeploymentView developmentDeploymentView = views.CreateDeploymentView(internetBankingSystem, "DevelopmentDeployment", "An example development deployment scenario for the Internet Banking System."); developmentDeploymentView.Environment = "Development"; developmentDeploymentView.Add(developerLaptop); developmentDeploymentView.PaperSize = PaperSize.A5_Landscape; DeploymentView liveDeploymentView = views.CreateDeploymentView(internetBankingSystem, "LiveDeployment", "An example live deployment scenario for the Internet Banking System."); liveDeploymentView.Environment = "Live"; liveDeploymentView.Add(bigBankDataCenter); liveDeploymentView.Add(customerMobileDevice); liveDeploymentView.Add(customerComputer); liveDeploymentView.Add(dataReplicationRelationship); liveDeploymentView.PaperSize = PaperSize.A5_Landscape; // colours, shapes and other diagram styling Styles styles = views.Configuration.Styles; styles.Add(new ElementStyle(Tags.SoftwareSystem) { Background = "#1168bd", Color = "#ffffff" }); styles.Add(new ElementStyle(Tags.Container) { Background = "#438dd5", Color = "#ffffff" }); styles.Add(new ElementStyle(Tags.Component) { Background = "#85bbf0", Color = "#000000" }); styles.Add(new ElementStyle(Tags.Person) { Background = "#08427b", Color = "#ffffff", Shape = Shape.Person, FontSize = 22 }); styles.Add(new ElementStyle(ExistingSystemTag) { Background = "#999999", Color = "#ffffff" }); styles.Add(new ElementStyle(BankStaffTag) { Background = "#999999", Color = "#ffffff" }); styles.Add(new ElementStyle(WebBrowserTag) { Shape = Shape.WebBrowser }); styles.Add(new ElementStyle(MobileAppTag) { Shape = Shape.MobileDeviceLandscape }); styles.Add(new ElementStyle(DatabaseTag) { Shape = Shape.Cylinder }); styles.Add(new ElementStyle(FailoverTag) { Opacity = 25 }); styles.Add(new RelationshipStyle(FailoverTag) { Opacity = 25, Position = 70 }); // documentation // - usually the documentation would be included from separate Markdown/AsciiDoc files, but this is just an example StructurizrDocumentationTemplate template = new StructurizrDocumentationTemplate(workspace); template.AddContextSection(internetBankingSystem, Format.Markdown, "Here is some context about the Internet Banking System...\n" + "![](embed:SystemLandscape)\n" + "![](embed:SystemContext)\n" + "### Internet Banking System\n...\n" + "### Mainframe Banking System\n...\n"); template.AddContainersSection(internetBankingSystem, Format.Markdown, "Here is some information about the containers within the Internet Banking System...\n" + "![](embed:Containers)\n" + "### Web Application\n...\n" + "### Database\n...\n"); template.AddComponentsSection(webApplication, Format.Markdown, "Here is some information about the API Application...\n" + "![](embed:Components)\n" + "### Sign in process\n" + "Here is some information about the Sign In Controller, including how the sign in process works...\n" + "![](embed:SignIn)"); template.AddDevelopmentEnvironmentSection(internetBankingSystem, Format.AsciiDoc, "Here is some information about how to set up a development environment for the Internet Banking System...\n" + "image::embed:DevelopmentDeployment[]"); template.AddDeploymentSection(internetBankingSystem, Format.AsciiDoc, "Here is some information about the live deployment environment for the Internet Banking System...\n" + "image::embed:LiveDeployment[]"); return(workspace); }
private const string DATABASE_TAG = "database"; // analizar el uso static void Main(string[] args) { // Crear el nuevo espacio de trabajo Workspace workspace = new Workspace("Arquitectura de Software - Plataforma de Gestion y Monitoreo de Transporte de Carga", "Diseño de la arquitectura de software de proyectos de transformacion digital"); Model model = workspace.Model; model.Enterprise = new Enterprise("Transport Manangement System"); // Agregar los elementos que contendra el sistema Person userCompany = model.AddPerson(Location.External, "Empresa", "Empresa que adquiere los servicios de la plataforma de gestion y seguimiento de transporte de carga"); Person userDriver = model.AddPerson(Location.External, "Chofer", "Persona encargada que transporta la carga de los clientes administrando el flujo de la operacion"); Person userOperator = model.AddPerson(Location.External, "Operador", "Persona encargada de adminstrar y monitorear las operaciones"); Person userClient = model.AddPerson(Location.External, "Cliente", "Persona interesada en realizar el seguimiento de su carga"); // SoftwareSystem tmsSoftwareSystem = model.AddSoftwareSystem(Location.Internal, "TMS Generico", "Plataforma de Gestion y Seguimiento del transporte y logistica de Carga a Nivel Nacional"); SoftwareSystem odooErpSoftwareSystem = model.AddSoftwareSystem(Location.Internal, "Odoo Sh", "ERP: Sistema de Planificacion de Recursos Empresariales"); SoftwareSystem mailServerSoftwareSystem = model.AddSoftwareSystem(Location.Internal, "Servidor de Correos", "Servidor de Correos Interno Microsoft Exchange"); SoftwareSystem fcmSoftwareSystem = model.AddSoftwareSystem(Location.Internal, "Firebase Cloud Messaging ", "Sistema de mensajeria en tiempo real multiplaforma ofrecido por Google"); SoftwareSystem azureBlobStorageSoftwareSystem = model.AddSoftwareSystem(Location.Internal, "Azure Blob Storage", "Servidor de Almacenamiento de archivos en la nube de Microsft Azure"); SoftwareSystem googlMapsPlatoformSoftwareSystem = model.AddSoftwareSystem(Location.Internal, "Google Maps Plataform", "Plataforma web que ofrece un conjunto de APIs (Aplication Interface Programming) para la gestion de mapas, rutas, direcciones, etc. Soportado por Google"); odooErpSoftwareSystem.AddTags(EXISTS_SYSTEM_TAG); mailServerSoftwareSystem.AddTags(EXISTS_SYSTEM_TAG); fcmSoftwareSystem.AddTags(EXISTS_SYSTEM_TAG); azureBlobStorageSoftwareSystem.AddTags(EXISTS_SYSTEM_TAG); googlMapsPlatoformSoftwareSystem.AddTags(EXISTS_SYSTEM_TAG); tmsSoftwareSystem.Uses(odooErpSoftwareSystem, "Integra la informacion contable de las operaciones de carga"); tmsSoftwareSystem.Uses(fcmSoftwareSystem, "Administra notificaciones y mensajes en tiempo real"); tmsSoftwareSystem.Uses(azureBlobStorageSoftwareSystem, "Administra los archivos generados por el sistema"); tmsSoftwareSystem.Uses(googlMapsPlatoformSoftwareSystem, "Integra los mapas en las aplicaciones"); tmsSoftwareSystem.Uses(mailServerSoftwareSystem, "Envia correos electronicos usando"); fcmSoftwareSystem.Delivers(userDriver, "Envia notificaciones push a la aplicación movil"); mailServerSoftwareSystem.Delivers(userClient, "Envia Correo electronico a"); userCompany.Uses(tmsSoftwareSystem, "Adquiere los servicios de la plataforma, administra y registra sus propias operaciones, choferes, clientes"); userDriver.Uses(tmsSoftwareSystem, "Oferta sus servicios y administra el flujo de la operacion"); userOperator.Uses(tmsSoftwareSystem, "Adminstrar y monitorear las operaciones, oportunidades de carga, operaciones, rutas, clientes y operadores"); userClient.Uses(tmsSoftwareSystem, "Administra sus operaciones y cotizaciones de nuevos servicios"); // Contenendores Container mobileApp = tmsSoftwareSystem.AddContainer("Mobile App", "Provee un conjunto de funcionalidades a los choferes como: postulaciones, notificaciones de posibilidades carga, gestion de operaciones, entre otros", "Flutter"); mobileApp.AddTags(MOBILE_APP_TAG); Container spaOperations = tmsSoftwareSystem.AddContainer("Single-Page Application (Portal Operaciones)", "Provee las funcionalidades de gestion y monitoreo operaciones, oportunidades, rutas de entre otras atraves del navegador web", "Javascript y Angular 9"); spaOperations.AddTags(SINGLE_PAGE_APPLICATION_TAG); Container spaClients = tmsSoftwareSystem.AddContainer("Single-Page Application (Portal Clientes)", "Provee las funcionalidades de seguimiento de operaciones y cotizaciones atraves del navegador web", "Javascript y Angular 9"); spaClients.AddTags(SINGLE_PAGE_APPLICATION_TAG); Container webApplication = tmsSoftwareSystem.AddContainer("Web Application", "Entrega el contenido estático y las Single-Page Application de los Portales de Operaciones y Clientes", "NodeJs y Express Framework"); Container apiTmsServicesApplication = tmsSoftwareSystem.AddContainer("API TMS Application", "Provee las funcionalidades de gestion de informacion para los portales via JSON/HTTPS API", "NodeJs y Express Framework"); Container apiAppServicesApplication = tmsSoftwareSystem.AddContainer("API Mobile Application", "Provee las funcionalidades de gestion de informacion para la aplicacion movil via JSON/HTTPS API", "NodeJs y Express Framework"); Container database = tmsSoftwareSystem.AddContainer("Database", "Almacena y Registra la informacion de la gestion de operaciones y procesos asociados como: Oportunidades, Postulaciones, Autenticacion de Usuarios, etc.", "Microsoft Azure SQL Database"); database.AddTags(DATABASE_TAG); userDriver.Uses(mobileApp, "Visualiza las oportunidades, operaciones, beneficios entre usando", "Flutter"); userOperator.Uses(webApplication, "Visita globaltms.la usando", "HTTPS"); userCompany.Uses(webApplication, "Visita globaltms.la usando", "HTTPS"); userClient.Uses(webApplication, "Visita globaltms.la usando", "HTTPS"); userCompany.Uses(spaOperations, "Administrar sus propias oportunidades, operaciones, rutas, clientes, choferes, entre otros. Usando", "HTTPS"); userOperator.Uses(spaOperations, "Visualiza las oportunidades, operaciones, rutas, clientes, choferes, entre otros. Usando", "HTTPS"); userClient.Uses(spaClients, "Visualiza las operaciones y cotizaciones de nuevos servicios usando", "HTTPS"); webApplication.Uses(spaClients, "Entrega al navegador web del cliente"); webApplication.Uses(spaOperations, "Entrega al navegador web del operador"); spaClients.Uses(googlMapsPlatoformSoftwareSystem, "Integra Mapa de Google en la Aplicacion Web", "HTTPS/XML"); spaOperations.Uses(googlMapsPlatoformSoftwareSystem, "Integra Mapa de Google en la Aplicacion Web", "HTTPS/XML"); mobileApp.Uses(googlMapsPlatoformSoftwareSystem, "Integra Mapa de Google en la Aplicacion Movil", "HTTPS/XML"); apiAppServicesApplication.Uses(database, "Lee y Escribe en", "Tedious MSSQL"); apiTmsServicesApplication.Uses(database, "Lee y Escribe en", "Tedious MSSQL"); apiAppServicesApplication.Uses(azureBlobStorageSoftwareSystem, "Administrar archivos en la nube usando", "HTTPS"); apiTmsServicesApplication.Uses(azureBlobStorageSoftwareSystem, "Administrar archivos en la nube usando", "HTTPS"); apiTmsServicesApplication.Uses(mailServerSoftwareSystem, "Envia correos electronicos usando", "SMTP"); apiTmsServicesApplication.Uses(odooErpSoftwareSystem, "Realiza solicitudes a la API", "HTTP/XML-RPC/JSON-RPC"); apiTmsServicesApplication.Uses(fcmSoftwareSystem, "Emision de mensajes del servidor usando", "HTTPS/JSON"); fcmSoftwareSystem.Uses(mobileApp, "Realiza difusion de los mensajes proveidos por el servidor usando", "HTTPS/JSON"); // EVENTUAL (HASTA AGREGAR LOS COMPONENTES), modificar al momento de agregar los componentes //spaClients.Uses(apiTmsServicesApplication, "Realiza solicitudes a la API", "HTTPS/JSON"); //spaOperations.Uses(apiTmsServicesApplication, "Realiza solicitudes a la API", "HTTPS/JSON"); //mobileApp.Uses(apiAppServicesApplication, "Realiza solicitudes a la API", "HTTPS/JSON"); // Componentes (API APP SERVICES) string expressApiController = "Express API Controller"; // Controllers Component userControllerMobile = apiAppServicesApplication.AddComponent("User Controller", "Permite a los usuarios autenticarse para acceder a la aplicacion movil", "Express API Controller"); Component carrierControllerMobile = apiAppServicesApplication.AddComponent("Carrier Controller", "Permite gestionar los datos relacionados a su perfil", "Express API Controller"); Component unitTransportControllerMobile = apiAppServicesApplication.AddComponent("UnitTransport Controller", "Permite gestionar los datos relacionados a su unidad de transporte", "Express API Controller"); Component loadingOrderControllerMobile = apiAppServicesApplication.AddComponent("LoadingOrder Controller", "Permite gestionar las operaciones vinculadas como tambien el flujo de cada una de ellas", "Express API Controller"); // Services Component servicePassportAuthenticationMobile = apiAppServicesApplication.AddComponent("Module Passport Authentication", "Provee autenticacion segura del lado del servidor", "Node Module"); Component serviceAzureBlobStorageMobile = apiAppServicesApplication.AddComponent("Service Azure Blob Storage", "Provee los metodos para administrar archivos a la nube de Azure", "Node Module"); // Business Component userBusinessMobile = apiAppServicesApplication.AddComponent("User Business", "Provee funcionalidades de administracion de usuarios", "Javascript Class"); Component carrierBusinessMobile = apiAppServicesApplication.AddComponent("Carrier Business", "Provee funcionalidades de gestion de informacion de los choferes", "Javascript Class"); Component unitTransportBusinessMobile = apiAppServicesApplication.AddComponent("UnitTransport Business", "Provee funcionalidades de gestion de informacion de las unidades de transporte", "Javascript Class"); Component loadingOrderBusinessMobile = apiAppServicesApplication.AddComponent("LoadingOrder Business", "Provee funcionalidades de gestion del flujo de datos de las ordenes de carga", "Javascript Class"); // Conexion a Base de datos Component moduleSequelizeOrmAppServicesMobile = apiAppServicesApplication.AddComponent("Module Sequelize ORM", "Provee una capa de abstraccion para la conexiona a la base de datos", "Node Module"); // Relations apiAppServicesApplication.Components.Where(comp => expressApiController.Equals(comp.Technology)) .ToList() .ForEach(comp => mobileApp.Uses(comp, "Realiza solicitudes a la API", "HTTPS/JSON")); userControllerMobile.Uses(servicePassportAuthenticationMobile, "Usa"); carrierControllerMobile.Uses(serviceAzureBlobStorageMobile, "Usa"); unitTransportControllerMobile.Uses(serviceAzureBlobStorageMobile, "Usa"); loadingOrderControllerMobile.Uses(serviceAzureBlobStorageMobile, "Usa"); serviceAzureBlobStorageMobile.Uses(azureBlobStorageSoftwareSystem, "Usa", "HTTPS"); userControllerMobile.Uses(userBusinessMobile, "Usa"); carrierControllerMobile.Uses(carrierBusinessMobile, "Usa"); unitTransportControllerMobile.Uses(unitTransportBusinessMobile, "Usa"); loadingOrderControllerMobile.Uses(loadingOrderBusinessMobile, "Usa"); userBusinessMobile.Uses(moduleSequelizeOrmAppServicesMobile, "Usa"); carrierBusinessMobile.Uses(moduleSequelizeOrmAppServicesMobile, "Usa"); unitTransportBusinessMobile.Uses(moduleSequelizeOrmAppServicesMobile, "Usa"); loadingOrderBusinessMobile.Uses(moduleSequelizeOrmAppServicesMobile, "Usa"); moduleSequelizeOrmAppServicesMobile.Uses(database, "Lee y Escribe en", "MSSQL Tedious"); // Componentes (API TMS SERVICES) // Controllers Component userControllerTms = apiTmsServicesApplication.AddComponent("User Controller", "Permite a los usuarios autenticarse para acceder a los portales web", "Express API Controller"); Component carrierControllerTms = apiTmsServicesApplication.AddComponent("Carrier Controller", "Permite gestionar los datos relacionados al perfil del chofer", "Express API Controller"); Component unitTransportControllerTms = apiTmsServicesApplication.AddComponent("UnitTransport Controller", "Permite gestionar los datos relacionados a su unidad de transporte", "Express API Controller"); Component loadingOrderControllerTms = apiTmsServicesApplication.AddComponent("LoadingOrder Controller", "Permite administrar las ordenes de carga", "Express API Controller"); Component opportunityControllerTms = apiTmsServicesApplication.AddComponent("Opportunity Controller", "Permite administrar las oportunidades de carga", "Express API Controller"); Component operationControllerTms = apiTmsServicesApplication.AddComponent("Operation Controller", "Permite administrar las operaciones y su flujo", "Express API Controller"); Component clientControllerTms = apiTmsServicesApplication.AddComponent("Client Controller", "Permite gestionar los datos de clientes", "Express API Controller"); // Services Component servicePassportAuthenticationTms = apiTmsServicesApplication.AddComponent("Module Passport Authentication", "Provee seguridad en autenticacion de usuario del lado del servidor", "Node Module"); Component serviceAzureBlobStorageTms = apiTmsServicesApplication.AddComponent("Service Azure Blob Storage", "Provee los metodos para administrar archivos a la nube de Azure", "Node Module"); Component serviceFirebaseCloudMessagingTms = apiTmsServicesApplication.AddComponent("Service Firebase Cloud Messaging", "Provee funcionalidades para emitir/recepcionar notificaciones en tiempo real", "API Firebase"); Component serviceOdooApiTms = apiTmsServicesApplication.AddComponent("Service Odoo API", "Provee funcionalidades de integracion con la base de datos de Odoo", "Node Module"); Component serviceMailerTms = apiTmsServicesApplication.AddComponent("Service NodeMailer", "Provee funcionalidades para enviar correos electronicos", "Node Module"); // Business Component userBusinessTms = apiTmsServicesApplication.AddComponent("User Business", "Provee funcionalidades de administracion de usuarios", "Javascript Class"); Component carrierBusinessTms = apiTmsServicesApplication.AddComponent("Carrier Business", "Provee funcionalidades de gestion de informacion de los choferes", "Javascript Class"); Component unitTransportBusinessTms = apiTmsServicesApplication.AddComponent("UnitTransport Business", "Provee funcionalidades de gestion de informacion de las unidades de transporte", "Javascript Class"); Component opportunityBusinessTms = apiTmsServicesApplication.AddComponent("Opportunity Business", "Provee funcionalidades de gestion del reclutamiento de choferes para las operaciones", "Javascript Class"); Component operationBusinessTms = apiTmsServicesApplication.AddComponent("Operation Business", "Provee funcionalidades de gestion y seguimiento de operaciones", "Javascript Class"); Component clientBusinessTms = apiTmsServicesApplication.AddComponent("Client Business", "Provee funcionalidades de gestion de los clientes", "Javascript Class"); Component loadingOrderBusinessTms = apiTmsServicesApplication.AddComponent("LoadingOrder Business", "Provee funcionalidades de gestion del flujo de datos de las ordenes de carga", "Javascript Class"); // Conexion a Base de datos Component moduleSequelizeOrmAppServicesTms = apiTmsServicesApplication.AddComponent("Module Sequelize ORM", "Provee una capa de abstraccion para la conexiona a la base de datos", "Node Module"); // Relations apiTmsServicesApplication.Components.Where(comp => expressApiController.Equals(comp.Technology)) .ToList() .ForEach(comp => spaOperations.Uses(comp, "Realiza solicitudes a la API", "HTTPS/JSON")); List <string> excludeControllersForClients = new List <string> { "Carrier Controller", "UnitTransport Controller", "Opportunity Controller" }; apiTmsServicesApplication.Components.Where(comp => expressApiController.Equals(comp.Technology)) .ToList() .ForEach(comp => { if (!excludeControllersForClients.Contains(comp.Name)) { spaClients.Uses(comp, "Realiza solicitudes a la API", "HTTPS/JSON"); } }); userControllerTms.Uses(servicePassportAuthenticationTms, "Usa"); carrierControllerTms.Uses(serviceFirebaseCloudMessagingTms, "Usa"); unitTransportControllerTms.Uses(serviceFirebaseCloudMessagingTms, "Usa"); loadingOrderControllerTms.Uses(serviceAzureBlobStorageTms, "Usa"); loadingOrderControllerTms.Uses(serviceFirebaseCloudMessagingTms, "Usa"); loadingOrderControllerTms.Uses(serviceOdooApiTms, "Usa"); operationControllerTms.Uses(serviceFirebaseCloudMessagingTms, "Usa"); operationControllerTms.Uses(serviceOdooApiTms, "Usa"); opportunityControllerTms.Uses(serviceFirebaseCloudMessagingTms, "Usa"); clientControllerTms.Uses(serviceMailerTms, "Usa"); serviceAzureBlobStorageTms.Uses(azureBlobStorageSoftwareSystem, "Usa", "HTTPS"); serviceMailerTms.Uses(mailServerSoftwareSystem, "Envia correos electronicos usando", "SMTP"); serviceOdooApiTms.Uses(odooErpSoftwareSystem, "Usa", "HTTP/XML-RPC/JSON-RPC"); serviceFirebaseCloudMessagingTms.Uses(fcmSoftwareSystem, "Usa", "HTTPS"); serviceAzureBlobStorageTms.Uses(azureBlobStorageSoftwareSystem, "Usa", "HTTPS"); userControllerTms.Uses(userBusinessTms, "Usa"); carrierControllerTms.Uses(carrierBusinessTms, "Usa"); unitTransportControllerTms.Uses(unitTransportBusinessTms, "Usa"); loadingOrderControllerTms.Uses(loadingOrderBusinessTms, "Usa"); operationControllerTms.Uses(operationBusinessTms, "Usa"); opportunityControllerTms.Uses(opportunityBusinessTms, "Usa"); clientControllerTms.Uses(clientBusinessTms, "Usa"); userBusinessTms.Uses(moduleSequelizeOrmAppServicesTms, "Usa"); carrierBusinessTms.Uses(moduleSequelizeOrmAppServicesTms, "Usa"); unitTransportBusinessTms.Uses(moduleSequelizeOrmAppServicesTms, "Usa"); loadingOrderBusinessTms.Uses(moduleSequelizeOrmAppServicesTms, "Usa"); opportunityBusinessTms.Uses(moduleSequelizeOrmAppServicesTms, "Usa"); operationBusinessTms.Uses(moduleSequelizeOrmAppServicesTms, "Usa"); clientBusinessTms.Uses(moduleSequelizeOrmAppServicesTms, "Usa"); moduleSequelizeOrmAppServicesTms.Uses(database, "Lee y Escribe en", "MSSQL Tedious"); model.AddImplicitRelationships(); // Definir la visualizacion de los diagramas ViewSet views = workspace.Views; SystemContextView systemContextView = views.CreateSystemContextView(tmsSoftwareSystem, "Contexto de Sistema", "Diagrama de Contexto de Sistema (Nivel 1)"); systemContextView.EnterpriseBoundaryVisible = false; systemContextView.AddNearestNeighbours(tmsSoftwareSystem); systemContextView.PaperSize = PaperSize.A5_Landscape; /*contextView.AddAllSoftwareSystems(); * contextView.AddAllPeople();*/ ContainerView containerView = views.CreateContainerView(tmsSoftwareSystem, "Contenedores de Sistema", "Diagrama de contenedores de Sistema (Nivel 2)"); containerView.Add(userOperator); containerView.Add(userClient); containerView.Add(userCompany); containerView.Add(userDriver); containerView.AddAllContainers(); containerView.AddAllSoftwareSystems(); containerView.Remove(tmsSoftwareSystem); // Componentes for API Mobile Application ComponentView componentMobileView = views.CreateComponentView(apiAppServicesApplication, "Componentes de Sistema - API Mobile", "Diagrama de Componentes de Sistema (Nivel 3)"); componentMobileView.Add(mobileApp); componentMobileView.Add(azureBlobStorageSoftwareSystem); componentMobileView.Add(database); componentMobileView.AddAllComponents(); componentMobileView.PaperSize = PaperSize.A5_Landscape; // Componentes for API TMS Application ComponentView componentTMSView = views.CreateComponentView(apiTmsServicesApplication, "Componentes de Sistema - API TMS", "Diagrama de Componentes de Sistema (Nivel 3)"); componentTMSView.Add(spaClients); componentTMSView.Add(spaOperations); componentTMSView.Add(azureBlobStorageSoftwareSystem); componentTMSView.Add(mailServerSoftwareSystem); componentTMSView.Add(odooErpSoftwareSystem); componentTMSView.Add(fcmSoftwareSystem); componentTMSView.Add(database); componentTMSView.AddAllComponents(); componentTMSView.PaperSize = PaperSize.A5_Landscape; // Agregar algo de documentacion StructurizrDocumentationTemplate template = new StructurizrDocumentationTemplate(workspace); template.AddContextSection(tmsSoftwareSystem, Format.Markdown, "Definiendo el contexto del sistema de software\n![](embed:SystemContext)"); // agregando estilos personalizados Styles styles = views.Configuration.Styles; styles.Add(new ElementStyle(Tags.SoftwareSystem) { Background = "#1168bd", Color = "#ffffff" }); styles.Add(new ElementStyle(Tags.Person) { Background = "#08427b", Color = "#ffffff", Shape = Shape.Person }); styles.Add(new ElementStyle(Tags.Container) { Background = "#438dd5", Color = "#ffffff" }); styles.Add(new ElementStyle(Tags.Component) { Background = "#85bbf0", Color = "#000000" }); styles.Add(new ElementStyle(EXISTS_SYSTEM_TAG) { Background = "#999999", Color = "#ffffff" }); styles.Add(new ElementStyle(MOBILE_APP_TAG) { Shape = Shape.MobileDeviceLandscape }); styles.Add(new ElementStyle(SINGLE_PAGE_APPLICATION_TAG) { Shape = Shape.WebBrowser }); styles.Add(new ElementStyle(DATABASE_TAG) { Shape = Shape.Cylinder }); // cargar el documento actual (formato JSON) updateWorkspaceToStructurizr(workspace); Console.WriteLine("Generated Diagram Sucessfully!"); }
private void PopulateWorkspace() { Model model = _workspace.Model; ViewSet views = _workspace.Views; model.Enterprise = new Enterprise("Some Enterprise"); Person user = model.AddPerson(Location.Internal, "User", ""); SoftwareSystem softwareSystem = model.AddSoftwareSystem(Location.Internal, "Software System", ""); user.Uses(softwareSystem, "Uses"); SoftwareSystem emailSystem = model.AddSoftwareSystem(Location.External, "E-mail System", ""); softwareSystem.Uses(emailSystem, "Sends e-mail using"); emailSystem.Delivers(user, "Delivers e-mails to"); Container webApplication = softwareSystem.AddContainer("Web Application", "", ""); Container database = softwareSystem.AddContainer("Database", "", ""); user.Uses(webApplication, null, "HTTP"); webApplication.Uses(database, "Reads from and writes to", "JDBC"); webApplication.Uses(emailSystem, "Sends e-mail using"); Component controller = webApplication.AddComponent("SomeController", "", "Spring MVC Controller"); Component emailComponent = webApplication.AddComponent("EmailComponent", ""); Component repository = webApplication.AddComponent("SomeRepository", "", "Spring Data"); user.Uses(controller, "Uses", "HTTP"); controller.Uses(repository, "Uses"); controller.Uses(emailComponent, "Sends e-mail using"); repository.Uses(database, "Reads from and writes to", "JDBC"); emailComponent.Uses(emailSystem, "Sends e-mails using", "SMTP"); DeploymentNode webServer = model.AddDeploymentNode("Web Server", "A server hosted at AWS EC2.", "Ubuntu 12.04 LTS"); webServer.AddDeploymentNode("Apache Tomcat", "The live web server", "Apache Tomcat 8.x") .Add(webApplication); DeploymentNode databaseServer = model.AddDeploymentNode("Database Server", "A server hosted at AWS EC2.", "Ubuntu 12.04 LTS"); databaseServer.AddDeploymentNode("MySQL", "The live database server", "MySQL 5.5.x") .Add(database); SystemLandscapeView systemLandscapeView = views.CreateSystemLandscapeView("enterpriseContext", ""); systemLandscapeView.AddAllElements(); SystemContextView systemContextView = views.CreateSystemContextView(softwareSystem, "systemContext", ""); systemContextView.AddAllElements(); ContainerView containerView = views.CreateContainerView(softwareSystem, "containers", ""); containerView.AddAllElements(); ComponentView componentView = views.CreateComponentView(webApplication, "components", ""); componentView.AddAllElements(); DynamicView dynamicView = views.CreateDynamicView(webApplication, "dynamic", ""); dynamicView.Add(user, "Requests /something", controller); dynamicView.Add(controller, repository); dynamicView.Add(repository, "select * from something", database); DeploymentView deploymentView = views.CreateDeploymentView(softwareSystem, "deployment", ""); deploymentView.AddAllDeploymentNodes(); }
static void Banking() { const long workspaceId = 65772; const string apiKey = "60814d99-843f-4209-aaf8-5543b56f7d22"; const string apiSecret = "3ee20c69-c531-4ae7-80ec-fdf71168069c"; StructurizrClient structurizrClient = new StructurizrClient(apiKey, apiSecret); Workspace workspace = new Workspace("Ezlabor", "Ezlabor - C4 Model"); Model model = workspace.Model; SoftwareSystem EzLaborystem = model.AddSoftwareSystem("Ezlabor System", "Ofrece el contenido estático y la aplicación desde una página de red de freelancers y empleadores"); SoftwareSystem gmailSystem = model.AddSoftwareSystem("Gmail System", "Sistema de correos electrónicos interno de google"); SoftwareSystem stripeSystem = model.AddSoftwareSystem("Stripe System", "Sistema de pagos por internet "); SoftwareSystem TwilioSystem = model.AddSoftwareSystem("Twilio System", "Sistema de verificiación de cuenta mediante SMS "); //SoftwareSystem googleMapsApi = model.AddSoftwareSystem("Google Maps API", "Permite a los clientes consultar información de sus cuentas y realizar operaciones."); Person Empresa = model.AddPerson("Empresa", "Compañia que busca los servicios de un freelancer"); Person Freelancer = model.AddPerson("Freelancer", "Personas especializadas en ciertos rubros que buscan trabajar de manera independiente"); Person Empleador = model.AddPerson("Empleador", "Persona con una microempresa o emprendimiento que necesita del servico de un freelancer"); EzLaborystem.AddTags("Main System"); gmailSystem.AddTags("Gmail API"); //googleMapsApi.AddTags("Google Maps API"); Empresa.Uses(EzLaborystem, "Visita el sitio usando", "[HTTPS]"); Freelancer.Uses(EzLaborystem, "Visita el sitio usando", "[HTTPS]"); Empleador.Uses(EzLaborystem, "Visita el sitio usando", "[HTTPS]"); EzLaborystem.Uses(gmailSystem, "Enviar mensajes de correos electrónicos interno de google"); EzLaborystem.Uses(stripeSystem, "Realiza peticiones a la API"); EzLaborystem.Uses(TwilioSystem, "Realiza peticiones a la API"); gmailSystem.Delivers(Empresa, "Envia mensajes de correo electrónico"); gmailSystem.Delivers(Freelancer, "Envia mensajes de correo electrónico"); gmailSystem.Delivers(Empleador, "Envia mensajes de correo electrónico"); ViewSet viewSet = workspace.Views; // 1. Diagrama de Contexto SystemContextView contextView = viewSet.CreateSystemContextView(EzLaborystem, "Contexto", "Diagrama de contexto - Ezlabor"); contextView.PaperSize = PaperSize.A4_Landscape; contextView.AddAllSoftwareSystems(); contextView.AddAllPeople(); Styles styles = viewSet.Configuration.Styles; styles.Add(new ElementStyle(Tags.Person) { Background = "#0a60ff", Color = "#ffffff", Shape = Shape.Person }); styles.Add(new ElementStyle("Gmail API") { Background = "#90714c", Color = "#ffffff", Shape = Shape.RoundedBox }); styles.Add(new ElementStyle("Google Maps API") { Background = "#a5cdff", Color = "#ffffff", Shape = Shape.RoundedBox }); // 2. Diagrama de Contenedores Container webApplication = EzLaborystem.AddContainer("Aplicación Web Responsive", "Permite alos usuarios administrar el perfil, ver los mensajes, ver ofertas laboraler, etc", "Angular, nginx port 80"); Container restApi = EzLaborystem.AddContainer("RESTful API", "Proporciona funcionalidad de red entre freelancers de perros y dueños", "SpringBoot, nginx port 5000"); Container database = EzLaborystem.AddContainer("Base de Datos", "Repositorio de información de los usuarios", "Mysql"); Container LandingPage = EzLaborystem.AddContainer("Landing Page", "Página con información de la StartUp", "Html, CSS y JS"); webApplication.AddTags("WebApp"); restApi.AddTags("API"); database.AddTags("Database"); LandingPage.AddTags("LandingPage"); Empresa.Uses(webApplication, "Usa", "https 443"); Empresa.Uses(LandingPage, "Usa", "https 443"); Freelancer.Uses(webApplication, "Usa", "https 443"); Freelancer.Uses(LandingPage, "Usa", "https 443"); Empleador.Uses(webApplication, "Usa", "https 443"); Empleador.Uses(LandingPage, "Usa", "https 443"); webApplication.Uses(restApi, "Usa", "https 443"); webApplication.Uses(stripeSystem, "https 443"); webApplication.Uses(gmailSystem, "https 443"); webApplication.Uses(TwilioSystem, "https 443"); restApi.Uses(database, "Persistencia de datos"); LandingPage.Uses(webApplication, "Redirige"); styles.Add(new ElementStyle("WebApp") { Background = "#9d33d6", Color = "#ffffff", Shape = Shape.WebBrowser, Icon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjM1MyIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMjU2IDI3MiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZD0iTS4xIDQ1LjUyMkwxMjUuOTA4LjY5N2wxMjkuMTk2IDQ0LjAyOC0yMC45MTkgMTY2LjQ1LTEwOC4yNzcgNTkuOTY2LTEwNi41ODMtNTkuMTY5TC4xIDQ1LjUyMnoiIGZpbGw9IiNFMjMyMzciLz48cGF0aCBkPSJNMjU1LjEwNCA0NC43MjVMMTI1LjkwOC42OTd2MjcwLjQ0NGwxMDguMjc3LTU5Ljg2NiAyMC45MTktMTY2LjU1eiIgZmlsbD0iI0I1MkUzMSIvPjxwYXRoIGQ9Ik0xMjYuMTA3IDMyLjI3NEw0Ny43MTQgMjA2LjY5M2wyOS4yODUtLjQ5OCAxNS43MzktMzkuMzQ3aDcwLjMyNWwxNy4yMzMgMzkuODQ1IDI3Ljk5LjQ5OC04Mi4xNzktMTc0LjkxN3ptLjIgNTUuODgybDI2LjQ5NiA1NS4zODNoLTQ5LjgwNmwyMy4zMS01NS4zODN6IiBmaWxsPSIjRkZGIi8+PC9zdmc+" }); styles.Add(new ElementStyle("API") { Background = "#929000", Color = "#ffffff", Shape = Shape.RoundedBox, Icon = "data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNzY3LjggNzY4IiB3aWR0aD0iMjQ5OSIgaGVpZ2h0PSIyNTAwIj48c3R5bGU+LnN0MHtmaWxsOiM3N2JjMWZ9PC9zdHlsZT48cGF0aCBjbGFzcz0ic3QwIiBkPSJNNjk4LjMgNDBjLTEwLjggMjUuOC0yNC41IDUwLjMtNDEgNzIuOEM1ODUuMSA0MC42IDQ4Ny4xIDAgMzg1IDAgMTczLjggMCAwIDE3NCAwIDM4NS41IDAgNDkxIDQzLjIgNTkyIDExOS42IDY2NC44bDE0LjIgMTIuNmM2OS40IDU4LjUgMTU3LjMgOTAuNyAyNDggOTAuNyAyMDAuOCAwIDM2OS42LTE1Ny40IDM4My45LTM1OCAxMC41LTk4LjItMTguMy0yMjIuNC02Ny40LTM3MC4xem0tNTI0IDYyN2MtNi4yIDcuNy0xNS43IDEyLjItMjUuNiAxMi4yLTE4LjEgMC0zMi45LTE0LjktMzIuOS0zM3MxNC45LTMzIDMyLjktMzNjNy41IDAgMTQuOSAyLjYgMjAuNyA3LjQgMTQuMSAxMS40IDE2LjMgMzIuMyA0LjkgNDYuNHptNTIyLjQtMTE1LjRjLTk1IDEyNi43LTI5Ny45IDg0LTQyOCA5MC4xIDAgMC0yMy4xIDEuNC00Ni4zIDUuMiAwIDAgOC43LTMuNyAyMC04IDkxLjMtMzEuOCAxMzQuNS0zOCAxOTAtNjYuNSAxMDQuNS01My4yIDIwNy44LTE2OS42IDIyOS4zLTI5MC43QzYyMS45IDM5OC4yIDUwMS4zIDQ5OC4zIDM5MS40IDUzOWMtNzUuMyAyNy44LTIxMS4zIDU0LjgtMjExLjMgNTQuOGwtNS41LTIuOUM4MiA1NDUuOCA3OS4yIDM0NS4xIDI0Ny41IDI4MC4zYzczLjctMjguNCAxNDQuMi0xMi44IDIyMy44LTMxLjggODUtMjAuMiAxODMuMy04NCAyMjMuMy0xNjcuMiA0NC44IDEzMy4xIDk4LjcgMzQxLjUgMi4xIDQ3MC4zeiIvPjwvc3ZnPg==" }); styles.Add(new ElementStyle("Database") { Background = "#ff0000", Color = "#ffffff", Shape = Shape.Cylinder }); styles.Add(new ElementStyle("LandingPage") { Background = "#d1c07b", Color = "#ffffff", Shape = Shape.WebBrowser }); ContainerView containerView = viewSet.CreateContainerView(EzLaborystem, "Contenedor", "Diagrama de contenedores - EzLabor"); contextView.PaperSize = PaperSize.A4_Landscape; containerView.AddAllElements(); // 3. Diagrama de Componentes //Controllers Component signinController = restApi.AddComponent("Sign in Controller", "Permite a los usuarios ingresar al sistema de Ezlabor", "SpringBoot REST Controller"); Component notificaionSystemController = restApi.AddComponent("Notification System Controller", "Permite al usuario recibir notificaciones", "SpringBoot REST Controller"); Component subscriptionController = restApi.AddComponent("Subscription System Controller", "Permite al usuario recibir notificaciones", "SpringBoot REST Controller"); Component MessageSystemController = restApi.AddComponent("Message System Controller", "Permite a los usuarios comunicarse mediante mensajes det texto", "SpringBoot REST Controller"); Component LocationsController = restApi.AddComponent("Location System Controller", "Permite a los usuarios ver los distintos tipos de localidades", "SpringBoot REST Controller"); Component UserProfileController = restApi.AddComponent("User profile System Controller", "Permite a los usuarios editar su perfil", "SpringBoot REST Controller"); Component HiringController = restApi.AddComponent("Hiring System Controller", "Permite usar los servicios de contratación y reunión que estan disponibles", "SpringBoot REST Controller"); //Services Component signinService = restApi.AddComponent("Sign in Service", "Permite usar los servicios de sign in que se encuentra en la API"); Component notificaionSystemService = restApi.AddComponent("Notification System Service", "Permite usar el servicio de notificación de la API"); Component subscriptionService = restApi.AddComponent("Subscription System Service", "Permite usar los servicios de subscripción de la API"); Component MessageSystemService = restApi.AddComponent("Message System Service", "Permite usar el servicio de mensajería de la API"); Component LocationsService = restApi.AddComponent("Locations System Service", "Permite usar el servicio de localización de la API"); Component UserProfileService = restApi.AddComponent("User profile System Service", "Permite usar el servicio de perfil de usuario de la API"); Component HiringService = restApi.AddComponent("Hiring System Service", "Permite usar el servicio de contratación de la API"); //Repositories Component signinRepository = restApi.AddComponent("Sign in Repository", "Permite la comunicación entre el servicio de sign in y la base de datos"); Component notificaionSystemRepository = restApi.AddComponent("Notification System Repository", "Permite la comunicación entre el servicio de notificación y la base de datos"); Component subscriptionRepository = restApi.AddComponent("Subscription System Repository", "Permite la comunicación entre el servicio de subscripción y la base de datos"); Component MessageSystemRepository = restApi.AddComponent("Message System Repository", "Permite la comunicación entre el servicio de mensajería y la base de datos"); Component LocationsRepository = restApi.AddComponent("Location System Repository", "Permite la comunicación entre el servicio localización y la base de datos"); Component UserProfileRepository = restApi.AddComponent("User profile System Repository", "Permite la comunicación entre el servicio de perfil de usuario y la base de datos"); Component HiringRepository = restApi.AddComponent("Hiring System Repository", "Permite la comunicación entre el servicio de contratación y la base de datos"); // Uses restApi.Components.Where(c => "SpringBoot REST Controller".Equals(c.Technology)).ToList().ForEach(c => webApplication.Uses(c, "Uses", "HTTPS")); signinController.Uses(signinService, "Uses"); notificaionSystemController.Uses(notificaionSystemService, "Uses"); subscriptionController.Uses(subscriptionService, "Uses"); MessageSystemController.Uses(MessageSystemService, "Uses"); LocationsController.Uses(LocationsService, "Uses"); UserProfileController.Uses(UserProfileService, "Uses"); HiringController.Uses(HiringService, "Uses"); signinService.Uses(signinRepository, "Uses"); notificaionSystemService.Uses(notificaionSystemRepository, "Uses"); subscriptionService.Uses(subscriptionRepository, "Uses"); MessageSystemService.Uses(MessageSystemRepository, "Uses"); LocationsService.Uses(LocationsRepository, "Uses"); UserProfileService.Uses(UserProfileRepository, "Uses"); HiringService.Uses(HiringRepository, "Uses"); signinRepository.Uses(database, "Lee y escribes datos"); notificaionSystemRepository.Uses(database, "Lee y escribes datos"); subscriptionRepository.Uses(database, "Lee y escribes datos"); MessageSystemRepository.Uses(database, "Lee y escribes datos"); LocationsRepository.Uses(database, "Lee y escribes datos"); UserProfileRepository.Uses(database, "Lee y escribes datos"); HiringRepository.Uses(database, "Lee y escribes datos"); ComponentView componentViewForRestApi = viewSet.CreateComponentView(restApi, "Components", "The components diagram for the REST API"); componentViewForRestApi.PaperSize = PaperSize.A4_Landscape; componentViewForRestApi.AddAllContainers(); componentViewForRestApi.AddAllComponents(); componentViewForRestApi.Add(Empleador); componentViewForRestApi.Add(Empresa); componentViewForRestApi.Add(Freelancer); structurizrClient.UnlockWorkspace(workspaceId); structurizrClient.PutWorkspace(workspaceId, workspace); }
static void Banking() { const long workspaceId = 0; const string apiKey = ""; const string apiSecret = ""; StructurizrClient structurizrClient = new StructurizrClient(apiKey, apiSecret); Workspace workspace = new Workspace("Banking", "Banking - C4 Model"); Model model = workspace.Model; SoftwareSystem internetBankingSystem = model.AddSoftwareSystem("Internet Banking", "Permite a los clientes consultar información de sus cuentas y realizar operaciones."); SoftwareSystem mainframeBankingSystem = model.AddSoftwareSystem("Mainframe Banking", "Almacena información del core bancario."); SoftwareSystem mobileAppSystem = model.AddSoftwareSystem("Mobile App", "Permite a los clientes consultar información de sus cuentas y realizar operaciones."); SoftwareSystem emailSystem = model.AddSoftwareSystem("SendGrid", "Servicio de envío de notificaciones por email."); Person cliente = model.AddPerson("Cliente", "Cliente del banco."); Person cajero = model.AddPerson("Cajero", "Empleado del banco."); mainframeBankingSystem.AddTags("Mainframe"); mobileAppSystem.AddTags("Mobile App"); emailSystem.AddTags("SendGrid"); cliente.Uses(internetBankingSystem, "Realiza consultas y operaciones bancarias."); cliente.Uses(mobileAppSystem, "Realiza consultas y operaciones bancarias."); cajero.Uses(mainframeBankingSystem, "Usa"); internetBankingSystem.Uses(mainframeBankingSystem, "Usa"); internetBankingSystem.Uses(emailSystem, "Envía notificaciones de email"); mobileAppSystem.Uses(internetBankingSystem, "Usa"); emailSystem.Delivers(cliente, "Envía notificaciones de email", "SendGrid"); ViewSet viewSet = workspace.Views; // 1. Diagrama de Contexto SystemContextView contextView = viewSet.CreateSystemContextView(internetBankingSystem, "Contexto", "Diagrama de contexto - Banking"); contextView.PaperSize = PaperSize.A4_Landscape; contextView.AddAllSoftwareSystems(); contextView.AddAllPeople(); //contextView.EnableAutomaticLayout(); Styles styles = viewSet.Configuration.Styles; styles.Add(new ElementStyle(Tags.Person) { Background = "#0a60ff", Color = "#ffffff", Shape = Shape.Person }); styles.Add(new ElementStyle("Mobile App") { Background = "#29c732", Color = "#ffffff", Shape = Shape.MobileDevicePortrait }); styles.Add(new ElementStyle("Mainframe") { Background = "#90714c", Color = "#ffffff", Shape = Shape.RoundedBox }); styles.Add(new ElementStyle("SendGrid") { Background = "#a5cdff", Color = "#ffffff", Shape = Shape.RoundedBox }); // 2. Diagrama de Contenedores Container webApplication = internetBankingSystem.AddContainer("Aplicación Web", "Permite a los clientes consultar información de sus cuentas y realizar operaciones.", "ReactJS, nginx port 80"); Container restApi = internetBankingSystem.AddContainer("RESTful API", "Permite a los clientes consultar información de sus cuentas y realizar operaciones.", "Net Core, nginx port 80"); Container worker = internetBankingSystem.AddContainer("Worker", "Manejador del bus de mensajes.", "Net Core"); Container database = internetBankingSystem.AddContainer("Base de Datos", "Repositorio de información bancaria.", "Oracle 12c port 1521"); Container messageBus = internetBankingSystem.AddContainer("Bus de Mensajes", "Transporte de eventos del dominio.", "RabbitMQ"); webApplication.AddTags("WebApp"); restApi.AddTags("API"); worker.AddTags("Worker"); database.AddTags("Database"); messageBus.AddTags("MessageBus"); cliente.Uses(webApplication, "Usa", "https 443"); webApplication.Uses(restApi, "Usa", "https 443"); worker.Uses(restApi, "Usa", "https 443"); worker.Uses(messageBus, "Usa"); worker.Uses(mainframeBankingSystem, "Usa"); restApi.Uses(database, "Usa", "jdbc 1521"); restApi.Uses(messageBus, "Usa"); restApi.Uses(emailSystem, "Usa", "https 443"); mobileAppSystem.Uses(restApi, "Usa"); styles.Add(new ElementStyle("WebApp") { Background = "#9d33d6", Color = "#ffffff", Shape = Shape.WebBrowser, Icon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xMS41IC0xMC4yMzE3NCAyMyAyMC40NjM0OCI+CiAgPHRpdGxlPlJlYWN0IExvZ288L3RpdGxlPgogIDxjaXJjbGUgY3g9IjAiIGN5PSIwIiByPSIyLjA1IiBmaWxsPSIjNjFkYWZiIi8+CiAgPGcgc3Ryb2tlPSIjNjFkYWZiIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIi8+CiAgICA8ZWxsaXBzZSByeD0iMTEiIHJ5PSI0LjIiIHRyYW5zZm9ybT0icm90YXRlKDYwKSIvPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIiB0cmFuc2Zvcm09InJvdGF0ZSgxMjApIi8+CiAgPC9nPgo8L3N2Zz4K" }); styles.Add(new ElementStyle("API") { Background = "#929000", Color = "#ffffff", Shape = Shape.RoundedBox, Icon = "https://dotnet.microsoft.com/static/images/redesign/downloads-dot-net-core.svg?v=U_8I9gzFF2Cqi5zUNx-kHJuou_BWNurkhN_kSm3mCmo" }); styles.Add(new ElementStyle("Worker") { Icon = "https://dotnet.microsoft.com/static/images/redesign/downloads-dot-net-core.svg?v=U_8I9gzFF2Cqi5zUNx-kHJuou_BWNurkhN_kSm3mCmo" }); styles.Add(new ElementStyle("Database") { Background = "#ff0000", Color = "#ffffff", Shape = Shape.Cylinder, Icon = "https://4.bp.blogspot.com/-5JVtZBLlouA/V2LhWdrafHI/AAAAAAAADeU/_3bo_QH1WGApGAl-U8RkrFzHjdH6ryMoQCLcB/s200/12cdb.png" }); styles.Add(new ElementStyle("MessageBus") { Width = 850, Background = "#fd8208", Color = "#ffffff", Shape = Shape.Pipe, Icon = "https://www.rabbitmq.com/img/RabbitMQ-logo.svg" }); ContainerView containerView = viewSet.CreateContainerView(internetBankingSystem, "Contenedor", "Diagrama de contenedores - Banking"); contextView.PaperSize = PaperSize.A4_Landscape; containerView.AddAllElements(); //containerView.EnableAutomaticLayout(); // 3. Diagrama de Componentes Component transactionController = restApi.AddComponent("Transactions Controller", "Allows users to perform transactions.", "Spring Boot REST Controller"); Component signinController = restApi.AddComponent("SignIn Controller", "Allows users to sign in to the Internet Banking System.", "Spring Boot REST Controller"); Component accountsSummaryController = restApi.AddComponent("Accounts Controller", "Provides customers with an summary of their bank accounts.", "Spring Boot REST Controller"); Component securityComponent = restApi.AddComponent("Security Component", "Provides functionality related to signing in, changing passwords, etc.", "Spring Bean"); Component mainframeBankingSystemFacade = restApi.AddComponent("Mainframe Banking System Facade", "A facade onto the mainframe banking system.", "Spring Bean"); restApi.Components.Where(c => "Spring Boot REST Controller".Equals(c.Technology)).ToList().ForEach(c => webApplication.Uses(c, "Uses", "HTTPS")); signinController.Uses(securityComponent, "Uses"); accountsSummaryController.Uses(mainframeBankingSystemFacade, "Uses"); securityComponent.Uses(database, "Reads from and writes to", "JDBC"); mainframeBankingSystemFacade.Uses(mainframeBankingSystem, "Uses", "XML/HTTPS"); ComponentView componentViewForRestApi = viewSet.CreateComponentView(restApi, "Components", "The components diagram for the REST API"); componentViewForRestApi.PaperSize = PaperSize.A4_Landscape; componentViewForRestApi.AddAllContainers(); componentViewForRestApi.AddAllComponents(); componentViewForRestApi.Add(cliente); componentViewForRestApi.Add(mainframeBankingSystem); //componentViewForRestApi.EnableAutomaticLayout(); structurizrClient.UnlockWorkspace(workspaceId); structurizrClient.PutWorkspace(workspaceId, workspace); }
static void Main(string[] args) { Workspace workspace = new Workspace("Financial Risk System", "This is a simple (incomplete) example C4 model based upon the financial risk system architecture kata, which can be found at http://bit.ly/sa4d-risksystem"); Model.Model model = workspace.Model; // create the basic model SoftwareSystem financialRiskSystem = model.AddSoftwareSystem(Location.Internal, "Financial Risk System", "Calculates the bank's exposure to risk for product X"); Person businessUser = model.AddPerson(Location.Internal, "Business User", "A regular business user"); businessUser.Uses(financialRiskSystem, "Views reports using"); Person configurationUser = model.AddPerson(Location.Internal, "Configuration User", "A regular business user who can also configure the parameters used in the risk calculations"); configurationUser.Uses(financialRiskSystem, "Configures parameters using"); SoftwareSystem tradeDataSystem = model.AddSoftwareSystem(Location.Internal, "Trade Data System", "The system of record for trades of type X"); financialRiskSystem.Uses(tradeDataSystem, "Gets trade data from"); SoftwareSystem referenceDataSystem = model.AddSoftwareSystem(Location.Internal, "Reference Data System", "Manages reference data for all counterparties the bank interacts with"); financialRiskSystem.Uses(referenceDataSystem, "Gets counterparty data from"); SoftwareSystem emailSystem = model.AddSoftwareSystem(Location.Internal, "E-mail system", "Microsoft Exchange"); financialRiskSystem.Uses(emailSystem, "Sends a notification that a report is ready to"); emailSystem.Delivers(businessUser, "Sends a notification that a report is ready to", "E-mail message", InteractionStyle.Asynchronous); SoftwareSystem centralMonitoringService = model.AddSoftwareSystem(Location.Internal, "Central Monitoring Service", "The bank-wide monitoring and alerting dashboard"); financialRiskSystem.Uses(centralMonitoringService, "Sends critical failure alerts to", "SNMP", InteractionStyle.Asynchronous).addTags(AlertTag); SoftwareSystem activeDirectory = model.AddSoftwareSystem(Location.Internal, "Active Directory", "Manages users and security roles across the bank"); financialRiskSystem.Uses(activeDirectory, "Uses for authentication and authorisation"); /* * // create some views * ViewSet viewSet = workspace.getViews(); * SystemContextView contextView = viewSet.createContextView(financialRiskSystem); * contextView.addAllSoftwareSystems(); * contextView.addAllPeople(); * * // tag and style some elements * Styles styles = viewSet.getConfiguration().getStyles(); * financialRiskSystem.addTags("Risk System"); * * styles.addElementStyle(Tags.ELEMENT).color("#ffffff").fontSize(34); * styles.addElementStyle("Risk System").background("#550000").color("#ffffff"); * styles.addElementStyle(Tags.SOFTWARE_SYSTEM).width(650).height(400).background("#801515").shape(Shape.RoundedBox); * styles.addElementStyle(Tags.PERSON).width(550).background("#d46a6a").shape(Shape.Person); * * styles.addRelationshipStyle(Tags.RELATIONSHIP).thickness(4).dashed(false).fontSize(32).width(400); * styles.addRelationshipStyle(Tags.SYNCHRONOUS).dashed(false); * styles.addRelationshipStyle(Tags.ASYNCHRONOUS).dashed(true); * styles.addRelationshipStyle(TAG_ALERT).color("#ff0000"); * * // and upload the model to structurizr.com * StructurizrClient structurizrClient = new StructurizrClient("key", "secret"); * structurizrClient.mergeWorkspace(31, workspace); */ foreach (SoftwareSystem softwareSystem in model.SoftwareSystems) { System.Console.WriteLine(softwareSystem.ToString()); } foreach (Person person in model.People) { System.Console.WriteLine(person.ToString()); } foreach (Relationship relationship in model.Relationships) { System.Console.WriteLine(relationship.ToString()); } System.Console.ReadKey(); }
static void Main(string[] args) { Workspace workspace = new Workspace("Financial Risk System", "A simple example C4 model based upon the financial risk system architecture kata, created using Structurizr for .NET"); Model model = workspace.Model; // create the basic model SoftwareSystem financialRiskSystem = model.AddSoftwareSystem(Location.Internal, "Financial Risk System", "Calculates the bank's exposure to risk for product X"); Person businessUser = model.AddPerson(Location.Internal, "Business User", "A regular business user"); businessUser.Uses(financialRiskSystem, "Views reports using"); Person configurationUser = model.AddPerson(Location.Internal, "Configuration User", "A regular business user who can also configure the parameters used in the risk calculations"); configurationUser.Uses(financialRiskSystem, "Configures parameters using"); SoftwareSystem tradeDataSystem = model.AddSoftwareSystem(Location.Internal, "Trade Data System", "The system of record for trades of type X"); financialRiskSystem.Uses(tradeDataSystem, "Gets trade data from"); SoftwareSystem referenceDataSystem = model.AddSoftwareSystem(Location.Internal, "Reference Data System", "Manages reference data for all counterparties the bank interacts with"); financialRiskSystem.Uses(referenceDataSystem, "Gets counterparty data from"); SoftwareSystem emailSystem = model.AddSoftwareSystem(Location.Internal, "E-mail system", "Microsoft Exchange"); financialRiskSystem.Uses(emailSystem, "Sends a notification that a report is ready to"); emailSystem.Delivers(businessUser, "Sends a notification that a report is ready to", "E-mail message", InteractionStyle.Asynchronous); SoftwareSystem centralMonitoringService = model.AddSoftwareSystem(Location.Internal, "Central Monitoring Service", "The bank-wide monitoring and alerting dashboard"); financialRiskSystem.Uses(centralMonitoringService, "Sends critical failure alerts to", "SNMP", InteractionStyle.Asynchronous).AddTags(AlertTag); SoftwareSystem activeDirectory = model.AddSoftwareSystem(Location.Internal, "Active Directory", "Manages users and security roles across the bank"); financialRiskSystem.Uses(activeDirectory, "Uses for authentication and authorisation"); Container webApplication = financialRiskSystem.AddContainer("Web Application", "Allows users to view reports and modify risk calculation parameters", "ASP.NET MVC"); businessUser.Uses(webApplication, "Views reports using"); configurationUser.Uses(webApplication, "Modifies risk calculation parameters using"); webApplication.Uses(activeDirectory, "Uses for authentication and authorisation"); Container batchProcess = financialRiskSystem.AddContainer("Batch Process", "Calculates the risk", "Windows Service"); batchProcess.Uses(emailSystem, "Sends a notification that a report is ready to"); batchProcess.Uses(tradeDataSystem, "Gets trade data from"); batchProcess.Uses(referenceDataSystem, "Gets counterparty data from"); batchProcess.Uses(centralMonitoringService, "Sends critical failure alerts to", "SNMP", InteractionStyle.Asynchronous).AddTags(AlertTag); Container fileSystem = financialRiskSystem.AddContainer("File System", "Stores risk reports", "Network File Share"); webApplication.Uses(fileSystem, "Consumes risk reports from"); batchProcess.Uses(fileSystem, "Publishes risk reports to"); Component scheduler = batchProcess.AddComponent("Scheduler", "Starts the risk calculation process at 5pm New York time", "Quartz.NET"); Component orchestrator = batchProcess.AddComponent("Orchestrator", "Orchestrates the risk calculation process", "C#"); Component tradeDataImporter = batchProcess.AddComponent("Trade data importer", "Imports data from the Trade Data System", "C#"); Component referenceDataImporter = batchProcess.AddComponent("Reference data importer", "Imports data from the Reference Data System", "C#"); Component riskCalculator = batchProcess.AddComponent("Risk calculator", "Calculates risk", "C#"); Component reportGenerator = batchProcess.AddComponent("Report generator", "Generates a Microsoft Excel compatible risk report", "C# and Microsoft.Office.Interop.Excel"); Component reportPublisher = batchProcess.AddComponent("Report distributor", "Publishes the report to the web application", "C#"); Component emailComponent = batchProcess.AddComponent("E-mail component", "Sends e-mails", "C#"); Component reportChecker = batchProcess.AddComponent("Report checker", "Checks that the report has been generated by 9am singapore time", "C#"); Component alertComponent = batchProcess.AddComponent("Alert component", "Sends SNMP alerts", "C# and #SNMP Library"); scheduler.Uses(orchestrator, "Starts"); scheduler.Uses(reportChecker, "Starts"); orchestrator.Uses(tradeDataImporter, "Imports data using"); tradeDataImporter.Uses(tradeDataSystem, "Imports data from"); orchestrator.Uses(referenceDataImporter, "Imports data using"); referenceDataImporter.Uses(referenceDataSystem, "Imports data from"); orchestrator.Uses(riskCalculator, "Calculates the risk using"); orchestrator.Uses(reportGenerator, "Generates the risk report using"); orchestrator.Uses(reportPublisher, "Publishes the risk report using"); reportPublisher.Uses(fileSystem, "Publishes the risk report to"); orchestrator.Uses(emailComponent, "Sends e-mail using"); emailComponent.Uses(emailSystem, "Sends a notification that a report is ready to"); reportChecker.Uses(alertComponent, "Sends alerts using"); alertComponent.Uses(centralMonitoringService, "Sends alerts using", "SNMP", InteractionStyle.Asynchronous).AddTags(AlertTag); // create some views ViewSet viewSet = workspace.Views; SystemContextView contextView = viewSet.CreateSystemContextView(financialRiskSystem, "Context", ""); contextView.PaperSize = PaperSize.A4_Landscape; contextView.AddAllSoftwareSystems(); contextView.AddAllPeople(); ContainerView containerView = viewSet.CreateContainerView(financialRiskSystem, "Containers", ""); contextView.PaperSize = PaperSize.A4_Landscape; containerView.AddAllElements(); ComponentView componentViewForBatchProcess = viewSet.CreateComponentView(batchProcess, "Components", ""); contextView.PaperSize = PaperSize.A3_Landscape; componentViewForBatchProcess.AddAllElements(); componentViewForBatchProcess.Remove(configurationUser); componentViewForBatchProcess.Remove(webApplication); componentViewForBatchProcess.Remove(activeDirectory); // tag and style some elements Styles styles = viewSet.Configuration.Styles; financialRiskSystem.AddTags("Risk System"); styles.Add(new ElementStyle(Tags.Element) { Color = "#ffffff", FontSize = 34 }); styles.Add(new ElementStyle("Risk System") { Background = "#8a458a" }); styles.Add(new ElementStyle(Tags.SoftwareSystem) { Width = 650, Height = 400, Background = "#510d51", Shape = Shape.Box }); styles.Add(new ElementStyle(Tags.Person) { Width = 550, Background = "#62256e", Shape = Shape.Person }); styles.Add(new ElementStyle(Tags.Container) { Width = 650, Height = 400, Background = "#a46ba4", Shape = Shape.Box }); styles.Add(new ElementStyle(Tags.Component) { Width = 550, Background = "#c9a1c9", Shape = Shape.Box }); styles.Add(new RelationshipStyle(Tags.Relationship) { Thickness = 4, Dashed = false, FontSize = 32, Width = 400 }); styles.Add(new RelationshipStyle(Tags.Synchronous) { Dashed = false }); styles.Add(new RelationshipStyle(Tags.Asynchronous) { Dashed = true }); styles.Add(new RelationshipStyle(AlertTag) { Color = "#ff0000" }); Documentation documentation = workspace.Documentation; FileInfo documentationRoot = new FileInfo(@"..\..\FinancialRiskSystem"); documentation.Add(financialRiskSystem, SectionType.Context, DocumentationFormat.Markdown, new FileInfo(Path.Combine(documentationRoot.FullName, "context.md"))); documentation.Add(financialRiskSystem, SectionType.FunctionalOverview, DocumentationFormat.Markdown, new FileInfo(Path.Combine(documentationRoot.FullName, "functional-overview.md"))); documentation.Add(financialRiskSystem, SectionType.QualityAttributes, DocumentationFormat.Markdown, new FileInfo(Path.Combine(documentationRoot.FullName, "quality-attributes.md"))); documentation.AddImages(documentationRoot); // add some example corporate branding Branding branding = viewSet.Configuration.Branding; branding.Font = new Font("Trebuchet MS"); branding.Color1 = new ColorPair("#510d51", "#ffffff"); branding.Color2 = new ColorPair("#62256e", "#ffffff"); branding.Color3 = new ColorPair("#a46ba4", "#ffffff"); branding.Color4 = new ColorPair("#c9a1c9", "#ffffff"); branding.Color5 = new ColorPair("#c9a1c9", "#ffffff"); branding.Logo = ImageUtils.GetImageAsDataUri(new FileInfo(Path.Combine(documentationRoot.FullName, "codingthearchitecture.png"))); // and upload the model to structurizr.com StructurizrClient structurizrClient = new StructurizrClient("key", "secret"); structurizrClient.PutWorkspace(9481, workspace); }
static void Main(string[] args) { Workspace workspace = new Workspace("Park Soft", "Software for parking system"); Model model = workspace.Model; ViewSet views = workspace.Views; AddContext(model, views); model.Enterprise = new Enterprise("System parkingowy"); Person customer = model.AddPerson( Location.External, "Klient", "Klient parkingu, " + "posiada konto w systemie"); Person parkingOperator = model.AddPerson( Location.External, "Operator", "Operator parkingu, " + "posiada konto w systemie"); SoftwareSystem clientPlatformSystem = model.AddSoftwareSystem( Location.Internal, "Platforma kliencka", "Pozwala na zarządzanie swoimi rezerwacjami"); customer.Uses(clientPlatformSystem, "Używa"); SoftwareSystem mainframeParkingSystem = model.AddSoftwareSystem( Location.Internal, "System parkingowy", "Core'owy system parkingowy."); clientPlatformSystem.Uses( mainframeParkingSystem, "Pobiera informacje/Wysyła informacje"); parkingOperator.Uses(mainframeParkingSystem, "obsługuje"); SoftwareSystem emailSystem = model.AddSoftwareSystem(Location.Internal, "E-mail System", "System e-mailowy Microsoft Exchange"); clientPlatformSystem.Uses(emailSystem, "Wysyła e-maile używając"); emailSystem.Delivers(customer, "Wysyła e-maile do"); clientPlatformSystem.Uses( mainframeParkingSystem, "Pobiera informacje/Wysyła informacje"); SystemContextView systemContextView = views.CreateSystemContextView( clientPlatformSystem, "SystemContext", "Diagram kontekstowy systemu parkingowego"); systemContextView.AddNearestNeighbours(clientPlatformSystem); systemContextView.AddAnimation(clientPlatformSystem); systemContextView.AddAnimation(customer); //systemContextView.AddAnimation(parkingOperator); systemContextView.AddAnimation(mainframeParkingSystem); //wcześniej zdefiniowany kontekst Container mobileApp = mainframeParkingSystem.AddContainer( "Aplikacja mobilna", "Dostarcza ograniczoną funkcjonalność bankowości online dla klienta", "Xamarin"); Container apiApplication = mainframeParkingSystem.AddContainer( "API", "Dostarcza funkcjonalność bankowości online poprzez JSON/HTTP", "Java i Spring MVC"); Container database = mainframeParkingSystem.AddContainer( "Baza danych", "Informacje o klientach, hashowane hasła, logi", "Relacyjna baza danych"); parkingOperator.Uses(mobileApp, "Używa", ""); apiApplication.Uses(database, "Czyta/Zapisuje", "JDBC"); apiApplication.Uses(mainframeParkingSystem, "Używa", "XML/HTTPS"); apiApplication.Uses(emailSystem, "Wysyła maile", "SMTP"); ContainerView containerView = views.CreateContainerView( clientPlatformSystem, "Containers", "Diagram kontenerów systemu Platformy Bankowowości Online"); containerView.Add(customer); containerView.AddAllContainers(); containerView.Add(mainframeParkingSystem); containerView.Add(emailSystem); containerView.AddAnimation( customer, mainframeParkingSystem, emailSystem); // containerView.AddAnimation(mobileApp); // containerView.AddAnimation(apiApplication); UploadWorkspaceToStructurizr(workspace); }