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)));
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            Workspace workspace = new Workspace("Music Sample Manager architecture", "This is a model of the architecture of the Music Sample Manager project.");
            Model     model     = workspace.Model;

            Person musician      = model.AddPerson("Musician", "A person who wants to write/record some music.");
            Person libraryAuthor = model.AddPerson("Author", "A person who authors samples to be used by musicians.");

            SoftwareSystem consoleApp = model.AddSoftwareSystem("msm.exe", "A console application that lets users perform MSM operations.");

            musician.Uses(consoleApp, "Uses");

            SoftwareSystem desktopGUIApp = model.AddSoftwareSystem("Desktop GUI App", "A desktop application that lets uers perform MSM operations.");

            musician.Uses(desktopGUIApp, "Uses");

            SoftwareSystem dawClient = model.AddSoftwareSystem("DAW Client", "Functionality built into DAWs that allows users to perform MSM operations.");

            musician.Uses(dawClient, "Uses");

            SoftwareSystem website = model.AddSoftwareSystem("Website", "Website that allows musicians to browse packages, and authors to publish/manage packages.");

            musician.Uses(website, "Uses packages from");
            libraryAuthor.Uses(website, "Publishes to");


            SoftwareSystem serverSoftware = model.AddSoftwareSystem("Server software", "Handles submissions to the database, authentication, serving requests for packages, etc.");

            consoleApp.Uses(serverSoftware, "Communicates with");
            dawClient.Uses(serverSoftware, "Interfaces with");

            SoftwareSystem localPackageCache = model.AddSoftwareSystem("Local package cache", "Cache of downloaded packages, to be used by DAW projects.");

            consoleApp.Uses(localPackageCache, "Interfaces with");
            dawClient.Uses(localPackageCache, "Works with");



            ViewSet           viewSet     = workspace.Views;
            SystemContextView contextView = viewSet.CreateSystemContextView(consoleApp, "SystemContext", "An example of a System Context diagram.");

            contextView.AddAllSoftwareSystems();
            contextView.AddAllPeople();

            Styles styles = viewSet.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
            });

            PublishWorkspace(workspace);
        }
Ejemplo n.º 3
0
        public void Test_AddRelationship_AllowsMultipleRelationshipsBetweenElements()
        {
            SoftwareSystem element1      = Model.AddSoftwareSystem("Element 1", "Description");
            SoftwareSystem element2      = Model.AddSoftwareSystem("Element 2", "Description");
            Relationship   relationship1 = element1.Uses(element2, "Uses in some way", "");
            Relationship   relationship2 = element1.Uses(element2, "Uses in another way", "");

            Assert.True(element1.Has(relationship1));
            Assert.True(element1.Has(relationship2));
            Assert.Equal(2, element1.Relationships.Count);
        }
Ejemplo n.º 4
0
        public void Test_AddRelationship_DisallowsTheSameRelationshipToBeAddedMoreThanOnce()
        {
            SoftwareSystem element1      = Model.AddSoftwareSystem("Element 1", "Description");
            SoftwareSystem element2      = Model.AddSoftwareSystem("Element 2", "Description");
            Relationship   relationship1 = element1.Uses(element2, "Uses", "");
            Relationship   relationship2 = element1.Uses(element2, "Uses", "");

            Assert.True(element1.Has(relationship1));
            Assert.Null(relationship2);
            Assert.Equal(1, element1.Relationships.Count);
        }
Ejemplo n.º 5
0
        public void Test_CopyLayoutInformation_DoesNotThrowAnExceptionWhenAddingAnElementToAView()
        {
            Workspace      workspace1       = new Workspace("1", "");
            SoftwareSystem softwareSystem1A = workspace1.Model.AddSoftwareSystem("Software System A");
            SoftwareSystem softwareSystem1B = workspace1.Model.AddSoftwareSystem("Software System B");

            softwareSystem1A.Uses(softwareSystem1B, "Uses");
            SystemLandscapeView view1 = workspace1.Views.CreateSystemLandscapeView("key", "description");

            view1.Add(softwareSystem1A);

            Workspace      workspace2       = new Workspace("2", "");
            SoftwareSystem softwareSystem2A = workspace2.Model.AddSoftwareSystem("Software System A");
            SoftwareSystem softwareSystem2B = workspace2.Model.AddSoftwareSystem("Software System B");

            softwareSystem2A.Uses(softwareSystem2B, "Uses");
            SystemLandscapeView view2 = workspace2.Views.CreateSystemLandscapeView("key", "description");

            view2.Add(softwareSystem2A);
            view2.Add(softwareSystem2B);

            DefaultLayoutMergeStrategy strategy = new DefaultLayoutMergeStrategy();

            strategy.CopyLayoutInformation(view1, view2);
        }
Ejemplo n.º 6
0
        public MonkeyFactory(Workspace workspace, IInfrastructureEnvironment environment)
        {
            System = workspace.Model.AddSoftwareSystem(
                Location.Internal,
                "Monkey Factory",
                "Azure cloud based backend for processing data created during production of monkeys");

            Hub              = new MonkeyHub(this, environment);
            CrmConnector     = new MonkeyCrmConnector(this, environment);
            EventStore       = new MonkeyEventStore(this, environment);
            UI               = new MonkeyUI(this, EventStore, environment);
            MessageProcessor = new MonkeyMessageProcessor(this, Hub, CrmConnector, EventStore, environment);

            TechnicalSupportUser = workspace.Model.AddPerson("Technical support user", "Responds to incidents during monkey production");
            TechnicalSupportUser.Uses(UI, "Gather information about system failures");

            ProductionShiftLead = workspace.Model.AddPerson("Production Shift leader", "Monitors monkey production");
            ProductionShiftLead.Uses(UI, "Monitor load on production systems");

            MonkeyProductionLine = workspace.Model.AddSoftwareSystem(Location.External, "Production Line", "Produces the actual monkeys");
            MonkeyProductionLine.Uses(Hub, "Send production telemetry data and failure events", "MQTT");

            Crm = workspace.Model.AddSoftwareSystem(Location.External, "CRM", "");
            Crm.Uses(CrmConnector, "Process failure events in order to create support tickets", "AMQP");
        }
Ejemplo n.º 7
0
        public void Test_HasEfferentRelationshipWith_ReturnsTrue_WhenTheSameElementIsSpecifiedAndACyclicRelationshipExists()
        {
            SoftwareSystem softwareSystem1 = Model.AddSoftwareSystem("System 1", "");

            softwareSystem1.Uses(softwareSystem1, "uses");
            Assert.True(softwareSystem1.HasEfferentRelationshipWith(softwareSystem1));
        }
Ejemplo n.º 8
0
        private void FindUsedBySoftwareSystemAnnotations(Component component, string typeName)
        {
            TypeDefinition type = _typeRepository.GetType(typeName);

            if (type == null)
            {
                Console.WriteLine("Could not find type " + typeName + " for component " + component.Name);
                return;
            }
            if (!type.HasCustomAttributes)
            {
                return;
            }

            var annotations = type.ResolvableAttributes <UsedBySoftwareSystemAttribute>().ToList();

            foreach (UsedBySoftwareSystemAttribute annotation in annotations)
            {
                SoftwareSystem system = component.Model.GetSoftwareSystemWithName(annotation.SoftwareSystemName);
                if (system != null)
                {
                    system.Uses(component, annotation.Description, annotation.Technology);
                }
                else
                {
                    Console.WriteLine("Could not find software system " + annotation.SoftwareSystemName + " using component " + component.Name);
                }
            }
        }
