diff --git a/settings.gradle b/settings.gradle index 57df82f6..8035bdd0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,4 +7,5 @@ include 'structurizr-core' include 'structurizr-dsl' include 'structurizr-export' include 'structurizr-import' -include 'structurizr-inspection' \ No newline at end of file +include 'structurizr-inspection' +include 'structurizr-neo4j' \ No newline at end of file diff --git a/structurizr-neo4j/README.md b/structurizr-neo4j/README.md new file mode 100644 index 00000000..c01eb1a5 --- /dev/null +++ b/structurizr-neo4j/README.md @@ -0,0 +1,5 @@ +# structurizr-neo4j + +[![Maven Central](https://img.shields.io/maven-central/v/com.structurizr/structurizr-neo4j.svg?label=Maven%20Central)](https://search.maven.org/artifact/com.structurizr/structurizr-neo4j) + +This library provides utilities to import a Structurizr workspace into Neo4j. \ No newline at end of file diff --git a/structurizr-neo4j/build.gradle b/structurizr-neo4j/build.gradle new file mode 100644 index 00000000..2c06e792 --- /dev/null +++ b/structurizr-neo4j/build.gradle @@ -0,0 +1,9 @@ +dependencies { + + api project(':structurizr-core') + implementation 'org.neo4j.driver:neo4j-java-driver:5.23.0' + + testImplementation project(':structurizr-client') + testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' + +} \ No newline at end of file diff --git a/structurizr-neo4j/src/main/java/com/structurizr/neo4j/SimpleLoader.java b/structurizr-neo4j/src/main/java/com/structurizr/neo4j/SimpleLoader.java new file mode 100644 index 00000000..727b06c5 --- /dev/null +++ b/structurizr-neo4j/src/main/java/com/structurizr/neo4j/SimpleLoader.java @@ -0,0 +1,36 @@ +package com.structurizr.neo4j; + +import com.structurizr.Workspace; +import com.structurizr.model.Element; +import com.structurizr.model.Relationship; +import com.structurizr.util.StringUtils; +import org.neo4j.driver.Driver; +import org.neo4j.driver.SessionConfig; + +public class SimpleLoader { + + public void load(Workspace workspace, Driver driver, String database) { + try (var session = driver.session(SessionConfig.builder().withDatabase(database).build())) { + for (Element element : workspace.getModel().getElements()) { + session.run(String.format( + "CREATE ( :Element { id: '%s', name: \"%s\", type: \"%s\" })", + element.getId(), element.getName(), element.getClass().getSimpleName().toLowerCase() + )); + } + + session.run("CREATE INDEX element_index FOR (n:Element) ON (n.id)"); + + for (Relationship relationship : workspace.getModel().getRelationships()) { + session.run(String.format( + """ + MATCH ( from:Element { id: '%s' } ), ( to:Element { id: '%s' } ) + CREATE (from)-[:HAS_RELATIONSHIP_WITH {role: '%s'}]->(to)""", + relationship.getSource().getId(), + relationship.getDestination().getId(), + !StringUtils.isNullOrEmpty(relationship.getDescription()) ? relationship.getDescription() : "uses" + )); + } + } + } + +} \ No newline at end of file diff --git a/structurizr-neo4j/src/test/java/com/structurizr/Example.java b/structurizr-neo4j/src/test/java/com/structurizr/Example.java new file mode 100644 index 00000000..4ef9f529 --- /dev/null +++ b/structurizr-neo4j/src/test/java/com/structurizr/Example.java @@ -0,0 +1,28 @@ +package com.structurizr; + +import com.structurizr.neo4j.SimpleLoader; +import com.structurizr.util.WorkspaceUtils; +import org.neo4j.driver.AuthTokens; +import org.neo4j.driver.Driver; +import org.neo4j.driver.GraphDatabase; +import org.neo4j.driver.Result; + +import java.io.File; + +public class Example { + + public static void main(String[] args) throws Exception { + Workspace workspace = WorkspaceUtils.loadWorkspaceFromJson(new File("workspace.json")); + + try (Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "password"))) { + try (var session = driver.session()) { + session.run("DROP DATABASE structurizr IF EXISTS"); + Result result = session.run("CREATE DATABASE structurizr"); + System.out.println(result.consume()); + } + + new SimpleLoader().load(workspace, driver, "structurizr"); + } + } + +} \ No newline at end of file