public void Test_AddRelationshipDirectly() { DynamicView dynamicView = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); dynamicView.Add(relationship); Assert.Equal(2, dynamicView.Elements.Count); }
private void Write(DynamicView view, TextWriter writer) { try { writer.WriteLine("@startuml"); writer.WriteLine("title " + view.Name); view.Elements .Select(ev => ev.Element) .Where(e => e is Person) .OrderBy(e => e.Name).ToList() .ForEach(e => writer.WriteLine("actor " + NameOf(e))); view.Relationships .OrderBy(rv => rv.Order).ToList() .ForEach(r => writer.WriteLine( String.Format("{0} -> {1} : {2}", NameOf(r.Relationship.Source), NameOf(r.Relationship.Destination), HasValue(r.Description) ? r.Description : HasValue(r.Relationship.Description) ? r.Relationship.Description : "" ) )); writer.WriteLine("@enduml"); writer.WriteLine(""); } catch (IOException e) { Console.WriteLine(e.StackTrace); } }
public void Test_GetRelationships_WhenTheOrderPropertyIsAString() { string characters = "abcdefghij"; containerA1.Uses(containerA2, "uses"); DynamicView view = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); for (int i = 0; i < 10; i++) { RelationshipView relationshipView = view.Add(containerA1, containerA2); relationshipView.Order = "1" + characters.ToCharArray()[i]; } List <RelationshipView> relationships = new List <RelationshipView>(view.Relationships); Assert.Equal("1a", relationships[0].Order); Assert.Equal("1b", relationships[1].Order); Assert.Equal("1c", relationships[2].Order); Assert.Equal("1d", relationships[3].Order); Assert.Equal("1e", relationships[4].Order); Assert.Equal("1f", relationships[5].Order); Assert.Equal("1g", relationships[6].Order); Assert.Equal("1h", relationships[7].Order); Assert.Equal("1i", relationships[8].Order); Assert.Equal("1j", relationships[9].Order); }
protected override void Write(DynamicView view, TextWriter writer) { WriteProlog(view, writer); IList <Element> innerElements = new List <Element>(); IList <Element> outerElements = new List <Element>(); if (view.Element != null) { // boundary check via parent var parentId = view.Element.Id; view.Elements .Select(ev => ev.Element) .OrderBy(e => e.Name).ToList() .ForEach(e => { if (e?.Parent?.Id == parentId || e?.Parent?.Parent?.Id == parentId || e?.Parent?.Parent?.Parent?.Id == parentId) { innerElements.Add(e); } else { outerElements.Add(e); } }); } else { // TODO: model based boundary checks are missing view.Elements .Select(ev => ev.Element) .OrderBy(e => e.Name).ToList() .ForEach(e => innerElements.Add(e)); } var showBoundary = (outerElements.Count > 0); outerElements .OrderBy(e => e.Name).ToList() .ForEach(e => Write(e, writer, 0)); if (showBoundary) { Write(view.Element, writer, 0, true); } innerElements .OrderBy(e => e.Name).ToList() .ForEach(e => Write(e, writer, showBoundary ? 1 : 0)); if (showBoundary) { writer.WriteLine("}"); } WriteDynamicInteractions(view.Relationships, writer); WriteEpilog(view, writer); }
public void Test_Add_AddsTheSourceAndDestinationElements_WhenARelationshipBetweenThemExists() { DynamicView dynamicView = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); dynamicView.Add(containerA1, containerA2); Assert.Equal(2, dynamicView.Elements.Count); }
public void Test_Add_AddsTheSourceAndDestinationElements_WhenARelationshipBetweenThemExistsAndTheDestinationIsAnExternalSoftwareSystem() { DynamicView dynamicView = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); containerA2.Uses(softwareSystemB, "", ""); dynamicView.Add(containerA2, softwareSystemB); Assert.Equal(2, dynamicView.Elements.Count); }
public DynamicView Get(string id) { DynamicView dynamicView = new DynamicView(); dynamicView.FormConfig = dynamicFormFacade.GetFormConfig(id); dynamicView.GridConfig = dynamicGridFacade.GetGridConfig(dynamicView.FormConfig.GridConfigId); return(dynamicView); }
public void Test_Add_ThrowsAnException_WhenThereIsNoRelationshipBetweenTheSourceAndDestinationElements() { DynamicView dynamicView = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); Assert.Throws <ArgumentException>(() => dynamicView.Add(containerA1, containerA3) ); }
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); }
public void ChangeDynamicView() { if (DynamicView.GetType() == typeof(View1)) { DynamicView = _View2; } else { DynamicView = _View1; } }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource //SetContentView(Resource.Layout.Main); JSONObject jsonObject; try { jsonObject = new JSONObject(readFile("sample.json", this)); } catch (JSONException je) { je.PrintStackTrace(); jsonObject = null; } if (jsonObject != null) { //SampleViewHolder sampleViewHolder = new SampleViewHolder(); //object[] os = sampleViewHolder.GetType().GetProperties()[0].GetCustomAttributes(true); //Type type = os[0].GetType(); //object[] os = sampleViewHolder.GetType().GetCustomAttributes(typeof(SampleViewHolder), true); /* create dynamic view and return the view with the holder class attached as tag */ View sampleView = DynamicView.createView(this, jsonObject, Java.Lang.Class.FromType(typeof(SampleViewHolder))); //View sampleView = DynamicView.createView(this, jsonObject, typeof(SampleViewHolder)); /* get the view with id "testClick" and attach the onClickListener */ ((SampleViewHolder)sampleView.Tag).clickableView.SetOnClickListener(this); //ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(this, new LayoutAttribute()); sampleView.LayoutParameters = new ViewGroup.LayoutParams(200, 200); /* add Layout Parameters in just created view and set as the contentView of the activity */ //sampleView.SetLayoutParams(new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT)); SetContentView(sampleView); } else { Log.Error("Json2View", "Could not load valid json file"); } //Set our view from the "main" layout resource //SetContentView(Resource.Layout.Main); //string path = Environment.ExternalStorageDirectory.Path;//.GetExternalStorageDirectory().getPath(); //LinearLayout root = this.FindViewById<LinearLayout>(Resource.Id.root); //this.Resources.GetLayout() //XmlReader xmlReader = XmlReader.Create(path + "//button.xml"); //LayoutInflater layoutInflater = LayoutInflater.From(this); //Android.Views.View view1 = layoutInflater.Inflate(Resource.Layout.button, root); //Android.Views.View view = layoutInflater.Inflate(xmlReader, null, false); }
public void Test_Add_ThrowsAnException_WhenTheScopeOfTheDynamicViewIsAContainerAndTheSameContainerIsAdded() { try { DynamicView dynamicView = workspace.Views.CreateDynamicView(containerA1, "key", "Description"); dynamicView.Add(containerA1, containerA2); Assert.Fail(); } catch (Exception e) { Assert.AreEqual("Container A1 is already the scope of this view and cannot be added to it.", e.Message); } }
public void Test_Add_ThrowsAnException_WhenTheScopeOfTheDynamicViewIsNotSpecifiedButAComponentIsAdded() { try { DynamicView dynamicView = Workspace.Views.CreateDynamicView("key", "Description"); dynamicView.Add(componentA1, componentA1); throw new TestFailedException(); } catch (ElementNotPermittedInViewException iae) { Assert.Equal("Only people and software systems can be added to this dynamic view.", iae.Message); } }
public void Test_Add_ThrowsAnException_WhenTheScopeOfTheDynamicViewIsAContainerAndTheParentSoftwareSystemIsAdded() { try { DynamicView dynamicView = Workspace.Views.CreateDynamicView(containerA1, "key", "Description"); dynamicView.Add(softwareSystemA, containerA2); throw new TestFailedException(); } catch (Exception e) { Assert.Equal("Software System A is already the scope of this view and cannot be added to it.", e.Message); } }
public void Test_Add_ThrowsAnException_WhenTheScopeOfTheDynamicViewIsASoftwareSystemButAContainerInAnotherSoftwareSystemIsAdded() { try { DynamicView dynamicView = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); dynamicView.Add(containerB1, containerA1); throw new TestFailedException(); } catch (Exception e) { Assert.Equal("Only containers that reside inside Software System A can be added to this view.", e.Message); } }
public void Test_Add_ThrowsAnException_WhenTheScopeOfTheDynamicViewIsASoftwareSystemButAComponentIsAdded() { try { DynamicView dynamicView = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); dynamicView.Add(componentA1, containerA1); throw new TestFailedException(); } catch (Exception e) { Assert.Equal("Components can't be added to a dynamic view when the scope is a software system.", e.Message); } }
public void Test_Add_ThrowsAnException_WhenTheScopeOfTheDynamicViewIsAContainerAndAComponentInAnotherContainerIsAdded() { try { DynamicView dynamicView = Workspace.Views.CreateDynamicView(containerA1, "key", "Description"); dynamicView.Add(componentA2, containerA2); throw new TestFailedException(); } catch (Exception e) { Assert.Equal("Only components that reside inside Container A1 can be added to this view.", e.Message); } }
public void Test_ParallelSequence() { Workspace = new Workspace("Name", "Description"); Model = Workspace.Model; SoftwareSystem softwareSystem = Model.AddSoftwareSystem("Name", "Description"); Person user = Model.AddPerson("User", "Description"); Container microservice1 = softwareSystem.AddContainer("Microservice 1", "", ""); Container database1 = softwareSystem.AddContainer("Database 1", "", ""); Container microservice2 = softwareSystem.AddContainer("Microservice 2", "", ""); Container database2 = softwareSystem.AddContainer("Database 2", "", ""); Container microservice3 = softwareSystem.AddContainer("Microservice 3", "", ""); Container database3 = softwareSystem.AddContainer("Database 3", "", ""); Container messageBus = softwareSystem.AddContainer("Message Bus", "", ""); user.Uses(microservice1, "Updates using"); microservice1.Delivers(user, "Sends updates to"); microservice1.Uses(database1, "Stores data in"); microservice1.Uses(messageBus, "Sends messages to"); microservice1.Uses(messageBus, "Sends messages to"); messageBus.Uses(microservice2, "Sends messages to"); messageBus.Uses(microservice3, "Sends messages to"); microservice2.Uses(database2, "Stores data in"); microservice3.Uses(database3, "Stores data in"); DynamicView view = Workspace.Views.CreateDynamicView(softwareSystem, "key", "Description"); view.Add(user, "1", microservice1); view.Add(microservice1, "2", database1); view.Add(microservice1, "3", messageBus); view.StartParallelSequence(); view.Add(messageBus, "4", microservice2); view.Add(microservice2, "5", database2); view.EndParallelSequence(); view.StartParallelSequence(); view.Add(messageBus, "4", microservice3); view.Add(microservice3, "5", database3); view.EndParallelSequence(); view.Add(microservice1, "5", database1); Assert.Equal(1, view.Relationships.Count(r => r.Order.Equals("1"))); Assert.Equal(1, view.Relationships.Count(r => r.Order.Equals("2"))); Assert.Equal(1, view.Relationships.Count(r => r.Order.Equals("3"))); Assert.Equal(3, view.Relationships.Count(r => r.Order.Equals("4"))); Assert.Equal(2, view.Relationships.Count(r => r.Order.Equals("5"))); }
public void Test_WriteDynamicView() { PopulateWorkspace(); DynamicView dynamicView = _workspace.Views.DynamicViews.First(); _plantUMLWriter.Write(dynamicView, _stringWriter); Assert.AreEqual("@startuml" + Environment.NewLine + "title Web Application - Dynamic" + Environment.NewLine + "actor User" + Environment.NewLine + "User -> SomeController : Requests /something" + Environment.NewLine + "SomeController -> SomeRepository : Uses" + Environment.NewLine + "SomeRepository -> Database : select * from something" + Environment.NewLine + "@enduml" + Environment.NewLine + Environment.NewLine, _stringWriter.ToString()); }
public void test_writeDynamicView() { PopulateWorkspace(); DynamicView dynamicView = _workspace.Views.DynamicViews.First(); _plantUMLWriter.Write(dynamicView, _stringWriter); Assert.Equal("@startuml" + Environment.NewLine + "title Web Application - Dynamic" + Environment.NewLine + "component \"Database\" <<Container>> as 8" + Environment.NewLine + "component \"SomeController\" <<Spring MVC Controller>> as 12" + Environment.NewLine + "component \"SomeRepository\" <<Spring Data>> as 14" + Environment.NewLine + "actor \"User\" <<Person>> as 1" + Environment.NewLine + "1 -> 12 : Requests /something" + Environment.NewLine + "12 -> 14 : Uses" + Environment.NewLine + "14 -> 8 : select * from something" + Environment.NewLine + "@enduml" + Environment.NewLine + Environment.NewLine, _stringWriter.ToString()); }
public void Test_NormalSequence() { Workspace = new Workspace("Name", "Description"); Model = Workspace.Model; SoftwareSystem softwareSystem = Model.AddSoftwareSystem("Software System", "Description"); Container container1 = softwareSystem.AddContainer("Container 1", "Description", "Technology"); Container container2 = softwareSystem.AddContainer("Container 2", "Description", "Technology"); Container container3 = softwareSystem.AddContainer("Container 3", "Description", "Technology"); container1.Uses(container2, "Uses"); container1.Uses(container3, "Uses"); DynamicView view = Workspace.Views.CreateDynamicView(softwareSystem, "key", "Description"); view.Add(container1, container2); view.Add(container1, container3); Assert.Same(container2, view.Relationships.First(rv => rv.Order.Equals("1")).Relationship.Destination); Assert.Same(container3, view.Relationships.First(rv => rv.Order.Equals("2")).Relationship.Destination); }
public void test_writeDynamicView() { PopulateWorkspace(); DynamicView dynamicView = _workspace.Views.DynamicViews.First(); _plantUMLWriter.Write(dynamicView, _stringWriter); Assert.Equal( @"@startuml title Web Application - Dynamic component ""Database"" <<Container>> as 8 component ""SomeController"" <<Spring MVC Controller>> as 12 component ""SomeRepository"" <<Spring Data>> as 14 actor ""User"" <<Person>> as 1 1 -> 12 : Requests /something 12 -> 14 : Uses 14 -> 8 : select * from something @enduml ".UnifyNewLine(), _stringWriter.ToString()); }
public void Write(DynamicView view, TextWriter writer) { if (view == null) { throw new ArgumentException("A dynamic view must be specified."); } try { WriteHeader(view, writer); view.Elements .Select(ev => ev.Element) .OrderBy(e => e.Name).ToList() .ForEach(e => Write(e, writer, false)); view.Relationships .OrderBy(rv => rv.Order).ToList() .ForEach(r => writer.WriteLine( String.Format("{0} -> {1} : {2}", r.Relationship.Source.Id, r.Relationship.Destination.Id, HasValue(r.Description) ? r.Description : HasValue(r.Relationship.Description) ? r.Relationship.Description : "" ) )); WriteFooter(writer); } catch (IOException e) { Console.WriteLine(e.StackTrace); } }
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"))); }
public void Test_GetRelationships_WhenTheOrderPropertyIsAnInteger() { containerA1.Uses(containerA2, "uses"); DynamicView view = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); for (int i = 0; i < 10; i++) { view.Add(containerA1, containerA2); } List <RelationshipView> relationships = new List <RelationshipView>(view.Relationships); Assert.Equal("1", relationships[0].Order); Assert.Equal("2", relationships[1].Order); Assert.Equal("3", relationships[2].Order); Assert.Equal("4", relationships[3].Order); Assert.Equal("5", relationships[4].Order); Assert.Equal("6", relationships[5].Order); Assert.Equal("7", relationships[6].Order); Assert.Equal("8", relationships[7].Order); Assert.Equal("9", relationships[8].Order); Assert.Equal("10", relationships[9].Order); }
public void Test_GetRelationships_WhenTheOrderPropertyIsADecimal() { containerA1.Uses(containerA2, "uses"); DynamicView view = Workspace.Views.CreateDynamicView(softwareSystemA, "key", "Description"); for (int i = 0; i < 10; i++) { RelationshipView relationshipView = view.Add(containerA1, containerA2); relationshipView.Order = "1." + i; } List <RelationshipView> relationships = new List <RelationshipView>(view.Relationships); Assert.Equal("1.0", relationships[0].Order); Assert.Equal("1.1", relationships[1].Order); Assert.Equal("1.2", relationships[2].Order); Assert.Equal("1.3", relationships[3].Order); Assert.Equal("1.4", relationships[4].Order); Assert.Equal("1.5", relationships[5].Order); Assert.Equal("1.6", relationships[6].Order); Assert.Equal("1.7", relationships[7].Order); Assert.Equal("1.8", relationships[8].Order); Assert.Equal("1.9", relationships[9].Order); }
public static async Task TestMinimalSelects(IDatabase database) { await DatabaseUnitTest.TruncateData(database); using (DynamicViewSet dynamicViewSet = new DynamicViewSet(database, listener: dataEventTransaction => { })) { DynamicView departmentDynamicView = dynamicViewSet.CreateDynamicView("department"); DynamicView employeeDynamicView = dynamicViewSet.CreateDynamicView("employee"); await dynamicViewSet.StartAsync(); await Task.Delay(200); int preSelectCount = database.SelectCount; await database.InsertAndCommitAsync <string>("employee", new { name = "Joe Sales", department_id = 1, }); await Task.Delay(200); // Should require doing two SELECTs to handle this INSERT (before and after SELECT) Assert.AreEqual(preSelectCount + 1, database.SelectCount); } }
public void Test_CopyLayoutInformationFrom() { Workspace workspace1 = new Workspace("", ""); Model model1 = workspace1.Model; SoftwareSystem softwareSystem1A = model1.AddSoftwareSystem("System A", "Description"); SoftwareSystem softwareSystem1B = model1.AddSoftwareSystem("System B", "Description"); Person person1 = model1.AddPerson("Person", "Description"); Relationship personUsesSoftwareSystem1 = person1.Uses(softwareSystem1A, "Uses"); // create a view with SystemA and Person (locations are set for both, relationship has vertices) StaticView staticView1 = new SystemContextView(softwareSystem1A, "context", "Description"); staticView1.Add(softwareSystem1B); staticView1.GetElementView(softwareSystem1B).X = 123; staticView1.GetElementView(softwareSystem1B).Y = 321; staticView1.Add(person1); staticView1.GetElementView(person1).X = 456; staticView1.GetElementView(person1).Y = 654; staticView1.GetRelationshipView(personUsesSoftwareSystem1).Vertices = new List <Vertex>() { new Vertex(123, 456) }; staticView1.GetRelationshipView(personUsesSoftwareSystem1).Position = 70; staticView1.GetRelationshipView(personUsesSoftwareSystem1).Routing = Routing.Orthogonal; // and create a dynamic view, as they are treated slightly differently DynamicView dynamicView1 = new DynamicView(model1, "dynamic", "Description"); dynamicView1.Add(person1, "Overridden description", softwareSystem1A); dynamicView1.GetElementView(person1).X = 111; dynamicView1.GetElementView(person1).Y = 222; dynamicView1.GetElementView(softwareSystem1A).X = 333; dynamicView1.GetElementView(softwareSystem1A).Y = 444; dynamicView1.GetRelationshipView(personUsesSoftwareSystem1).Vertices = new List <Vertex>() { new Vertex(555, 666) }; dynamicView1.GetRelationshipView(personUsesSoftwareSystem1).Position = 30; dynamicView1.GetRelationshipView(personUsesSoftwareSystem1).Routing = Routing.Direct; Workspace workspace2 = new Workspace("", ""); Model model2 = workspace2.Model; // creating these in the opposite order will cause them to get different internal IDs SoftwareSystem softwareSystem2B = model2.AddSoftwareSystem("System B", "Description"); SoftwareSystem softwareSystem2A = model2.AddSoftwareSystem("System A", "Description"); Person person2 = model2.AddPerson("Person", "Description"); Relationship personUsesSoftwareSystem2 = person2.Uses(softwareSystem2A, "Uses"); // create a view with SystemB and Person (locations are 0,0 for both) StaticView staticView2 = new SystemContextView(softwareSystem2A, "context", "Description"); staticView2.Add(softwareSystem2B); staticView2.Add(person2); Assert.Equal(0, staticView2.GetElementView(softwareSystem2B).X); Assert.Equal(0, staticView2.GetElementView(softwareSystem2B).Y); Assert.Equal(0, staticView2.GetElementView(softwareSystem2B).X); Assert.Equal(0, staticView2.GetElementView(softwareSystem2B).Y); Assert.Equal(0, staticView2.GetElementView(person2).X); Assert.Equal(0, staticView2.GetElementView(person2).Y); Assert.True(staticView2.GetRelationshipView(personUsesSoftwareSystem2).Vertices.Count == 0); // and create a dynamic view (locations are 0,0) DynamicView dynamicView2 = new DynamicView(model2, "dynamic", "Description"); dynamicView2.Add(person2, "Overridden description", softwareSystem2A); staticView2.CopyLayoutInformationFrom(staticView1); Assert.Equal(0, staticView2.GetElementView(softwareSystem2A).X); Assert.Equal(0, staticView2.GetElementView(softwareSystem2A).Y); Assert.Equal(123, staticView2.GetElementView(softwareSystem2B).X); Assert.Equal(321, staticView2.GetElementView(softwareSystem2B).Y); Assert.Equal(456, staticView2.GetElementView(person2).X); Assert.Equal(654, staticView2.GetElementView(person2).Y); Vertex vertex1 = staticView2.GetRelationshipView(personUsesSoftwareSystem2).Vertices[0]; Assert.Equal(123, vertex1.X); Assert.Equal(456, vertex1.Y); Assert.Equal(70, staticView2.GetRelationshipView(personUsesSoftwareSystem2).Position); Assert.Equal(Routing.Orthogonal, staticView2.GetRelationshipView(personUsesSoftwareSystem2).Routing); dynamicView2.CopyLayoutInformationFrom(dynamicView1); Assert.Equal(111, dynamicView2.GetElementView(person2).X); Assert.Equal(222, dynamicView2.GetElementView(person2).Y); Assert.Equal(333, dynamicView2.GetElementView(softwareSystem2A).X); Assert.Equal(444, dynamicView2.GetElementView(softwareSystem2A).Y); Vertex vertex2 = dynamicView2.GetRelationshipView(personUsesSoftwareSystem2).Vertices[0]; Assert.Equal(555, vertex2.X); Assert.Equal(666, vertex2.Y); Assert.Equal(30, dynamicView2.GetRelationshipView(personUsesSoftwareSystem2).Position); Assert.Equal(Routing.Direct, dynamicView2.GetRelationshipView(personUsesSoftwareSystem2).Routing); }
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); }
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); }