Auto gen relationship graphs 44/13144/3
authorJvD_Ericsson <jeff.van.dam@est.tech>
Mon, 1 Jul 2024 13:12:37 +0000 (14:12 +0100)
committerJvD_Ericsson <jeff.van.dam@est.tech>
Thu, 4 Jul 2024 13:43:23 +0000 (14:43 +0100)
Generate relationship graphs in the pgsql-schema-generator
from the relationships defined in the provided yang models

Output location and option to generate the files in application.yaml

Issue-ID: SMO-156
Change-Id: Ie2b007b854c4134cc547c39850c9c60096663226
Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech>
pgsql-schema-generator/pom.xml
pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/Processor.java
pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/relationshipgrapghgenerator/RelationshipGraphGenerator.java [new file with mode: 0644]
pgsql-schema-generator/src/main/resources/application.yaml
pgsql-schema-generator/src/test/java/org/oran/smo/teiv/pgsqlgenerator/EndToEndTest.java
pgsql-schema-generator/src/test/resources/application.yaml

index 48fa2cf..5d59065 100644 (file)
             <version>${version.lombok}</version>
             <scope>provided</scope>
         </dependency>
+
+        <!--graphing dependencies -->
+        <dependency>
+            <groupId>guru.nidi</groupId>
+            <artifactId>graphviz-java</artifactId>
+            <version>0.18.1</version>
+        </dependency>
+
         <!-- Test Dependencies -->
         <dependency>
             <groupId>org.mockito</groupId>
index 38f9898..8ce696e 100644 (file)
@@ -28,6 +28,7 @@ import java.util.List;
 
 import org.oran.smo.teiv.pgsqlgenerator.schema.data.DataSchemaGenerator;
 import org.oran.smo.teiv.pgsqlgenerator.schema.model.ModelSchemaGenerator;