Ejemplo n.º 9
0
        public void Test_HasEfferentRelationshipWith_ReturnsTrue_WhenThereIsARelationship()
        {
            SoftwareSystem softwareSystem1 = Model.AddSoftwareSystem("System 1", "");
            SoftwareSystem softwareSystem2 = Model.AddSoftwareSystem("System 2", "");

            softwareSystem1.Uses(softwareSystem2, "uses");
            Assert.True(softwareSystem1.HasEfferentRelationshipWith(softwareSystem2));
        }
Ejemplo n.º 10
0
        public void Test_HasAfferentRelationships_ReturnsFalse_WhenThereAreNoIncomingRelationships()
        {
            SoftwareSystem softwareSystem1 = model.AddSoftwareSystem("System 1", "");
            SoftwareSystem softwareSystem2 = model.AddSoftwareSystem("System 2", "");

            softwareSystem1.Uses(softwareSystem2, "Uses");

            Assert.IsFalse(softwareSystem1.HasAfferentRelationships());
        }
Ejemplo n.º 11
0
        public void Test_HasAfferentRelationships_ReturnsTrue_WhenThereAreIncomingRelationships()
        {
            SoftwareSystem softwareSystem1 = Model.AddSoftwareSystem("System 1", "");
            SoftwareSystem softwareSystem2 = Model.AddSoftwareSystem("System 2", "");

            softwareSystem1.Uses(softwareSystem2, "Uses");

            Assert.True(softwareSystem2.HasAfferentRelationships());
        }
