Auto gen entity graph 63/13163/2
authorJvD_Ericsson <jeff.van.dam@est.tech>
Thu, 4 Jul 2024 13:36:27 +0000 (14:36 +0100)
committerJvD_Ericsson <jeff.van.dam@est.tech>
Tue, 9 Jul 2024 14:43:40 +0000 (15:43 +0100)
Generate entity and object graphs in the pgsql-schema-generator
from the entites defined in the provided yang models

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

Data types are DB datatypes not YANG

Issue-ID: SMO-156
Change-Id: Id529c2c2cfdb3af1d7f53394e3e09ef93389d968
Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech>
pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/Processor.java
pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/grapghgenerator/EntityGraphGenerator.java [new file with mode: 0644]
pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/grapghgenerator/RelationshipGraphGenerator.java [moved from pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/relationshipgrapghgenerator/RelationshipGraphGenerator.java with 94% similarity]
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 8ce696e..943a15e 100644 (file)
@@ -26,9 +26,10 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import org.oran.smo.teiv.pgsqlgenerator.grapghgenerator.EntityGraphGenerator;
 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.oran.smo.teiv.pgsqlgenerator.grapghgenerator.RelationshipGraphGenerator;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ResourceUtils;
@@ -44,6 +45,7 @@ public class Processor {
     private final DataSchemaGenerator dataSchemaGenerator;
     private final ModelSchemaGenerator modelSchemaGenerator;
     private final RelationshipGraphGenerator relationshipGraphGenerator;
+    private final EntityGraphGenerator entityGraphGenerator;
     @Value("${yang-model.source}")
     private String yangModelDirectory;
 
@@ -64,6 +66,7 @@ public class Processor {
         List<Relationship> relationshipsFromModelService = yangModelProcessor.getRelationshipsFromYang(pathToImplementing);
 
         relationshipGraphGenerator.generate(relationshipsFromModelService, entitiesFromModelService);
+        entityGraphGenerator.generate(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/grapghgenerator/EntityGraphGenerator.java b/pgsql-schema-generator/src/main/java/org/oran/smo/teiv/pgsqlgenerator/grapghgenerator/EntityGraphGenerator.java
new file mode 100644 (file)
index 0000000..78ea033
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  ============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.grapghgenerator;
+
+import guru.nidi.graphviz.attribute.*;
+import guru.nidi.graphviz.engine.Format;
+import guru.nidi.graphviz.engine.Graphviz;
+import guru.nidi.graphviz.model.Factory;
+import guru.nidi.graphviz.model.MutableGraph;
+import guru.nidi.graphviz.model.MutableNode;
+import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.pgsqlgenerator.Attribute;
+import org.oran.smo.teiv.pgsqlgenerator.Entity;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import static guru.nidi.graphviz.attribute.Rank.RankDir;
+
+@Component
+@Slf4j
+public class EntityGraphGenerator {
+
+    @Value("${graphs.generate}")
+    private boolean generateEntityGraph;
+
+    @Value("${graphs.output}")
+    private String graphOutput;
+
+    public void generate(List<Entity> entities) throws IOException {
+        if (generateEntityGraph) {
+            List<String> moduleNames = entities.stream().map(Entity::getModuleReferenceName).distinct().toList();
+            for (String moduleName : moduleNames) {
+                List<Entity> moduleEntities = entities.stream().filter(entity -> moduleName.equals(entity
+                        .getModuleReferenceName())).toList();
+                generateGraph(moduleName, moduleEntities);
+            }
+        } else {
+            log.info("graphs.generate set to false");
+        }
+    }
+
+    private void generateGraph(String name, List<Entity> entities) throws IOException {
+        MutableGraph g = prepareGraph(entities, name);
+        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<Entity> moduleEntities, String moduleName) {
+        MutableGraph g = Factory.mutGraph(moduleName).setDirected(true).graphAttrs().add(Rank.dir(RankDir.LEFT_TO_RIGHT))
+                .nodeAttrs().add(Shape.RECT, Style.BOLD, Color.BLACK, Style.FILLED, Color.LIGHTGRAY.fill());
+        MutableNode moduleNameNode = Factory.mutNode(moduleName).attrs().add(Color.LIGHTBLUE.fill());
+        g.add(moduleNameNode);
+        for (Entity moduleEntity : moduleEntities) {
+            MutableNode moduleNode = Factory.mutNode(moduleEntity.getEntityName());
+            g.add(moduleNode);
+            g.add(moduleNameNode.addLink(Factory.to(moduleNode)));
+            List<Attribute> attributes = moduleEntity.getAttributes();
+            if (!attributes.isEmpty()) {
+                addAttributeNodeToGraph(g, attributes, moduleEntity, moduleNode);
+            }
+        }
+        return g;
+    }
+
+    private void addAttributeNodeToGraph(MutableGraph graph, List<Attribute> attributes, Entity moduleEntity,
+            MutableNode moduleNode) {
+        String label = "<TABLE border='1' cellborder='0' cellspacing='0' cellpadding='4'>";
+        for (Attribute attribute : attributes) {
+            label = label.concat("<TR> <TD bgcolor='#EEEEEE' align='left'>" + attribute
+                    .getName() + "</TD> <TD align='right' bgcolor='#EEEEEE'>" + attribute.getDataType() + "</TD> </TR>");
+        }
+        label = label.concat("</TABLE>");
+        MutableNode attributeNode = Factory.mutNode(moduleEntity.getEntityName() + "-attributes").attrs().add(Label.html(
+                label));
+        graph.add(attributeNode);
+        graph.add(moduleNode.addLink(attributeNode));
+    }
+}
@@ -18,7 +18,7 @@
  *  SPDX-License-Identifier: Apache-2.0
  *  ============LICENSE_END=========================================================
  */
-package org.oran.smo.teiv.pgsqlgenerator.relationshipgrapghgenerator;
+package org.oran.smo.teiv.pgsqlgenerator.grapghgenerator;
 
 import guru.nidi.graphviz.model.Factory;
 import guru.nidi.graphviz.model.MutableGraph;
@@ -40,10 +40,10 @@ import java.util.List;
 @Slf4j
 public class RelationshipGraphGenerator {
 
-    @Value("${relationship-graph.generate}")
+    @Value("${graphs.generate}")
     private boolean generateRelationshipGraph;
 
-    @Value("${relationship-graph.output}")
+    @Value("${graphs.output}")
     private String graphOutput;
 
     public void generate(List<Relationship> relationships, List<Entity> entities) throws IOException {
@@ -58,7 +58,7 @@ public class RelationshipGraphGenerator {
             }
             generateGraph("overall", relationships, entities);
         } else {
-            log.info("generate-relationship-graph set to false");
+            log.info("graphs.generate set to false");
         }
     }
 
index b75e40d..1e3f11f 100644 (file)
@@ -34,6 +34,6 @@ schema:
     output: target/01_init-oran-smo-teiv-model.sql
 exclusions:
   model-names: metadata, decorators
-relationship-graph:
+graphs:
   generate: true
   output: target/graphs
index d77a504..fcd4dae 100644 (file)
@@ -55,7 +55,7 @@ class EndToEndTest {
     @Value("${schema.model.output}")
     private String actualModelSql;
 
-    @Value("${relationship-graph.output}")
+    @Value("${graphs.output}")
     private String graphOutput;
 
     @Test
index 1701ce0..82829f7 100644 (file)
@@ -37,6 +37,6 @@ test-result:
     model: src/test/resources/expected-db-schema/result_01_init-oran-smo-teiv-model.sql
 exclusions:
   model-names: metadata, decorators
-relationship-graph:
+graphs:
   generate: true
   output: target/test-classes/graphs
\ No newline at end of file