public static void main(String[] args) throws Exception { Workspace workspace = new Workspace("Corporate Branding", "This is a model of my software system."); Model model = workspace.getModel(); Person user = model.addPerson("User", "A user of my software system."); SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System", "My software system."); user.uses(softwareSystem, "Uses"); ViewSet views = workspace.getViews(); SystemContextView contextView = views.createSystemContextView(softwareSystem, "SystemContext", "An example of a System Context diagram."); contextView.addAllSoftwareSystems(); contextView.addAllPeople(); Styles styles = views.getConfiguration().getStyles(); styles.addElementStyle(Tags.PERSON).shape(Shape.Person); StructurizrDocumentationTemplate template = new StructurizrDocumentationTemplate(workspace); template.addContextSection(softwareSystem, Format.Markdown, "Here is some context about the software system...\n\n"); Branding branding = views.getConfiguration().getBranding(); branding.setLogo(ImageUtils.getImageAsDataUri(new File("./docs/images/structurizr-logo.png"))); StructurizrClient structurizrClient = new StructurizrClient(API_KEY, API_SECRET); structurizrClient.putWorkspace(WORKSPACE_ID, workspace); }
/** * Writes the views in the given workspace as PlantUML definitions, to the specified writer. * * @param workspace the workspace containing the views to be written * @param writer the Writer to write to */ public void write(Workspace workspace, Writer writer) { if (workspace == null) { throw new IllegalArgumentException("A workspace must be provided."); } if (writer == null) { throw new IllegalArgumentException("A writer must be provided."); } workspace.getViews().getSystemLandscapeViews().forEach(v -> write(v, writer)); workspace.getViews().getSystemContextViews().forEach(v -> write(v, writer)); workspace.getViews().getContainerViews().forEach(v -> write(v, writer)); workspace.getViews().getComponentViews().forEach(v -> write(v, writer)); workspace.getViews().getDynamicViews().forEach(v -> write(v, writer)); workspace.getViews().getDeploymentViews().forEach(v -> write(v, writer)); }
@Test public void test_createComponentView_ThrowsAnException_WhenASoftwareSystemIsSpecified() { try { new Workspace("", "").getViews().createComponentView(null, null, "Description"); fail(); } catch (IllegalArgumentException iae) { assertEquals("A container must be specified.", iae.getMessage()); } }
/** * Writes the views in the given workspace as DOT notation, to the specified Writer. * * @param workspace the workspace containing the views to be written * @param writer the Writer to write to */ public void write(Workspace workspace, Writer writer) { workspace.getViews().getSystemContextViews().forEach(v -> write(v, null, writer)); workspace.getViews().getContainerViews().forEach(v -> write(v, v.getSoftwareSystem(), writer)); workspace.getViews().getComponentViews().forEach(v -> write(v, v.getContainer(), writer)); }
@Test public void test_setEnterpriseContextViews_IsSupportedForOlderWorkspaces() { ViewSet views = new Workspace("", "").getViews(); SystemLandscapeView systemLandscapeView = views.createSystemLandscapeView("key", "Description"); views.setEnterpriseContextViews(Collections.singleton(systemLandscapeView)); assertEquals(1, views.getSystemLandscapeViews().size()); assertSame(systemLandscapeView, views.getSystemLandscapeViews().iterator().next()); }
SystemContextView contextView = views.createSystemContextView(springPetClinic, "context", "The System Context diagram for the Spring PetClinic system."); contextView.addAllSoftwareSystems(); contextView.addAllPeople(); ContainerView containerView = views.createContainerView(springPetClinic, "containers", "The Containers diagram for the Spring PetClinic system."); containerView.addAllPeople(); containerView.addAllSoftwareSystems(); containerView.addAllContainers(); ComponentView componentView = views.createComponentView(webApplication, "components", "The Components diagram for the Spring PetClinic web application."); componentView.addAllComponents(); componentView.addAllPeople(); Component vetRepository = webApplication.getComponentWithName("VetRepository"); DynamicView dynamicView = views.createDynamicView(webApplication, "viewListOfVets", "Shows how the \"view list of vets\" feature works."); dynamicView.add(clinicEmployee, "Requests list of vets from /vets", vetController); dynamicView.add(vetController, "Calls findAll", vetRepository); dynamicView.add(vetRepository, "select * from vets", relationalDatabase); Styles styles = views.getConfiguration().getStyles(); styles.addElementStyle("Spring PetClinic").background("#6CB33E").color("#ffffff"); styles.addElementStyle(Tags.PERSON).background("#519823").color("#ffffff").shape(Shape.Person);
@Test public void test_add_ThrowsAnException_WhenTheScopeOfTheDynamicViewIsASoftwareSystemAndTheSameSoftwareSystemIsAdded() { try { DynamicView dynamicView = workspace.getViews().createDynamicView(softwareSystemA, "key", "Description"); dynamicView.add(softwareSystemA, containerA1); fail(); } catch (Exception e) { assertEquals("Software System A is already the scope of this view and cannot be added to it.", e.getMessage()); } }
@Test public void test_copyLayoutInformationFrom_CopiesThePaperSize_WhenThePaperSizeIsNotSet() { Workspace workspace1 = createWorkspace(); SoftwareSystem softwareSystem1 = workspace1.getModel().getSoftwareSystemWithName("Software System"); SystemContextView view1 = workspace1.getViews().createSystemContextView(softwareSystem1, "context", "Description"); view1.setPaperSize(PaperSize.A3_Landscape); Workspace workspace2 = createWorkspace(); SoftwareSystem softwareSystem2 = workspace2.getModel().getSoftwareSystemWithName("Software System"); SystemContextView view2 = workspace2.getViews().createSystemContextView(softwareSystem2, "context", "Description"); workspace2.getViews().copyLayoutInformationFrom(workspace1.getViews()); assertEquals(PaperSize.A3_Landscape, view2.getPaperSize()); }
@Test public void test_createSystemLandscapeView_DoesNotThrowAnException_WhenUniqueKeysAreSpecified() { Workspace workspace = new Workspace("Name", "Description"); workspace.getViews().createSystemLandscapeView("key1", "Description"); workspace.getViews().createSystemLandscapeView("key2", "Description"); }
SystemContextView contextView = views.createSystemContextView(adrTools, "SystemContext", "The system context diagram for adr-tools."); contextView.addAllElements(); ContainerView containerView = views.createContainerView(adrTools, "Containers", "The container diagram for adr-tools."); containerView.addAllElements(); adrToolsImporter.importArchitectureDecisionRecords(adrTools); Styles styles = views.getConfiguration().getStyles(); styles.addElementStyle(Tags.ELEMENT).shape(Shape.RoundedBox).color("#ffffff"); styles.addElementStyle(Tags.SOFTWARE_SYSTEM).background("#18ADAD").color("#ffffff");
@Test public void test_putAndGetWorkspace_WithoutEncryption() throws Exception { Workspace workspace = new Workspace("Structurizr client library tests - without encryption", "A test workspace for the Structurizr client library"); SoftwareSystem softwareSystem = workspace.getModel().addSoftwareSystem("Software System", "Description"); Person person = workspace.getModel().addPerson("Person", "Description"); person.uses(softwareSystem, "Uses"); SystemContextView systemContextView = workspace.getViews().createSystemContextView(softwareSystem, "SystemContext", "Description"); systemContextView.addAllElements(); structurizrClient.putWorkspace(20081, workspace); workspace = structurizrClient.getWorkspace(20081); assertTrue(workspace.getModel().contains(softwareSystem)); assertTrue(workspace.getModel().contains(person)); assertEquals(1, workspace.getModel().getRelationships().size()); assertEquals(1, workspace.getViews().getSystemContextViews().size()); // and check the archive version is readable Workspace archivedWorkspace = new JsonReader().read(new FileReader(getArchivedWorkspace())); assertEquals(20081, archivedWorkspace.getId()); assertEquals("Structurizr client library tests - without encryption", archivedWorkspace.getName()); assertEquals(1, archivedWorkspace.getModel().getSoftwareSystems().size()); }
@Test public void test_createSystemContextView_ThrowsAnException_WhenADuplicateKeyIsSpecified() { try { Workspace workspace = new Workspace("Name", "Description"); SoftwareSystem softwareSystem = workspace.getModel().addSoftwareSystem("Software System", "Description"); workspace.getViews().createSystemContextView(softwareSystem, "key", "Description"); workspace.getViews().createSystemContextView(softwareSystem, "key", "Description"); fail(); } catch (IllegalArgumentException iae) { assertEquals("A view with the key key already exists.", iae.getMessage()); } }
public static void main(String[] args) throws Exception { Workspace workspace = new Workspace("Filtered Views", "An example of using filtered views."); Model model = workspace.getModel(); Person user = model.addPerson("User", "A description of the user."); SoftwareSystem softwareSystemA = model.addSoftwareSystem("Software System A", "A description of software system A."); SoftwareSystem softwareSystemB = model.addSoftwareSystem("Software System B", "A description of software system B."); softwareSystemB.addTags(FUTURE_STATE); user.uses(softwareSystemA, "Uses for tasks 1 and 2").addTags(CURRENT_STATE); user.uses(softwareSystemA, "Uses for task 1").addTags(FUTURE_STATE); user.uses(softwareSystemB, "Uses for task 2").addTags(FUTURE_STATE); ViewSet views = workspace.getViews(); SystemLandscapeView systemLandscapeView = views.createSystemLandscapeView("SystemLandscape", "An example System Landscape diagram."); systemLandscapeView.addAllElements(); views.createFilteredView(systemLandscapeView, "CurrentState", "The current system landscape.", FilterMode.Exclude, FUTURE_STATE); views.createFilteredView(systemLandscapeView, "FutureState", "The future state system landscape after Software System B is live.", FilterMode.Exclude, CURRENT_STATE); Styles styles = views.getConfiguration().getStyles(); styles.addElementStyle(Tags.ELEMENT).color("#ffffff"); styles.addElementStyle(Tags.SOFTWARE_SYSTEM).background("#91a437").shape(Shape.RoundedBox); styles.addElementStyle(Tags.PERSON).background("#6a7b15").shape(Shape.Person); StructurizrClient structurizrClient = new StructurizrClient(API_KEY, API_SECRET); structurizrClient.putWorkspace(WORKSPACE_ID, workspace); }
@Test public void test_createFilteredView_ThrowsAnException_WhenADuplicateKeyIsUsed() { Workspace workspace = new Workspace("Name", "Description"); SystemLandscapeView view = workspace.getViews().createSystemLandscapeView("systemLandscape", "Description"); workspace.getViews().createFilteredView(view, "filtered", "Description", FilterMode.Include, "tag1", "tag2"); try { workspace.getViews().createFilteredView(view, "filtered", "Description", FilterMode.Include, "tag1", "tag2"); fail(); } catch (IllegalArgumentException iae) { assertEquals("A view with the key filtered already exists.", iae.getMessage()); } }
public static void main(String[] args) throws Exception { Workspace workspace = new Workspace("Styling Relationships", "This is a model of my software system."); Model model = workspace.getModel(); Person user = model.addPerson("User", "A user of my software system."); SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System", "My software system."); Container webApplication = softwareSystem.addContainer("Web Application", "My web application.", "Java and Spring MVC"); Container database = softwareSystem.addContainer("Database", "My database.", "Relational database schema"); user.uses(webApplication, "Uses", "HTTPS"); webApplication.uses(database, "Reads from and writes to", "JDBC"); ViewSet views = workspace.getViews(); ContainerView containerView = views.createContainerView(softwareSystem, "containers", "An example of a container diagram."); containerView.addAllElements(); Styles styles = workspace.getViews().getConfiguration().getStyles(); // example 1 // styles.addRelationshipStyle(Tags.RELATIONSHIP).color("#ff0000"); // example 2 // model.getRelationships().stream().filter(r -> "HTTPS".equals(r.getTechnology())).forEach(r -> r.addTags("HTTPS")); // model.getRelationships().stream().filter(r -> "JDBC".equals(r.getTechnology())).forEach(r -> r.addTags("JDBC")); // styles.addRelationshipStyle("HTTPS").color("#ff0000"); // styles.addRelationshipStyle("JDBC").color("#0000ff"); StructurizrClient structurizrClient = new StructurizrClient(API_KEY, API_SECRET); structurizrClient.putWorkspace(WORKSPACE_ID, workspace); }
@Test public void test_backwardsCompatibilityOfRenamingEnterpriseContextViewsToSystemLandscapeViews() throws Exception { Workspace workspace = new Workspace("Name", "Description"); workspace.getViews().createSystemLandscapeView("key", "description"); JsonWriter jsonWriter = new JsonWriter(false); StringWriter stringWriter = new StringWriter(); jsonWriter.write(workspace, stringWriter); String workspaceAsJson = stringWriter.toString(); workspaceAsJson = workspaceAsJson.replaceAll("systemLandscapeViews", "enterpriseContextViews"); JsonReader jsonReader = new JsonReader(); StringReader stringReader = new StringReader(workspaceAsJson); workspace = jsonReader.read(stringReader); assertEquals(1, workspace.getViews().getSystemLandscapeViews().size()); }
protected String backgroundOf(View view, Element element) { return view.getViewSet().getConfiguration().getStyles().findElementStyle(element).getBackground(); }
public static void main(String[] args) throws Exception { Workspace workspace = new Workspace("HTTP-based health checks example", "An example of how to use the HTTP-based health checks feature"); Model model = workspace.getModel(); ViewSet views = workspace.getViews(); SoftwareSystem structurizr = model.addSoftwareSystem("Structurizr", "A publishing platform for software architecture diagrams and documentation based upon the C4 model."); Container webApplication = structurizr.addContainer("structurizr.com", "Provides all of the server-side functionality of Structurizr, serving static and dynamic content to users.", "Java and Spring MVC"); Container database = structurizr.addContainer("Database", "Stores information about users, workspaces, etc.", "Relational Database Schema"); database.addTags(DATABASE_TAG); webApplication.uses(database, "Reads from and writes to", "JDBC"); DeploymentNode amazonWebServices = model.addDeploymentNode("Amazon Web Services", "", "us-east-1"); DeploymentNode pivotalWebServices = amazonWebServices.addDeploymentNode("Pivotal Web Services", "Platform as a Service provider.", "Cloud Foundry"); ContainerInstance liveWebApplication = pivotalWebServices.addDeploymentNode("www.structurizr.com", "An open source Java EE web server.", "Apache Tomcat") .add(webApplication); ContainerInstance liveDatabaseInstance = amazonWebServices.addDeploymentNode("Amazon RDS", "Database as a Service provider.", "MySQL") .add(database); // add health checks to the container instances, which return a simple HTTP 200 to say everything is okay liveWebApplication.addHealthCheck("Web Application is running", "https://www.structurizr.com/health"); liveDatabaseInstance.addHealthCheck("Database is accessible from Web Application", "https://www.structurizr.com/health/database"); // the pass/fail status from the health checks is used to supplement any deployment views that include the container instances that have health checks defined DeploymentView deploymentView = views.createDeploymentView(structurizr, "Deployment", "A deployment diagram showing the live environment."); deploymentView.setEnvironment("Live"); deploymentView.addAllDeploymentNodes(); views.getConfiguration().getStyles().addElementStyle(Tags.ELEMENT).color("#ffffff"); views.getConfiguration().getStyles().addElementStyle(DATABASE_TAG).shape(Shape.Cylinder); StructurizrClient structurizrClient = new StructurizrClient(API_KEY, API_SECRET); structurizrClient.putWorkspace(WORKSPACE_ID, workspace); }
@Test public void test_writeEnterpriseContextView() throws Exception { populateWorkspace(); SystemLandscapeView systemLandscapeView = workspace.getViews().getSystemLandscapeViews() .stream().findFirst().get(); plantUMLWriter.write(systemLandscapeView, stringWriter); assertEquals(SYSTEM_LANDSCAPE_VIEW, stringWriter.toString()); }
@Test public void test_copyLayoutInformationFrom_DoesNotDoAnythingIfThereIsNoComponentViewToCopyInformationFrom() { Workspace workspace1 = createWorkspace(); Workspace workspace2 = createWorkspace(); Container container2 = workspace2.getModel().getSoftwareSystemWithName("Software System").getContainerWithName("Container"); ComponentView view2 = workspace2.getViews().createComponentView(container2, "components", "Description"); view2.addAllElements(); workspace2.getViews().copyLayoutInformationFrom(workspace1.getViews()); assertEquals(0, view2.getElements().iterator().next().getX()); // default assertNull(view2.getPaperSize()); // default }