Ejemplo n.º 12
0
        public void Test_ModifyRelationship_ModifiesAnExistingRelationship_WhenThatRelationshipDoesNotAlreadyExist()
        {
            SoftwareSystem element1     = Model.AddSoftwareSystem("Element 1", "Description");
            SoftwareSystem element2     = Model.AddSoftwareSystem("Element 2", "Description");
            Relationship   relationship = element1.Uses(element2, "", "");

            Model.ModifyRelationship(relationship, "Uses", "Technology");
            Assert.Equal("Uses", relationship.Description);
            Assert.Equal("Technology", relationship.Technology);
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        public void Test_GetEfferentRelationshipWith_ReturnsCyclicRelationship_WhenTheSameElementIsSpecifiedAndACyclicRelationshipExists()
        {
            SoftwareSystem softwareSystem1 = Model.AddSoftwareSystem("System 1", "");

            softwareSystem1.Uses(softwareSystem1, "uses");

            Relationship relationship = softwareSystem1.GetEfferentRelationshipWith(softwareSystem1);

            Assert.Same(softwareSystem1, relationship.Source);
            Assert.Equal("uses", relationship.Description);
            Assert.Same(softwareSystem1, relationship.Destination);
        }
Ejemplo n.º 15
0
        public void Test_GetEfferentRelationshipWith_ReturnsTheRelationship_WhenThereIsARelationship()
        {
            SoftwareSystem softwareSystem1 = Model.AddSoftwareSystem("System 1", "");
            SoftwareSystem softwareSystem2 = Model.AddSoftwareSystem("System 2", "");

            softwareSystem1.Uses(softwareSystem2, "uses");

            Relationship relationship = softwareSystem1.GetEfferentRelationshipWith(softwareSystem2);

            Assert.Same(softwareSystem1, relationship.Source);
            Assert.Equal("uses", relationship.Description);
            Assert.Same(softwareSystem2, relationship.Destination);
        }
Ejemplo n.º 16
0
        public void Test_AddRelationship_ThrowsAnException_WhenTheDestinationIsAChildOfTheSource()
        {
            SoftwareSystem softwareSystem = Model.AddSoftwareSystem("Software System", "");
            Container      container      = softwareSystem.AddContainer("Container", "", "");
            Component      component      = container.AddComponent("Component", "", "");

            try
            {
                softwareSystem.Uses(container, "Uses");
                throw new TestFailedException();
            }
            catch (ArgumentException ae)
            {
                Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
                Assert.Equal(0, softwareSystem.Relationships.Count);
            }

            try
            {
                container.Uses(component, "Uses");
                throw new TestFailedException();
            }
            catch (ArgumentException ae)
            {
                Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
                Assert.Equal(0, softwareSystem.Relationships.Count);
            }

            try
            {
                softwareSystem.Uses(component, "Uses");
                throw new TestFailedException();
            }
            catch (ArgumentException ae)
            {
                Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
                Assert.Equal(0, softwareSystem.Relationships.Count);
            }
        }
Ejemplo n.º 17
0
        public void Test_ParallelSequence()
        {
            Workspace = new Workspace("Name", "Description");
            Model     = Workspace.Model;
            SoftwareSystem softwareSystemA  = Model.AddSoftwareSystem("A", "");
            SoftwareSystem softwareSystemB  = Model.AddSoftwareSystem("B", "");
            SoftwareSystem softwareSystemC1 = Model.AddSoftwareSystem("C1", "");
            SoftwareSystem softwareSystemC2 = Model.AddSoftwareSystem("C2", "");
            SoftwareSystem softwareSystemD  = Model.AddSoftwareSystem("D", "");
            SoftwareSystem softwareSystemE  = Model.AddSoftwareSystem("E", "");

            // A -> B -> C1 -> D -> E
            // A -> B -> C2 -> D -> E
            softwareSystemA.Uses(softwareSystemB, "uses");
            softwareSystemB.Uses(softwareSystemC1, "uses");
            softwareSystemC1.Uses(softwareSystemD, "uses");
            softwareSystemB.Uses(softwareSystemC2, "uses");
            softwareSystemC2.Uses(softwareSystemD, "uses");
            softwareSystemD.Uses(softwareSystemE, "uses");

            DynamicView view = Workspace.Views.CreateDynamicView("key", "Description");

            view.Add(softwareSystemA, softwareSystemB);
            view.StartParallelSequence();
            view.Add(softwareSystemB, softwareSystemC1);
            view.Add(softwareSystemC1, softwareSystemD);
            view.EndParallelSequence();
            view.StartParallelSequence();
            view.Add(softwareSystemB, softwareSystemC2);
            view.Add(softwareSystemC2, softwareSystemD);
            view.EndParallelSequence(true);
            view.Add(softwareSystemD, softwareSystemE);

            Assert.Equal(1, view.Relationships.Count(r => r.Order.Equals("1")));
            Assert.Equal(2, view.Relationships.Count(r => r.Order.Equals("2")));
            Assert.Equal(2, view.Relationships.Count(r => r.Order.Equals("3")));
            Assert.Equal(1, view.Relationships.Count(r => r.Order.Equals("4")));
        }
Ejemplo n.º 18
0
        public void Test_ModifyRelationship_ThrowsAnException_WhenThatRelationshipDoesAlreadyExist()
        {
            SoftwareSystem element1     = Model.AddSoftwareSystem("Element 1", "Description");
            SoftwareSystem element2     = Model.AddSoftwareSystem("Element 2", "Description");
            Relationship   relationship = element1.Uses(element2, "Uses", "Technology");

            try
            {
                Model.ModifyRelationship(relationship, "Uses", "Technology");
                throw new TestFailedException();
            }
            catch (ArgumentException ae)
            {
                Assert.Equal("This relationship exists already: {1 | Element 1 | Description} ---[Uses]---> {2 | Element 2 | Description}", ae.Message);
            }
        }
Ejemplo n.º 19
0
        public void Test_AddDefaultElements()
        {
            Person         user1           = Model.AddPerson("User 1");
            Person         user2           = Model.AddPerson("User 2");
            SoftwareSystem softwareSystem1 = Model.AddSoftwareSystem("Software System 1");
            SoftwareSystem softwareSystem2 = Model.AddSoftwareSystem("Software System 2");

            user1.Uses(softwareSystem1, "");
            softwareSystem1.Uses(softwareSystem2, "");
            user2.Uses(softwareSystem2, "");

            view = Views.CreateSystemContextView(softwareSystem1, "key", "description");
            view.AddDefaultElements();

            Assert.Equal(3, view.Elements.Count);
            Assert.True(view.Elements.Contains(new ElementView(user1)));
            Assert.False(view.Elements.Contains(new ElementView(user2)));
            Assert.True(view.Elements.Contains(new ElementView(softwareSystem1)));
            Assert.True(view.Elements.Contains(new ElementView(softwareSystem2)));
        }
Ejemplo n.º 20
0
        public void Test_AddAnimationStep()
        {
            SoftwareSystem element1 = Model.AddSoftwareSystem("Software System 1", "");
            SoftwareSystem element2 = Model.AddSoftwareSystem("Software System 2", "");
            SoftwareSystem element3 = Model.AddSoftwareSystem("Software System 3", "");

            Relationship relationship1_2 = element1.Uses(element2, "uses");
            Relationship relationship2_3 = element2.Uses(element3, "uses");

            SystemLandscapeView view = Workspace.Views.CreateSystemLandscapeView("key", "Description");

            view.AddAllElements();

            view.AddAnimation(element1);
            view.AddAnimation(element2);
            view.AddAnimation(element3);

            Animation step1 = view.Animations.First(step => step.Order == 1);

            Assert.Equal(1, step1.Elements.Count);
            Assert.True(step1.Elements.Contains(element1.Id));
            Assert.Equal(0, step1.Relationships.Count);

            Animation step2 = view.Animations.First(step => step.Order == 2);

            Assert.Equal(1, step2.Elements.Count);
            Assert.True(step2.Elements.Contains(element2.Id));
            Assert.Equal(1, step2.Relationships.Count);
            Assert.True(step2.Relationships.Contains(relationship1_2.Id));

            Animation step3 = view.Animations.First(step => step.Order == 3);

            Assert.Equal(1, step3.Elements.Count);
            Assert.True(step3.Elements.Contains(element3.Id));
            Assert.Equal(1, step3.Relationships.Count);
            Assert.True(step3.Relationships.Contains(relationship2_3.Id));
        }
Ejemplo n.º 21
0
        static void Main()
        {
            Workspace workspace = new Workspace("Widgets Limited", "Sells widgets to customers online.");
            Model     model     = workspace.Model;
            ViewSet   views     = workspace.Views;
            Styles    styles    = views.Configuration.Styles;

            model.Enterprise = new Enterprise("Widgets Limited");

            Person         customer            = model.AddPerson(Location.External, "Customer", "A customer of Widgets Limited.");
            Person         customerServiceUser = model.AddPerson(Location.Internal, "Customer Service Agent", "Deals with customer enquiries.");
            SoftwareSystem ecommerceSystem     = model.AddSoftwareSystem(Location.Internal, "E-commerce System", "Allows customers to buy widgets online via the widgets.com website.");
            SoftwareSystem fulfilmentSystem    = model.AddSoftwareSystem(Location.Internal, "Fulfilment System", "Responsible for processing and shipping of customer orders.");
            SoftwareSystem taxamo = model.AddSoftwareSystem(Location.External, "Taxamo", "Calculates local tax (for EU B2B customers) and acts as a front-end for Braintree Payments.");

            taxamo.Url = "https://www.taxamo.com";
            SoftwareSystem braintreePayments = model.AddSoftwareSystem(Location.External, "Braintree Payments", "Processes credit card payments on behalf of Widgets Limited.");

            braintreePayments.Url = "https://www.braintreepayments.com";
            SoftwareSystem jerseyPost = model.AddSoftwareSystem(Location.External, "Jersey Post", "Calculates worldwide shipping costs for packages.");

            model.People.Where(p => p.Location == Location.External).ToList().ForEach(p => p.AddTags(ExternalTag));
            model.People.Where(p => p.Location == Location.Internal).ToList().ForEach(p => p.AddTags(InternalTag));

            model.SoftwareSystems.Where(ss => ss.Location == Location.External).ToList().ForEach(ss => ss.AddTags(ExternalTag));
            model.SoftwareSystems.Where(ss => ss.Location == Location.Internal).ToList().ForEach(ss => ss.AddTags(InternalTag));

            customer.InteractsWith(customerServiceUser, "Asks questions to", "Telephone");
            customerServiceUser.Uses(ecommerceSystem, "Looks up order information using");
            customer.Uses(ecommerceSystem, "Places orders for widgets using");
            ecommerceSystem.Uses(fulfilmentSystem, "Sends order information to");
            fulfilmentSystem.Uses(jerseyPost, "Gets shipping charges from");
            ecommerceSystem.Uses(taxamo, "Delegates credit card processing to");
            taxamo.Uses(braintreePayments, "Uses for credit card processing");

            EnterpriseContextView enterpriseContextView = views.CreateEnterpriseContextView("EnterpriseContext", "The enterprise context for Widgets Limited.");

            enterpriseContextView.AddAllElements();

            SystemContextView ecommerceSystemContext = views.CreateSystemContextView(ecommerceSystem, "EcommerceSystemContext", "The system context diagram for the Widgets Limited e-commerce system.");

            ecommerceSystemContext.AddNearestNeighbours(ecommerceSystem);
            ecommerceSystemContext.Remove(customer.GetEfferentRelationshipWith(customerServiceUser));

            SystemContextView fulfilmentSystemContext = views.CreateSystemContextView(fulfilmentSystem, "FulfilmentSystemContext", "The system context diagram for the Widgets Limited fulfilment system.");

            fulfilmentSystemContext.AddNearestNeighbours(fulfilmentSystem);

            DynamicView dynamicView = views.CreateDynamicView("CustomerSupportCall", "A high-level overview of the customer support call process.");

            dynamicView.Add(customer, customerServiceUser);
            dynamicView.Add(customerServiceUser, ecommerceSystem);

            StructurizrDocumentationTemplate template = new StructurizrDocumentationTemplate(workspace);

            template.AddSection("Enterprise Context", 1, Format.Markdown, "Here is some information about the Widgets Limited enterprise context... ![](embed:EnterpriseContext)");
            template.AddContextSection(ecommerceSystem, Format.Markdown, "This is the context section for the E-commerce System... ![](embed:EcommerceSystemContext)");
            template.AddContextSection(fulfilmentSystem, Format.Markdown, "This is the context section for the Fulfilment System... ![](embed:FulfilmentSystemContext)");

            styles.Add(new ElementStyle(Tags.SoftwareSystem)
            {
                Shape = Shape.RoundedBox
            });
            styles.Add(new ElementStyle(Tags.Person)
            {
                Shape = Shape.Person
            });

            styles.Add(new ElementStyle(Tags.Element)
            {
                Color = "#ffffff"
            });
            styles.Add(new ElementStyle(ExternalTag)
            {
                Background = "#EC5381", Border = Border.Dashed
            });
            styles.Add(new ElementStyle(InternalTag)
            {
                Background = "#B60037"
            });

            StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);

            structurizrClient.PutWorkspace(WorkspaceId, workspace);
        }
        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);
        }
Ejemplo n.º 23
0
        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);
        }
        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();
        }
