This repository has been archived by the owner on Dec 23, 2023. It is now read-only.
/
BigBankPlc.cs
263 lines (217 loc) · 17.9 KB
/
BigBankPlc.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
using System.Linq;
using Structurizr.Api;
using Structurizr.Core.Util;
using Structurizr.Documentation;
namespace Structurizr.Examples
{
/// <summary>
/// This is an example workspace to illustrate the key features of Structurizr,
/// based around a fictional Internet Banking System for Big Bank plc.
///
/// The live workspace is available to view at https://structurizr.com/share/36141
/// </summary>
public class BigBankPlc
{
private const long WorkspaceId = 36141;
private const string ApiKey = "key";
private const string ApiSecret = "secret";
private const string ExistingSystemTag = "Existing System";
private const string BankStaffTag = "Bank Staff";
private const string WebBrowserTag = "Web Browser";
private const string MobileAppTag = "Mobile App";
private const string DatabaseTag = "Database";
private const string FailoverTag = "Failover";
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, "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.");
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", "");
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 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");
apiApplication.Components.Where(c => "Spring MVC Rest Controller".Equals(c.Technology)).ToList().ForEach(c => singlePageApplication.Uses(c, "Uses", "HTTPS"));
apiApplication.Components.Where(c => "Spring MVC Rest Controller".Equals(c.Technology)).ToList().ForEach(c => mobileApp.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");
model.AddImplicitRelationships();
// deployment nodes and container instances
DeploymentNode developerLaptop = model.AddDeploymentNode("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", "", "Google Chrome, Mozilla Firefox, Apple Safari or Microsoft Edge").Add(singlePageApplication);
DeploymentNode customerMobileDevice = model.AddDeploymentNode("Customer's mobile device", "", "Apple iOS or Android");
customerMobileDevice.Add(mobileApp);
DeploymentNode customerComputer = model.AddDeploymentNode("Customer's computer", "", "Microsoft Windows or Apple macOS");
customerComputer.AddDeploymentNode("Web Browser", "", "Google Chrome, Mozilla Firefox, Apple Safari or Microsoft Edge").Add(singlePageApplication);
DeploymentNode bigBankDataCenter = model.AddDeploymentNode("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 secondaryDatabaseServer = bigBankDataCenter.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(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.PaperSize = PaperSize.A5_Landscape;
if (usePaidFeatures)
{
// animations are not available with the Free Plan
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);
// 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.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, FontSize = 22});
styles.Add(new ElementStyle(ExistingSystemTag) { Background = "#999999"});
styles.Add(new ElementStyle(BankStaffTag) { Background = "#999999" });
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;
}
static void Main()
{
StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);
structurizrClient.PutWorkspace(WorkspaceId, Create(true));
}
}
}