def test_interact_with_workspace_without_encryption(settings): # Set up a toy workspace. workspace = Workspace( id=settings.workspace_id, name="e2e-tests - without encryption", description="A test workspace for the structurizr-python client.", ) system = workspace.model.add_software_system( name="Software System", description="Description" ) person = workspace.model.add_person(name="Person", description="Description") person.uses(system, "") context_view = workspace.views.create_system_context_view( software_system=system, key="SystemContext", description="Description" ) context_view.add_all_elements() # Upload the workspace and immediately retrieve it again. with StructurizrClient(settings=settings) as client: client.put_workspace(workspace) remote_ws = client.get_workspace() # Verify the remote workspace. assert remote_ws.model.get_software_system_with_name("Software System") is not None assert remote_ws.model.get_person_with_name("Person") is not None assert len(remote_ws.model.relationships) == 1 assert len(remote_ws.views.get_system_context_views()) == 1 # Verify the generated archive. archives = list(settings.workspace_archive_location.glob("*.json.gz")) assert len(archives) == 1 archived_ws: Workspace = Workspace.load(archives[0]) assert archived_ws.id == 20081 assert archived_ws.name == "structurizr-python e2e-tests - without encryption" assert len(archived_ws.model.software_systems) == 1
def test_workspace_overridding_zip_flag(monkeypatch, tmp_path: Path): """Test that default zipping can be overridden explicitly.""" monkeypatch.syspath_prepend(EXAMPLES) example = import_module("getting_started") workspace = example.main() filepath = tmp_path / "test_workspace.json.gz" workspace.dump(filepath, zip=False) contents = filepath.read_text() assert "My software system" in contents # Make sure can be loaded even though its not zipped and ends with .gz Workspace.load(filepath)
def main() -> Workspace: """Create the 'getting started' example.""" workspace = Workspace( name="Getting Started", description="This is a model of my software system.", ) model = workspace.model user = model.add_person(name="User", description="A user of my software system.") software_system = model.add_software_system( name="Software System", description="My software system." ) user.uses(software_system, "Uses") context_view = workspace.views.create_system_context_view( software_system=software_system, key="SystemContext", description="An example of a System Context diagram.", ) context_view.add_all_elements() context_view.paper_size = PaperSize.A5_Landscape styles = workspace.views.configuration.styles styles.add( ElementStyle(tag=Tags.SOFTWARE_SYSTEM, background="#1168bd", color="#ffffff") ) styles.add( ElementStyle( tag=Tags.PERSON, background="#08427b", color="#ffffff", shape=Shape.Person, ) ) return workspace
def test_serialize_workspace(example, filename, monkeypatch): """Expect that .""" monkeypatch.syspath_prepend(EXAMPLES) example = import_module(example) path = DEFINITIONS / filename expected = Workspace.load(path) assert example.main() == expected
def test_load_workspace_from_bytes(monkeypatch): """Test loading from bytes rather than string.""" path = DEFINITIONS / "GettingStarted.json" with open(path, mode="rb") as file: binary_content = file.read() workspace = Workspace.loads(binary_content) assert workspace.model.software_systems != set()
def test_serialize_workspace(example, filename, monkeypatch): """Expect that .""" monkeypatch.syspath_prepend(EXAMPLES) example = import_module(example) path = DEFINITIONS / filename # TODO (midnighter): Use `from_orm` like `.construct` bypassing validation. ( # Requires a pull request on pydantic.) expected = WorkspaceIO.from_orm(Workspace.load(path)) actual = WorkspaceIO.from_orm(example.main()) assert json.loads(actual.json()) == json.loads(expected.json())
def test_empty_workspace_without_encryption(settings): workspace = Workspace( id=settings.workspace_id, name="e2e-tests - without encryption", description="A test workspace for the structurizr-python client.", ) with StructurizrClient(settings=settings) as client: client.put_workspace(workspace) remote_ws = client.get_workspace() assert remote_ws.name == workspace.name assert remote_ws.description == workspace.description
def test_save_and_load_workspace_to_string(monkeypatch): """Test saving as a JSON string and reloading.""" monkeypatch.syspath_prepend(EXAMPLES) example = import_module("getting_started") workspace = example.main() json_string: str = workspace.dumps(indent=2) workspace2 = Workspace.loads(json_string) expected = WorkspaceIO.from_orm(workspace) actual = WorkspaceIO.from_orm(workspace2) assert json.loads(actual.json()) == json.loads(expected.json())
def test_model_deserialises_deployment_nodes(filename: str): """Ensure deserialisaton of deployment nodes works.""" path = DEFINITIONS / filename workspace = Workspace.load(path) model = workspace.model db_server = model.get_element("59") assert db_server.name == "Docker Container - Database Server" assert db_server is not None assert db_server.model is model assert db_server.parent.name == "Developer Laptop" assert db_server.parent.parent is None
def test_save_and_load_workspace_to_gzipped_file(monkeypatch, tmp_path: Path): """Test saving as a zipped JSON file and reloading.""" monkeypatch.syspath_prepend(EXAMPLES) example = import_module("getting_started") workspace = example.main() filepath = tmp_path / "test_workspace.json.gz" workspace.dump(filepath) workspace2 = Workspace.load(filepath) expected = WorkspaceIO.from_orm(workspace) actual = WorkspaceIO.from_orm(workspace2) assert json.loads(actual.json()) == json.loads(expected.json())
def test_loading_workspace_with_groups(): """Check loading an example workspace with groupings defined.""" path = DEFINITIONS / "Grouping.json" workspace = Workspace.load(path) consumer_a = workspace.model.get_element("1") consumer_d = workspace.model.get_element("4") assert consumer_a.name == "Consumer A" assert consumer_a.group == "Consumers - Group 1" assert consumer_d.name == "Consumer D" assert consumer_d.group == "Consumers - Group 2" service_2_api = workspace.model.get_element("9") assert service_2_api.name == "Service 2 API" assert service_2_api.group == "Service 2"
def test_relationships_after_deserialisation_are_consistent(filename: str): """Ensure deserialisaton leaves realationships consistent.""" path = DEFINITIONS / filename workspace = Workspace.load(path) model = workspace.model atm = model.get_software_system_with_id("9") mainframe = model.get_software_system_with_id("4") customer = model.get_element("1") assert len(atm.relationships) == 1 assert (len(list(atm.get_relationships())) == 2 ) # One to mainframe, one from personal banking customer assert len(list(atm.get_afferent_relationships())) == 1 assert next(atm.get_afferent_relationships()).source is customer assert len(list(atm.get_efferent_relationships())) == 1 assert next(atm.get_efferent_relationships()).destination is mainframe
def workspace(): from structurizr import Workspace return Workspace("Name", "Description")
def empty_workspace() -> Workspace: """Provide an empty Workspace on demand for test cases to use.""" return Workspace(name="Name", description="Description")
def main() -> Workspace: """Create the financial risk system example.""" ALERT_TAG = "Alert" workspace = Workspace( name="Financial Risk System", description= "This is a simple (incomplete) example C4 model based upon the " "financial risk system architecture kata, which can be found at " "https://structurizr.com/help/examples.", ) model = workspace.model financial_risk_system = model.add_software_system( name="Financial Risk System", description="Calculates the bank's exposure to risk for product X.", ) business_user = model.add_person(name="Business User", description="A regular business user.") business_user.uses(destination=financial_risk_system, description="Views reports using") configuration_user = model.add_person( name="Configuration User", description= "A regular business user who can also configure the parameters " "used in the risk calculations.", ) configuration_user.uses(destination=financial_risk_system, description="Configures parameters using") trade_data_system = model.add_software_system( name="Trade Data System", description="The system of record for trades of type X.", ) financial_risk_system.uses(destination=trade_data_system, description="Gets trade data from") reference_data_system = model.add_software_system( name="Reference Data System", description= "Manages reference data for all counterparties the bank interacts " "with.", ) financial_risk_system.uses(destination=reference_data_system, description="Gets counterparty data from") reference_data_system_v2 = model.add_software_system( name="Reference Data System v2.0", description= "Manages reference data for all counterparties the bank interacts " "with.", ) reference_data_system_v2.tags.add("Future State") financial_risk_system.uses( destination=reference_data_system_v2, description="Gets counterparty data from").tags.add("Future State") email_system = model.add_software_system( name="E-mail system", description="The bank's Microsoft Exchange system.") financial_risk_system.uses( destination=email_system, description="Sends a notification that a report is ready to", ) email_system.delivers( destination=business_user, description="Sends a notification that a report is ready to", technology="E-mail message", interaction_style=InteractionStyle.Asynchronous, ) central_monitoring_service = model.add_software_system( name="Central Monitoring Service", description="The bank's central monitoring and alerting dashboard.", ) financial_risk_system.uses( destination=central_monitoring_service, description="Sends critical failure alerts to", technology="SNMP", interaction_style=InteractionStyle.Asynchronous, ).tags.add(ALERT_TAG) active_directory = model.add_software_system( name="Active Directory", description="The bank's authentication and authorisation system.", ) financial_risk_system.uses( destination=active_directory, description="Uses for user authentication and authorisation", ) views = workspace.views contextView = views.create_system_context_view( software_system=financial_risk_system, key="Context", description=( "An example System Context diagram for the Financial Risk System " "architecture kata."), ) contextView.add_all_software_systems() contextView.add_all_people() styles = views.configuration.styles financial_risk_system.tags.add("Risk System") styles.add(ElementStyle(tag=Tags.ELEMENT, color="#ffffff", font_size=34)) styles.add( ElementStyle(tag="Risk System", background="#550000", color="#ffffff")) styles.add( ElementStyle( tag=Tags.SOFTWARE_SYSTEM, width=650, height=400, background="#801515", shape=Shape.RoundedBox, )) styles.add( ElementStyle(tag=Tags.PERSON, width=550, background="#d46a6a", shape=Shape.Person)) styles.add( RelationshipStyle(tag=Tags.RELATIONSHIP, thickness=4, dashed=False, font_size=32, width=400)) styles.add(RelationshipStyle(tag=Tags.SYNCHRONOUS, dashed=False)) styles.add(RelationshipStyle(tag=Tags.ASYNCHRONOUS, dashed=True)) styles.add(RelationshipStyle(tag=ALERT_TAG, color="#ff0000")) styles.add( ElementStyle(tag="Future State", opacity=30, border=Border.Dashed)) styles.add(RelationshipStyle(tag="Future State", opacity=30, dashed=True)) return workspace
def test_deserialize_workspace(filename): """Expect that a trivial workspace definition is successfully deserialized.""" path = DEFINITIONS / filename Workspace.load(path)
def test_load_unknown_file_raises_file_not_found(): """Test that attempting to load a non-existent file raises FileNotFound.""" with pytest.raises(FileNotFoundError): Workspace.load("foobar.json")
def main(): """Create the financial risk system example.""" workspace = Workspace( name="Financial Risk System", description="This is a simple (incomplete) example C4 model based upon the " "financial risk system architecture kata which can be found at " "https://structurizr.com/help/examples.", ) model = workspace.model financial_risk_system = model.add_software_system( name="Financial Risk System", description="Calculates the bank's exposure to risk for product X.", ) business_user = model.add_person( name="Business User", description="A regular business user." ) business_user.uses( destination=financial_risk_system, description="View reports using" ) configuration_user = model.add_person( name="Configuration User", description="A regular business user who can also configure the parameters " "used in the risk calculations.", ) configuration_user.uses( destination=financial_risk_system, description="Configures parameters using" ) trade_data_system = model.add_software_system( name="Trade Data System", description="The system of record for trades of type X.", ) financial_risk_system.uses( destination=trade_data_system, description="Gets trade data from" ) reference_data_system = model.add_software_system( name="Reference Data System", description="Manages reference data for all counterparties the bank interacts " "with.", ) financial_risk_system.uses( destination=reference_data_system, description="Gets counterparty data from" ) reference_data_system_v2 = model.add_software_system( name="Reference Data System v2.0", description="Manages reference data for all counterparties the bank interacts " "with.", ) reference_data_system_v2.add_tags("Future State") financial_risk_system.uses( destination=reference_data_system_v2, description="Gets counterparty data from" ).add_tags("Future State") email_system = model.add_software_system( name="E-mail system", description="The bank's Microsoft Exchange system." ) financial_risk_system.uses( destination=email_system, description="Sends a notification that a report is ready to", ) email_system.delivers( destination=business_user, description="Sends a notification that a report is ready to", technology="E-mail message", interaction_style=InteractionStyle.Asynchronous, ) central_monitoring_service = model.add_software_system( name="Central Monitoring Service", description="The bank's central monitoring and alerting dashboard.", ) financial_risk_system.uses( destination=central_monitoring_service, description="Sends critical failure alerts to", technology="SNMP", interaction_style=InteractionStyle.Asynchronous, ).add_tags(TAG_ALERT) active_directory = model.add_software_system( name="Active Directory", description="The bank's authentication and authorisation system.", ) financial_risk_system.uses( destination=active_directory, description="Uses for user authentication and authorisation", )
def create_big_bank_workspace(): """Create the big bank example.""" workspace = Workspace( name="Big Bank plc", description=( "This is an example workspace to illustrate the key features of " "Structurizr, based around a fictional online banking system." ), ) existing_system_tag = "Existing System" bank_staff_tag = "Bank Staff" web_browser_tag = "Web Browser" mobile_app_tag = "Mobile App" database_tag = "Database" failover_tag = "Failover" model = workspace.model views = workspace.views model.enterprise = Enterprise(name="Big Bank plc") # people and software systems customer = model.add_person( location=Location.External, name="Personal Banking Customer", description="A customer of the bank, with personal bank accounts.", id="customer", ) internet_banking_system = model.add_software_system( location=Location.Internal, name="Internet Banking System", description=( "Allows customers to view information about " "their bank accounts, and make payments." ), id="internetBankingSystem", ) customer.uses( internet_banking_system, "Views account balances, and makes payments using" ) mainframe_banking_system = model.add_software_system( location=Location.Internal, name="Mainframe Banking System", description=( "Stores all of the core banking information " "about customers, accounts, transactions, etc." ), id="mainframe", ) mainframe_banking_system.tags.add(existing_system_tag) internet_banking_system.uses( mainframe_banking_system, "Gets account information from, and makes payments using", ) email_system = model.add_software_system( location=Location.Internal, name="E-mail System", description="The internal Microsoft Exchange e-mail system.", id="email", ) internet_banking_system.uses( destination=email_system, description="Sends e-mail using", ) email_system.tags.add(existing_system_tag) email_system.delivers( destination=customer, description="Sends e-mails to", ) atm = model.add_software_system( location=Location.Internal, name="ATM", description="Allows customers to withdraw cash.", id="atm", ) atm.tags.add(existing_system_tag) atm.uses(mainframe_banking_system, "Uses") customer.uses(atm, "Withdraws cash using") customer_service_staff = model.add_person( location=Location.Internal, name="Customer Service Staff", description="Customer service staff within the bank.", id="supportStaff", ) customer_service_staff.tags.add(bank_staff_tag) customer_service_staff.uses(mainframe_banking_system, "Uses") customer.interacts_with( customer_service_staff, "Asks questions to", technology="Telephone" ) back_office_staff = model.add_person( location=Location.Internal, name="Back Office Staff", description="Administration and support staff within the bank.", id="backoffice", ) back_office_staff.tags.add(bank_staff_tag) back_office_staff.uses(mainframe_banking_system, "Uses") # containers single_page_application = internet_banking_system.add_container( "Single-Page Application", ( "Provides all of the Internet banking functionality " "to customers via their web browser." ), "JavaScript and Angular", id="singlePageApplication", ) single_page_application.tags.add(web_browser_tag) mobile_app = internet_banking_system.add_container( "Mobile App", "Provides a limited subset of the Internet banking functionality to customers via their mobile device.", "Xamarin", id="mobileApp", ) mobile_app.tags.add(mobile_app_tag) web_application = internet_banking_system.add_container( "Web Application", "Delivers the static content and the Internet banking single page application.", "Java and Spring MVC", id="webApplication", ) api_application = internet_banking_system.add_container( "API Application", "Provides Internet banking functionality via a JSON/HTTPS API.", "Java and Spring MVC", id="apiApplication", ) database = internet_banking_system.add_container( "Database", "Stores user registration information, hashed authentication credentials, access logs, etc.", "Relational Database Schema", id="database", ) database.tags.add(database_tag) customer.uses(web_application, "Uses", technology="HTTPS") customer.uses(single_page_application, "Uses") customer.uses(mobile_app, "Uses") web_application.uses( single_page_application, "Delivers to the customers web browser" ) api_application.uses(database, "Reads from and writes to", technology="JDBC") api_application.uses(mainframe_banking_system, "Uses", technology="XML/HTTPS") api_application.uses(email_system, "Sends e-mail using", technology="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 signin_controller = api_application.add_component( name="Sign In Controller", description="Allows users to sign in to the Internet Banking System.", technology="Spring MVC Rest Controller", id="signinController", ) accounts_summary_controller = api_application.add_component( name="Accounts Summary Controller", description="Provides customers with a summary of their bank accounts.", technology="Spring MVC Rest Controller", id="accountsSummaryController", ) reset_password_controller = api_application.add_component( name="Reset Password Controller", description="Allows users to reset their passwords with a single use URL.", technology="Spring MVC Rest Controller", id="resetPasswordController", ) security_component = api_application.add_component( name="Security Component", description="Provides functionality related to signing in, changing passwords, etc.", technology="Spring Bean", id="securityComponent", ) mainframe_banking_systemFacade = api_application.add_component( name="Mainframe Banking System Facade", description="A facade onto the mainframe banking system.", technology="Spring Bean", id="mainframeBankingSystemFacade", ) email_component = api_application.add_component( name="E-mail Component", description="Sends e-mails to users.", technology="Spring Bean", id="emailComponent", ) for component in api_application.components: if component.technology == "Spring MVC Rest Controller": single_page_application.uses(component, "Makes API calls to", "JSON/HTTPS") mobile_app.uses(component, "Makes API calls to", "JSON/HTTPS") signin_controller.uses(security_component, "Uses") accounts_summary_controller.uses(mainframe_banking_systemFacade, "Uses") reset_password_controller.uses(security_component, "Uses") reset_password_controller.uses(email_component, "Uses") security_component.uses(database, "Reads from and writes to", "JDBC") mainframe_banking_systemFacade.uses(mainframe_banking_system, "Uses", "XML/HTTPS") email_component.uses(email_system, "Sends e-mail using") # TODO:! # model.AddImplicitRelationships() # deployment nodes and container instances developer_laptop = model.add_deployment_node( environment="Development", name="Developer Laptop", description="A developer laptop.", technology="Microsoft Windows 10 or Apple macOS", ) apache_tomcat = developer_laptop.add_deployment_node( name="Docker - Web Server", description="A Docker container.", technology="Docker", ).add_deployment_node( name="Apache Tomcat", description="An open source Java EE web server.", technology="Apache Tomcat 8.x", instances=1, properties={"Xmx": "512M", "Xms": "1024M", "Java Version": "8"}, ) apache_tomcat.add_container(web_application) apache_tomcat.add_container(api_application) developer_laptop.add_deployment_node( "Docker - Database Server", "A Docker container.", "Docker" ).add_deployment_node( "Database Server", "A development database.", "Oracle 12c" ).add_container( database ) developer_laptop.add_deployment_node( "Web Browser", "", "Chrome, Firefox, Safari, or Edge" ).add_container(single_page_application) customer_mobile_device = model.add_deployment_node( "Customer's mobile device", "", "Apple iOS or Android", environment="Live" ) customer_mobile_device.add_container(mobile_app) customer_computer = model.add_deployment_node( "Customer's computer", "", "Microsoft Windows or Apple macOS", environment="Live", ) customer_computer.add_deployment_node( "Web Browser", "", "Chrome, Firefox, Safari, or Edge" ).add_container(single_page_application) big_bank_data_center = model.add_deployment_node( "Big Bank plc", "", "Big Bank plc data center", environment="Live" ) live_web_server = big_bank_data_center.add_deployment_node( "bigbank-web***", "A web server residing in the web server farm, accessed via F5 BIG-IP LTMs.", "Ubuntu 16.04 LTS", instances=4, properties={"Location": "London and Reading"}, ) live_web_server.add_deployment_node( "Apache Tomcat", "An open source Java EE web server.", "Apache Tomcat 8.x", instances=1, properties={"Xmx": "512M", "Xms": "1024M", "Java Version": "8"}, ).add_container(web_application) live_api_server = big_bank_data_center.add_deployment_node( "bigbank-api***", "A web server residing in the web server farm, accessed via F5 BIG-IP LTMs.", "Ubuntu 16.04 LTS", instances=8, properties={"Location": "London and Reading"}, ) live_api_server.add_deployment_node( "Apache Tomcat", "An open source Java EE web server.", "Apache Tomcat 8.x", instances=1, properties={"Xmx": "512M", "Xms": "1024M", "Java Version": "8"}, ).add_container(api_application) primary_database_server = big_bank_data_center.add_deployment_node( "bigbank-db01", "The primary database server.", "Ubuntu 16.04 LTS", instances=1, properties={"Location": "London"}, ).add_deployment_node( "Oracle - Primary", "The primary, live database server.", "Oracle 12c" ) primary_database_server.add_container(database) big_bank_db_02 = big_bank_data_center.add_deployment_node( "bigbank-db02", "The secondary database server.", "Ubuntu 16.04 LTS", instances=1, properties={"Location": "Reading"}, ) big_bank_db_02.tags.add(failover_tag) secondary_database_server = big_bank_db_02.add_deployment_node( "Oracle - Secondary", "A secondary, standby database server, used for failover purposes only.", "Oracle 12c", ) secondary_database_server.tags.add(failover_tag) secondary_database = secondary_database_server.add_container(database) # # model.Relationships.Where(r=>r.Destination.Equals(secondary_database)).ToList().ForEach(r=>r.tags.add(failover_tag)) # dataReplicationRelationship = primary_database_server.uses( # secondary_database_server, "Replicates data to", "" # ) # secondary_database.tags.add(failover_tag) # views/diagrams system_landscape_view = views.create_system_landscape_view( key="SystemLandscape", description="The system landscape diagram for Big Bank plc.", ) system_landscape_view.add_all_elements() system_landscape_view.paper_size = PaperSize.A5_Landscape system_context_view = views.create_system_context_view( software_system=internet_banking_system, key="SystemContext", description="The system context diagram for the Internet Banking System.", ) system_context_view.enterprise_boundary_visible = False system_context_view.add_nearest_neighbours(internet_banking_system) system_context_view.paper_size = PaperSize.A5_Landscape container_view = views.create_container_view( software_system=internet_banking_system, key="Containers", description="The container diagram for the Internet Banking System.", ) container_view.add(customer) container_view.add_all_containers() container_view.add(mainframe_banking_system) container_view.add(email_system) container_view.paper_size = PaperSize.A5_Landscape component_view = views.create_component_view( container=api_application, key="Components", description="The component diagram for the API Application.", ) component_view.add(mobile_app) component_view.add(single_page_application) component_view.add(database) component_view.add_all_components() component_view.add(mainframe_banking_system) component_view.add(email_system) component_view.paper_size = PaperSize.A5_Landscape # systemLandscapeView.AddAnimation(internet_banking_system, customer, mainframe_banking_system, emailSystem) # systemLandscapeView.AddAnimation(atm) # systemLandscapeView.AddAnimation(customerServiceStaff, back_office_staff) # systemContextView.AddAnimation(internet_banking_system) # systemContextView.AddAnimation(customer) # systemContextView.AddAnimation(mainframe_banking_system) # systemContextView.AddAnimation(emailSystem) # containerView.AddAnimation(customer, mainframe_banking_system, emailSystem) # containerView.AddAnimation(webApplication) # containerView.AddAnimation(singlePageApplication) # containerView.AddAnimation(mobile_app) # containerView.AddAnimation(apiApplication) # containerView.AddAnimation(database) # componentView.AddAnimation(singlePageApplication, mobile_app) # componentView.AddAnimation(signinController, securityComponent, database) # componentView.AddAnimation(accountsSummaryController, mainframe_banking_systemFacade, mainframe_banking_system) # 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(internet_banking_system, "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(internet_banking_system, "LiveDeployment", "An example live deployment scenario for the Internet Banking System.") # liveDeploymentView.Environment = "Live" # liveDeploymentView.Add(big_bank_data_center) # liveDeploymentView.Add(customerMobileDevice) # liveDeploymentView.Add(customerComputer) # liveDeploymentView.Add(dataReplicationRelationship) # liveDeploymentView.PaperSize = PaperSize.A5_Landscape # colours, shapes and other diagram styling styles = views.configuration.styles styles.add( ElementStyle(tag=Tags.SOFTWARE_SYSTEM, background="#1168bd", color="#ffffff") ) styles.add(ElementStyle(tag=Tags.CONTAINER, background="#438dd5", color="#ffffff")) styles.add(ElementStyle(tag=Tags.COMPONENT, background="#85bbf0", color="#000000")) styles.add( ElementStyle( tag=Tags.PERSON, background="#08427b", color="#ffffff", shape=Shape.Person, font_size=22, ) ) styles.add( ElementStyle(tag=existing_system_tag, background="#999999", color="#ffffff") ) styles.add(ElementStyle(tag=bank_staff_tag, background="#999999", color="#ffffff")) styles.add(ElementStyle(tag=web_browser_tag, shape=Shape.WebBrowser)) styles.add(ElementStyle(tag=mobile_app_tag, shape=Shape.MobileDeviceLandscape)) styles.add(ElementStyle(tag=database_tag, shape=Shape.Cylinder)) styles.add(ElementStyle(tag=failover_tag, opacity=25)) styles.add(RelationshipStyle(tag=failover_tag, opacity=25, position=70)) return workspace