Ejemplo n.º 25
0
        private void BuildC4Model()
        {
            // Add stakeholders en Systemen
            SoftwareSystem boekhoudSysteem = model.AddSoftwareSystem(Location.Internal, "Boekhoudsysteem", "Boekhoudsysteem voor midden en kleinbedrijf en ZZP'er");

            SoftwareSystem itsmSysteem = model.AddSoftwareSystem(Location.Internal, "ITSM Systeem", "Interne CRM applicatie");

            itsmSysteem.AddTags(InternalSystemTag);
            boekhoudSysteem.Uses(itsmSysteem, "Haalt abonnement gegevens op");

            SoftwareSystem website = model.AddSoftwareSystem(Location.Internal, "Website", $"publieke website van {BedrijfsNaam}");

            website.AddTags(WebBrowserTag);
            website.Uses(itsmSysteem, "Registreert een abonnement");

            SoftwareSystem webshop = model.AddSoftwareSystem(Location.External, "Webshop", $"Webshopkoppeling names klant met Boekhoudsysteem");

            webshop.AddTags(ExternalSystemTag);
            boekhoudSysteem.Uses(webshop, "krijgt gegevens van");

            SoftwareSystem bank = model.AddSoftwareSystem(Location.External, "Bank", $"Bankkoppeling names klant met Boekhoudsysteem");

            bank.AddTags(ExternalSystemTag);
            boekhoudSysteem.Uses(bank, "krijgt gegevens van");

            Person hoofdgebruiker = model.AddPerson(Location.External, "Hoofdgebruiker", "De gebruiker van de klant die het abonnenement heeft afgesloten");

            hoofdgebruiker.Uses(boekhoudSysteem, Gebruikt);
            hoofdgebruiker.Uses(website, Gebruikt);

            Person gebruiker = model.AddPerson(Location.External, "Gebruiker", "De medewerker van de klant");

            gebruiker.Uses(boekhoudSysteem, Gebruikt);

            Person accountant = model.AddPerson(Location.External, "Accountant", "De accountant van de klant");

            accountant.Uses(boekhoudSysteem, Gebruikt);
            hoofdgebruiker.InteractsWith(accountant, "Vraagt controle aan bij");

            Person helpdesk = model.AddPerson(Location.Internal, "Helpdeskmedewerker", $"Helpdeskmedewerker van {BedrijfsNaam}");

            helpdesk.Uses(boekhoudSysteem, Gebruikt);
            helpdesk.Uses(itsmSysteem, Gebruikt);
            hoofdgebruiker.InteractsWith(helpdesk, "Vraagt hulp van");

            // Extra diagram: Systeemlandschap
            SystemLandscapeView systemLandscapeView = views.CreateSystemLandscapeView("SystemLandscape", "System Context diagram Boekhoudsysteem.");

            systemLandscapeView.AddAllElements();
            systemLandscapeView.EnableAutomaticLayout();

            // containers
            Container coreModule = boekhoudSysteem.AddContainer("Core Module", "Basis module voor inrichting, gebruikers", "C#");

            coreModule.AddTags(Tags.Container);
            coreModule.Uses(itsmSysteem, "krijgt gegevens van");

            Container bankModule = boekhoudSysteem.AddContainer("Bank Module", "Importeren van betaalgegevens", "C#");

            bankModule.AddTags(Tags.Container);
            bankModule.Uses(bank, "krijgt gegevens van");

            Container koppelingModule = boekhoudSysteem.AddContainer("Koppelingen Module", "Module voor inrichten diverse externe koppelingen", "C#");

            koppelingModule.AddTags(Tags.Container);
            koppelingModule.Uses(webshop, "krijgt gegevens van");

            Container boekhoudModule = boekhoudSysteem.AddContainer("Boekhoud Module", "Basis onderdelen van een Boekhoudsysteem zoals dagboeken en rapportages", "C#");

            boekhoudModule.AddTags(Tags.Container);
            boekhoudModule.Uses(webshop, "krijgt gegevens van");

            Container facturatieModule = boekhoudSysteem.AddContainer("Facturatie Module", "Facturatie en Offerte module", "C#");

            facturatieModule.AddTags(Tags.Container);
            facturatieModule.Uses(boekhoudModule, "geeft verkooporders aan");

            Container importModule = boekhoudSysteem.AddContainer("Import Module", "Module voor import en export gegevens", "C#");

            importModule.AddTags(Tags.Container);
            importModule.Uses(boekhoudModule, "geeft relaties aan");
            importModule.Uses(facturatieModule, "geeft artikelen aan");

            hoofdgebruiker.Uses(coreModule, Gebruikt);
            hoofdgebruiker.Uses(boekhoudModule, Gebruikt);
            hoofdgebruiker.Uses(facturatieModule, Gebruikt);
            hoofdgebruiker.Uses(bankModule, Gebruikt);
            hoofdgebruiker.Uses(koppelingModule, Gebruikt);
            hoofdgebruiker.Uses(importModule, Gebruikt);

            gebruiker.Uses(boekhoudModule, Gebruikt);
            gebruiker.Uses(facturatieModule, Gebruikt);
            gebruiker.Uses(bankModule, Gebruikt);

            accountant.Uses(boekhoudModule, Gebruikt);
            helpdesk.Uses(boekhoudModule, Gebruikt);

            Container databaseSystem = boekhoudSysteem.AddContainer("Systeem Database", "Opslag gebruikers, abonnement, administratie gegevens, hashed authentication credentials, access logs, etc.", "Relational Database Schema");

            databaseSystem.AddTags(DatabaseTag);
            coreModule.Uses(databaseSystem, Gebruikt);

            Container databaseAccount = boekhoudSysteem.AddContainer("Boekhouding Database", "Opslag boekhouding per abonnement per administratie", "Relational Database Schema");

            databaseAccount.AddTags(DatabaseTag);
            boekhoudModule.Uses(databaseAccount, Gebruikt);
            facturatieModule.Uses(databaseAccount, Gebruikt);
            bankModule.Uses(databaseAccount, Gebruikt);

            // Components
            Component bankImportView = bankModule.AddComponent("Bank statement Import", "Importscherm bankafschriften", "ASP.Net Webform");

            bankImportView.AddTags(WebBrowserTag);
            Component bankPaymentLogic = bankModule.AddComponent("Payment logic service", "Businesslaag bankafschriften", "C#");

            bankPaymentLogic.AddTags(InternalSystemTag);
            Component bankPaymentData = bankModule.AddComponent("Payment data service", "Datalaag bankafschriften", "C#");

            bankPaymentData.AddTags(InternalSystemTag);

            bankImportView.Uses(bankPaymentLogic, Gebruikt);
            bankPaymentLogic.Uses(bankPaymentData, Gebruikt);
            bankPaymentLogic.Uses(bank, Gebruikt);

            Component bankPaymentView = bankModule.AddComponent("Bank payments", "Betaalopdrachten", "ASP.Net Webform");

            bankPaymentView.AddTags(WebBrowserTag);
            bankPaymentView.Uses(bankPaymentLogic, Gebruikt);

            Component bankInstellingView = bankModule.AddComponent("Instellingen Bankstatements", "Instellingen bankafschriften", "ASP.Net Webform");

            bankInstellingView.AddTags(WebBrowserTag);
            Component bankInstellingLogic = bankModule.AddComponent("Bankinstellingen logic service", "Businesslaag bankinstellingen", "C#");

            bankInstellingLogic.AddTags(InternalSystemTag);
            Component bankInstellingData = bankModule.AddComponent("Bankinstellingen data service", "Datalaag bankinstellingen", "C#");

            bankInstellingData.AddTags(InternalSystemTag);

            bankInstellingView.Uses(bankInstellingLogic, Gebruikt);
            bankInstellingLogic.Uses(bankInstellingData, Gebruikt);

            bankPaymentData.Uses(databaseAccount, "Leest en schrijft naar", "Linq2Sql");
            bankInstellingData.Uses(databaseAccount, "Leest en schrijft naar", "Linq2Sql");

            Component importExportView = importModule.AddComponent("Artikel Import", "Importscherm artikelen", "ASP.Net Webform");

            importExportView.AddTags(WebBrowserTag);
            Component importExportLogic = importModule.AddComponent("Import Export logic service", "Businesslaag import export functionaliteit", "C#");

            importExportLogic.AddTags(InternalSystemTag);
            Component importExportData = importModule.AddComponent("Import Export data service", "Datalaag import export functionaliteit", "C#");

            importExportData.AddTags(InternalSystemTag);

            importExportView.Uses(importExportLogic, Gebruikt);
            importExportLogic.Uses(importExportData, Gebruikt);
            importExportData.Uses(databaseAccount, "Leest en schrijft naar", "Linq2Sql");

            // Add Views
            SystemContextView contextView = views.CreateSystemContextView(boekhoudSysteem, "SystemContext", "System Context diagram Boekhoudsysteem.");

            contextView.AddNearestNeighbours(boekhoudSysteem);
            contextView.EnableAutomaticLayout();

            ContainerView containerView = views.CreateContainerView(boekhoudSysteem, "Containers", "Het container diagram voor het boekhoudsysteem.");

            containerView.EnableAutomaticLayout();
            containerView.Add(hoofdgebruiker);
            containerView.Add(gebruiker);
            containerView.Add(accountant);
            containerView.Add(helpdesk);
            containerView.AddAllContainers();
            containerView.Add(webshop);
            containerView.Add(bank);
            containerView.Add(itsmSysteem);

            ComponentView bankComponentView = views.CreateComponentView(bankModule, "Bank Components", "Component diagram van de Bank module");

            bankComponentView.EnableAutomaticLayout();
            bankComponentView.Add(databaseAccount);
            bankComponentView.AddAllComponents();
            bankComponentView.Add(bank);

            ComponentView importExportComponentView = views.CreateComponentView(importModule, "Import-Export Components", "Component diagram van de Import Export module.");

            importExportComponentView.EnableAutomaticLayout();
            importExportComponentView.Add(databaseAccount);
            importExportComponentView.AddAllComponents();

            // Extra diagram: Deployment
            const string Productie = "Productieomgeving";

            DeploymentNode productieOmgeving = model.AddDeploymentNode(Productie, $"{BedrijfsNaam}", "", $"{BedrijfsNaam} data center");
            DeploymentNode customerComputer  = model.AddDeploymentNode(Productie, "Gebruiker's computer", "", "Microsoft Windows or Apple macOS");

            customerComputer.AddDeploymentNode("Web Browser", "", "Chrome, Firefox, Edge or IE11").Add(boekhoudModule);
            customerComputer.AddTags(WebBrowserTag);

            DeploymentNode productieWebServer = productieOmgeving.AddDeploymentNode($"{BedrijfsNaam}-web***", "Een webserver gehost in een webserver farm", "Windows 2019", 2, DictionaryUtils.Create("Location=Amsterdam"));

            productieWebServer
            .AddDeploymentNode("Microsoft IIS", "Microsoft web server.", "IIS", 1, DictionaryUtils.Create("Xmx=512M", "Xms=1024M", ".Net Framework 4.8"))
            .Add(boekhoudModule);
            customerComputer.Uses(productieWebServer, Gebruikt, "https");

            DeploymentNode primaryDatabaseServer = productieOmgeving
                                                   .AddDeploymentNode($"{BedrijfsNaam}-db01", "Primary database server.", "Windows 2019", 1, DictionaryUtils.Create("Location=Amsterdam"))
                                                   .AddDeploymentNode("SQL Server - Primary", $"Primary, {Productie} databaseserver.", "SqlServer 2017");

            primaryDatabaseServer.Add(databaseSystem);
            primaryDatabaseServer.Add(databaseAccount);

            DeploymentNode failoverDb = productieOmgeving.AddDeploymentNode($"{BedrijfsNaam}-db02", "Secondary database server.", "Windows 2019", 1, DictionaryUtils.Create("Location=Amsterdam"));

            failoverDb.AddTags(FailoverTag);

            DeploymentNode secondaryDatabaseServer = failoverDb.AddDeploymentNode("SQL Server - Secondary", "Secondary, standby database server, alleen voor failover.", "SqlServer 2017");

            secondaryDatabaseServer.AddTags(FailoverTag);

            ContainerInstance secondaryDatabaseSystem  = secondaryDatabaseServer.Add(databaseSystem);
            ContainerInstance secondaryDatabaseAccount = secondaryDatabaseServer.Add(databaseAccount);

            model.Relationships.Where(r => r.Destination.Equals(secondaryDatabaseSystem)).ToList().ForEach(r => r.AddTags(FailoverTag));
            model.Relationships.Where(r => r.Destination.Equals(secondaryDatabaseAccount)).ToList().ForEach(r => r.AddTags(FailoverTag));
            Relationship dataReplicationRelationship = primaryDatabaseServer.Uses(secondaryDatabaseServer, "Replicates data to", "");

            secondaryDatabaseSystem.AddTags(FailoverTag);
            secondaryDatabaseAccount.AddTags(FailoverTag);

            DeploymentView systeemDeploymentView = views.CreateDeploymentView(boekhoudSysteem, Productie, $"De productieomgeving van {BedrijfsNaam}.");

            //systeemDeploymentView.EnableAutomaticLayout();
            systeemDeploymentView.Environment = Productie;
            systeemDeploymentView.Add(productieOmgeving);
            systeemDeploymentView.Add(customerComputer);
            systeemDeploymentView.Add(dataReplicationRelationship);

            // Set 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
            });
            styles.Add(new ElementStyle(InternalSystemTag)
            {
                Background = "#999999", Color = "#ffffff"
            });
            styles.Add(new ElementStyle(ExternalSystemTag)
            {
                Background = "#999999", Color = "#ffffff"
            });
            styles.Add(new ElementStyle(WebBrowserTag)
            {
                Shape = Shape.WebBrowser
            });
            styles.Add(new ElementStyle(DatabaseTag)
            {
                Shape = Shape.Cylinder
            });
            styles.Add(new ElementStyle(FailoverTag)
            {
                Opacity = 25
            });
            styles.Add(new RelationshipStyle(FailoverTag)
            {
                Opacity = 25, Position = 70
            });
        }