+import org.oran.smo.teiv.pgsqlgenerator.relationshipgrapghgenerator.RelationshipGraphGenerator;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ResourceUtils;
@@ -42,6 +43,7 @@ public class Processor {
     private final YangModelProcessor yangModelProcessor;
     private final DataSchemaGenerator dataSchemaGenerator;
     private final ModelSchemaGenerator modelSchemaGenerator;
+    private final RelationshipGraphGenerator relationshipGraphGenerator;
     @Value("${yang-model.source}")
     private String yangModelDirectory;
 
@@ -61,6 +63,7 @@ public class Processor {
 
         List<Relationship> relationshipsFromModelService = yangModelProcessor.getRelationshipsFromYang(pathToImplementing);
 
+        relationshipGraphGenerator.generate(relationshipsFromModelService, entitiesFromModelService);
         dataSchemaGenerator.generate(moduleReferences, entitiesFromModelService, relationshipsFromModelService);
         modelSchemaGenerator.generate(moduleReferences, entitiesFromModelService, relationshipsFromModelService);
     }
diff --git a/pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/relationshipgrapghgenerator/RelationshipGraphGenerator.java b/pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/relationshipgrapghgenerator/RelationshipGraphGenerator.java
new file mode 100644 (file)
index 0000000..0cd60fd
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 Ericsson
+ *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+package org.oran.smo.teiv.pgsqlgenerator.relationshipgrapghgenerator;
+
+import guru.nidi.graphviz.model.Factory;
+import guru.nidi.graphviz.model.MutableGraph;
+import guru.nidi.graphviz.model.MutableNode;
+import lombok.extern.slf4j.Slf4j;
+import guru.nidi.graphviz.attribute.Label;
+import guru.nidi.graphviz.engine.Format;
+import guru.nidi.graphviz.engine.Graphviz;
+import org.oran.smo.teiv.pgsqlgenerator.Entity;
+import org.oran.smo.teiv.pgsqlgenerator.Relationship;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+@Component
+@Slf4j
+public class RelationshipGraphGenerator {
+
+    @Value("${relationship-graph.generate}")
+    private boolean generateRelationshipGraph;
+
+    @Value("${relationship-graph.output}")
+    private String graphOutput;
+
+    public void generate(List<Relationship> relationships, List<Entity> entities) throws IOException {
+        if (generateRelationshipGraph) {
+            List<String> moduleNames = relationships.stream().map(Relationship::getModuleReferenceName).distinct().toList();
+            for (String moduleName : moduleNames) {
+                List<Relationship> moduleRelationships = relationships.stream().filter(relationship -> moduleName.equals(
+                        relationship.getModuleReferenceName())).toList();
+                List<Entity> moduleEntities = entities.stream().filter(entity -> moduleName.equals(entity
+                        .getModuleReferenceName())).toList();
+                generateGraph(moduleName, moduleRelationships, moduleEntities);
+            }
+            generateGraph("overall", relationships, entities);
+        } else {
+            log.info("generate-relationship-graph set to false");
+        }
+    }
+
+    private void generateGraph(String name, List<Relationship> relationships, List<Entity> entities) throws IOException {
+        MutableGraph g = prepareGraph(relationships, entities);
+        File outputFile = new File(graphOutput, name);
+        Graphviz.fromGraph(g).render(Format.SVG).toFile(outputFile);
+        log.info("Graph rendered to: {}", outputFile.getAbsolutePath());
+    }
+
+    private MutableGraph prepareGraph(List<Relationship> moduleRelationships, List<Entity> moduleEntities) {
+        MutableGraph g = Factory.mutGraph("moduleName").setDirected(false);
+        for (Entity moduleEntity : moduleEntities) {
+            MutableNode node = Factory.mutNode(moduleEntity.getEntityName());
+            g.add(node);
+        }
+        for (Relationship moduleRelationship : moduleRelationships) {
+            MutableNode nodeA = Factory.mutNode(moduleRelationship.getASideMOType());
+            g.add(nodeA);
+            MutableNode nodeB = Factory.mutNode(moduleRelationship.getBSideMOType());
+            g.add(nodeB);
+            String label = moduleRelationship.getName().split("_")[1];
+            g.add(nodeA.addLink(Factory.to(nodeB).with(Label.of(label))));
+        }
+        return g;
+    }
+}
index e2fb82b..b75e40d 100644 (file)
@@ -34,3 +34,6 @@ schema:
     output: target/01_init-oran-smo-teiv-model.sql
 exclusions:
   model-names: metadata, decorators
+relationship-graph:
+  generate: true
+  output: target/graphs
index 1ba8f74..d77a504 100644 (file)
@@ -55,6 +55,9 @@ class EndToEndTest {
     @Value("${schema.model.output}")
     private String actualModelSql;
 
+    @Value("${relationship-graph.output}")
+    private String graphOutput;
+
     @Test
     @Order(1)
     void generateDataAndModelSchemaTest() throws IOException {
@@ -63,10 +66,13 @@ class EndToEndTest {
         processor.process();
         File generatedDataSql = new File(actualDataSql);
         File generatedModelSql = new File(actualModelSql);
+        File generatedGraphs = new File(graphOutput);
 
         //then
         Assertions.assertTrue(generatedDataSql.exists());
         Assertions.assertTrue(generatedModelSql.exists());
+        Assertions.assertTrue(generatedGraphs.exists() && generatedGraphs.isDirectory() && generatedGraphs
+                .listFiles().length > 0);
     }
 
     @Test
index fe3176f..1701ce0 100644 (file)
@@ -36,4 +36,7 @@ test-result:
     data: src/test/resources/expected-db-schema/result_00_init-oran-smo-teiv-data.sql
     model: src/test/resources/expected-db-schema/result_01_init-oran-smo-teiv-model.sql
 exclusions:
-  model-names: metadata, decorators
\ No newline at end of file
+  model-names: metadata, decorators
+relationship-graph:
+  generate: true
+  output: target/test-classes/graphs
\ No newline at end of file