Ejemplo n.º 26
0
        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);
        }
Ejemplo n.º 27
0
        public void Test_Tags_WhenThereAreNoTags()
        {
            Relationship relationship = _softwareSystem1.Uses(_softwareSystem2, "uses");

            Assert.Equal("Relationship,Synchronous", relationship.Tags);
        }
Ejemplo n.º 28
0
        static void Banking()
        {
            const long   workspaceId = 0;
            const string apiKey      = "";
            const string apiSecret   = "";

            StructurizrClient structurizrClient = new StructurizrClient(apiKey, apiSecret);
            Workspace         workspace         = new Workspace("C4 Model Microservices - Sistema de Monitoreo", "Sistema de Monitoreo del Traslado Aéreo de Vacunas SARS-CoV-2");
            Model             model             = workspace.Model;
            ViewSet           viewSet           = workspace.Views;

            // 1. Diagrama de Contexto
            SoftwareSystem monitoringSystem = model.AddSoftwareSystem("Monitoreo del Traslado Aéreo de Vacunas SARS-CoV-2", "Permite el seguimiento y monitoreo del traslado aéreo a nuestro país de las vacunas para la COVID-19.");
            SoftwareSystem googleMaps       = model.AddSoftwareSystem("Google Maps", "Plataforma que ofrece una REST API de información geo referencial.");
            SoftwareSystem aircraftSystem   = model.AddSoftwareSystem("Aircraft System", "Permite transmitir información en tiempo real por el avión del vuelo a nuestro sistema");

            Person ciudadano  = model.AddPerson("Ciudadano", "Ciudadano peruano.");
            Person periodista = model.AddPerson("Periodista", "Periodista de los diferentes medios de prensa.");
            Person developer  = model.AddPerson("Developer", "Developer - Open Data.");

            ciudadano.Uses(monitoringSystem, "Realiza consultas para mantenerse al tanto de la planificación de los vuelos hasta la llegada del lote de vacunas al Perú");
            periodista.Uses(monitoringSystem, "Realiza consultas para mantenerse al tanto de la planificación de los vuelos hasta la llegada del lote de vacunas al Perú");
            developer.Uses(monitoringSystem, "Realiza consultas a la REST API para mantenerse al tanto de la planificación de los vuelos hasta la llegada del lote de vacunas al Perú");
            monitoringSystem.Uses(aircraftSystem, "Consulta información en tiempo real por el avión del vuelo");
            monitoringSystem.Uses(googleMaps, "Usa");

            SystemContextView contextView = viewSet.CreateSystemContextView(monitoringSystem, "Contexto", "Diagrama de contexto");

            contextView.PaperSize = PaperSize.A4_Landscape;
            contextView.AddAllSoftwareSystems();
            contextView.AddAllPeople();

            // Tags
            monitoringSystem.AddTags("SistemaMonitoreo");
            googleMaps.AddTags("GoogleMaps");
            aircraftSystem.AddTags("AircraftSystem");
            ciudadano.AddTags("Ciudadano");
            periodista.AddTags("Periodista");
            developer.AddTags("Developer");

            Styles styles = viewSet.Configuration.Styles;

            styles.Add(new ElementStyle("Ciudadano")
            {
                Background = "#0a60ff", Color = "#ffffff", Shape = Shape.Person
            });
            styles.Add(new ElementStyle("Periodista")
            {
                Background = "#08427b", Color = "#ffffff", Shape = Shape.Person
            });
            styles.Add(new ElementStyle("Developer")
            {
                Background = "#facc2e", Shape = Shape.Robot
            });
            styles.Add(new ElementStyle("SistemaMonitoreo")
            {
                Background = "#008f39", Color = "#ffffff", Shape = Shape.RoundedBox
            });
            styles.Add(new ElementStyle("GoogleMaps")
            {
                Background = "#90714c", Color = "#ffffff", Shape = Shape.RoundedBox
            });
            styles.Add(new ElementStyle("AircraftSystem")
            {
                Background = "#2f95c7", Color = "#ffffff", Shape = Shape.RoundedBox
            });

            // 2. Diagrama de Contenedores
            Container mobileApplication        = monitoringSystem.AddContainer("Mobile App", "Permite a los usuarios visualizar un dashboard con el resumen de toda la información del traslado de los lotes de vacunas.", "Flutter");
            Container webApplication           = monitoringSystem.AddContainer("Web App", "Permite a los usuarios visualizar un dashboard con el resumen de toda la información del traslado de los lotes de vacunas.", "Flutter Web");
            Container landingPage              = monitoringSystem.AddContainer("Landing Page", "", "Flutter Web");
            Container apiGateway               = monitoringSystem.AddContainer("API Gateway", "API Gateway", "Spring Boot port 8080");
            Container flightPlanningContext    = monitoringSystem.AddContainer("Flight Planning Context", "Bounded Context del Microservicio de Planificación de Vuelos", "Spring Boot port 8081");
            Container airportContext           = monitoringSystem.AddContainer("Airport Context", "Bounded Context del Microservicio de información de Aeropuertos", "Spring Boot port 8082");
            Container aircraftInventoryContext = monitoringSystem.AddContainer("Aircraft Inventory Context", "Bounded Context del Microservicio de Inventario de Aviones", "Spring Boot port 8083");
            Container vaccinesInventoryContext = monitoringSystem.AddContainer("Vaccines Inventory Context", "Bounded Context del Microservicio de Inventario de Vacunas", "Spring Boot port 8084");
            Container monitoringContext        = monitoringSystem.AddContainer("Monitoring Context", "Bounded Context del Microservicio de Monitoreo en tiempo real del status y ubicación del vuelo que transporta las vacunas", "Spring Boot port 8085");
            Container messageBus               =
                monitoringSystem.AddContainer("Bus de Mensajes en Cluster de Alta Disponibilidad", "Transporte de eventos del dominio.", "RabbitMQ");
            Container flightPlanningContextDatabase     = monitoringSystem.AddContainer("Flight Planning Context DB", "", "Oracle");
            Container airportContextDatabase            = monitoringSystem.AddContainer("Airport Context DB", "", "Oracle");
            Container aircraftInventoryContextDatabase  = monitoringSystem.AddContainer("Aircraft Inventory Context DB", "", "Oracle");
            Container vaccinesInventoryContextDatabase  = monitoringSystem.AddContainer("Vaccines Inventory Context DB", "", "Oracle");
            Container monitoringContextDatabase         = monitoringSystem.AddContainer("Monitoring Context DB", "", "Oracle");
            Container monitoringContextReplicaDatabase  = monitoringSystem.AddContainer("Monitoring Context DB Replica", "", "Oracle");
            Container monitoringContextReactiveDatabase = monitoringSystem.AddContainer("Monitoring Context Reactive DB", "", "Firebase Cloud Firestore");

            ciudadano.Uses(mobileApplication, "Consulta");
            ciudadano.Uses(webApplication, "Consulta");
            ciudadano.Uses(landingPage, "Consulta");
            periodista.Uses(mobileApplication, "Consulta");
            periodista.Uses(webApplication, "Consulta");
            periodista.Uses(landingPage, "Consulta");
            mobileApplication.Uses(apiGateway, "API Request", "JSON/HTTPS");
            webApplication.Uses(apiGateway, "API Request", "JSON/HTTPS");
            developer.Uses(apiGateway, "API Request", "JSON/HTTPS");
            apiGateway.Uses(flightPlanningContext, "API Request", "JSON/HTTPS");
            apiGateway.Uses(airportContext, "API Request", "JSON/HTTPS");
            apiGateway.Uses(aircraftInventoryContext, "API Request", "JSON/HTTPS");
            apiGateway.Uses(vaccinesInventoryContext, "API Request", "JSON/HTTPS");
            apiGateway.Uses(monitoringContext, "API Request", "JSON/HTTPS");
            flightPlanningContext.Uses(messageBus, "Publica y consume eventos del dominio");
            flightPlanningContext.Uses(flightPlanningContextDatabase, "", "JDBC");
            airportContext.Uses(messageBus, "Publica y consume eventos del dominio");
            airportContext.Uses(airportContextDatabase, "", "JDBC");
            aircraftInventoryContext.Uses(messageBus, "Publica y consume eventos del dominio");
            aircraftInventoryContext.Uses(aircraftInventoryContextDatabase, "", "JDBC");
            vaccinesInventoryContext.Uses(messageBus, "Publica y consume eventos del dominio");
            vaccinesInventoryContext.Uses(vaccinesInventoryContextDatabase, "", "JDBC");
            monitoringContext.Uses(messageBus, "Publica y consume eventos del dominio");
            monitoringContext.Uses(monitoringContextDatabase, "", "JDBC");
            monitoringContext.Uses(monitoringContextReplicaDatabase, "", "JDBC");
            monitoringContext.Uses(monitoringContextReactiveDatabase, "", "");
            monitoringContextDatabase.Uses(monitoringContextReplicaDatabase, "Replica");
            monitoringContext.Uses(googleMaps, "API Request", "JSON/HTTPS");
            monitoringContext.Uses(aircraftSystem, "API Request", "JSON/HTTPS");

            // Tags
            mobileApplication.AddTags("MobileApp");
            webApplication.AddTags("WebApp");
            landingPage.AddTags("LandingPage");
            apiGateway.AddTags("APIGateway");
            flightPlanningContext.AddTags("FlightPlanningContext");
            flightPlanningContextDatabase.AddTags("FlightPlanningContextDatabase");
            airportContext.AddTags("AirportContext");
            airportContextDatabase.AddTags("AirportContextDatabase");
            aircraftInventoryContext.AddTags("AircraftInventoryContext");
            aircraftInventoryContextDatabase.AddTags("AircraftInventoryContextDatabase");
            vaccinesInventoryContext.AddTags("VaccinesInventoryContext");
            vaccinesInventoryContextDatabase.AddTags("VaccinesInventoryContextDatabase");
            monitoringContext.AddTags("MonitoringContext");
            monitoringContextDatabase.AddTags("MonitoringContextDatabase");
            monitoringContextReplicaDatabase.AddTags("MonitoringContextReplicaDatabase");
            monitoringContextReactiveDatabase.AddTags("MonitoringContextReactiveDatabase");
            messageBus.AddTags("MessageBus");

            styles.Add(new ElementStyle("MobileApp")
            {
                Background = "#9d33d6", Color = "#ffffff", Shape = Shape.MobileDevicePortrait, Icon = ""
            });
            styles.Add(new ElementStyle("WebApp")
            {
                Background = "#9d33d6", Color = "#ffffff", Shape = Shape.WebBrowser, Icon = ""
            });
            styles.Add(new ElementStyle("LandingPage")
            {
                Background = "#929000", Color = "#ffffff", Shape = Shape.WebBrowser, Icon = ""
            });
            styles.Add(new ElementStyle("APIGateway")
            {
                Shape = Shape.RoundedBox, Background = "#0000ff", Color = "#ffffff", Icon = ""
            });
            styles.Add(new ElementStyle("FlightPlanningContext")
            {
                Shape = Shape.Hexagon, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("FlightPlanningContextDatabase")
            {
                Shape = Shape.Cylinder, Background = "#ff0000", Color = "#ffffff", Icon = ""
            });
            styles.Add(new ElementStyle("AirportContext")
            {
                Shape = Shape.Hexagon, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("AirportContextDatabase")
            {
                Shape = Shape.Cylinder, Background = "#ff0000", Color = "#ffffff", Icon = ""
            });
            styles.Add(new ElementStyle("AircraftInventoryContext")
            {
                Shape = Shape.Hexagon, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("AircraftInventoryContextDatabase")
            {
                Shape = Shape.Cylinder, Background = "#ff0000", Color = "#ffffff", Icon = ""
            });
            styles.Add(new ElementStyle("VaccinesInventoryContext")
            {
                Shape = Shape.Hexagon, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("VaccinesInventoryContextDatabase")
            {
                Shape = Shape.Cylinder, Background = "#ff0000", Color = "#ffffff", Icon = ""
            });
            styles.Add(new ElementStyle("MonitoringContext")
            {
                Shape = Shape.Hexagon, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("MonitoringContextDatabase")
            {
                Shape = Shape.Cylinder, Background = "#ff0000", Color = "#ffffff", Icon = ""
            });
            styles.Add(new ElementStyle("MonitoringContextReplicaDatabase")
            {
                Shape = Shape.Cylinder, Background = "#ff0000", Color = "#ffffff", Icon = ""
            });
            styles.Add(new ElementStyle("MonitoringContextReactiveDatabase")
            {
                Shape = Shape.Cylinder, Background = "#ff0000", Color = "#ffffff", Icon = ""
            });
            styles.Add(new ElementStyle("MessageBus")
            {
                Width = 850, Background = "#fd8208", Color = "#ffffff", Shape = Shape.Pipe, Icon = ""
            });

            ContainerView containerView = viewSet.CreateContainerView(monitoringSystem, "Contenedor", "Diagrama de contenedores");

            contextView.PaperSize = PaperSize.A4_Landscape;
            containerView.AddAllElements();

            // 3. Diagrama de Componentes
            Component domainLayer                  = monitoringContext.AddComponent("Domain Layer", "", "Spring Boot");
            Component monitoringController         = monitoringContext.AddComponent("Monitoring Controller", "REST API endpoints de monitoreo.", "Spring Boot REST Controller");
            Component monitoringApplicationService = monitoringContext.AddComponent("Monitoring Application Service", "Provee métodos para el monitoreo, pertenece a la capa Application de DDD", "Spring Component");
            Component flightRepository             = monitoringContext.AddComponent("Flight Repository", "Información del vuelo", "Spring Component");
            Component vaccineLoteRepository        = monitoringContext.AddComponent("VaccineLote Repository", "Información de lote de vacunas", "Spring Component");
            Component locationRepository           = monitoringContext.AddComponent("Location Repository", "Ubicación del vuelo", "Spring Component");
            Component aircraftSystemFacade         = monitoringContext.AddComponent("Aircraft System Facade", "", "Spring Component");

            apiGateway.Uses(monitoringController, "", "JSON/HTTPS");
            monitoringController.Uses(monitoringApplicationService, "Invoca métodos de monitoreo");
            monitoringController.Uses(aircraftSystemFacade, "Usa");
            monitoringApplicationService.Uses(domainLayer, "Usa", "");
            monitoringApplicationService.Uses(flightRepository, "", "JDBC");
            monitoringApplicationService.Uses(vaccineLoteRepository, "", "JDBC");
            monitoringApplicationService.Uses(locationRepository, "", "JDBC");
            flightRepository.Uses(monitoringContextDatabase, "", "JDBC");
            vaccineLoteRepository.Uses(monitoringContextDatabase, "", "JDBC");
            locationRepository.Uses(monitoringContextDatabase, "", "JDBC");
            locationRepository.Uses(monitoringContextReactiveDatabase, "", "");
            locationRepository.Uses(googleMaps, "", "JSON/HTTPS");
            aircraftSystemFacade.Uses(aircraftSystem, "JSON/HTTPS");

            // Tags
            domainLayer.AddTags("DomainLayer");
            monitoringController.AddTags("MonitoringController");
            monitoringApplicationService.AddTags("MonitoringApplicationService");
            flightRepository.AddTags("FlightRepository");
            vaccineLoteRepository.AddTags("VaccineLoteRepository");
            locationRepository.AddTags("LocationRepository");
            aircraftSystemFacade.AddTags("AircraftSystemFacade");

            styles.Add(new ElementStyle("DomainLayer")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("MonitoringController")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("MonitoringApplicationService")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("MonitoringDomainModel")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("FlightStatus")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("FlightRepository")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("VaccineLoteRepository")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("LocationRepository")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });
            styles.Add(new ElementStyle("AircraftSystemFacade")
            {
                Shape = Shape.Component, Background = "#facc2e", Icon = ""
            });

            ComponentView componentView = viewSet.CreateComponentView(monitoringContext, "Components", "Component Diagram");

            componentView.PaperSize = PaperSize.A4_Landscape;
            componentView.Add(mobileApplication);
            componentView.Add(webApplication);
            componentView.Add(apiGateway);
            componentView.Add(monitoringContextDatabase);
            componentView.Add(monitoringContextReactiveDatabase);
            componentView.Add(aircraftSystem);
            componentView.Add(googleMaps);
            componentView.AddAllComponents();

            structurizrClient.UnlockWorkspace(workspaceId);
            structurizrClient.PutWorkspace(workspaceId, 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!");
        }
Ejemplo n.º 30
0
        private static Workspace Create(bool usePaidFeatures)
        {
            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, "Customer", "A customer of the bank.");

            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.");

            internetBankingSystem.Uses(mainframeBankingSystem, "Uses");

            SoftwareSystem atm = model.AddSoftwareSystem(Location.Internal, "ATM", "Allows customers to withdraw cash.");

            atm.Uses(mainframeBankingSystem, "Uses");
            customer.Uses(atm, "Withdraws cash using");

            Person bankStaff = model.AddPerson(Location.Internal, "Bank Staff", "Staff within the bank.");

            bankStaff.Uses(mainframeBankingSystem, "Uses");

            // containers
            Container webApplication = internetBankingSystem.AddContainer("Web Application", "Provides all of the Internet banking functionality to customers.", "Java and Spring MVC");
            Container database       = internetBankingSystem.AddContainer("Database", "Stores interesting data.", "Relational Database Schema");

            database.AddTags(DatabaseTag);

            customer.Uses(webApplication, "Uses", "HTTPS");
            webApplication.Uses(database, "Reads from and writes to", "JDBC");
            webApplication.Uses(mainframeBankingSystem, "Uses", "XML/HTTPS");

            // 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 homePageController           = webApplication.AddComponent("Home Page Controller", "Serves up the home page.", "Spring MVC Controller");
            Component signinController             = webApplication.AddComponent("Sign In Controller", "Allows users to sign in to the Internet Banking System.", "Spring MVC Controller");
            Component accountsSummaryController    = webApplication.AddComponent("Accounts Summary Controller", "Provides customers with an summary of their bank accounts.", "Spring MVC Controller");
            Component securityComponent            = webApplication.AddComponent("Security Component", "Provides functionality related to signing in, changing passwords, etc.", "Spring Bean");
            Component mainframeBankingSystemFacade = webApplication.AddComponent("Mainframe Banking System Facade", "A facade onto the mainframe banking system.", "Spring Bean");

            webApplication.Components.Where(c => "Spring MVC Controller".Equals(c.Technology)).ToList().ForEach(c => customer.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");

            // deployment nodes and container instances
            DeploymentNode developerLaptop = model.AddDeploymentNode("Developer Laptop", "A developer laptop.", "Windows 7 or 10");

            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"))
            .Add(webApplication);

            developerLaptop.AddDeploymentNode("Docker Container - Database Server", "A Docker container.", "Docker")
            .AddDeploymentNode("Database Server", "A development database.", "Oracle 12c")
            .Add(database);

            DeploymentNode liveWebServer = model.AddDeploymentNode("bigbank-web***", "A web server residing in the web server farm, accessed via F5 BIG-IP LTMs.", "Ubuntu 16.04 LTS", 8, DictionaryUtils.Create("Location=London"));

            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 primaryDatabaseServer = model.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 secondaryDatabaseServer = model.AddDeploymentNode("bigbank-db02", "The secondary database server.", "Ubuntu 16.04 LTS", 1, DictionaryUtils.Create("Location=Reading"))
                                                     .AddDeploymentNode("Oracle - Secondary", "A secondary, standby database server, used for failover purposes only.", "Oracle 12c");
            ContainerInstance secondaryDatabase = secondaryDatabaseServer.Add(database);

            model.Relationships.Where(r => r.Destination.Equals(secondaryDatabase)).ToList().ForEach(r => r.AddTags("Failover"));
            Relationship dataReplicationRelationship = primaryDatabaseServer.Uses(secondaryDatabaseServer, "Replicates data to", "");

            secondaryDatabase.AddTags("Failover");

            // views/diagrams
            EnterpriseContextView enterpriseContextView = views.CreateEnterpriseContextView("SystemLandscape", "The system landscape diagram for Big Bank plc.");

            enterpriseContextView.AddAllElements();
            enterpriseContextView.PaperSize = PaperSize.A5_Landscape;

            SystemContextView systemContextView = views.CreateSystemContextView(internetBankingSystem, "SystemContext", "The system context diagram for the Internet Banking System.");

            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.PaperSize = PaperSize.A5_Landscape;

            ComponentView componentView = views.CreateComponentView(webApplication, "Components", "The component diagram for the Web Application");

            componentView.AddAllContainers();
            componentView.AddAllComponents();
            componentView.Add(customer);
            componentView.Add(mainframeBankingSystem);
            componentView.PaperSize = PaperSize.A5_Landscape;

            if (usePaidFeatures)
            {
                // dynamic diagrams, deployment diagrams and corporate branding are not available with the Free Plan
                DynamicView dynamicView = views.CreateDynamicView(webApplication, "SignIn", "Summarises how the sign in feature works.");
                dynamicView.Add(customer, "Requests /signin from", signinController);
                dynamicView.Add(customer, "Submits credentials to", signinController);
                dynamicView.Add(signinController, "Calls isAuthenticated() on", securityComponent);
                dynamicView.Add(securityComponent, "select * from users u 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.Add(developerLaptop);
                developmentDeploymentView.PaperSize = PaperSize.A5_Landscape;

                DeploymentView liveDeploymentView = views.CreateDeploymentView(internetBankingSystem, "LiveDeployment", "An example live deployment scenario for the Internet Banking System.");
                liveDeploymentView.Add(liveWebServer);
                liveDeploymentView.Add(primaryDatabaseServer);
                liveDeploymentView.Add(secondaryDatabaseServer);
                liveDeploymentView.Add(dataReplicationRelationship);
                liveDeploymentView.PaperSize = PaperSize.A5_Landscape;
            }

            // colours, shapes and other diagram styling
            Styles styles = views.Configuration.Styles;

            styles.Add(new ElementStyle(Tags.Element)
            {
                Color = "#ffffff"
            });
            styles.Add(new ElementStyle(Tags.SoftwareSystem)
            {
                Background = "#1168bd"
            });
            styles.Add(new ElementStyle(Tags.Container)
            {
                Background = "#438dd5"
            });
            styles.Add(new ElementStyle(Tags.Component)
            {
                Background = "#85bbf0", Color = "#000000"
            });
            styles.Add(new ElementStyle(Tags.Person)
            {
                Background = "#08427b", Shape = Shape.Person
            });
            styles.Add(new ElementStyle(DatabaseTag)
            {
                Shape = Shape.Cylinder
            });
            styles.Add(new ElementStyle("Failover")
            {
                Opacity = 25
            });
            styles.Add(new RelationshipStyle("Failover")
            {
                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:EnterpriseContext)\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 Web 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);
        }