aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlastimil Starec <vlastimil.starec@orange.com>2020-04-14 21:49:47 +0200
committerVlastimil Starec <vlastimil.starec@orange.com>2020-04-16 22:52:21 +0200
commit6c4672dbb3cccd6c7d8cdfde2f59a97af7cfac42 (patch)
treef2415c6e0de9c63a7b7ebe41adc62120dc45a9ea
parent208ab81cd84c06387d6ce7ad335b3fbe4d51ac04 (diff)
Perform repository cleanup
1. Perform whitespace cleanup in source files Changes are almost exclusively in indentation and line breaks. Some safe spelling fixes may had gotten staged too. 2. Update license file and license headers on java files Change "2019" to "2019-2020" (fix 2017-2018 in some cases). Convert to block comment format. Make "Orange Intellectual Property" consistent across headers. 3. Prepend javascript files with license headers 4. Rename frontend filenames to lowercase 5. Add missing semicolons after statements in react files Issue-ID: AAI-2861 Signed-off-by: Vlastimil Starec <vlastimil.starec@orange.com> Change-Id: Ieee5562ce9e360da3db1f990a6cf4c1b1e56f657
-rw-r--r--LICENSE.md2
-rw-r--r--README.md8
-rw-r--r--graphgraph-fe/package.json78
-rw-r--r--graphgraph-fe/src/App.css53
-rw-r--r--graphgraph-fe/src/App.js124
-rw-r--r--graphgraph-fe/src/App.test.js9
-rw-r--r--graphgraph-fe/src/DownloadExport.js29
-rw-r--r--graphgraph-fe/src/Graph.js342
-rw-r--r--graphgraph-fe/src/GraphHops.css9
-rw-r--r--graphgraph-fe/src/GraphHops.js70
-rw-r--r--graphgraph-fe/src/GraphInfoMenu.js67
-rw-r--r--graphgraph-fe/src/GraphSettings.js239
-rw-r--r--graphgraph-fe/src/GraphSettingsMenu.js24
-rw-r--r--graphgraph-fe/src/PathBreadCrumb.js26
-rw-r--r--graphgraph-fe/src/PopupSettings.js27
-rw-r--r--graphgraph-fe/src/ValidationModal.js49
-rw-r--r--graphgraph-fe/src/app.css53
-rw-r--r--graphgraph-fe/src/app.js152
-rw-r--r--graphgraph-fe/src/app.test.js29
-rw-r--r--graphgraph-fe/src/constants.js24
-rw-r--r--graphgraph-fe/src/download_export.js43
-rw-r--r--graphgraph-fe/src/graph.css (renamed from graphgraph-fe/src/Graph.css)1
-rw-r--r--graphgraph-fe/src/graph.js372
-rw-r--r--graphgraph-fe/src/graph_hops.css8
-rw-r--r--graphgraph-fe/src/graph_hops.js79
-rw-r--r--graphgraph-fe/src/graph_info_menu.css (renamed from graphgraph-fe/src/GraphInfoMenu.css)7
-rw-r--r--graphgraph-fe/src/graph_info_menu.js81
-rw-r--r--graphgraph-fe/src/graph_settings.css (renamed from graphgraph-fe/src/GraphSettings.css)2
-rw-r--r--graphgraph-fe/src/graph_settings.js256
-rw-r--r--graphgraph-fe/src/graph_settings_menu.css (renamed from graphgraph-fe/src/GraphSettingsMenu.css)7
-rw-r--r--graphgraph-fe/src/graph_settings_menu.js45
-rw-r--r--graphgraph-fe/src/index.css18
-rw-r--r--graphgraph-fe/src/index.js36
-rw-r--r--graphgraph-fe/src/path_breadcrumb.js46
-rw-r--r--graphgraph-fe/src/popup_settings.css (renamed from graphgraph-fe/src/PopupSettings.css)1
-rw-r--r--graphgraph-fe/src/popup_settings.js40
-rw-r--r--graphgraph-fe/src/requests.js52
-rw-r--r--graphgraph-fe/src/serviceWorker.js135
-rw-r--r--graphgraph-fe/src/service_worker.js146
-rw-r--r--graphgraph-fe/src/validation_modal.css (renamed from graphgraph-fe/src/ValidationModal.css)8
-rw-r--r--graphgraph-fe/src/validation_modal.js58
-rw-r--r--pom.xml160
-rwxr-xr-xrun.sh6
-rw-r--r--src/main/java/org/onap/aai/graphgraph/App.java62
-rw-r--r--src/main/java/org/onap/aai/graphgraph/ArgumentParser.java107
-rw-r--r--src/main/java/org/onap/aai/graphgraph/Config.java45
-rw-r--r--src/main/java/org/onap/aai/graphgraph/CorsFilter.java62
-rw-r--r--src/main/java/org/onap/aai/graphgraph/ModelExporter.java415
-rw-r--r--src/main/java/org/onap/aai/graphgraph/SchemaResource.java77
-rw-r--r--src/main/java/org/onap/aai/graphgraph/SchemaValidator.java158
-rw-r--r--src/main/java/org/onap/aai/graphgraph/dto/Edge.java45
-rw-r--r--src/main/java/org/onap/aai/graphgraph/dto/Graph.java45
-rw-r--r--src/main/java/org/onap/aai/graphgraph/dto/NodeName.java41
-rw-r--r--src/main/java/org/onap/aai/graphgraph/dto/NodeProperty.java44
-rw-r--r--src/main/java/org/onap/aai/graphgraph/dto/Property.java44
-rw-r--r--src/main/java/org/onap/aai/graphgraph/dto/ValidationProblems.java55
-rw-r--r--src/main/java/org/onap/aai/graphgraph/reader/BasicSchemaReader.java675
-rw-r--r--src/main/java/org/onap/aai/graphgraph/reader/EdgeType.java60
-rw-r--r--src/main/java/org/onap/aai/graphgraph/reader/MetadataEdge.java112
-rw-r--r--src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java45
-rw-r--r--src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java44
-rw-r--r--src/main/java/org/onap/aai/graphgraph/velocity/VelocityAssociation.java204
-rw-r--r--src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntity.java144
-rw-r--r--src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntityProperty.java96
-rw-r--r--src/main/java/org/onap/aai/graphgraph/velocity/VelocityId.java51
-rw-r--r--src/main/resources/docker-assembly.xml12
-rw-r--r--src/main/resources/etc/auth/realm.properties22
-rw-r--r--src/main/resources/model_export.vm280
-rw-r--r--src/test/java/org/onap/aai/graphgraph/AppTest.java38
69 files changed, 3143 insertions, 2861 deletions
diff --git a/LICENSE.md b/LICENSE.md
index 3b84f7e..2ecf92c 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,4 +1,4 @@
-Copyright © 2019 Orange Intellectual Property. All rights reserved.
+Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.md b/README.md
index 3251be3..84ee8e0 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ To start the frontend just run the following command:
The UI will be available on http://localhost:3000
-In order to start the webservices run the App.java from your Java IDE (the service runs on localhost port 8080).
+In order to start the webservices run the App.java from your Java IDE (the service runs on localhost port 8080).
## Building docker images
@@ -22,7 +22,7 @@ In order to start the webservices run the App.java from your Java IDE (the servi
## Running GraphGraph locally
-You have to start a local instance (i.e. localhost) of schema-service. Afterwards build the GraphGraph JAR file with:
+You have to start a local instance (i.e. localhost) of schema-service. Afterwards build the GraphGraph JAR file with:
### `mvn clean install`
@@ -30,6 +30,6 @@ Go into the target directory and run the JAR file with -d switch:
### `java -jar graphgraph-X.Y.jar -d`
-where X.Y is the current version. For more options run the help via:
+where X.Y is the current version. For more options run the help via:
-### `java -jar graphgraph-X.Y.jar -h` \ No newline at end of file
+### `java -jar graphgraph-X.Y.jar -h`
diff --git a/graphgraph-fe/package.json b/graphgraph-fe/package.json
index eaae97a..a124d60 100644
--- a/graphgraph-fe/package.json
+++ b/graphgraph-fe/package.json
@@ -1,41 +1,41 @@
{
- "name": "graphgraph-fe",
- "version": "0.0.1",
- "private": true,
- "dependencies": {
- "bootstrap-css-only": "3.3.7",
- "d3": "5.7.0",
- "eslint-config-react-app": "3.0.6",
- "react": "^16.8.6",
- "react-table": "6.10.0",
- "react-bootstrap": "0.32.4",
- "react-dom": "^16.8.6",
- "react-numeric-input": "2.2.3",
- "react-scripts": "2.1.1",
- "reactjs-popup": "1.3.2",
- "underscore": "1.9.1"
- },
- "scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
- "eject": "react-scripts eject"
- },
- "eslintConfig": {
- "extends": "react-app"
- },
- "browserslist": [
- ">0.2%",
- "not dead",
- "not ie <= 11",
- "not op_mini all"
- ],
- "devDependencieseslint": {
- "eslint": "^5.6.0",
- "eslint-config-standard": "^12.0.0",
- "eslint-plugin-import": "^2.17.2",
- "eslint-plugin-node": "^8.0.1",
- "eslint-plugin-promise": "^4.1.1",
- "eslint-plugin-standard": "^4.0.0"
- }
+ "name": "graphgraph-fe",
+ "version": "0.0.1",
+ "private": true,
+ "dependencies": {
+ "bootstrap-css-only": "3.3.7",
+ "d3": "5.7.0",
+ "eslint-config-react-app": "3.0.6",
+ "react": "^16.8.6",
+ "react-table": "6.10.0",
+ "react-bootstrap": "0.32.4",
+ "react-dom": "^16.8.6",
+ "react-numeric-input": "2.2.3",
+ "react-scripts": "2.1.1",
+ "reactjs-popup": "1.3.2",
+ "underscore": "1.9.1"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test",
+ "eject": "react-scripts eject"
+ },
+ "eslintConfig": {
+ "extends": "react-app"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ],
+ "devDependencieseslint": {
+ "eslint": "^5.6.0",
+ "eslint-config-standard": "^12.0.0",
+ "eslint-plugin-import": "^2.17.2",
+ "eslint-plugin-node": "^8.0.1",
+ "eslint-plugin-promise": "^4.1.1",
+ "eslint-plugin-standard": "^4.0.0"
+ }
}
diff --git a/graphgraph-fe/src/App.css b/graphgraph-fe/src/App.css
deleted file mode 100644
index 74c1327..0000000
--- a/graphgraph-fe/src/App.css
+++ /dev/null
@@ -1,53 +0,0 @@
-.App {
-width: 100%;
-height: 100%;
-position: absolute;
-top: 0;
-left: 0;
-}
-
-.App-logo {
- animation: App-logo-spin infinite 20s linear;
- height: 40vmin;
-}
-
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-
-.App-link {
- color: #61dafb;
-}
-
-@keyframes App-logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-.root {
-width: 100%;
-height: 100%;
-position: absolute;
-top: 0;
-left: 0;
-}
-
-.graph-area{
- border-style: solid;
- border-color: darkgray;
- border-width: 1px 0 1px 0;
- position: relative;
- width: 100%;
- height: 70%;
-}
diff --git a/graphgraph-fe/src/App.js b/graphgraph-fe/src/App.js
deleted file mode 100644
index 788aca1..0000000
--- a/graphgraph-fe/src/App.js
+++ /dev/null
@@ -1,124 +0,0 @@
-import React from 'react'
-import './App.css'
-import Graph from './Graph'
-import GraphSettingsMenu from './GraphSettingsMenu'
-import GraphInfoMenu from './GraphInfoMenu'
-import _ from 'underscore'
-import { nodeProperty, edgeProperty } from './requests'
-import * as constants from './constants'
-
-var emptyState = {
- selectedSchema: '', // currently selected schema
- graph: {
- nodeNames: [], // names of nodes
- edges: [], // edges (each edge has source, target, type and a list of key value properties for tooltip)
- paths: [] // all paths between start node and end node
- },
- displayedProperties: [], // properties of currently thing (edge or node)
- nodeStates: {}, // possible states CLICKED - the currently selected node PATH - currently displayed path
- pathIndex: 0, // array index to paths i.e. which path from paths is currently displayed
- selectedEdge: { source: 'none', target: 'none' } // defines currently selected edge like like a js object - {source: "pserver", target: "vserver"}
-}
-
-class App extends React.Component {
- constructor (props, context) {
- super(props, context)
- this.graphdata = this.graphdata.bind(this)
- this.changePaths = this.changePaths.bind(this)
- this.loadNodeProperties = this.loadNodeProperties.bind(this)
- this.loadEdgeProperties = this.loadEdgeProperties.bind(this)
- this.computeNodeStatesFromPath = this.computeNodeStatesFromPath.bind(this)
- this.computeNodeStates = this.computeNodeStates.bind(this)
-
- this.state = emptyState
- }
-
- loadNodeProperties (nodeName) {
- var s = this.state
- fetch(nodeProperty(s.selectedSchema, nodeName))
- .then(response => response.json())
- .then(p => {
- s['displayedProperties'] = p
- s['nodeStates'] = this.computeNodeStates(s['pathIndex'])
- // select node
- s['nodeStates'][nodeName] = constants.CLICKED
- // unselect edge
- s['selectedEdge']['source'] = ''
- s['selectedEdge']['target'] = ''
- this.setState(s)
- })
- }
-
- loadEdgeProperties (source, target) {
- var s = this.state
- fetch(edgeProperty(s.selectedSchema, source, target))
- .then(response => response.json())
- .then(p => {
- s['displayedProperties'] = p
- // select edge
- s['selectedEdge']['source'] = source
- s['selectedEdge']['target'] = target
- // unselect node
- s['nodeStates'] = this.computeNodeStates(s['pathIndex'])
- this.setState(s)
- })
- }
-
- graphdata (data, selectedGraphSchema, graphFingerprint) {
- var s = this.state
- s['selectedSchema'] = selectedGraphSchema
- s['graphFingerprint'] = graphFingerprint
- s['graph'] = data
- // TODO this should be handled more gracefully ...
- if (_.isEmpty(data.edges)) {
- alert('The graph has no edges, nothing to display')
- }
- s['displayedProperties'] = data.startNodeProperties
- if (_.isArray(data.paths) && !_.isEmpty(data.paths)) {
- s['paths'] = data.paths
- s['nodeStates'] = this.computeNodeStatesFromPath(data.paths[0])
- s['pathIndex'] = 0
- } else {
- s['paths'] = []
- s['nodeStates'] = {}
- }
- this.setState(s)
- return data
- }
-
- computeNodeStatesFromPath (path) {
- return _.reduce(path, (acc, node) => {
- acc[node.id] = constants.PATH
- return acc
- }, {})
- }
-
- computeNodeStates (pathIndex) {
- return this.computeNodeStatesFromPath(this.state.paths[pathIndex])
- }
-
- changePaths (pathIndex, selectedNode) {
- var s = this.state
- s['pathIndex'] = pathIndex
- this.setState(s)
- this.loadNodeProperties(selectedNode)
- }
-
- render () {
- let n = _.invert(this.state.nodeStates)[constants.CLICKED]
-
- let selectedNode = _.isUndefined(n) ? '' : n
- return (
- <div className="App">
- <GraphSettingsMenu graphData={this.graphdata} nodePropsLoader={this.loadNodeProperties} selectedNode={selectedNode}/>
- <div className='graph-area'>
- <Graph graphFingerprint={this.state.graphFingerprint} edgePropsLoader={this.loadEdgeProperties} selectedEdge={this.state.selectedEdge} nodes={this.state.graph.nodeNames} edges={this.state.graph.edges} nodeStates={this.state.nodeStates} nodePropsLoader={this.loadNodeProperties}/>
- </div>
-
- <GraphInfoMenu pathCallback={this.changePaths} paths={ this.state.graph.paths } nodeProperties={ this.state.displayedProperties} />
- </div>
- )
- }
-}
-
-export default App
diff --git a/graphgraph-fe/src/App.test.js b/graphgraph-fe/src/App.test.js
deleted file mode 100644
index 4bf1935..0000000
--- a/graphgraph-fe/src/App.test.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
-import App from './App'
-
-it('renders without crashing', () => {
- const div = document.createElement('div')
- ReactDOM.render(<App />, div)
- ReactDOM.unmountComponentAtNode(div)
-})
diff --git a/graphgraph-fe/src/DownloadExport.js b/graphgraph-fe/src/DownloadExport.js
deleted file mode 100644
index b031773..0000000
--- a/graphgraph-fe/src/DownloadExport.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from 'react'
-import { Button } from 'react-bootstrap'
-import { exportSchema } from './requests'
-
-
-class DownloadExport extends React.Component {
- constructor (props, context) {
- super(props, context)
- this.download = this.download.bind(this)
- }
-
- download() {
-
- setTimeout(() => {
- const response = {
- file: exportSchema(this.props.schemaVersion),
- };
- window.open(response.file);
- }, 100);
- }
-
- render() {
- return (
- <Button onClick={this.download}>Download as XMI</Button>
- );
- }
-}
-
-export default DownloadExport
diff --git a/graphgraph-fe/src/Graph.js b/graphgraph-fe/src/Graph.js
deleted file mode 100644
index c4b1aa0..0000000
--- a/graphgraph-fe/src/Graph.js
+++ /dev/null
@@ -1,342 +0,0 @@
-import React from 'react'
-import * as d3 from 'd3'
-import './Graph.css'
-import _ from 'underscore'
-import * as constants from './constants'
-
-const CLICKED_COLOR = 'blue'
-const PATH_COLOR = 'red'
-const EDGE_MOUSE_OVER_COLOR = 'yellow'
-const EDGE_NORMAL_COLOR = '#ccc'
-const EDGE_LABEL_COLOR = 'black'
-const NODE_NORMAL_COLOR = '#E3E3E3'
-const NODE_LABEL_COLOR = 'black'
-const NODE_MOUSE_OVER_COLOR = '#F6F6F6'
-const NODE_BORDER_COLOR = 'lightgray'
-
-// variable holds state in order to determine if graph should be redrawn completely
-// it breaks the react concept, so a better approach is needed
-var graphFingerprint = ''
-
-var htmlfyProperties = function (properties) {
- return "<div class='d3-tip'>" + (_.reduce(properties, (html, e) => { return html + "<span style='color: lightgray'>" + e.propertyName + ':</span> <span>' + e.propertyValue + '</span><br/>' }, '')) + '</div>'
-}
-
-var mouseOverEdge = function (edge, div) {
- div.transition()
- .duration(20)
- .style('opacity', 0.9)
- div.html(htmlfyProperties(edge.tooltipProperties))
- .style('left', `${d3.event.pageX}px`)
- .style('top', `${d3.event.pageY - 28}px`)
-}
-
-var mouseOutEdge = function (edge, div) {
- div.transition()
- .duration(6000)
- .style('opacity', 0)
-}
-
-var addEdgePaths = function (links, g) {
- d3.select('body').append('div')
- .attr('class', 'tooltip')
- .style('opacity', 0)
- g.selectAll('.edgepath')
- .data(links)
- .enter()
- .append('path')
- .attr('d', d => `M ${d.source.x} ${d.source.y} L ${d.target.x} ${d.target.y}`)
- .attr('class', 'edgepath')
- .attr('fill-opacity', 0)
- .attr('stroke-opacity', 0)
- .attr('fill', EDGE_LABEL_COLOR)
- .attr('id', (d, i) => `edgepath${i}`)
-}
-
-var chooseColor = function (state) {
- if (state === constants.CLICKED) {
- return CLICKED_COLOR
- }
-
- if (state === constants.PATH) {
- return PATH_COLOR
- }
-
- return NODE_NORMAL_COLOR
-}
-
-var redrawNodeColors = function (nodeStates, selectedEdge) {
- d3.selectAll('svg').selectAll('g').selectAll('circle').style('fill', n => chooseColor(nodeStates[n.id]))
- d3.selectAll('svg').selectAll('g').selectAll('line').style('stroke', EDGE_NORMAL_COLOR).attr('oldStroke', EDGE_NORMAL_COLOR)
- d3.selectAll('svg').selectAll('g').selectAll('line').filter(edge => edge.source.id === selectedEdge.source && edge.target.id === selectedEdge.target).attr('oldStroke', CLICKED_COLOR).style('stroke', CLICKED_COLOR)
-}
-
-var addEdgeLabels = function (links, g, div) {
- var edgelabels = g.selectAll('.edgelabel')
- .data(links)
- .enter()
- .append('text')
- .attr('class', 'edgelabel')
- .attr('text-anchor', 'middle')
- .attr('dx', 200)
- .attr('dy', 0)
- .attr('font-size', '22px')
- .attr('id', (d, i) => `edgelabel${i}`)
-
- edgelabels.append('textPath')
- .attr('xlink:href', (d, i) => `#edgepath${i}`)
- .text((d, i) => d.type)
-}
-
-var addNodeLabels = function (nodes, g) {
- g.selectAll('.nodelabel')
- .data(nodes)
- .enter()
- .append('text')
- .attr('x', d => d.x - 14)
- .attr('y', d => d.y - 17)
- .attr('class', 'nodelabel')
- .attr('fill', NODE_LABEL_COLOR)
- .attr('font-size', '32px')
- .text(d => d.id)
- .on('mouseenter', onNodeLabelMouseOver)
- .on('mouseout', onNodeLabelMouseOut)
-}
-
-var addLinks = function (links, g, div, edgePropsLoader) {
- let ss = _.filter(links, l => l.source.id === l.target.id)
-
- let selfLinks = _.isUndefined(ss) ? [] : ss
-
- g.selectAll('ellipse')
- .data(selfLinks)
- .enter().append('ellipse')
- .attr('fill-opacity', 0)
- .attr('rx', d => 100)
- .attr('ry', d => 16)
- .attr('cx', d => d.target.x + 80)
- .attr('cy', d => d.target.y)
- .style('stroke', NODE_BORDER_COLOR)
- .attr('stroke-width', 5)
- .on('click', edge => edgePropsLoader(edge.source.id, edge.target.id))
- .on('mouseenter', function (edge) {
- mouseOverEdge(edge, div)
- d3.select(this)
- .transition()
- .attr('oldStroke', EDGE_NORMAL_COLOR)
- .duration(10)
- .style('stroke', EDGE_MOUSE_OVER_COLOR)
- })
- .on('mouseleave', function (edge) {
- mouseOutEdge(edge, div)
- var strokeColor = d3.select(this).attr('oldStroke')
- d3.select(this)
- .transition()
- .duration(300)
- .style('stroke', strokeColor)
- })
-
- g.selectAll('.edgelooplabel')
- .data(selfLinks)
- .enter()
- .append('text')
- .attr('x', d => d.source.x + 35)
- .attr('y', d => d.source.y + 50)
- .attr('class', 'edgelooplabel')
- .attr('fill', NODE_LABEL_COLOR)
- .attr('font-size', '22px')
- .text(d => d.type)
-
- g.selectAll('line')
- .data(links)
- .enter().append('line')
- .attr('stroke-width', 5)
- .attr('x1', d => d.source.x)
- .attr('y1', d => d.source.y)
- .attr('x2', d => d.target.x)
- .attr('y2', d => d.target.y)
- .attr('id', (d, i) => `edge${i}`)
- .attr('marker-end', 'url(#arrowhead)')
- .style('stroke', EDGE_NORMAL_COLOR)
- .on('click', edge => edgePropsLoader(edge.source.id, edge.target.id))
- .on('mouseenter', function (edge) {
- mouseOverEdge(edge, div)
- d3.select(this)
- .transition()
- .attr('oldStroke', EDGE_NORMAL_COLOR)
- .duration(10)
- .style('stroke', EDGE_MOUSE_OVER_COLOR)
- })
- .on('mouseleave', function (edge) {
- mouseOutEdge(edge, div)
- var strokeColor = d3.select(this).attr('oldStroke')
- d3.select(this)
- .transition()
- .duration(300)
- .style('stroke', strokeColor)
- })
-}
-
-var addMarkers = function (g, svg) {
- g.append('defs').append('marker')
- .attr('id', 'arrowhead')
- .attr('viewBox', '-0 -5 10 10')
- .attr('refX', '20')
- .attr('refY', '0')
- .attr('orient', 'auto')
- .attr('markerWidth', '4')
- .attr('markerHeight', '4')
- .attr('xoverflow', 'visible')
- .append('svg:path')
- .attr('d', 'M 0,-5 L 10 ,0 L 0,5')
- .attr('fill', EDGE_NORMAL_COLOR)
- .attr('stroke', EDGE_NORMAL_COLOR)
-
- var zoomHandler = d3.zoom()
- .on('zoom', _ => g.attr('transform', d3.event.transform))
-
- zoomHandler(svg)
- zoomHandler.translateTo(svg, -7000, -4000)
- zoomHandler.scaleTo(svg, 0.08)
-}
-
-var drawGraph = function (nodes, links, g, simulation, svg, addNodes, edgePropsLoader) {
- for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); i < n; ++i) {
- simulation.tick()
- }
-
- var div = d3.select('body').append('div')
- .attr('class', 'tooltip')
- .style('opacity', 0)
-
- addLinks(links, g, div, edgePropsLoader)
- addNodes(nodes, g)
- addNodeLabels(nodes, g)
- addEdgePaths(links, g)
- addEdgeLabels(links, g, div)
- addMarkers(g, svg)
-}
-
-var prepareLinks = function (nodes, links) {
- var result = []
- links.forEach(e => {
- var sourceNode = nodes.filter(n => n.id === e.source)[0]
- var targetNode = nodes.filter(n => n.id === e.target)[0]
-
- result.push({
- source: sourceNode,
- target: targetNode,
- type: e.type,
- tooltipProperties: e.tooltipProperties
- })
- })
-
- return result
-}
-
-var createSimulation = function (nodes, links) {
- return d3.forceSimulation(nodes)
- .force('charge', d3.forceManyBody().strength(-201))
- .force('link', d3.forceLink(links).distance(1200).strength(1).iterations(400))
- .force('collision', d3.forceCollide().radius(d => 310))
- .force('x', d3.forceX())
- .force('y', d3.forceY())
- .stop()
-}
-
-var createSvg = function () {
- var svg = d3.select('#graph').append('svg').attr('height', '100%').attr('width', '100%')
- var g = svg.append('g')
-
- return { 'g': g, 'svg': svg }
-}
-
-var onNodeLabelMouseOut = function () {
- d3.select(this)
- .transition()
- .duration(600)
- .attr('font-size', '32px')
-}
-
-var onNodeLabelMouseOver = function () {
- d3.select(this)
- .transition()
- .duration(200)
- .attr('font-size', '232px')
-}
-
-var onNodeMouseOver = function () {
- var oldFill = d3.select(this).style('fill')
- d3.select(this)
- .transition()
- .duration(200)
- .attr('r', 31)
- .attr('oldFill', oldFill)
- .style('fill', NODE_MOUSE_OVER_COLOR)
-}
-
-var onNodeMouseOut = function (nodeStates) {
- var oldFill = d3.select(this).attr('oldFill')
- d3.select(this)
- .transition()
- .duration(300)
- .attr('r', 23)
- .style('fill', oldFill)
-}
-
-class Graph extends React.Component {
- onNodeClick (x) {
- // on mouse out the node will change color read from 'oldFill' attribute
- d3.selectAll('svg').selectAll('g').selectAll('circle').filter(c => c.id === x.id).attr('oldFill', CLICKED_COLOR)
- this.props.nodePropsLoader(x.id)
- }
-
- addNodes (nodes, g) {
- g.selectAll('circle')
- .data(nodes)
- .enter().append('circle')
- .attr('cx', d => d.x)
- .attr('cy', d => d.y)
- .style('fill', n => {
- return chooseColor(this.props.nodeStates[n.id])
- })
- .style('stroke', NODE_BORDER_COLOR)
- .attr('stroke-width', 3)
- .attr('r', 23)
- .on('click', this.onNodeClick)
- .on('mouseover', onNodeMouseOver)
- .on('mouseout', onNodeMouseOut)
- }
-
- reCreateGraph () {
- d3.select('#graph').selectAll('*').remove()
-
- var nodes = this.props.nodes
- var links = prepareLinks(this.props.nodes, this.props.edges)
- var o = createSvg()
- var simulation = createSimulation(nodes, links)
-
- drawGraph(nodes, links, o.g, simulation, o.svg, this.addNodes, this.props.edgePropsLoader)
- }
-
- constructor (props, context) {
- super(props, context)
-
- this.reCreateGraph = this.reCreateGraph.bind(this)
- this.addNodes = this.addNodes.bind(this)
- this.onNodeClick = this.onNodeClick.bind(this)
- }
-
- render () {
- if (this.props.graphFingerprint !== graphFingerprint) {
- this.reCreateGraph()
- graphFingerprint = this.props.graphFingerprint
- } else {
- redrawNodeColors(this.props.nodeStates, this.props.selectedEdge)
- }
-
- return (<div id="graph"/>)
- }
-}
-
-export default Graph
diff --git a/graphgraph-fe/src/GraphHops.css b/graphgraph-fe/src/GraphHops.css
deleted file mode 100644
index b6207eb..0000000
--- a/graphgraph-fe/src/GraphHops.css
+++ /dev/null
@@ -1,9 +0,0 @@
-
-.hops-input{
-display: flex;
-flex-direction: column;
-}
-
-.hops-input-field{
-width: 190px;
-}
diff --git a/graphgraph-fe/src/GraphHops.js b/graphgraph-fe/src/GraphHops.js
deleted file mode 100644
index de7a4cc..0000000
--- a/graphgraph-fe/src/GraphHops.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import React from 'react'
-import { Label } from 'react-bootstrap'
-import NumericInput from 'react-numeric-input'
-import './GraphHops.css'
-
-var createNumInput = function (label, callback, current) {
- return (
- <div>
- <Label>{label}</Label>
- <NumericInput onChange={callback} min={1} max={500} value={current} className="hops-input-field" />
- </div>
- )
-}
-
-class GraphHops extends React.Component {
- constructor (props) {
- super(props)
-
- this.state = {
- value: this.props.defaultValue
- }
- let p = props.parentHops
- let c = props.cousinHops
- let ch = props.childHops
-
- this.onChangeParent = (e) => this._onChangeParent(e)
- this.onChangeCousin = (e) => this._onChangeCousin(e)
- this.onChangeChild = (e) => this._onChangeChild(e)
- this.onChange = (hopsName, num) => this._onChange(hopsName, num)
- this.state = { parentHops: p, childHops: ch, cousinHops: c }
- }
-
- _onChange (hopsName, num) {
- var s = this.state
- s[hopsName] = num
- this.setState(s)
- this.props.updateHops(this.state.parentHops, this.state.cousinHops, this.state.childHops)
- }
-
- _onChangeParent (e) {
- this.onChange('parentHops', e)
- }
-
- _onChangeCousin (e) {
- this.onChange('cousinHops', e)
- }
-
- _onChangeChild (e) {
- this.onChange('childHops', e)
- }
-
- render () {
- if (this.props.edgeFilter === 'Edgerules'){
- return (
- <div className="hops-input">
- {createNumInput('edgerule hops', this.onChangeCousin, this.state.cousinHops)}
- </div>
- )
- }
-
- return (
- <div className="hops-input">
- {createNumInput('parent hops', this.onChangeParent, this.state.parentHops)}
- {createNumInput('child hops', this.onChangeChild, this.state.childHops)}
- </div>
- )
- }
-}
-
-export default GraphHops
diff --git a/graphgraph-fe/src/GraphInfoMenu.js b/graphgraph-fe/src/GraphInfoMenu.js
deleted file mode 100644
index d001d50..0000000
--- a/graphgraph-fe/src/GraphInfoMenu.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import React from 'react'
-import './GraphInfoMenu.css'
-import PathBreadCrumb from './PathBreadCrumb'
-import _ from 'underscore'
-import ReactTable from "react-table";
-import "react-table/react-table.css";
-
-class GraphInfoMenu extends React.Component {
-
- render () {
- var paths = this.props.paths
- var callback = this.props.pathCallback
- var showPaths = _.isArray(paths) && !_.isEmpty(paths)
- var breadcrumbs = _.map(paths, (path, i) => <PathBreadCrumb key={i} index={i} pathCallback={callback} path={path}/>)
- return (
- <div className="node-property-list">
- <div className="fixed-height-container" style={{ display: showPaths ? 'block' : 'none' }}>
- <p className='path-heading'>Paths</p>
- {breadcrumbs}
- </div>
- <div className="kv-table datatable">
- <ReactTable pageSizeOptions={[4, 25]} data={this.props.nodeProperties}
- columns={[
- {
- Header: "Attribute",
- accessor: "propertyName",
- minWidth: 40
- },
- {
- Header: "Type",
- accessor: "type",
- minWidth: 70
- },
- {
- Header: "Description",
- accessor: "description",
- minWidth: 260
- },
- {
- id: "Key",
- Header: "Key",
- accessor: p => p.key ? "yes" : "",
- minWidth: 20
- },
- {
- id: "Index",
- Header: "Index",
- accessor: p => p.index ? "yes" : "",
- minWidth: 20
- },
- {
- id: "Required",
- Header: "Required",
- accessor: p => p.required ? "yes" : "",
- minWidth: 20
- }
- ]}
- defaultPageSize={4}
- className="-striped -highlight"
- />
- </div>
- </div>
- )
- }
-}
-
-export default GraphInfoMenu
diff --git a/graphgraph-fe/src/GraphSettings.js b/graphgraph-fe/src/GraphSettings.js
deleted file mode 100644
index d511068..0000000
--- a/graphgraph-fe/src/GraphSettings.js
+++ /dev/null
@@ -1,239 +0,0 @@
-import React from 'react'
-import _ from 'underscore'
-import { DropdownButton, MenuItem, Label } from 'react-bootstrap'
-import './GraphSettings.css'
-import Popup from './PopupSettings'
-import ValidationModal from './ValidationModal'
-import DownloadExport from './DownloadExport'
-import { validateSchema, pathGraph, basicGraph, schemas, nodeNames } from './requests'
-
-var emptyState = {
- schemaProblems: [],
- nodeNames: [],
- fromNode: '',
- graph: {
- nodeNames: [],
- edges: []
- },
- showHops: false,
- enableDestinationNode: false,
- toNode: '',
- edgeFilter: 'Edgerules',
- hops: {
- parents: 1,
- cousin: 1,
- child: 1
- },
- selectedSchema: ''
-}
-
-class GraphSettings extends React.Component {
- constructor (props, context) {
- super(props, context)
- this.onChangeStartNode = this.onChangeStartNode.bind(this)
- this.onSelectNode = this.onSelectNode.bind(this)
- this.selectSchema = this.selectSchema.bind(this)
- this.onChangeToNode = this.onChangeToNode.bind(this)
- this.loadInitialGraph = this.loadInitialGraph.bind(this)
- this.updateHops = this.updateHops.bind(this)
- this.changeEdgeFilter = this.changeEdgeFilter.bind(this)
- this.graphFingerprint = this.graphFingerprint.bind(this)
- this.state = emptyState
- }
- // this serves as a config 'fingerprint' to know if the d3 visualisation should be redrawn from scratch or just updated
- graphFingerprint (schema, from, to, parents, cousin, child, edgeFilter) {
- return `${schema}:${from}:${to}:${parents}:${cousin}:${child}:${edgeFilter}`
- }
-
- loadInitialGraph (startNode, endNode, parentHops, cousinHops, childHops, edgeFilter) {
- if (this.state.selectedSchema === '' || startNode === 'none') {
- var s = this.state
- s['edgeFilter'] = edgeFilter
- this.setState(s)
- return
- }
- if (startNode === 'all') {
- endNode = 'none'
- }
-
- let requestUri = endNode === 'none'
- ? basicGraph(this.state.selectedSchema, startNode, parentHops, cousinHops, childHops, edgeFilter) : pathGraph(this.state.selectedSchema, startNode, endNode, edgeFilter)
-
- fetch(requestUri)
- .then(response => response.json())
- .then(g => {
- let schema = this.state.selectedSchema
-
- let f = this.graphFingerprint(schema, startNode, endNode, parentHops, cousinHops, childHops, edgeFilter)
- this.props.graphData(g, this.state.selectedSchema, f)
- return g
- })
- .then(g => {
- var s = this.state
- s['hops']['parents'] = parentHops
- s['hops']['cousin'] = cousinHops
- s['hops']['child'] = childHops
- s['fromNode'] = startNode
- s['toNode'] = endNode
- s['graph'] = g
- s['edgeFilter'] = edgeFilter
- s['showHops'] = endNode === 'none' && startNode !== 'none' && startNode !== 'all'
- s['enableDestinationNode'] = startNode !== 'none' && startNode !== 'all'
- this.setState(s)
-
- if (startNode !== 'all') {
- this.onSelectNode(startNode)
- }
- })
- }
-
- selectSchema (schema) {
- var s = this.state
- s['selectedSchema'] = schema
- fetch(nodeNames(schema, s['edgeFilter']))
- .then(response => response.json())
- .then(nodeNames => {
- s['fromNode'] = s['toNode'] = 'none'
- s['nodeNames'] = nodeNames
- this.setState(s)
- })
- fetch(validateSchema(schema))
- .then(response => response.json())
- .then(p => {
- s['schemaProblems'] = p.problems
- this.setState(s)
- })
- }
-
- changeEdgeFilter (edgeFilter) {
- fetch(nodeNames(this.state.selectedSchema, edgeFilter))
- .then(response => response.json())
- .then(nodeNames => {
- let s = this.state
- s['edgeFilter'] = edgeFilter
- s['fromNode'] = s['toNode'] = 'none'
- s['nodeNames'] = nodeNames
- this.setState(s)
- })
- this.loadInitialGraph(
- this.state.fromNode,
- this.state.toNode,
- this.state.hops.parents,
- this.state.hops.cousin,
- this.state.hops.child,
- edgeFilter
- )
- }
-
- updateHops (parentHops, cousinHops, childHops) {
- this.loadInitialGraph(
- this.state.fromNode,
- this.state.toNode,
- parentHops,
- cousinHops,
- childHops,
- this.state.edgeFilter)
- }
-
- onChangeToNode (eventKey) {
- this.loadInitialGraph(this.state.fromNode,
- eventKey,
- this.state.hops.parents,
- this.state.hops.cousin,
- this.state.hops.child,
- this.state.edgeFilter)
- }
-
- onSelectNode (eventKey) {
- this.props.nodePropsLoader(eventKey)
- }
-
- onChangeStartNode (eventKey) {
- this.loadInitialGraph(eventKey, this.state.toNode,
- this.state.hops.parents,
- this.state.hops.cousin,
- this.state.hops.child,
- this.state.edgeFilter)
- }
-
- componentDidMount () {
- fetch(schemas())
- .then(response => response.json())
- .then(schemas => {
- let s = this.state
- s['schemas'] = schemas
- this.setState(s)
- })
- }
-
- render () {
- var schemas = _.map(this.state.schemas, (x, k) => <MenuItem key={k} eventKey={x}>{x}</MenuItem>)
-
- var items = _.map(this.state.nodeNames, (x, k) => <MenuItem key={k} eventKey={x.id}>{x.id}</MenuItem>)
- let sortedNames = _.sortBy(this.state.graph.nodeNames, 'id')
- var currentNodeNames = _.map(sortedNames, (x, k) => <MenuItem key={k} eventKey={x.id}>{x.id}</MenuItem>)
-
- var fromItems = items.slice()
- fromItems.unshift(<MenuItem key='divider' divider />)
- fromItems.unshift(<MenuItem key='all' eventKey='all'>all</MenuItem>)
-
- items.unshift(<MenuItem key='anotherdivider' divider />)
- items.unshift(<MenuItem key='none' eventKey='none'>none</MenuItem>)
-
- let edgeFilterItems = [
- <MenuItem key='Edgerules' eventKey='Edgerules'>Edgerules</MenuItem>,
- <MenuItem key='Parents' eventKey='Parents'>Parent-child (OXM structure)</MenuItem>,
- ]
- return (
- <div>
- <div className="graph-menu">
- <div className="startendnode-dropdown">
- <div>
- <Label>Schemas</Label>
- <DropdownButton className="schemas-dropdown" onSelect={this.selectSchema} id="schemas" title={this.state.selectedSchema}>
- {schemas}
- </DropdownButton>
- </div>
- <div className="source-dropdown-div">
- <Label>Source Node</Label>
- <DropdownButton className="node-dropdown" onSelect={this.onChangeStartNode} id="namesFrom" title={this.state.fromNode}>
- {fromItems}
- </DropdownButton>
- </div>
- <div>
- <Label>Destination Node</Label>
- <DropdownButton disabled={!this.state.enableDestinationNode} className="node-dropdown" onSelect={this.onChangeToNode} id="namesTo" title={this.state.toNode}>
- {items}
- </DropdownButton>
- </div>
- <div className="source-dropdown-div">
- <Label>Edge filter</Label>
- <DropdownButton className="node-dropdown" onSelect={this.changeEdgeFilter} id="filterEdge" title={this.state.edgeFilter}>
- {edgeFilterItems}
- </DropdownButton>
- </div>
- <div className="source-dropdown-div">
- <Label>Selected Node</Label>
- <DropdownButton className="node-dropdown" onSelect={this.onSelectNode} id="selectedNode" title={this.props.selectedNode}>
- {currentNodeNames}
- </DropdownButton>
- </div>
-
- <Popup isDisabled={!this.state.showHops} edgeFilter={this.state.edgeFilter} parentHops={this.state.hops.parents} childHops={this.state.hops.child} cousinHops={this.state.hops.cousin} updateHops={this.updateHops}/>
- <div className="modal-button">
- <ValidationModal schemaProblems={this.state.schemaProblems}/>
- </div>
-
- <div className="modal-button">
- <DownloadExport schemaVersion={this.state.selectedSchema}/>
- </div>
-
- </div>
-
- </div>
- </div>
- )
- }
-}
-
-export default GraphSettings
diff --git a/graphgraph-fe/src/GraphSettingsMenu.js b/graphgraph-fe/src/GraphSettingsMenu.js
deleted file mode 100644
index 5ce1e12..0000000
--- a/graphgraph-fe/src/GraphSettingsMenu.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react'
-import GraphSettings from './GraphSettings'
-import { Navbar, Nav } from 'react-bootstrap'
-import './GraphSettingsMenu.css'
-
-class GraphSettingsMenu extends React.Component {
- render () {
- return (
- <Navbar className='navbar-adjust'>
- <Navbar.Header>
- <Navbar.Brand>
- <a href="https://gerrit.onap.org/r/gitweb?p=aai/graphgraph.git">GraphGraph</a>
- </Navbar.Brand>
- </Navbar.Header>
- <Nav className="mr-auto">
- <Navbar.Collapse className='mr-sm-2'>
- <GraphSettings selectedNode={this.props.selectedNode} graphData={this.props.graphData} nodePropsLoader={this.props.nodePropsLoader} />
- </Navbar.Collapse>
-</Nav>
- </Navbar>)
- }
-}
-
-export default GraphSettingsMenu
diff --git a/graphgraph-fe/src/PathBreadCrumb.js b/graphgraph-fe/src/PathBreadCrumb.js
deleted file mode 100644
index a2c508a..0000000
--- a/graphgraph-fe/src/PathBreadCrumb.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import _ from 'underscore'
-import React from 'react'
-import { Breadcrumb } from 'react-bootstrap'
-
-class PathBreadCrumb extends React.Component {
- constructor (props, context) {
- super(props, context)
- this.pathSelected = this.pathSelected.bind(this)
- }
-
- pathSelected (evt) {
- evt.preventDefault()
- // the data is only piggyback riding on the "target" property .. not nice but works
- this.props.pathCallback(this.props.index, evt.target.getAttribute('target'))
- }
-
- render () {
- var path = this.props.path
- var callback = this.pathSelected
- var items = _.map(path, (item, i) => <Breadcrumb.Item key={i} target={item.id} onClick={callback}> {item.id} </Breadcrumb.Item>)
-
- return (<Breadcrumb>{items}</Breadcrumb>)
- }
-}
-
-export default PathBreadCrumb
diff --git a/graphgraph-fe/src/PopupSettings.js b/graphgraph-fe/src/PopupSettings.js
deleted file mode 100644
index cb8a533..0000000
--- a/graphgraph-fe/src/PopupSettings.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import React from 'react'
-import Popup from 'reactjs-popup'
-import './PopupSettings.css'
-import GraphHops from './GraphHops'
-
-class PopupMenu extends React.Component {
- render () {
- return (
- <Popup trigger={<button className='settings-button' disabled={this.props.isDisabled}>Hops</button>} position="bottom right">
- {close => (
- <div>
- <GraphHops edgeFilter={this.props.edgeFilter} parentHops={this.props.parentHops} childHops={this.props.childHops} cousinHops={this.props.cousinHops} updateHops={this.props.updateHops} />
- <button
- type="button"
- className="link-button, close"
- onClick={close}>
- &times;
- </button>
- </div>
- )}
- </Popup>
-
- )
- }
-}
-
-export default PopupMenu
diff --git a/graphgraph-fe/src/ValidationModal.js b/graphgraph-fe/src/ValidationModal.js
deleted file mode 100644
index 8bf1989..0000000
--- a/graphgraph-fe/src/ValidationModal.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import _ from 'underscore'
-import React from 'react'
-import './ValidationModal.css'
-import { Button, Modal, ListGroup, ListGroupItem } from 'react-bootstrap'
-
-
-class ValidationModal extends React.Component {
- constructor(...args) {
- super(...args);
- this.state = { showModal: false };
-
- this.close = () => {
- this.setState({ showModal: false });
- };
-
- this.open = () => {
- this.setState({ showModal: true });
- };
- }
-
- renderBackdrop(props) {
- return <div {...props} className="modal-backdrop" />;
- }
-
- render() {
- var problems = this.props.schemaProblems
- var items = _.map(problems, (problem, i) => <ListGroupItem key={i}> {problem} </ListGroupItem>)
- return (
- <div>
- <Button onClick={this.open}>Validate schema</Button>
- <Modal
- onHide={this.close}
- className="modal-validator"
- aria-labelledby="modal-label"
- show={this.state.showModal}
- renderBackdrop={this.renderBackdrop}
- >
- <div className="modal-list">
- <ListGroup>
- {items}
- </ListGroup>
- </div>
- </Modal>
- </div>
- );
- }
-}
-
-export default ValidationModal
diff --git a/graphgraph-fe/src/app.css b/graphgraph-fe/src/app.css
new file mode 100644
index 0000000..8c39ae0
--- /dev/null
+++ b/graphgraph-fe/src/app.css
@@ -0,0 +1,53 @@
+.App {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+.App-logo {
+ animation: App-logo-spin infinite 20s linear;
+ height: 40vmin;
+}
+
+.App-header {
+ background-color: #282c34;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-size: calc(10px + 2vmin);
+ color: white;
+}
+
+.App-link {
+ color: #61dafb;
+}
+
+@keyframes App-logo-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.root {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+.graph-area{
+ border-style: solid;
+ border-color: darkgray;
+ border-width: 1px 0 1px 0;
+ position: relative;
+ width: 100%;
+ height: 70%;
+}
diff --git a/graphgraph-fe/src/app.js b/graphgraph-fe/src/app.js
new file mode 100644
index 0000000..30eb3d8
--- /dev/null
+++ b/graphgraph-fe/src/app.js
@@ -0,0 +1,152 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import './app.css';
+import Graph from './graph.js';
+import GraphSettingsMenu from './graph_settings_menu.js';
+import GraphInfoMenu from './graph_info_menu.js';
+import _ from 'underscore';
+import { nodeProperty, edgeProperty } from './requests.js';
+import * as constants from './constants.js';
+
+var emptyState = {
+ // currently selected schema
+ selectedSchema: '',
+ graph: {
+ // names of nodes
+ nodeNames: [],
+ // edges (each edge has source, target, type and a list of key value properties for tooltip)
+ edges: [],
+ // all paths between start node and end node
+ paths: []
+ },
+ // properties of currently thing (edge or node)
+ displayedProperties: [],
+ // possible states:
+ // CLICKED - the currently selected node
+ // PATH - currently displayed path
+ nodeStates: {},
+ // array index to paths i.e. which path from paths is currently displayed
+ pathIndex: 0,
+ // defines currently selected edge like a js object - {source: "pserver", target: "vserver"}
+ selectedEdge: { source: 'none', target: 'none' }
+};
+
+class App extends React.Component {
+ constructor (props, context) {
+ super(props, context);
+ this.graphdata = this.graphdata.bind(this);
+ this.changePaths = this.changePaths.bind(this);
+ this.loadNodeProperties = this.loadNodeProperties.bind(this);
+ this.loadEdgeProperties = this.loadEdgeProperties.bind(this);
+ this.computeNodeStatesFromPath = this.computeNodeStatesFromPath.bind(this);
+ this.computeNodeStates = this.computeNodeStates.bind(this);
+ this.state = emptyState;
+ }
+
+ loadNodeProperties (nodeName) {
+ var s = this.state;
+ fetch(nodeProperty(s.selectedSchema, nodeName))
+ .then(response => response.json())
+ .then(p => {
+ s['displayedProperties'] = p;
+ s['nodeStates'] = this.computeNodeStates(s['pathIndex']);
+ // select node
+ s['nodeStates'][nodeName] = constants.CLICKED;
+ // unselect edge
+ s['selectedEdge']['source'] = '';
+ s['selectedEdge']['target'] = '';
+ this.setState(s);
+ });
+ }
+
+ loadEdgeProperties (source, target) {
+ var s = this.state;
+ fetch(edgeProperty(s.selectedSchema, source, target))
+ .then(response => response.json())
+ .then(p => {
+ s['displayedProperties'] = p;
+ // select edge
+ s['selectedEdge']['source'] = source;
+ s['selectedEdge']['target'] = target;
+ // unselect node
+ s['nodeStates'] = this.computeNodeStates(s['pathIndex']);
+ this.setState(s);
+ });
+ }
+
+ graphdata (data, selectedGraphSchema, graphFingerprint) {
+ var s = this.state;
+ s['selectedSchema'] = selectedGraphSchema;
+ s['graphFingerprint'] = graphFingerprint;
+ s['graph'] = data;
+ // TODO this should be handled more gracefully ...
+ if (_.isEmpty(data.edges)) {
+ alert('The graph has no edges, nothing to display');
+ }
+ s['displayedProperties'] = data.startNodeProperties;
+ if (_.isArray(data.paths) && !_.isEmpty(data.paths)) {
+ s['paths'] = data.paths;
+ s['nodeStates'] = this.computeNodeStatesFromPath(data.paths[0]);
+ s['pathIndex'] = 0;
+ } else {
+ s['paths'] = [];
+ s['nodeStates'] = {};
+ }
+ this.setState(s);
+ return data;
+ }
+
+ computeNodeStatesFromPath (path) {
+ return _.reduce(path, (acc, node) => {
+ acc[node.id] = constants.PATH;
+ return acc;
+ }, {});
+ }
+
+ computeNodeStates (pathIndex) {
+ return this.computeNodeStatesFromPath(this.state.paths[pathIndex]);
+ }
+
+ changePaths (pathIndex, selectedNode) {
+ var s = this.state;
+ s['pathIndex'] = pathIndex;
+ this.setState(s);
+ this.loadNodeProperties(selectedNode);
+ }
+
+ render () {
+ let n = _.invert(this.state.nodeStates)[constants.CLICKED];
+
+ let selectedNode = _.isUndefined(n) ? '' : n;
+ return (
+ <div className="App">
+ <GraphSettingsMenu graphData={this.graphdata} nodePropsLoader={this.loadNodeProperties} selectedNode={selectedNode}/>
+ <div className='graph-area'>
+ <Graph graphFingerprint={this.state.graphFingerprint} edgePropsLoader={this.loadEdgeProperties} selectedEdge={this.state.selectedEdge} nodes={this.state.graph.nodeNames} edges={this.state.graph.edges} nodeStates={this.state.nodeStates} nodePropsLoader={this.loadNodeProperties}/>
+ </div>
+ <GraphInfoMenu pathCallback={this.changePaths} paths={ this.state.graph.paths } nodeProperties={ this.state.displayedProperties}/>
+ </div>
+ );
+ }
+}
+
+export default App;
diff --git a/graphgraph-fe/src/app.test.js b/graphgraph-fe/src/app.test.js
new file mode 100644
index 0000000..893bcbb
--- /dev/null
+++ b/graphgraph-fe/src/app.test.js
@@ -0,0 +1,29 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './app.js';
+
+it('renders without crashing', () => {
+ const div = document.createElement('div');
+ ReactDOM.render(<App/>, div);
+ ReactDOM.unmountComponentAtNode(div);
+});
diff --git a/graphgraph-fe/src/constants.js b/graphgraph-fe/src/constants.js
index 6076e6f..9181850 100644
--- a/graphgraph-fe/src/constants.js
+++ b/graphgraph-fe/src/constants.js
@@ -1,2 +1,22 @@
-export const CLICKED = 'clicked'
-export const PATH = 'on-path'
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+export const CLICKED = 'clicked';
+export const PATH = 'on-path';
diff --git a/graphgraph-fe/src/download_export.js b/graphgraph-fe/src/download_export.js
new file mode 100644
index 0000000..21b2829
--- /dev/null
+++ b/graphgraph-fe/src/download_export.js
@@ -0,0 +1,43 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import { Button } from 'react-bootstrap';
+import { exportSchema } from './requests.js';
+
+class DownloadExport extends React.Component {
+ constructor (props, context) {
+ super(props, context);
+ this.download = this.download.bind(this);
+ }
+
+ download() {
+ setTimeout(() => {
+ const response = { file: exportSchema(this.props.schemaVersion) };
+ window.open(response.file);
+ }, 100);
+ }
+
+ render() {
+ return <Button onClick={this.download}>Download as XMI</Button>;
+ }
+}
+
+export default DownloadExport;
diff --git a/graphgraph-fe/src/Graph.css b/graphgraph-fe/src/graph.css
index 1e5c7d8..0c9460f 100644
--- a/graphgraph-fe/src/Graph.css
+++ b/graphgraph-fe/src/graph.css
@@ -17,4 +17,3 @@
color: #fff;
border-radius: 2px;
}
-
diff --git a/graphgraph-fe/src/graph.js b/graphgraph-fe/src/graph.js
new file mode 100644
index 0000000..492959a
--- /dev/null
+++ b/graphgraph-fe/src/graph.js
@@ -0,0 +1,372 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import * as d3 from 'd3';
+import './graph.css';
+import _ from 'underscore';
+import * as constants from './constants.js';
+
+const CLICKED_COLOR = 'blue';
+const PATH_COLOR = 'red';
+const EDGE_MOUSE_OVER_COLOR = 'yellow';
+const EDGE_NORMAL_COLOR = '#ccc';
+const EDGE_LABEL_COLOR = 'black';
+const NODE_NORMAL_COLOR = '#E3E3E3';
+const NODE_LABEL_COLOR = 'black';
+const NODE_MOUSE_OVER_COLOR = '#F6F6F6';
+const NODE_BORDER_COLOR = 'lightgray';
+
+// variable holds state in order to determine if graph should be redrawn completely
+// it breaks the react concept, so a better approach is needed
+var graphFingerprint = '';
+
+var htmlfyProperties = function (properties) {
+ return "<div class='d3-tip'>" + (_.reduce(properties, (html, e) => {
+ return html + "<span style='color: lightgray'>" +
+ e.propertyName + ':</span> <span>' +
+ e.propertyValue + '</span><br/>';
+ }, '')) + '</div>';
+};
+
+var mouseOverEdge = function (edge, div) {
+ div.transition()
+ .duration(20)
+ .style('opacity', 0.9);
+ div.html(htmlfyProperties(edge.tooltipProperties))
+ .style('left', `${d3.event.pageX}px`)
+ .style('top', `${d3.event.pageY - 28}px`);
+};
+
+var mouseOutEdge = function (edge, div) {
+ div.transition()
+ .duration(6000)
+ .style('opacity', 0);
+};
+
+var addEdgePaths = function (links, g) {
+ d3.select('body').append('div')
+ .attr('class', 'tooltip')
+ .style('opacity', 0);
+ g.selectAll('.edgepath')
+ .data(links)
+ .enter()
+ .append('path')
+ .attr('d', d => `M ${d.source.x} ${d.source.y} L ${d.target.x} ${d.target.y}`)
+ .attr('class', 'edgepath')
+ .attr('fill-opacity', 0)
+ .attr('stroke-opacity', 0)
+ .attr('fill', EDGE_LABEL_COLOR)
+ .attr('id', (d, i) => `edgepath${i}`);
+};
+
+var chooseColor = function (state) {
+ if (state === constants.CLICKED) {
+ return CLICKED_COLOR;
+ }
+ if (state === constants.PATH) {
+ return PATH_COLOR;
+ }
+ return NODE_NORMAL_COLOR;
+};
+
+var redrawNodeColors = function (nodeStates, selectedEdge) {
+ d3.selectAll('svg').selectAll('g').selectAll('circle')
+ .style('fill', n => chooseColor(nodeStates[n.id]));
+ d3.selectAll('svg').selectAll('g').selectAll('line')
+ .style('stroke', EDGE_NORMAL_COLOR).attr('oldStroke', EDGE_NORMAL_COLOR);
+ d3.selectAll('svg').selectAll('g').selectAll('line')
+ .filter(edge => edge.source.id === selectedEdge.source && edge.target.id === selectedEdge.target)
+ .attr('oldStroke', CLICKED_COLOR)
+ .style('stroke', CLICKED_COLOR);
+};
+
+var addEdgeLabels = function (links, g, div) {
+ var edgelabels = g.selectAll('.edgelabel')
+ .data(links)
+ .enter()
+ .append('text')
+ .attr('class', 'edgelabel')
+ .attr('text-anchor', 'middle')
+ .attr('dx', 200)
+ .attr('dy', 0)
+ .attr('font-size', '22px')
+ .attr('id', (d, i) => `edgelabel${i}`);
+
+ edgelabels.append('textPath')
+ .attr('xlink:href', (d, i) => `#edgepath${i}`)
+ .text((d, i) => d.type);
+};
+
+var addNodeLabels = function (nodes, g) {
+ g.selectAll('.nodelabel')
+ .data(nodes)
+ .enter()
+ .append('text')
+ .attr('x', d => d.x - 14)
+ .attr('y', d => d.y - 17)
+ .attr('class', 'nodelabel')
+ .attr('fill', NODE_LABEL_COLOR)
+ .attr('font-size', '32px')
+ .text(d => d.id)
+ .on('mouseenter', onNodeLabelMouseOver)
+ .on('mouseout', onNodeLabelMouseOut);
+};
+
+var addLinks = function (links, g, div, edgePropsLoader) {
+ let ss = _.filter(links, l => l.source.id === l.target.id);
+
+ let selfLinks = _.isUndefined(ss) ? [] : ss;
+
+ g.selectAll('ellipse')
+ .data(selfLinks)
+ .enter().append('ellipse')
+ .attr('fill-opacity', 0)
+ .attr('rx', d => 100)
+ .attr('ry', d => 16)
+ .attr('cx', d => d.target.x + 80)
+ .attr('cy', d => d.target.y)
+ .style('stroke', NODE_BORDER_COLOR)
+ .attr('stroke-width', 5)
+ .on('click', edge => edgePropsLoader(edge.source.id, edge.target.id))
+ .on('mouseenter', function (edge) {
+ mouseOverEdge(edge, div);
+ d3.select(this)
+ .transition()
+ .attr('oldStroke', EDGE_NORMAL_COLOR)
+ .duration(10)
+ .style('stroke', EDGE_MOUSE_OVER_COLOR);
+ })
+ .on('mouseleave', function (edge) {
+ mouseOutEdge(edge, div);
+ var strokeColor = d3.select(this).attr('oldStroke');
+ d3.select(this)
+ .transition()
+ .duration(300)
+ .style('stroke', strokeColor);
+ });
+
+ g.selectAll('.edgelooplabel')
+ .data(selfLinks)
+ .enter()
+ .append('text')
+ .attr('x', d => d.source.x + 35)
+ .attr('y', d => d.source.y + 50)
+ .attr('class', 'edgelooplabel')
+ .attr('fill', NODE_LABEL_COLOR)
+ .attr('font-size', '22px')
+ .text(d => d.type);
+
+ g.selectAll('line')
+ .data(links)
+ .enter().append('line')
+ .attr('stroke-width', 5)
+ .attr('x1', d => d.source.x)
+ .attr('y1', d => d.source.y)
+ .attr('x2', d => d.target.x)
+ .attr('y2', d => d.target.y)
+ .attr('id', (d, i) => `edge${i}`)
+ .attr('marker-end', 'url(#arrowhead)')
+ .style('stroke', EDGE_NORMAL_COLOR)
+ .on('click', edge => edgePropsLoader(edge.source.id, edge.target.id))
+ .on('mouseenter', function (edge) {
+ mouseOverEdge(edge, div);
+ d3.select(this)
+ .transition()
+ .attr('oldStroke', EDGE_NORMAL_COLOR)
+ .duration(10)
+ .style('stroke', EDGE_MOUSE_OVER_COLOR);
+ })
+ .on('mouseleave', function (edge) {
+ mouseOutEdge(edge, div);
+ var strokeColor = d3.select(this).attr('oldStroke');
+ d3.select(this)
+ .transition()
+ .duration(300)
+ .style('stroke', strokeColor);
+ });
+};
+
+var addMarkers = function (g, svg) {
+ g.append('defs').append('marker')
+ .attr('id', 'arrowhead')
+ .attr('viewBox', '-0 -5 10 10')
+ .attr('refX', '20')
+ .attr('refY', '0')
+ .attr('orient', 'auto')
+ .attr('markerWidth', '4')
+ .attr('markerHeight', '4')
+ .attr('xoverflow', 'visible')
+ .append('svg:path')
+ .attr('d', 'M 0,-5 L 10 ,0 L 0,5')
+ .attr('fill', EDGE_NORMAL_COLOR)
+ .attr('stroke', EDGE_NORMAL_COLOR);
+
+ var zoomHandler = d3.zoom()
+ .on('zoom', _ => g.attr('transform', d3.event.transform));
+
+ zoomHandler(svg);
+ zoomHandler.translateTo(svg, -7000, -4000);
+ zoomHandler.scaleTo(svg, 0.08);
+};
+
+var drawGraph = function (nodes, links, g, simulation, svg, addNodes, edgePropsLoader) {
+ for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay()));
+ i < n; ++i) {
+ simulation.tick();
+ }
+
+ var div = d3.select('body').append('div')
+ .attr('class', 'tooltip')
+ .style('opacity', 0);
+
+ addLinks(links, g, div, edgePropsLoader);
+ addNodes(nodes, g);
+ addNodeLabels(nodes, g);
+ addEdgePaths(links, g);
+ addEdgeLabels(links, g, div);
+ addMarkers(g, svg);
+};
+
+var prepareLinks = function (nodes, links) {
+ var result = [];
+ links.forEach(e => {
+ var sourceNode = nodes.filter(n => n.id === e.source)[0];
+ var targetNode = nodes.filter(n => n.id === e.target)[0];
+
+ result.push({
+ source: sourceNode,
+ target: targetNode,
+ type: e.type,
+ tooltipProperties: e.tooltipProperties
+ });
+ });
+
+ return result;
+};
+
+var createSimulation = function (nodes, links) {
+ return d3.forceSimulation(nodes)
+ .force('charge', d3.forceManyBody().strength(-201))
+ .force('link', d3.forceLink(links).distance(1200).strength(1).iterations(400))
+ .force('collision', d3.forceCollide().radius(d => 310))
+ .force('x', d3.forceX())
+ .force('y', d3.forceY())
+ .stop();
+};
+
+var createSvg = function () {
+ var svg = d3.select('#graph').append('svg').attr('height', '100%').attr('width', '100%');
+ var g = svg.append('g');
+
+ return { 'g': g, 'svg': svg };
+};
+
+var onNodeLabelMouseOut = function () {
+ d3.select(this)
+ .transition()
+ .duration(600)
+ .attr('font-size', '32px');
+};
+
+var onNodeLabelMouseOver = function () {
+ d3.select(this)
+ .transition()
+ .duration(200)
+ .attr('font-size', '232px');
+};
+
+var onNodeMouseOver = function () {
+ var oldFill = d3.select(this).style('fill');
+ d3.select(this)
+ .transition()
+ .duration(200)
+ .attr('r', 31)
+ .attr('oldFill', oldFill)
+ .style('fill', NODE_MOUSE_OVER_COLOR);
+};
+
+var onNodeMouseOut = function (nodeStates) {
+ var oldFill = d3.select(this).attr('oldFill');
+ d3.select(this)
+ .transition()
+ .duration(300)
+ .attr('r', 23)
+ .style('fill', oldFill);
+};
+
+class Graph extends React.Component {
+ onNodeClick (x) {
+ // on mouse out the node will change color read from 'oldFill' attribute
+ d3.selectAll('svg').selectAll('g').selectAll('circle')
+ .filter(c => c.id === x.id)
+ .attr('oldFill', CLICKED_COLOR);
+ this.props.nodePropsLoader(x.id);
+ }
+
+ addNodes (nodes, g) {
+ g.selectAll('circle')
+ .data(nodes)
+ .enter().append('circle')
+ .attr('cx', d => d.x)
+ .attr('cy', d => d.y)
+ .style('fill', n => {
+ return chooseColor(this.props.nodeStates[n.id]);
+ })
+ .style('stroke', NODE_BORDER_COLOR)
+ .attr('stroke-width', 3)
+ .attr('r', 23)
+ .on('click', this.onNodeClick)
+ .on('mouseover', onNodeMouseOver)
+ .on('mouseout', onNodeMouseOut);
+ }
+
+ reCreateGraph () {
+ d3.select('#graph').selectAll('*').remove();
+
+ var nodes = this.props.nodes;
+ var links = prepareLinks(this.props.nodes, this.props.edges);
+ var o = createSvg();
+ var simulation = createSimulation(nodes, links);
+
+ drawGraph(nodes, links, o.g, simulation, o.svg, this.addNodes, this.props.edgePropsLoader);
+ }
+
+ constructor (props, context) {
+ super(props, context);
+
+ this.reCreateGraph = this.reCreateGraph.bind(this);
+ this.addNodes = this.addNodes.bind(this);
+ this.onNodeClick = this.onNodeClick.bind(this);
+ }
+
+ render () {
+ if (this.props.graphFingerprint !== graphFingerprint) {
+ this.reCreateGraph();
+ graphFingerprint = this.props.graphFingerprint;
+ } else {
+ redrawNodeColors(this.props.nodeStates, this.props.selectedEdge);
+ }
+
+ return <div id="graph"/>;
+ }
+}
+
+export default Graph;
diff --git a/graphgraph-fe/src/graph_hops.css b/graphgraph-fe/src/graph_hops.css
new file mode 100644
index 0000000..474b661
--- /dev/null
+++ b/graphgraph-fe/src/graph_hops.css
@@ -0,0 +1,8 @@
+.hops-input{
+ display: flex;
+ flex-direction: column;
+}
+
+.hops-input-field{
+ width: 190px;
+}
diff --git a/graphgraph-fe/src/graph_hops.js b/graphgraph-fe/src/graph_hops.js
new file mode 100644
index 0000000..da98db2
--- /dev/null
+++ b/graphgraph-fe/src/graph_hops.js
@@ -0,0 +1,79 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import { Label } from 'react-bootstrap';
+import NumericInput from 'react-numeric-input';
+import './graph_hops.css';
+
+var createNumInput = function (label, callback, current) {
+ return (
+ <div>
+ <Label>{label}</Label>
+ <NumericInput onChange={callback} min={1} max={500} value={current} className="hops-input-field"/>
+ </div>
+ );
+};
+
+class GraphHops extends React.Component {
+ constructor (props) {
+ super(props);
+
+ this.state = { value: this.props.defaultValue };
+ let p = props.parentHops;
+ let c = props.cousinHops;
+ let ch = props.childHops;
+
+ this.onChangeParent = (e) => this._onChangeParent(e);
+ this.onChangeCousin = (e) => this._onChangeCousin(e);
+ this.onChangeChild = (e) => this._onChangeChild(e);
+ this.onChange = (hopsName, num) => this._onChange(hopsName, num);
+ this.state = { parentHops: p, childHops: ch, cousinHops: c };
+ }
+
+ _onChange (hopsName, num) {
+ var s = this.state;
+ s[hopsName] = num;
+ this.setState(s);
+ this.props.updateHops(this.state.parentHops, this.state.cousinHops, this.state.childHops);
+ }
+
+ _onChangeParent (e) {
+ this.onChange('parentHops', e);
+ }
+
+ _onChangeCousin (e) {
+ this.onChange('cousinHops', e);
+ }
+
+ _onChangeChild (e) {
+ this.onChange('childHops', e);
+ }
+
+ render () {
+ if (this.props.edgeFilter === 'Edgerules') {
+ return <div className="hops-input">{createNumInput('edgerule hops', this.onChangeCousin, this.state.cousinHops)}</div>;
+ }
+
+ return <div className="hops-input">{createNumInput('parent hops', this.onChangeParent, this.state.parentHops)} {createNumInput('child hops', this.onChangeChild, this.state.childHops)}</div>;
+ }
+}
+
+export default GraphHops;
diff --git a/graphgraph-fe/src/GraphInfoMenu.css b/graphgraph-fe/src/graph_info_menu.css
index 24a2719..6182210 100644
--- a/graphgraph-fe/src/GraphInfoMenu.css
+++ b/graphgraph-fe/src/graph_info_menu.css
@@ -6,15 +6,15 @@
}
.pagination {
- margin: 0 12px 0 20px !important;
+ margin: 0 12px 0 20px !important;
}
.fixed-height-container {
overflow: scroll;
float:top;
height: 200px;
- width:40%;
- padding:3px;
+ width:40%;
+ padding:3px;
background:white;
}
@@ -70,4 +70,3 @@
margin-right: 0;
margin-left: 0;
}
-
diff --git a/graphgraph-fe/src/graph_info_menu.js b/graphgraph-fe/src/graph_info_menu.js
new file mode 100644
index 0000000..66ffbba
--- /dev/null
+++ b/graphgraph-fe/src/graph_info_menu.js
@@ -0,0 +1,81 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import './graph_info_menu.css';
+import PathBreadcrumb from './path_breadcrumb.js';
+import _ from 'underscore';
+import ReactTable from "react-table";
+import "react-table/react-table.css";
+
+class GraphInfoMenu extends React.Component {
+ render () {
+ var paths = this.props.paths;
+ var callback = this.props.pathCallback;
+ var showPaths = _.isArray(paths) && !_.isEmpty(paths);
+ var breadcrumbs = _.map(
+ paths, (path, i) => <PathBreadcrumb key={i} index={i} pathCallback={callback} path={path}/>);
+ return (
+ <div className="node-property-list">
+ <div className="fixed-height-container" style={{ display: showPaths ? 'block' : 'none' }}><p className='path-heading'>Paths</p>{breadcrumbs}</div>
+ <div className="kv-table datatable">
+ <ReactTable pageSizeOptions={[4, 25]} data={this.props.nodeProperties} columns={[
+ {
+ Header: "Attribute",
+ accessor: "propertyName",
+ minWidth: 40
+ },
+ {
+ Header: "Type",
+ accessor: "type",
+ minWidth: 70
+ },
+ {
+ Header: "Description",
+ accessor: "description",
+ minWidth: 260
+ },
+ {
+ id: "Key",
+ Header: "Key",
+ accessor: p => p.key ? "yes" : "",
+ minWidth: 20
+ },
+ {
+ id: "Index",
+ Header: "Index",
+ accessor: p => p.index ? "yes" : "",
+ minWidth: 20
+ },
+ {
+ id: "Required",
+ Header: "Required",
+ accessor: p => p.required ? "yes" : "",
+ minWidth: 20
+ }
+ ]} defaultPageSize={4} className="-striped -highlight"
+ />
+ </div>
+ </div>
+ );
+ }
+}
+
+export default GraphInfoMenu;
diff --git a/graphgraph-fe/src/GraphSettings.css b/graphgraph-fe/src/graph_settings.css
index 6fb4550..c30cda9 100644
--- a/graphgraph-fe/src/GraphSettings.css
+++ b/graphgraph-fe/src/graph_settings.css
@@ -29,7 +29,7 @@
}
-.modal-button
+.modal-button
{
padding-top: 20px;
margin: 0;
diff --git a/graphgraph-fe/src/graph_settings.js b/graphgraph-fe/src/graph_settings.js
new file mode 100644
index 0000000..c8f03f1
--- /dev/null
+++ b/graphgraph-fe/src/graph_settings.js
@@ -0,0 +1,256 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import _ from 'underscore';
+import { DropdownButton, MenuItem, Label } from 'react-bootstrap';
+import './graph_settings.css';
+import Popup from './popup_settings.js';
+import ValidationModal from './validation_modal.js';
+import DownloadExport from './download_export.js';
+import { validateSchema, pathGraph, basicGraph, schemas, nodeNames } from './requests.js';
+
+var emptyState = {
+ schemaProblems: [],
+ nodeNames: [],
+ fromNode: '',
+ graph: {
+ nodeNames: [],
+ edges: []
+ },
+ showHops: false,
+ enableDestinationNode: false,
+ toNode: '',
+ edgeFilter: 'Edgerules',
+ hops: {
+ parents: 1,
+ cousin: 1,
+ child: 1
+ },
+ selectedSchema: ''
+};
+
+class GraphSettings extends React.Component {
+ constructor (props, context) {
+ super(props, context);
+ this.onChangeStartNode = this.onChangeStartNode.bind(this);
+ this.onSelectNode = this.onSelectNode.bind(this);
+ this.selectSchema = this.selectSchema.bind(this);
+ this.onChangeToNode = this.onChangeToNode.bind(this);
+ this.loadInitialGraph = this.loadInitialGraph.bind(this);
+ this.updateHops = this.updateHops.bind(this);
+ this.changeEdgeFilter = this.changeEdgeFilter.bind(this);
+ this.graphFingerprint = this.graphFingerprint.bind(this);
+ this.state = emptyState;
+ }
+
+ /* this serves as a config 'fingerprint' to know if the d3 visualisation
+ should be redrawn from scratch or just updated */
+ graphFingerprint (schema, from, to, parents, cousin, child, edgeFilter) {
+ return `${schema}:${from}:${to}:${parents}:${cousin}:${child}:${edgeFilter}`;
+ }
+
+ loadInitialGraph (startNode, endNode, parentHops, cousinHops, childHops, edgeFilter) {
+ if (this.state.selectedSchema === '' || startNode === 'none') {
+ var s = this.state;
+ s['edgeFilter'] = edgeFilter;
+ this.setState(s);
+ return;
+ }
+ if (startNode === 'all') {
+ endNode = 'none';
+ }
+
+ let requestUri = endNode === 'none'
+ ? basicGraph(
+ this.state.selectedSchema, startNode, parentHops, cousinHops, childHops, edgeFilter)
+ : pathGraph(
+ this.state.selectedSchema, startNode, endNode, edgeFilter);
+
+ fetch(requestUri)
+ .then(response => response.json())
+ .then(g => {
+ let schema = this.state.selectedSchema;
+ let f = this.graphFingerprint(
+ schema, startNode, endNode, parentHops, cousinHops, childHops, edgeFilter);
+ this.props.graphData(g, this.state.selectedSchema, f);
+ return g;
+ })
+ .then(g => {
+ var s = this.state;
+ s['hops']['parents'] = parentHops;
+ s['hops']['cousin'] = cousinHops;
+ s['hops']['child'] = childHops;
+ s['fromNode'] = startNode;
+ s['toNode'] = endNode;
+ s['graph'] = g;
+ s['edgeFilter'] = edgeFilter;
+ s['showHops'] = endNode === 'none' && startNode !== 'none' && startNode !== 'all';
+ s['enableDestinationNode'] = startNode !== 'none' && startNode !== 'all';
+ this.setState(s);
+
+ if (startNode !== 'all') {
+ this.onSelectNode(startNode);
+ }
+ });
+ }
+
+ selectSchema (schema) {
+ var s = this.state;
+ s['selectedSchema'] = schema;
+ fetch(nodeNames(schema, s['edgeFilter']))
+ .then(response => response.json())
+ .then(nodeNames => {
+ s['fromNode'] = s['toNode'] = 'none';
+ s['nodeNames'] = nodeNames;
+ this.setState(s);
+ });
+ fetch(validateSchema(schema))
+ .then(response => response.json())
+ .then(p => {
+ s['schemaProblems'] = p.problems;
+ this.setState(s);
+ });
+ }
+
+ changeEdgeFilter (edgeFilter) {
+ fetch(nodeNames(this.state.selectedSchema, edgeFilter))
+ .then(response => response.json())
+ .then(nodeNames => {
+ let s = this.state;
+ s['edgeFilter'] = edgeFilter;
+ s['fromNode'] = s['toNode'] = 'none';
+ s['nodeNames'] = nodeNames;
+ this.setState(s);
+ });
+ this.loadInitialGraph(
+ this.state.fromNode,
+ this.state.toNode,
+ this.state.hops.parents,
+ this.state.hops.cousin,
+ this.state.hops.child,
+ edgeFilter
+ );
+ }
+
+ updateHops (parentHops, cousinHops, childHops) {
+ this.loadInitialGraph(
+ this.state.fromNode,
+ this.state.toNode,
+ parentHops,
+ cousinHops,
+ childHops,
+ this.state.edgeFilter
+ );
+ }
+
+ onChangeToNode (eventKey) {
+ this.loadInitialGraph(
+ this.state.fromNode,
+ eventKey,
+ this.state.hops.parents,
+ this.state.hops.cousin,
+ this.state.hops.child,
+ this.state.edgeFilter
+ );
+ }
+
+ onSelectNode (eventKey) {
+ this.props.nodePropsLoader(eventKey);
+ }
+
+ onChangeStartNode (eventKey) {
+ this.loadInitialGraph(
+ eventKey,
+ this.state.toNode,
+ this.state.hops.parents,
+ this.state.hops.cousin,
+ this.state.hops.child,
+ this.state.edgeFilter
+ );
+ }
+
+ componentDidMount () {
+ fetch(schemas())
+ .then(response => response.json())
+ .then(schemas => {
+ let s = this.state;
+ s['schemas'] = schemas;
+ this.setState(s);
+ });
+ }
+
+ render () {
+ var schemas = _.map(this.state.schemas, (x, k) => <MenuItem key={k} eventKey={x}>{x}</MenuItem>);
+
+ var items = _.map(this.state.nodeNames, (x, k) => <MenuItem key={k} eventKey={x.id}>{x.id}</MenuItem>);
+ let sortedNames = _.sortBy(this.state.graph.nodeNames, 'id');
+ var currentNodeNames = _.map(sortedNames, (x, k) => <MenuItem key={k} eventKey={x.id}>{x.id}</MenuItem>);
+
+ var fromItems = items.slice();
+ fromItems.unshift(<MenuItem key='divider' divider/>);
+ fromItems.unshift(<MenuItem key='all' eventKey='all'>all</MenuItem>);
+
+ items.unshift(<MenuItem key='anotherdivider' divider/>);
+ items.unshift(<MenuItem key='none' eventKey='none'>none</MenuItem>);
+
+ let edgeFilterItems = [
+ <MenuItem key='Edgerules' eventKey='Edgerules'>Edgerules</MenuItem>,
+ <MenuItem key='Parents' eventKey='Parents'>Parent-child (OXM structure)</MenuItem>,
+ ];
+ return (
+ <div>
+ <div className="graph-menu">
+ <div className="startendnode-dropdown">
+ <div>
+ <Label>Schemas</Label>
+ <DropdownButton className="schemas-dropdown" onSelect={this.selectSchema} id="schemas" title={this.state.selectedSchema}>{schemas}</DropdownButton>
+ </div>
+ <div className="source-dropdown-div">
+ <Label>Source Node</Label>
+ <DropdownButton className="node-dropdown" onSelect={this.onChangeStartNode} id="namesFrom" title={this.state.fromNode}>{fromItems}</DropdownButton>
+ </div>
+ <div>
+ <Label>Destination Node</Label>
+ <DropdownButton disabled={!this.state.enableDestinationNode} className="node-dropdown" onSelect={this.onChangeToNode} id="namesTo" title={this.state.toNode}>{items}</DropdownButton>
+ </div>
+ <div className="source-dropdown-div">
+ <Label>Edge filter</Label>
+ <DropdownButton className="node-dropdown" onSelect={this.changeEdgeFilter} id="filterEdge" title={this.state.edgeFilter}>{edgeFilterItems}</DropdownButton>
+ </div>
+ <div className="source-dropdown-div">
+ <Label>Selected Node</Label>
+ <DropdownButton className="node-dropdown" onSelect={this.onSelectNode} id="selectedNode" title={this.props.selectedNode}>{currentNodeNames}</DropdownButton>
+ </div>
+ <Popup isDisabled={!this.state.showHops} edgeFilter={this.state.edgeFilter} parentHops={this.state.hops.parents} childHops={this.state.hops.child} cousinHops={this.state.hops.cousin} updateHops={this.updateHops}/>
+ <div className="modal-button">
+ <ValidationModal schemaProblems={this.state.schemaProblems}/>
+ </div>
+ <div className="modal-button">
+ <DownloadExport schemaVersion={this.state.selectedSchema}/>
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
+
+export default GraphSettings;
diff --git a/graphgraph-fe/src/GraphSettingsMenu.css b/graphgraph-fe/src/graph_settings_menu.css
index 466d07d..718dfa0 100644
--- a/graphgraph-fe/src/GraphSettingsMenu.css
+++ b/graphgraph-fe/src/graph_settings_menu.css
@@ -1,12 +1,11 @@
-
.navbar.navbar-adjust{
-margin-bottom: 0px;
+ margin-bottom: 0px;
}
.navbar-adjust .container {
-margin-left: 0;
+ margin-left: 0;
}
.navbar-adjust .container .navbar-header {
-margin-right: 250px;
+ margin-right: 250px;
}
diff --git a/graphgraph-fe/src/graph_settings_menu.js b/graphgraph-fe/src/graph_settings_menu.js
new file mode 100644
index 0000000..05def48
--- /dev/null
+++ b/graphgraph-fe/src/graph_settings_menu.js
@@ -0,0 +1,45 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import GraphSettings from './graph_settings.js';
+import { Navbar, Nav } from 'react-bootstrap';
+import './graph_settings_menu.css';
+
+class GraphSettingsMenu extends React.Component {
+ render () {
+ return (
+ <Navbar className='navbar-adjust'>
+ <Navbar.Header>
+ <Navbar.Brand>
+ <a href="https://gerrit.onap.org/r/gitweb?p=aai/graphgraph.git">GraphGraph</a>
+ </Navbar.Brand>
+ </Navbar.Header>
+ <Nav className="mr-auto">
+ <Navbar.Collapse className='mr-sm-2'>
+ <GraphSettings selectedNode={this.props.selectedNode} graphData={this.props.graphData} nodePropsLoader={this.props.nodePropsLoader}/>
+ </Navbar.Collapse>
+ </Nav>
+ </Navbar>
+ );
+ }
+}
+
+export default GraphSettingsMenu;
diff --git a/graphgraph-fe/src/index.css b/graphgraph-fe/src/index.css
index cee5f34..cf5eae8 100644
--- a/graphgraph-fe/src/index.css
+++ b/graphgraph-fe/src/index.css
@@ -1,14 +1,14 @@
body {
- margin: 0;
- padding: 0;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
- "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
- sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ margin: 0;
+ padding: 0;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
+ "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
- monospace;
+ font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
+ monospace;
}
diff --git a/graphgraph-fe/src/index.js b/graphgraph-fe/src/index.js
index bdd3da2..4269967 100644
--- a/graphgraph-fe/src/index.js
+++ b/graphgraph-fe/src/index.js
@@ -1,13 +1,33 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
-import './index.css'
-import App from './App'
-import * as serviceWorker from './serviceWorker'
-import 'bootstrap-css-only/css/bootstrap.css'
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
-ReactDOM.render(<App />, document.getElementById('root'))
+import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import App from './app.js';
+import * as serviceWorker from './service_worker.js';
+import 'bootstrap-css-only/css/bootstrap.css';
+
+ReactDOM.render(<App/>, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
-serviceWorker.unregister()
+serviceWorker.unregister();
diff --git a/graphgraph-fe/src/path_breadcrumb.js b/graphgraph-fe/src/path_breadcrumb.js
new file mode 100644
index 0000000..6ed9d16
--- /dev/null
+++ b/graphgraph-fe/src/path_breadcrumb.js
@@ -0,0 +1,46 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import _ from 'underscore';
+import React from 'react';
+import { Breadcrumb } from 'react-bootstrap';
+
+class PathBreadcrumb extends React.Component {
+ constructor (props, context) {
+ super(props, context);
+ this.pathSelected = this.pathSelected.bind(this);
+ }
+
+ pathSelected (evt) {
+ evt.preventDefault();
+ // the data is only piggyback riding on the "target" property .. not nice but works
+ this.props.pathCallback(this.props.index, evt.target.getAttribute('target'));
+ }
+
+ render () {
+ var path = this.props.path;
+ var callback = this.pathSelected;
+ var items = _.map(path, (item, i) => <Breadcrumb.Item key={i} target={item.id} onClick={callback}> {item.id} </Breadcrumb.Item>);
+
+ return <Breadcrumb>{items}</Breadcrumb>;
+ }
+}
+
+export default PathBreadcrumb;
diff --git a/graphgraph-fe/src/PopupSettings.css b/graphgraph-fe/src/popup_settings.css
index f80e264..2a548af 100644
--- a/graphgraph-fe/src/PopupSettings.css
+++ b/graphgraph-fe/src/popup_settings.css
@@ -13,4 +13,3 @@
text-decoration: none;
font-size: 25px;
}
-
diff --git a/graphgraph-fe/src/popup_settings.js b/graphgraph-fe/src/popup_settings.js
new file mode 100644
index 0000000..2430ab2
--- /dev/null
+++ b/graphgraph-fe/src/popup_settings.js
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import React from 'react';
+import Popup from 'reactjs-popup';
+import './popup_settings.css';
+import GraphHops from './graph_hops.js';
+
+class PopupMenu extends React.Component {
+ render () {
+ return (
+ <Popup trigger={<button className='settings-button' disabled={this.props.isDisabled}>Hops</button>} position="bottom right">
+ {close => (
+ <div>
+ <GraphHops edgeFilter={this.props.edgeFilter} parentHops={this.props.parentHops} childHops={this.props.childHops} cousinHops={this.props.cousinHops} updateHops={this.props.updateHops}/>
+ <button type="button" className="link-button, close" onClick={close}>&times;</button>
+ </div>
+ )}</Popup>
+ );
+ }
+}
+
+export default PopupMenu;
diff --git a/graphgraph-fe/src/requests.js b/graphgraph-fe/src/requests.js
index 8a86e0c..ae41f78 100644
--- a/graphgraph-fe/src/requests.js
+++ b/graphgraph-fe/src/requests.js
@@ -1,35 +1,55 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
const host = window.location.hostname;
const port = window.location.port;
const protocol = window.location.protocol;
export function schemas () {
- return `${protocol}//${host}:${port}/schemas`
-}
+ return `${protocol}//${host}:${port}/schemas`;
+};
export function validateSchema (schema) {
- return `${protocol}//${host}:${port}/schemas/${schema}/validation`
-}
+ return `${protocol}//${host}:${port}/schemas/${schema}/validation`;
+};
export function exportSchema (schema) {
- return `${protocol}//${host}:${port}/schemas/${schema}/xmiexport`
-}
+ return `${protocol}//${host}:${port}/schemas/${schema}/xmiexport`;
+};
export function nodeNames (schema, edgeFilter) {
- return `${protocol}//${host}:${port}/schemas/${schema}/nodes?edgeFilter=${edgeFilter}`
-}
+ return `${protocol}//${host}:${port}/schemas/${schema}/nodes?edgeFilter=${edgeFilter}`;
+};
export function basicGraph (schema, node, parentHops, cousinHops, childHops, edgeFilter) {
- return `${protocol}//${host}:${port}/schemas/${schema}/graph/basic?node=${node}&parentHops=${parentHops}&cousinHops=${cousinHops}&childHops=${childHops}&edgeFilter=${edgeFilter}`
-}
+ return `${protocol}//${host}:${port}/schemas/${schema}/graph/basic?node=${node}&parentHops=${parentHops}&cousinHops=${cousinHops}&childHops=${childHops}&edgeFilter=${edgeFilter}`;
+};
export function pathGraph (schema, fromNode, toNode, edgeFilter) {
- return `${protocol}//${host}:${port}/schemas/${schema}/graph/paths?fromNode=${fromNode}&toNode=${toNode}&edgeFilter=${edgeFilter}`
-}
+ return `${protocol}//${host}:${port}/schemas/${schema}/graph/paths?fromNode=${fromNode}&toNode=${toNode}&edgeFilter=${edgeFilter}`;
+};
export function nodeProperty (schema, node) {
- return `${protocol}//${host}:${port}/schemas/${schema}/nodes/${node}`
-}
+ return `${protocol}//${host}:${port}/schemas/${schema}/nodes/${node}`;
+};
export function edgeProperty (schema, fromNode, toNode) {
- return `${protocol}//${host}:${port}/schemas/${schema}/edges?fromNode=${fromNode}&toNode=${toNode}`
-}
+ return `${protocol}//${host}:${port}/schemas/${schema}/edges?fromNode=${fromNode}&toNode=${toNode}`;
+};
diff --git a/graphgraph-fe/src/serviceWorker.js b/graphgraph-fe/src/serviceWorker.js
deleted file mode 100644
index 5c6ead6..0000000
--- a/graphgraph-fe/src/serviceWorker.js
+++ /dev/null
@@ -1,135 +0,0 @@
-// This optional code is used to register a service worker.
-// register() is not called by default.
-
-// This lets the app load faster on subsequent visits in production, and gives
-// it offline capabilities. However, it also means that developers (and users)
-// will only see deployed updates on subsequent visits to a page, after all the
-// existing tabs open on the page have been closed, since previously cached
-// resources are updated in the background.
-
-// To learn more about the benefits of this model and instructions on how to
-// opt-in, read http://bit.ly/CRA-PWA
-
-const isLocalhost = Boolean(
- window.location.hostname === 'localhost' ||
- // [::1] is the IPv6 localhost address.
- window.location.hostname === '[::1]' ||
- // 127.0.0.1/8 is considered localhost for IPv4.
- window.location.hostname.match(
- /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
- )
-)
-
-export function register (config) {
- if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
- // The URL constructor is available in all browsers that support SW.
- const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href)
- if (publicUrl.origin !== window.location.origin) {
- // Our service worker won't work if PUBLIC_URL is on a different origin
- // from what our page is served on. This might happen if a CDN is used to
- // serve assets; see https://github.com/facebook/create-react-app/issues/2374
- return
- }
-
- window.addEventListener('load', () => {
- const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
-
- if (isLocalhost) {
- // This is running on localhost. Let's check if a service worker still exists or not.
- checkValidServiceWorker(swUrl, config)
-
- // Add some additional logging to localhost, pointing developers to the
- // service worker/PWA documentation.
- navigator.serviceWorker.ready.then(() => {
- console.log(
- 'This web app is being served cache-first by a service ' +
- 'worker. To learn more, visit http://bit.ly/CRA-PWA'
- )
- })
- } else {
- // Is not localhost. Just register service worker
- registerValidSW(swUrl, config)
- }
- })
- }
-}
-
-function registerValidSW (swUrl, config) {
- navigator.serviceWorker
- .register(swUrl)
- .then(registration => {
- registration.onupdatefound = () => {
- const installingWorker = registration.installing
- if (installingWorker == null) {
- return
- }
- installingWorker.onstatechange = () => {
- if (installingWorker.state === 'installed') {
- if (navigator.serviceWorker.controller) {
- // At this point, the updated precached content has been fetched,
- // but the previous service worker will still serve the older
- // content until all client tabs are closed.
- console.log(
- 'New content is available and will be used when all ' +
- 'tabs for this page are closed. See http://bit.ly/CRA-PWA.'
- )
-
- // Execute callback
- if (config && config.onUpdate) {
- config.onUpdate(registration)
- }
- } else {
- // At this point, everything has been precached.
- // It's the perfect time to display a
- // "Content is cached for offline use." message.
- console.log('Content is cached for offline use.')
-
- // Execute callback
- if (config && config.onSuccess) {
- config.onSuccess(registration)
- }
- }
- }
- }
- }
- })
- .catch(error => {
- console.error('Error during service worker registration:', error)
- })
-}
-
-function checkValidServiceWorker (swUrl, config) {
- // Check if the service worker can be found. If it can't reload the page.
- fetch(swUrl)
- .then(response => {
- // Ensure service worker exists, and that we really are getting a JS file.
- const contentType = response.headers.get('content-type')
- if (
- response.status === 404 ||
- (contentType != null && contentType.indexOf('javascript') === -1)
- ) {
- // No service worker found. Probably a different app. Reload the page.
- navigator.serviceWorker.ready.then(registration => {
- registration.unregister().then(() => {
- window.location.reload()
- })
- })
- } else {
- // Service worker found. Proceed as normal.
- registerValidSW(swUrl, config)
- }
- })
- .catch(() => {
- console.log(
- 'No internet connection found. App is running in offline mode.'
- )
- })
-}
-
-export function unregister () {
- if ('serviceWorker' in navigator) {
- navigator.serviceWorker.ready.then(registration => {
- registration.unregister()
- })
- }
-}
diff --git a/graphgraph-fe/src/service_worker.js b/graphgraph-fe/src/service_worker.js
new file mode 100644
index 0000000..0ac740b
--- /dev/null
+++ b/graphgraph-fe/src/service_worker.js
@@ -0,0 +1,146 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+// This optional code is used to register a service worker.
+// register() is not called by default.
+
+// This lets the app load faster on subsequent visits in production, and gives
+// it offline capabilities. However, it also means that developers (and users)
+// will only see deployed updates on subsequent visits to a page, after all the
+// existing tabs open on the page have been closed, since previously cached
+// resources are updated in the background.
+
+// To learn more about the benefits of this model and instructions on how to
+// opt-in, read http://bit.ly/CRA-PWA
+
+const isLocalhost = Boolean(
+ window.location.hostname === 'localhost' ||
+ // [::1] is the IPv6 localhost address.
+ window.location.hostname === '[::1]' ||
+ // 127.0.0.1/8 is considered localhost for IPv4.
+ window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
+);
+
+export function register (config) {
+ if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
+ // The URL constructor is available in all browsers that support SW.
+ const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
+ if (publicUrl.origin !== window.location.origin) {
+ // Our service worker won't work if PUBLIC_URL is on a different origin
+ // from what our page is served on. This might happen if a CDN is used to
+ // serve assets; see https://github.com/facebook/create-react-app/issues/2374
+ return;
+ }
+
+ window.addEventListener('load', () => {
+ const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
+
+ if (isLocalhost) {
+ // This is running on localhost. Let's check if a service worker still exists or not.
+ checkValidServiceWorker(swUrl, config);
+
+ // Add some additional logging to localhost, pointing developers to the
+ // service worker/PWA documentation.
+ navigator.serviceWorker.ready.then(() => {
+ console.log(
+ 'This web app is being served cache-first by a service ' +
+ 'worker. To learn more, visit http://bit.ly/CRA-PWA'
+ );
+ });
+ } else {
+ // Is not localhost. Just register service worker
+ registerValidSW(swUrl, config);
+ }
+ });
+ }
+}
+
+function registerValidSW (swUrl, config) {
+ navigator.serviceWorker
+ .register(swUrl)
+ .then(registration => {
+ registration.onupdatefound = () => {
+ const installingWorker = registration.installing;
+ if (installingWorker == null) {
+ return;
+ }
+ installingWorker.onstatechange = () => {
+ if (installingWorker.state === 'installed') {
+ if (navigator.serviceWorker.controller) {
+ // At this point, the updated precached content has been fetched,
+ // but the previous service worker will still serve the older
+ // content until all client tabs are closed.
+ console.log('New content is available and will be used when all ' +
+ 'tabs for this page are closed. See http://bit.ly/CRA-PWA.');
+
+ // Execute callback
+ if (config && config.onUpdate) {
+ config.onUpdate(registration);
+ }
+ } else {
+ // At this point, everything has been precached.
+ // It's the perfect time to display a
+ // "Content is cached for offline use." message.
+ console.log('Content is cached for offline use.');
+
+ // Execute callback
+ if (config && config.onSuccess) {
+ config.onSuccess(registration);
+ }
+ }
+ }
+ };
+ };
+ })
+ .catch(error => {
+ console.error('Error during service worker registration:', error);
+ });
+}
+
+function checkValidServiceWorker (swUrl, config) {
+ // Check if the service worker can be found. If it can't reload the page.
+ fetch(swUrl)
+ .then(response => {
+ // Ensure service worker exists, and that we really are getting a JS file.
+ const contentType = response.headers.get('content-type');
+ if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) {
+ // No service worker found. Probably a different app. Reload the page.
+ navigator.serviceWorker.ready.then(registration => {
+ registration.unregister().then(() => {
+ window.location.reload();
+ });
+ });
+ } else {
+ // Service worker found. Proceed as normal.
+ registerValidSW(swUrl, config);
+ }
+ })
+ .catch(() => {
+ console.log('No internet connection found. App is running in offline mode.');
+ });
+}
+
+export function unregister () {
+ if ('serviceWorker' in navigator) {
+ navigator.serviceWorker.ready.then(registration => {
+ registration.unregister();
+ });
+ }
+};
diff --git a/graphgraph-fe/src/ValidationModal.css b/graphgraph-fe/src/validation_modal.css
index 56b4567..4fe12a9 100644
--- a/graphgraph-fe/src/ValidationModal.css
+++ b/graphgraph-fe/src/validation_modal.css
@@ -1,7 +1,7 @@
.modal-content
{
-height: 100%;
-width: 100%;
+ height: 100%;
+ width: 100%;
}
.modal-validator
@@ -16,9 +16,9 @@ width: 100%;
backgroundColor: 'white';
boxShadow: '0 5px 15px rgba(0,0,0,.5)';
padding: 0;
-}
+}
-.modal-backdrop
+.modal-backdrop
{
position: 'fixed';
zIndex: 1040;
diff --git a/graphgraph-fe/src/validation_modal.js b/graphgraph-fe/src/validation_modal.js
new file mode 100644
index 0000000..1944c36
--- /dev/null
+++ b/graphgraph-fe/src/validation_modal.js
@@ -0,0 +1,58 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import _ from 'underscore';
+import React from 'react';
+import './validation_modal.css';
+import { Button, Modal, ListGroup, ListGroupItem } from 'react-bootstrap';
+
+class ValidationModal extends React.Component {
+ constructor(...args) {
+ super(...args);
+ this.state = { showModal: false };
+ this.close = () => {
+ this.setState({ showModal: false });
+ };
+ this.open = () => {
+ this.setState({ showModal: true });
+ };
+ }
+
+ renderBackdrop(props) {
+ return <div {...props} className="modal-backdrop"/>;
+ }
+
+ render() {
+ var problems = this.props.schemaProblems;
+ var items = _.map(problems, (problem, i) => <ListGroupItem key={i}>{problem}</ListGroupItem>);
+ return (
+ <div>
+ <Button onClick={this.open}>Validate schema</Button>
+ <Modal onHide={this.close} className="modal-validator" aria-labelledby="modal-label" show={this.state.showModal} renderBackdrop={this.renderBackdrop}>
+ <div className="modal-list">
+ <ListGroup>{items}</ListGroup>
+ </div>
+ </Modal>
+ </div>
+ );
+ }
+}
+
+export default ValidationModal;
diff --git a/pom.xml b/pom.xml
index 4c0e5cf..798a3d2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -46,9 +46,9 @@
</dependencyManagement>
<dependencies>
<dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
-</dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@@ -186,82 +186,82 @@
</includes>
</resource>
</resources>
- <plugins>
- <plugin>
- <groupId>com.github.eirslett</groupId>
- <artifactId>frontend-maven-plugin</artifactId>
- <version>1.7.6</version>
- <executions>
- <execution>
- <id>install node</id>
- <goals>
- <goal>install-node-and-npm</goal>
- </goals>
- <phase>generate-resources</phase>
- <configuration>
- <workingDirectory>${project.basedir}/graphgraph-fe</workingDirectory>
- <nodeVersion>v10.10.0</nodeVersion>
- </configuration>
- </execution>
- <execution>
- <id>npm install</id>
- <goals>
- <goal>npm</goal>
- </goals>
- <phase>generate-resources</phase>
- <configuration>
- <workingDirectory>${project.basedir}/graphgraph-fe</workingDirectory>
- <arguments>install</arguments>
- </configuration>
- </execution>
- <execution>
- <id>npm build</id>
- <goals>
- <goal>npm</goal>
- </goals>
- <phase>generate-resources</phase>
- <configuration>
- <workingDirectory>${project.basedir}/graphgraph-fe</workingDirectory>
- <arguments>run build</arguments>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-resources-plugin</artifactId>
- <version>3.1.0</version>
- <executions>
- <execution>
- <id>copy-resources-ui</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.build.directory}/classes/public</outputDirectory>
- <resources>
- <resource>
- <directory>${project.basedir}/graphgraph-fe/build</directory>
- <filtering>false</filtering>
- </resource>
- </resources>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <version>2.1.2.RELEASE</version>
- <executions>
- <execution>
- <goals>
- <goal>repackage</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
+ <plugins>
+ <plugin>
+ <groupId>com.github.eirslett</groupId>
+ <artifactId>frontend-maven-plugin</artifactId>
+ <version>1.7.6</version>
+ <executions>
+ <execution>
+ <id>install node</id>
+ <goals>
+ <goal>install-node-and-npm</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <workingDirectory>${project.basedir}/graphgraph-fe</workingDirectory>
+ <nodeVersion>v10.10.0</nodeVersion>
+ </configuration>
+ </execution>
+ <execution>
+ <id>npm install</id>
+ <goals>
+ <goal>npm</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <workingDirectory>${project.basedir}/graphgraph-fe</workingDirectory>
+ <arguments>install</arguments>
+ </configuration>
+ </execution>
+ <execution>
+ <id>npm build</id>
+ <goals>
+ <goal>npm</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <workingDirectory>${project.basedir}/graphgraph-fe</workingDirectory>
+ <arguments>run build</arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.1.0</version>
+ <executions>
+ <execution>
+ <id>copy-resources-ui</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/classes/public</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/graphgraph-fe/build</directory>
+ <filtering>false</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>2.1.2.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
</build>
<!-- Start of ONAP Specific Repositories -->
<repositories>
diff --git a/run.sh b/run.sh
index 7a53739..4cfe34b 100755
--- a/run.sh
+++ b/run.sh
@@ -1,5 +1,5 @@
-#!/bin/sh
-cd ./graphgraph-fe/
+#!/bin/sh
+cd ./graphgraph-fe/
npm run build
cd ..
-mvn clean spring-boot:run
+mvn clean spring-boot:run
diff --git a/src/main/java/org/onap/aai/graphgraph/App.java b/src/main/java/org/onap/aai/graphgraph/App.java
index ed1bb9a..1c6bc61 100644
--- a/src/main/java/org/onap/aai/graphgraph/App.java
+++ b/src/main/java/org/onap/aai/graphgraph/App.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph;
@@ -40,32 +40,35 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
-public class App{
+public class App {
+
public static EdgeIngestor edgeIngestor;
public static Map<String, MoxyLoader> moxyLoaders = new HashMap<>();
// TODO
// this should be used properly within Spring as this is a 'static' workaround due
// to some initialization issues. By all means feel free to improve and move it to Spring
- public static void loadSchemes(ConfigurableApplicationContext context){
+ public static void loadSchemes(ConfigurableApplicationContext context) {
String version;
for (int i = 10; i < 19; i++) {
version = "v" + i;
- moxyLoaders.put(version, new MoxyLoader(new SchemaVersion(version), (NodeIngestor) context.getBean("nodeIngestor")) );
+ moxyLoaders.put(version, new MoxyLoader(
+ new SchemaVersion(version), (NodeIngestor) context.getBean("nodeIngestor"))
+ );
}
}
- public static void main( String[] args ) throws IOException {
+ public static void main(String[] args) throws IOException {
ArgumentParser parser = new ArgumentParser().parseArguments(args);
- if (parser.isPrintHelp()){
+ if (parser.isPrintHelp()) {
parser.printHelp();
return;
}
- SpringApplication app = new SpringApplication(App.class);
+ SpringApplication app = new SpringApplication(App.class);
- if (parser.isRunLocally()){
+ if (parser.isRunLocally()) {
copyKeystore(app);
}
@@ -74,7 +77,7 @@ public class App{
loadSchemes(context);
edgeIngestor = (EdgeIngestor) context.getBean("edgeIngestor");
- if (parser.shoudGenerateUml()){
+ if (parser.shouldGenerateUrl()) {
writeExportedModel(exportModel(parser.getSchemaVersion()));
System.exit(0);
}
@@ -83,9 +86,10 @@ public class App{
private static void copyKeystore(SpringApplication app) throws IOException {
Path path = Paths.get("etc/auth/aai_keystore");
if (Files.notExists(path)) {
- FileUtils.copyInputStreamToFile(Objects
- .requireNonNull(app.getClassLoader().getResourceAsStream("etc/auth/aai_keystore")),
- path.toFile());
+ FileUtils.copyInputStreamToFile(
+ Objects.requireNonNull(app.getClassLoader().getResourceAsStream("etc/auth/aai_keystore")),
+ path.toFile()
+ );
}
}
}
diff --git a/src/main/java/org/onap/aai/graphgraph/ArgumentParser.java b/src/main/java/org/onap/aai/graphgraph/ArgumentParser.java
index 4405723..e156e39 100644
--- a/src/main/java/org/onap/aai/graphgraph/ArgumentParser.java
+++ b/src/main/java/org/onap/aai/graphgraph/ArgumentParser.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph;
@@ -24,51 +24,50 @@ import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
public class ArgumentParser {
- @Option(name = "-g", usage = "generates schema model for Papyrus and exits where XY is the version", metaVar = "vXY")
- private String schemaVersion;
-
- @Option(name = "-d", usage = "connect to dev version of schema-service (use JAR bundled keystore)")
- private boolean runLocally;
- @Option(name = "-h", usage = "print help and exit")
- private boolean printHelp;
+ CmdLineParser parser;
+ @Option(name = "-g", usage = "generates schema model for Papyrus and exits where XY is the version",
+ metaVar = "vXY")
+ private String schemaVersion;
+ @Option(name = "-d", usage = "connect to dev version of schema-service (use JAR bundled keystore)")
+ private boolean runLocally;
+ @Option(name = "-h", usage = "print help and exit")
+ private boolean printHelp;
- CmdLineParser parser;
+ public ArgumentParser parseArguments(String[] args) {
+ parser = new CmdLineParser(this);
- public ArgumentParser parseArguments(String [] args){
- parser = new CmdLineParser(this);
+ try {
+ parser.parseArgument(args);
+ } catch (CmdLineException e) {
+ System.err.println(e.getMessage());
+ parser.printUsage(System.err);
+ }
- try {
- parser.parseArgument(args);
- } catch( CmdLineException e ) {
- System.err.println(e.getMessage());
- parser.printUsage(System.err);
+ return this;
}
- return this;
- }
-
- public String getSchemaVersion() {
- return schemaVersion;
- }
+ public String getSchemaVersion() {
+ return schemaVersion;
+ }
- public void setSchemaVersion(String schemaVersion) {
- this.schemaVersion = schemaVersion;
- }
+ public void setSchemaVersion(String schemaVersion) {
+ this.schemaVersion = schemaVersion;
+ }
- public boolean shoudGenerateUml(){
- return schemaVersion != null;
- }
+ public boolean shouldGenerateUrl() {
+ return schemaVersion != null;
+ }
- public boolean isRunLocally() {
- return runLocally;
- }
+ public boolean isRunLocally() {
+ return runLocally;
+ }
- public boolean isPrintHelp() {
- return printHelp;
- }
+ public boolean isPrintHelp() {
+ return printHelp;
+ }
- public void printHelp(){
- parser.printUsage(System.out);
- }
+ public void printHelp() {
+ parser.printUsage(System.out);
+ }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/Config.java b/src/main/java/org/onap/aai/graphgraph/Config.java
index 1d4152b..bbc082f 100644
--- a/src/main/java/org/onap/aai/graphgraph/Config.java
+++ b/src/main/java/org/onap/aai/graphgraph/Config.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph;
@@ -31,9 +31,9 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {
- "org.onap.aai.config",
- "org.onap.aai.setup",
- "org.onap.aai.graphgraph"
+ "org.onap.aai.config",
+ "org.onap.aai.setup",
+ "org.onap.aai.graphgraph"
})
public class Config {
@@ -41,7 +41,7 @@ public class Config {
String schemaVersions;
@Bean
- SchemaRepository createSchemaRepository(){
+ SchemaRepository createSchemaRepository() {
List<SchemaReader> readers = new LinkedList<>();
for (String s : schemaVersions.split(",")) {
readers.add(new BasicSchemaReader(s));
@@ -50,4 +50,3 @@ public class Config {
}
}
-
diff --git a/src/main/java/org/onap/aai/graphgraph/CorsFilter.java b/src/main/java/org/onap/aai/graphgraph/CorsFilter.java
index 448a2ea..ab97255 100644
--- a/src/main/java/org/onap/aai/graphgraph/CorsFilter.java
+++ b/src/main/java/org/onap/aai/graphgraph/CorsFilter.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph;
@@ -30,15 +30,17 @@ import org.springframework.web.filter.OncePerRequestFilter;
@Component
public class CorsFilter extends OncePerRequestFilter {
- @Override
- protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
- final FilterChain filterChain) throws ServletException, IOException {
- response.addHeader("Access-Control-Allow-Origin", "*");
- response.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, HEAD");
- response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
- response.addHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Credentials");
- response.addHeader("Access-Control-Allow-Credentials", "true");
- response.addIntHeader("Access-Control-Max-Age", 10);
- filterChain.doFilter(request, response);
- }
-} \ No newline at end of file
+ @Override
+ protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
+ final FilterChain filterChain) throws ServletException, IOException {
+ response.addHeader("Access-Control-Allow-Origin", "*");
+ response.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, HEAD");
+ response.addHeader("Access-Control-Allow-Headers",
+ "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
+ response.addHeader("Access-Control-Expose-Headers",
+ "Access-Control-Allow-Origin, Access-Control-Allow-Credentials");
+ response.addHeader("Access-Control-Allow-Credentials", "true");
+ response.addIntHeader("Access-Control-Max-Age", 10);
+ filterChain.doFilter(request, response);
+ }
+}
diff --git a/src/main/java/org/onap/aai/graphgraph/ModelExporter.java b/src/main/java/org/onap/aai/graphgraph/ModelExporter.java
index 36070db..047bd92 100644
--- a/src/main/java/org/onap/aai/graphgraph/ModelExporter.java
+++ b/src/main/java/org/onap/aai/graphgraph/ModelExporter.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph;
@@ -54,214 +54,221 @@ import org.onap.aai.setup.SchemaVersion;
public class ModelExporter {
- private static final String AAIMODEL_UML_FILENAME = "aaimodel.uml";
- private static final String VELOCITY_TEMPLATE_FILENAME = "model_export.vm";
- private static final boolean OXM_ENABLED = false;
- private static final String camelCaseRegex = "(?=[A-Z][a-z])";
- private static Map<String, Introspector> allEntities;
- private static Multimap<String, EdgeRule> getEdgeRules(String schemaVersion) {
- try {
- Multimap<String, EdgeRule> allRules = App.edgeIngestor.getAllRules(new SchemaVersion(schemaVersion));
- allEntities = App.moxyLoaders.get(schemaVersion).getAllObjects();
- if (OXM_ENABLED) {
- addOxmRelationships(allRules, allEntities);
- }
- return allRules;
- } catch (EdgeRuleNotFoundException e) {
- e.printStackTrace();
- }
-
- return null;
- }
+ private static final String AAIMODEL_UML_FILENAME = "aaimodel.uml";
+ private static final String VELOCITY_TEMPLATE_FILENAME = "model_export.vm";
+ private static final boolean OXM_ENABLED = false;
+ private static final String camelCaseRegex = "(?=[A-Z][a-z])";
+ private static Map<String, Introspector> allEntities;
- private static void addOxmRelationships(Multimap<String, EdgeRule> allRules,
- Map<String, Introspector> allEntities) {
- for (Entry<String, Introspector> currentParent : allEntities.entrySet()) {
- currentParent.getValue().getProperties().stream()
- .filter(v -> allEntities.containsKey(v))
- .filter(v -> !currentParent.getKey().equals(v))
- .forEach(v -> {
- String key = currentParent.getKey() + "|" + v;
- if (!allRules.containsKey(key)) {
- allRules.put(key, createEdgeRule(currentParent.getKey(), v));
+ private static Multimap<String, EdgeRule> getEdgeRules(String schemaVersion) {
+ try {
+ Multimap<String, EdgeRule> allRules = App.edgeIngestor.getAllRules(new SchemaVersion(schemaVersion));
+ allEntities = App.moxyLoaders.get(schemaVersion).getAllObjects();
+ if (OXM_ENABLED) {
+ addOxmRelationships(allRules, allEntities);
}
- });
+ return allRules;
+ } catch (EdgeRuleNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ return null;
}
- }
- private static EdgeRule createEdgeRule(String parent, String child) {
- Map<String, String> edgeRuleProps = new HashMap<>();
- edgeRuleProps.put(EdgeField.FROM.toString(), child);
- edgeRuleProps.put(EdgeField.TO.toString(), parent);
- edgeRuleProps.put(EdgeField.DIRECTION.toString(), Direction.OUT.toString()); //TODO check direction
- edgeRuleProps.put(EdgeField.LABEL.toString(), "OXM Parent-Child");
- edgeRuleProps.put(EdgeField.MULTIPLICITY.toString(), MultiplicityRule.MANY2ONE.toString());
- edgeRuleProps.put(EdgeField.DEFAULT.toString(), Boolean.toString(false));
- edgeRuleProps.put(EdgeField.PRIVATE.toString(), Boolean.toString(false));
- edgeRuleProps.put(EdgeField.DELETE_OTHER_V.toString(), DirectionNotation.DIRECTION.toString());
- edgeRuleProps.put(EdgeField.PREVENT_DELETE.toString(), DirectionNotation.DIRECTION.toString());
- edgeRuleProps.put(EdgeField.CONTAINS.toString(), DirectionNotation.DIRECTION.toString());
- edgeRuleProps.put(EdgeField.DESCRIPTION.toString(), "fake edgerule representing parent-child");
- return new EdgeRule(edgeRuleProps);
- }
+ private static void addOxmRelationships(
+ Multimap<String, EdgeRule> allRules,
+ Map<String, Introspector> allEntities) {
+ for (Entry<String, Introspector> currentParent : allEntities.entrySet()) {
+ currentParent.getValue().getProperties().stream()
+ .filter(v -> allEntities.containsKey(v))
+ .filter(v -> !currentParent.getKey().equals(v))
+ .forEach(v -> {
+ String key = currentParent.getKey() + "|" + v;
+ if (!allRules.containsKey(key)) {
+ allRules.put(key, createEdgeRule(currentParent.getKey(), v));
+ }
+ });
+ }
+ }
- static String exportModel(String schemaVersion) {
- Map<String, Introspector> allObjects = App.moxyLoaders.get(schemaVersion).getAllObjects();
- Template t = initVelocity();
- VelocityContext context = populateVelocityContext(schemaVersion, allObjects);
- StringWriter writer = new StringWriter();
- t.merge( context, writer );
- return writer.toString();
- }
+ private static EdgeRule createEdgeRule(String parent, String child) {
+ Map<String, String> edgeRuleProps = new HashMap<>();
+ edgeRuleProps.put(EdgeField.FROM.toString(), child);
+ edgeRuleProps.put(EdgeField.TO.toString(), parent);
+ edgeRuleProps.put(EdgeField.DIRECTION.toString(), Direction.OUT.toString()); //TODO check direction
+ edgeRuleProps.put(EdgeField.LABEL.toString(), "OXM Parent-Child");
+ edgeRuleProps.put(EdgeField.MULTIPLICITY.toString(), MultiplicityRule.MANY2ONE.toString());
+ edgeRuleProps.put(EdgeField.DEFAULT.toString(), Boolean.toString(false));
+ edgeRuleProps.put(EdgeField.PRIVATE.toString(), Boolean.toString(false));
+ edgeRuleProps.put(EdgeField.DELETE_OTHER_V.toString(), DirectionNotation.DIRECTION.toString());
+ edgeRuleProps.put(EdgeField.PREVENT_DELETE.toString(), DirectionNotation.DIRECTION.toString());
+ edgeRuleProps.put(EdgeField.CONTAINS.toString(), DirectionNotation.DIRECTION.toString());
+ edgeRuleProps.put(EdgeField.DESCRIPTION.toString(), "fake edgerule representing parent-child");
+ return new EdgeRule(edgeRuleProps);
+ }
- static void writeExportedModel(String result) {
- try {
- FileWriter fw = new FileWriter(AAIMODEL_UML_FILENAME);
- fw.write(result);
- fw.close();
- } catch (IOException e) {
- e.printStackTrace();
+ static String exportModel(String schemaVersion) {
+ Map<String, Introspector> allObjects = App.moxyLoaders.get(schemaVersion).getAllObjects();
+ Template t = initVelocity();
+ VelocityContext context = populateVelocityContext(schemaVersion, allObjects);
+ StringWriter writer = new StringWriter();
+ t.merge(context, writer);
+ return writer.toString();
}
- }
- private static VelocityContext populateVelocityContext(String schemaVersion,
- Map<String, Introspector> allObjects) {
- VelocityContext context = new VelocityContext();
- Multimap<String, EdgeRule> edgeRules = getEdgeRules(schemaVersion);
- Set<VelocityEntity> entityList = createEntityList(edgeRules);
- Set<VelocityAssociation> associationsList = createVelocityAssociations(entityList, edgeRules);
- updateEntities(entityList, associationsList, allObjects);
- context.put("entityList", entityList);
- context.put("associationList", associationsList);
- return context;
- }
+ static void writeExportedModel(String result) {
+ try {
+ FileWriter fw = new FileWriter(AAIMODEL_UML_FILENAME);
+ fw.write(result);
+ fw.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
- private static Template initVelocity() {
- VelocityEngine ve = new VelocityEngine();
- ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
- ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
- ve.init();
- return ve.getTemplate(VELOCITY_TEMPLATE_FILENAME);
- }
+ private static VelocityContext populateVelocityContext(
+ String schemaVersion,
+ Map<String, Introspector> allObjects) {
+ VelocityContext context = new VelocityContext();
+ Multimap<String, EdgeRule> edgeRules = getEdgeRules(schemaVersion);
+ Set<VelocityEntity> entityList = createEntityList(edgeRules);
+ Set<VelocityAssociation> associationsList = createVelocityAssociations(entityList, edgeRules);
+ updateEntities(entityList, associationsList, allObjects);
+ context.put("entityList", entityList);
+ context.put("associationList", associationsList);
+ return context;
+ }
- private static void updateEntities(Set<VelocityEntity> entityList,
- Set<VelocityAssociation> associationsList,
- Map<String, Introspector> allObjects) {
- entityList.forEach(e -> {
- List<VelocityAssociation> associations = associationsList.stream()
- .filter(a -> a.getFromEntityId().equals(e.getId())).collect(
- Collectors.toList());
- updateNeighbour(entityList, associations);
- String description = allEntities.get(e.getName()).getMetadata(ObjectMetadata.DESCRIPTION);
- e.setDescription(StringUtil.isBlank(description) ? "no description is available" : description);
- });
+ private static Template initVelocity() {
+ VelocityEngine ve = new VelocityEngine();
+ ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
+ ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
+ ve.init();
+ return ve.getTemplate(VELOCITY_TEMPLATE_FILENAME);
+ }
- entityList.forEach(entity -> entity.setProperties(getPropertiesForEntity(allObjects.get(entity.getName()), entityList)));
+ private static void updateEntities(
+ Set<VelocityEntity> entityList,
+ Set<VelocityAssociation> associationsList,
+ Map<String, Introspector> allObjects) {
+ entityList.forEach(e -> {
+ List<VelocityAssociation> associations = associationsList.stream()
+ .filter(a -> a.getFromEntityId().equals(e.getId())).collect(
+ Collectors.toList());
+ updateNeighbour(entityList, associations);
+ String description = allEntities.get(e.getName()).getMetadata(ObjectMetadata.DESCRIPTION);
+ e.setDescription(StringUtil.isBlank(description) ? "no description is available" : description);
+ });
- }
+ entityList.forEach(
+ entity -> entity.setProperties(getPropertiesForEntity(allObjects.get(entity.getName()), entityList)));
- private static void updateNeighbour(
- Set<VelocityEntity> entityList, List<VelocityAssociation> associations) {
- associations.forEach(ass -> {
- VelocityEntity velocityEntity = entityList.stream()
- .filter(e -> e.getId().equals(ass.getToEntityId())).findFirst().get();
- velocityEntity.addNeighbours(ass);
- });
- }
+ }
- private static Set<VelocityEntityProperty> getPropertiesForEntity(Introspector introspector,
- Set<VelocityEntity> entityList) {
- return introspector.getProperties().stream()
- .map(p -> new VelocityEntityProperty(
- p,
- introspector.getType(p),
- findVelocityEntity(introspector.getType(p), entityList)))
- .collect(
- Collectors.toSet());
- }
+ private static void updateNeighbour(
+ Set<VelocityEntity> entityList, List<VelocityAssociation> associations) {
+ associations.forEach(ass -> {
+ VelocityEntity velocityEntity = entityList.stream()
+ .filter(e -> e.getId().equals(ass.getToEntityId())).findFirst().get();
+ velocityEntity.addNeighbours(ass);
+ });
+ }
- private static Set<VelocityEntity> createEntityList(
- Multimap<String, EdgeRule> edgeRules) {
- return Objects.requireNonNull(edgeRules).values().stream()
- .flatMap(er -> Stream.of(er.getFrom(), er.getTo()))
- .map(VelocityEntity::new)
- .collect(Collectors.toSet());
- }
+ private static Set<VelocityEntityProperty> getPropertiesForEntity(
+ Introspector introspector,
+ Set<VelocityEntity> entityList) {
+ return introspector.getProperties().stream()
+ .map(p -> new VelocityEntityProperty(
+ p,
+ introspector.getType(p),
+ findVelocityEntity(introspector.getType(p), entityList)))
+ .collect(
+ Collectors.toSet());
+ }
- private static Set<VelocityAssociation> createVelocityAssociations(Set<VelocityEntity> entities,
- Multimap<String, EdgeRule> edgeRules) {
- return edgeRules.values().stream().flatMap(er -> {
- VelocityAssociation out = createVelocityAssociation(entities, er.getFrom(), er.getTo(),
- er.getLabel(), er.getMultiplicityRule().name(), er.getContains());
- VelocityAssociation in = createVelocityAssociation(entities, er.getTo(), er.getFrom(),
- er.getLabel(), er.getMultiplicityRule().name(), er.getContains());
- switch (er.getDirection()) {
- case OUT:
- return Stream.of(out);
- case IN:
- return Stream.of(in);
- case BOTH:
- return Stream.of(out, in);
- default:
- return null;
- }
- }).collect(Collectors.toSet());
- }
+ private static Set<VelocityEntity> createEntityList(
+ Multimap<String, EdgeRule> edgeRules) {
+ return Objects.requireNonNull(edgeRules).values().stream()
+ .flatMap(er -> Stream.of(er.getFrom(), er.getTo()))
+ .map(VelocityEntity::new)
+ .collect(Collectors.toSet());
+ }
- private static VelocityAssociation createVelocityAssociation(Set<VelocityEntity> entities,
- String from, String to, String label, String multiplicity, String contains) {
- VelocityEntity fromEntity = entities.stream().filter(ent -> ent.getName().equals(from))
- .findFirst().get();
- VelocityEntity toEntity = entities.stream().filter(ent -> ent.getName().equals(to)).findFirst()
- .get();
- switch (contains) {
- case "IN":
- return new VelocityAssociation(
- fromEntity,
- toEntity,
- String.format("%s - %s (%s)", from, to, shortenLabel(label)),
- multiplicity,
- true);
- case "OUT":
- return new VelocityAssociation(
- toEntity,
- fromEntity,
- String.format("%s - %s (%s)", to, from, shortenLabel(label)),
- multiplicity.equals("ONE2MANY") ? "MANY2ONE" : multiplicity,
- true);
- default:
- return new VelocityAssociation(
- fromEntity,
- toEntity,
- String.format("%s - %s (%s)", from, to, shortenLabel(label)),
- multiplicity,
- false);
+ private static Set<VelocityAssociation> createVelocityAssociations(
+ Set<VelocityEntity> entities,
+ Multimap<String, EdgeRule> edgeRules) {
+ return edgeRules.values().stream().flatMap(er -> {
+ VelocityAssociation out = createVelocityAssociation(entities, er.getFrom(), er.getTo(),
+ er.getLabel(), er.getMultiplicityRule().name(), er.getContains());
+ VelocityAssociation in = createVelocityAssociation(entities, er.getTo(), er.getFrom(),
+ er.getLabel(), er.getMultiplicityRule().name(), er.getContains());
+ switch (er.getDirection()) {
+ case OUT:
+ return Stream.of(out);
+ case IN:
+ return Stream.of(in);
+ case BOTH:
+ return Stream.of(out, in);
+ default:
+ return null;
+ }
+ }).collect(Collectors.toSet());
}
- }
- private static String shortenLabel(String label) {
- if (label.contains(".")) {
- String[] split = label.split("\\.");
- return split[split.length - 1];
+ private static VelocityAssociation createVelocityAssociation(
+ Set<VelocityEntity> entities, String from, String to, String label, String multiplicity, String contains) {
+ VelocityEntity fromEntity = entities.stream()
+ .filter(ent -> ent.getName().equals(from)).findFirst().get();
+ VelocityEntity toEntity = entities.stream()
+ .filter(ent -> ent.getName().equals(to)).findFirst().get();
+ switch (contains) {
+ case "IN":
+ return new VelocityAssociation(
+ fromEntity,
+ toEntity,
+ String.format("%s - %s (%s)", from, to, shortenLabel(label)),
+ multiplicity,
+ true);
+ case "OUT":
+ return new VelocityAssociation(
+ toEntity,
+ fromEntity,
+ String.format("%s - %s (%s)", to, from, shortenLabel(label)),
+ multiplicity.equals("ONE2MANY") ? "MANY2ONE" : multiplicity,
+ true);
+ default:
+ return new VelocityAssociation(
+ fromEntity,
+ toEntity,
+ String.format("%s - %s (%s)", from, to, shortenLabel(label)),
+ multiplicity,
+ false);
+ }
}
- return label;
- }
+ private static String shortenLabel(String label) {
+ if (label.contains(".")) {
+ String[] split = label.split("\\.");
+ return split[split.length - 1];
+ }
- private static VelocityEntity findVelocityEntity(String entityName, Set<VelocityEntity> entities) {
- if (entityName.startsWith("java.lang")){
- return null;
+ return label;
}
- if ( ! entityName.startsWith("inventory.aai.onap.org")){
- return null;
- }
+ private static VelocityEntity findVelocityEntity(String entityName, Set<VelocityEntity> entities) {
+ if (entityName.startsWith("java.lang")) {
+ return null;
+ }
- String[] split = entityName.split("\\.");
- String entityNameRoot = split[split.length - 1];
- final Pattern pattern = Pattern.compile(camelCaseRegex);
- final Matcher matcher = pattern.matcher(entityNameRoot.substring(1, entityNameRoot.length()));
- String finalEntityNameRoot = (entityNameRoot.charAt(0) + matcher.replaceAll("-")).toLowerCase();
- return entities.stream().filter(e -> e.getName().equals(finalEntityNameRoot)).findFirst().orElse(null);
- }
-} \ No newline at end of file
+ if (!entityName.startsWith("inventory.aai.onap.org")) {
+ return null;
+ }
+
+ String[] split = entityName.split("\\.");
+ String entityNameRoot = split[split.length - 1];
+ final Pattern pattern = Pattern.compile(camelCaseRegex);
+ final Matcher matcher = pattern.matcher(entityNameRoot.substring(1));
+ String finalEntityNameRoot = (entityNameRoot.charAt(0) + matcher.replaceAll("-")).toLowerCase();
+ return entities.stream().filter(e -> e.getName().equals(finalEntityNameRoot)).findFirst().orElse(null);
+ }
+}
diff --git a/src/main/java/org/onap/aai/graphgraph/SchemaResource.java b/src/main/java/org/onap/aai/graphgraph/SchemaResource.java
index b38ef7b..577e235 100644
--- a/src/main/java/org/onap/aai/graphgraph/SchemaResource.java
+++ b/src/main/java/org/onap/aai/graphgraph/SchemaResource.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph;
@@ -43,67 +43,66 @@ public class SchemaResource {
SchemaRepository repository;
@RequestMapping("/schemas")
- public List<String> loadSchemaNames() {
+ public List<String> loadSchemaNames() {
return repository.getAllSchemaNames();
}
-
@RequestMapping("/schemas/{schema}/nodes")
- public List<NodeName> loadVertexNames(@PathVariable("schema") String schemaName,
- @RequestParam("edgeFilter") String edgeFilter) {
+ public List<NodeName> loadVertexNames(
+ @PathVariable("schema") String schemaName,
+ @RequestParam("edgeFilter") String edgeFilter) {
return repository.getSchemaReader(schemaName).getAllVertexNames(edgeFilter);
}
@RequestMapping("/schemas/{schema}/nodes/{node}")
- public List<NodeProperty> loadProperties(@PathVariable("schema") String schemaName, @PathVariable("node") String node) {
+ public List<NodeProperty> loadProperties(
+ @PathVariable("schema") String schemaName,
+ @PathVariable("node") String node) {
return repository.getSchemaReader(schemaName).getVertexProperties(node);
}
-
@RequestMapping("/schemas/{schema}/edges")
- public List<Property> loadedgeProperties (
+ public List<Property> loadEdgeProperties(
@PathVariable("schema") String schemaName,
@RequestParam("fromNode") String fromNodeName,
@RequestParam("toNode") String toNodeName) {
return repository.getSchemaReader(schemaName).getEdgeProperties(fromNodeName, toNodeName, "edgerule");
}
-
@RequestMapping("/schemas/{schema}/graph/basic")
- public Graph loadGraph (
+ public Graph loadGraph(
@PathVariable("schema") String schemaName,
@RequestParam("node") String initialNodeName,
@RequestParam("parentHops") Integer parentHops,
@RequestParam("cousinHops") Integer cousinHops,
@RequestParam("childHops") Integer childHops,
- @RequestParam("edgeFilter") String edgeFilter)
- {
- Graph graph = repository.getSchemaReader(schemaName).getGraph(initialNodeName, parentHops, cousinHops, childHops, edgeFilter);
- graph.setPaths(Collections.emptyList());
- return graph;
+ @RequestParam("edgeFilter") String edgeFilter) {
+ Graph graph = repository.getSchemaReader(schemaName)
+ .getGraph(initialNodeName, parentHops, cousinHops, childHops, edgeFilter);
+ graph.setPaths(Collections.emptyList());
+ return graph;
}
-
@RequestMapping("/schemas/{schema}/graph/paths")
- public Graph loadGraphWithPaths (
+ public Graph loadGraphWithPaths(
@PathVariable("schema") String schemaName,
@RequestParam("fromNode") String fromNode,
@RequestParam("toNode") String toNode,
- @RequestParam("edgeFilter") String edgeFilter)
- {
+ @RequestParam("edgeFilter") String edgeFilter) {
return repository.getSchemaReader(schemaName).getGraph(fromNode, toNode, edgeFilter);
}
@RequestMapping("/schemas/{schema}/validation")
- public ValidationProblems validateSchema ( @PathVariable("schema") String schemaName) {
+ public ValidationProblems validateSchema(
+ @PathVariable("schema") String schemaName) {
return new SchemaValidator().validate(schemaName);
}
@RequestMapping(value = "/schemas/{schema}/xmiexport", produces = MediaType.TEXT_XML_VALUE)
@ResponseBody
- public String exportSchema ( @PathVariable("schema") String schemaName) {
+ public String exportSchema(
+ @PathVariable("schema") String schemaName) {
return ModelExporter.exportModel(schemaName);
}
}
-
diff --git a/src/main/java/org/onap/aai/graphgraph/SchemaValidator.java b/src/main/java/org/onap/aai/graphgraph/SchemaValidator.java
index aa260aa..076c31e 100644
--- a/src/main/java/org/onap/aai/graphgraph/SchemaValidator.java
+++ b/src/main/java/org/onap/aai/graphgraph/SchemaValidator.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph;
@@ -32,70 +32,74 @@ import org.onap.aai.graphgraph.dto.ValidationProblems;
import org.onap.aai.graphgraph.reader.BasicSchemaReader;
public class SchemaValidator {
- private Graph edgerules;
- private Graph oxm;
- public ValidationProblems validate(String schemaVersion) {
- ValidationProblems validationProblems = new ValidationProblems();
- BasicSchemaReader schema = new BasicSchemaReader(schemaVersion);
- oxm = schema.getGraph("all", 0, 0, 0, "Parents");
- edgerules = schema.getGraph("all", 0, 0, 0, "Edgerules");
- checkIfDanglingEdgerules(validationProblems);
- checkIfObsoleteOxm(validationProblems);
- schema.getSchemaErrors().forEach(validationProblems::addProblem);
- return validationProblems;
- }
+ private Graph edgerules;
+ private Graph oxm;
+
+ public ValidationProblems validate(String schemaVersion) {
+ ValidationProblems validationProblems = new ValidationProblems();
+ BasicSchemaReader schema = new BasicSchemaReader(schemaVersion);
+ oxm = schema.getGraph("all", 0, 0, 0, "Parents");
+ edgerules = schema.getGraph("all", 0, 0, 0, "Edgerules");
+
+ checkIfDanglingEdgerules(validationProblems);
+ checkIfObsoleteOxm(validationProblems);
+ schema.getSchemaErrors().forEach(validationProblems::addProblem);
+ return validationProblems;
+ }
- /**
- * computes nodes connected to relationship-list but not used in edgerules
- * @param validationProblems
- */
- private void checkIfObsoleteOxm(ValidationProblems validationProblems) {
- Set<String> relationshipListConnected = getAllNodesConnectedToRelationshipList();
- Set<String> nodesInEdgerules = getEdgerulePairs().stream().flatMap(p -> Stream.of(p._1, p._2))
- .collect(Collectors.toSet());
- relationshipListConnected.removeAll(nodesInEdgerules);
- relationshipListConnected.forEach(n ->
- validationProblems.addProblem(String.format("%s is associated with relationship-list in OXM but not present in edgerules", n)));
- }
+ /**
+ * computes nodes connected to relationship-list but not used in edgerules
+ * @param validationProblems
+ */
+ private void checkIfObsoleteOxm(ValidationProblems validationProblems) {
+ Set<String> relationshipListConnected = getAllNodesConnectedToRelationshipList();
+ Set<String> nodesInEdgerules = getEdgerulePairs().stream()
+ .flatMap(p -> Stream.of(p._1, p._2))
+ .collect(Collectors.toSet());
+ relationshipListConnected.removeAll(nodesInEdgerules);
+ relationshipListConnected.forEach(n -> validationProblems.addProblem(
+ String.format("%s is associated with relationship-list in OXM but not present in edgerules",
+ n)));
+ }
- private Set<Tuple2<String, String>> getEdgerulePairs() {
- return edgerules.getEdges().stream()
- .map(e -> Tuple.of(e.getSource(), e.getTarget())).collect(
- Collectors.toSet());
- }
+ private Set<Tuple2<String, String>> getEdgerulePairs() {
+ return edgerules.getEdges().stream()
+ .map(e -> Tuple.of(e.getSource(), e.getTarget()))
+ .collect(Collectors.toSet());
+ }
- /**
- * computes edgerules which don't have the necessary connection to relationship-list in OXM
- * @param validationProblems
- */
- private void checkIfDanglingEdgerules(
- ValidationProblems validationProblems) {
- Set<Tuple2<String, String>> edgerulePairs = getEdgerulePairs();
- edgerulePairs.removeAll(getOxmPairs());
- edgerulePairs.forEach( erp ->
- validationProblems.addProblem(String.format("%s and %s are associated in edgerules but not in OXM (via relationship-list)", erp._1, erp._2)));
- }
+ /**
+ * computes edgerules which don't have the necessary connection to relationship-list in OXM
+ * @param validationProblems
+ */
+ private void checkIfDanglingEdgerules(ValidationProblems validationProblems) {
+ Set<Tuple2<String, String>> edgerulePairs = getEdgerulePairs();
+ edgerulePairs.removeAll(getOxmPairs());
+ edgerulePairs.forEach(erp -> validationProblems.addProblem(
+ String.format("%s and %s are associated in edgerules but not in OXM (via relationship-list)",
+ erp._1, erp._2)));
+ }
- private Set<Tuple2<String, String>> getOxmPairs() {
- Set<Tuple2<String, String>> pairs = new HashSet<>();
- Set<String> inRelationshipList = getAllNodesConnectedToRelationshipList();
+ private Set<Tuple2<String, String>> getOxmPairs() {
+ Set<Tuple2<String, String>> pairs = new HashSet<>();
+ Set<String> inRelationshipList = getAllNodesConnectedToRelationshipList();
- inRelationshipList.forEach(edge1 ->
- inRelationshipList.forEach(edge2 -> {
- pairs.add(Tuple.of(edge1, edge2));
- }));
- return pairs;
- }
+ inRelationshipList.forEach(edge1 -> inRelationshipList
+ .forEach(edge2 -> pairs.add(Tuple.of(edge1, edge2))));
+ return pairs;
+ }
- private Set<String> getAllNodesConnectedToRelationshipList() {
- List<Edge> edges = oxm.getEdges();
- Set<String> inRelationshipList = edges.stream().filter(e -> e.getSource().equals("relationship-list")).map(
- Edge::getTarget).collect(
- Collectors.toSet());
- inRelationshipList.addAll(edges.stream().filter(e -> e.getTarget().equals("relationship-list"))
- .map(Edge::getSource).collect(
- Collectors.toSet()));
- return inRelationshipList;
- }
+ private Set<String> getAllNodesConnectedToRelationshipList() {
+ List<Edge> edges = oxm.getEdges();
+ Set<String> inRelationshipList = edges.stream()
+ .filter(e -> e.getSource().equals("relationship-list"))
+ .map(Edge::getTarget)
+ .collect(Collectors.toSet());
+ inRelationshipList.addAll(edges.stream()
+ .filter(e -> e.getTarget().equals("relationship-list"))
+ .map(Edge::getSource)
+ .collect(Collectors.toSet()));
+ return inRelationshipList;
+ }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/dto/Edge.java b/src/main/java/org/onap/aai/graphgraph/dto/Edge.java
index 5154e5b..c3ba8df 100644
--- a/src/main/java/org/onap/aai/graphgraph/dto/Edge.java
+++ b/src/main/java/org/onap/aai/graphgraph/dto/Edge.java
@@ -1,26 +1,25 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.dto;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
public class Edge {
@@ -49,14 +48,14 @@ public class Edge {
return source;
}
- public List<NodeName> getNodeNames() {
- return Arrays.asList(new NodeName(source), new NodeName(target));
- }
-
public void setSource(String source) {
this.source = source;
}
+ public List<NodeName> getNodeNames() {
+ return Arrays.asList(new NodeName(source), new NodeName(target));
+ }
+
public String getTarget() {
return target;
}
diff --git a/src/main/java/org/onap/aai/graphgraph/dto/Graph.java b/src/main/java/org/onap/aai/graphgraph/dto/Graph.java
index 83e5977..7d5f957 100644
--- a/src/main/java/org/onap/aai/graphgraph/dto/Graph.java
+++ b/src/main/java/org/onap/aai/graphgraph/dto/Graph.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.dto;
@@ -23,12 +23,15 @@ import java.util.Collections;
import java.util.List;
public class Graph {
+
private List<NodeName> nodeNames;
private List<Edge> edges;
private List<List<NodeName>> paths;
private List<NodeProperty> startNodeProperties;
- public Graph(List<NodeName> nodeNames, List<Edge> edges, List<List<NodeName>> pathsList, List<NodeProperty> startNodeProperties) {
+ public Graph(
+ List<NodeName> nodeNames, List<Edge> edges,
+ List<List<NodeName>> pathsList, List<NodeProperty> startNodeProperties) {
this.nodeNames = nodeNames;
this.edges = edges;
this.paths = pathsList;
@@ -36,8 +39,8 @@ public class Graph {
}
public static Graph emptyGraph() {
- return new Graph(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(),
- Collections.emptyList());
+ return new Graph(
+ Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
}
public List<NodeProperty> getStartNodeProperties() {
diff --git a/src/main/java/org/onap/aai/graphgraph/dto/NodeName.java b/src/main/java/org/onap/aai/graphgraph/dto/NodeName.java
index 992609c..013f1aa 100644
--- a/src/main/java/org/onap/aai/graphgraph/dto/NodeName.java
+++ b/src/main/java/org/onap/aai/graphgraph/dto/NodeName.java
@@ -1,25 +1,26 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.dto;
public class NodeName {
+
private String id;
public NodeName(String name) {
@@ -56,8 +57,6 @@ public class NodeName {
@Override
public String toString() {
- return "NodeName{" +
- "id='" + id + '\'' +
- '}';
+ return "NodeName{" + "id='" + id + '\'' + '}';
}
}
diff --git a/src/main/java/org/onap/aai/graphgraph/dto/NodeProperty.java b/src/main/java/org/onap/aai/graphgraph/dto/NodeProperty.java
index 93b04cf..0daa9f4 100644
--- a/src/main/java/org/onap/aai/graphgraph/dto/NodeProperty.java
+++ b/src/main/java/org/onap/aai/graphgraph/dto/NodeProperty.java
@@ -1,33 +1,35 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.dto;
public class NodeProperty extends Property {
+
private String description;
private String type;
private boolean key;
private boolean index;
private boolean required;
- public NodeProperty(String propertyName,
- String description, String type, boolean key, boolean index, boolean required) {
+ public NodeProperty(
+ String propertyName, String description, String type,
+ boolean key, boolean index, boolean required) {
super(propertyName, "");
this.description = description;
this.type = type;
@@ -92,7 +94,7 @@ public class NodeProperty extends Property {
@Override
public int hashCode() {
- return getPropertyName().hashCode();
+ return getPropertyName().hashCode();
}
@Override
diff --git a/src/main/java/org/onap/aai/graphgraph/dto/Property.java b/src/main/java/org/onap/aai/graphgraph/dto/Property.java
index add7dc1..a08b0ec 100644
--- a/src/main/java/org/onap/aai/graphgraph/dto/Property.java
+++ b/src/main/java/org/onap/aai/graphgraph/dto/Property.java
@@ -1,25 +1,26 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.dto;
-public class Property implements Comparable<Property>{
+public class Property implements Comparable<Property> {
+
private String propertyName;
private String propertyValue;
@@ -59,7 +60,6 @@ public class Property implements Comparable<Property>{
return false;
}
return propertyValue.equals(property.propertyValue);
-
}
@Override
@@ -71,8 +71,8 @@ public class Property implements Comparable<Property>{
@Override
public int compareTo(Property o) {
- if (o.getPropertyName().equals(getPropertyName()) && o.getPropertyValue() != null
- && getPropertyValue() != null) {
+ if (o.getPropertyName().equals(getPropertyName())
+ && o.getPropertyValue() != null && getPropertyValue() != null) {
return getPropertyValue().compareTo(o.getPropertyValue());
}
diff --git a/src/main/java/org/onap/aai/graphgraph/dto/ValidationProblems.java b/src/main/java/org/onap/aai/graphgraph/dto/ValidationProblems.java
index 9b031d0..976058d 100644
--- a/src/main/java/org/onap/aai/graphgraph/dto/ValidationProblems.java
+++ b/src/main/java/org/onap/aai/graphgraph/dto/ValidationProblems.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.dto;
@@ -23,17 +23,18 @@ import java.util.LinkedList;
import java.util.List;
public class ValidationProblems {
+
private List<String> problems = new LinkedList<>();
- public List<String> getProblems() {
- return problems;
- }
+ public List<String> getProblems() {
+ return problems;
+ }
- public void setProblems(List<String> problems) {
- this.problems = problems;
- }
+ public void setProblems(List<String> problems) {
+ this.problems = problems;
+ }
- public void addProblem(String problem) {
- problems.add(problem);
- }
+ public void addProblem(String problem) {
+ problems.add(problem);
+ }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/reader/BasicSchemaReader.java b/src/main/java/org/onap/aai/graphgraph/reader/BasicSchemaReader.java
index b2d766b..7f903f7 100644
--- a/src/main/java/org/onap/aai/graphgraph/reader/BasicSchemaReader.java
+++ b/src/main/java/org/onap/aai/graphgraph/reader/BasicSchemaReader.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.reader;
@@ -50,357 +50,356 @@ import org.onap.aai.setup.SchemaVersion;
public class BasicSchemaReader implements SchemaReader {
- private Map<String, Introspector> allEntities;
- private Graph<String, MetadataEdge> graph = new DefaultDirectedGraph<>(MetadataEdge.class);
- private EdgeIngestor edgeIngestor;
- private String version;
- private List<String> schemaErrors = new LinkedList<>();
+ private Map<String, Introspector> allEntities;
+ private Graph<String, MetadataEdge> graph = new DefaultDirectedGraph<>(MetadataEdge.class);
+ private EdgeIngestor edgeIngestor;
+ private String version;
+ private List<String> schemaErrors = new LinkedList<>();
- public List<String> getSchemaErrors() {
- return schemaErrors;
- }
+ public BasicSchemaReader(String version) {
+ this.version = version;
+ }
- public BasicSchemaReader(String version) {
- this.version = version;
- }
+ public List<String> getSchemaErrors() {
+ return schemaErrors;
+ }
- private void init() {
- if (allEntities != null) {
- return;
+ private void init() {
+ if (allEntities != null) {
+ return;
+ }
+ allEntities = App.moxyLoaders.get(getSchemaName()).getAllObjects();
+ edgeIngestor = App.edgeIngestor;
+ graph = createGraph(true, true);
}
- allEntities = App.moxyLoaders.get(getSchemaName()).getAllObjects();
- edgeIngestor = App.edgeIngestor;
- graph = createGraph(true, true);
- }
-
- private Graph<String, MetadataEdge> createGraph(boolean withParentChild, boolean withEdgeRules) {
- Graph<String, MetadataEdge> graph = new DefaultDirectedGraph<>(MetadataEdge.class);
- for (Entry<String, Introspector> currentParent : allEntities.entrySet()) {
- graph.addVertex(currentParent.getKey());
- currentParent.getValue().getProperties().stream()
- .filter(v -> allEntities.containsKey(v))
- .filter(v -> !currentParent.getKey().equals(v))
- .forEach(v -> {
- graph.addVertex(v);
- if (withParentChild) {
- addParentChildEdge(currentParent.getKey(), v, graph);
- }
- });
+
+ private Graph<String, MetadataEdge> createGraph(boolean withParentChild, boolean withEdgeRules) {
+ Graph<String, MetadataEdge> graph = new DefaultDirectedGraph<>(MetadataEdge.class);
+ for (Entry<String, Introspector> currentParent : allEntities.entrySet()) {
+ graph.addVertex(currentParent.getKey());
+ currentParent.getValue().getProperties().stream()
+ .filter(v -> allEntities.containsKey(v))
+ .filter(v -> !currentParent.getKey().equals(v))
+ .forEach(v -> {
+ graph.addVertex(v);
+ if (withParentChild) {
+ addParentChildEdge(currentParent.getKey(), v, graph);
+ }
+ });
+ }
+
+ if (!withEdgeRules) {
+ return graph;
+ }
+
+ Multimap<String, EdgeRule> allRules = null;
+ try {
+ allRules = edgeIngestor.getAllRules(new SchemaVersion(getSchemaName()));
+ } catch (EdgeRuleNotFoundException e) {
+ //TODO fix
+ }
+
+ allRules.asMap().values().stream()
+ .flatMap(e -> e.stream())
+ .forEach(e -> {
+ switch (e.getDirection()) {
+ case OUT:
+ addEdgerule(e.getFrom(), e.getTo(), e.getLabel(), graph);
+ break;
+ case IN:
+ addEdgerule(e.getTo(), e.getFrom(), e.getLabel(), graph);
+ break;
+ case BOTH:
+ addEdgerule(e.getFrom(), e.getTo(), e.getLabel(), graph);
+ addEdgerule(e.getTo(), e.getFrom(), e.getLabel(), graph);
+ break;
+ }
+ });
+
+ return graph;
+ }
+
+ private void addEdgerule(String parent, String child, String label, Graph<String, MetadataEdge> graph) {
+ //shortening labels, long edge names are unreadable in the UI
+ if (label.contains(".")) {
+ String[] split = label.split("\\.");
+ label = split[split.length - 1];
+ }
+ checkVertexExist(graph, parent);
+ checkVertexExist(graph, child);
+
+ graph.addEdge(child, parent,
+ new MetadataEdge(EdgeType.EDGE_RULE.getTypeName(), child, parent, label));
+ }
+
+ private void checkVertexExist(Graph<String, MetadataEdge> graph, String vertex) {
+ if (!graph.vertexSet().contains(vertex)) {
+ graph.addVertex(vertex);
+ schemaErrors.add(String.format("Schema is inconsistent, missing node %s", vertex));
+ }
+ }
+
+ private void addParentChildEdge(String parent, String child, Graph<String, MetadataEdge> graph) {
+ graph.addEdge(parent, child,
+ new MetadataEdge(EdgeType.PARENT.getTypeName(), parent, child, EdgeType.PARENT.getTypeName()));
+ graph.addEdge(child, parent,
+ new MetadataEdge(EdgeType.CHILD.getTypeName(), child, parent, EdgeType.CHILD.getTypeName()));
+ }
+
+ @Override
+ public String getSchemaName() {
+ return version;
+ }
+
+ @Override
+ public List<NodeName> getAllVertexNames(String edgeFilter) {
+ init();
+
+ return createGraph(
+ isParentChildFilter(edgeFilter),
+ isEdgeRulesFilter(edgeFilter)).edgeSet().stream()
+ .flatMap(e -> Arrays.asList(e.getSource(), e.getTarget()).stream())
+ .sorted().distinct()
+ .map(NodeName::new)
+ .collect(Collectors.toList());
}
- if (!withEdgeRules) {
- return graph;
+ @Override
+ public List<NodeProperty> getVertexProperties(String nodeName) {
+ init();
+
+ if (!allEntities.containsKey(nodeName)) {
+ return Collections.emptyList();
+ }
+ Introspector introspector = allEntities.get(nodeName);
+ List<String> properties = introspector.getProperties().stream().sorted().collect(Collectors.toList());
+
+ return properties.stream()
+ .map(p -> new NodeProperty(
+ p,
+ introspector.getPropertyMetadata(p).getOrDefault(
+ PropertyMetadata.DESCRIPTION, "no description available"),
+ introspector.getType(p),
+ introspector.getAllKeys().contains(p),
+ introspector.getIndexedProperties().contains(p),
+ introspector.getRequiredProperties().contains(p)))
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public List<Property> getEdgeProperties(String fromNode, String toNode, String type) {
+ init();
+ if (type.equals(EdgeType.EDGE_RULE.getTypeName())) {
+ try {
+ List<EdgeRule> rules = edgeIngestor.getAllRules(new SchemaVersion(getSchemaName()))
+ .asMap().values().stream()
+ .flatMap(Collection::stream)
+ .filter(identifyEdgeRule(fromNode, toNode))
+ .collect(Collectors.toList());
+
+ Optional<List<Property>> properties = rules.stream().map(this::edgeRuleProperties).findFirst();
+ return properties.orElse(Collections.emptyList());
+
+ } catch (EdgeRuleNotFoundException e) {
+ //TODO fix
+ }
+ }
+ return Collections.emptyList();
}
- Multimap<String, EdgeRule> allRules = null;
- try {
- allRules = edgeIngestor.getAllRules(new SchemaVersion(getSchemaName()));
- } catch (EdgeRuleNotFoundException e) {
- //TODO fix
+ private Predicate<EdgeRule> identifyEdgeRule(String fromNode, String toNode) {
+ return e -> {
+ switch (e.getDirection()) {
+ case OUT:
+ return e.getFrom().equals(fromNode) && e.getTo().equals(toNode);
+ case IN:
+ return e.getFrom().equals(toNode) && e.getTo().equals(fromNode);
+ case BOTH:
+ return e.getFrom().equals(toNode) && e.getTo().equals(fromNode)
+ || e.getFrom().equals(fromNode) && e.getTo().equals(toNode);
+ default:
+ return false;
+ }
+ };
}
- allRules.asMap().values().stream().flatMap(e -> e.stream()).forEach(e -> {
- switch (e.getDirection()) {
- case OUT:
- addEdgerule(e.getFrom(), e.getTo(), e.getLabel(), graph);
- break;
- case IN:
- addEdgerule(e.getTo(), e.getFrom(), e.getLabel(), graph);
- break;
- case BOTH:
- addEdgerule(e.getFrom(), e.getTo(), e.getLabel(), graph);
- addEdgerule(e.getTo(), e.getFrom(), e.getLabel(), graph);
- break;
- }
- });
-
- return graph;
- }
-
- private void addEdgerule(String parent, String child, String label,
- Graph<String, MetadataEdge> graph) {
- //shortening labels, long edge names are unreadable in the UI
- if (label.contains(".")) {
- String[] split = label.split("\\.");
- label = split[split.length - 1];
+ private List<Property> edgeRuleProperties(EdgeRule r) {
+ List<Property> ps = new LinkedList<>();
+ ps.add(new Property("Multiplicity", r.getMultiplicityRule().name()));
+ ps.add(new Property("Is default edge", String.valueOf(r.isDefault())));
+ ps.add(new Property("Description", r.getDescription()));
+ ps.add(new Property("Is private edge", String.valueOf(r.isPrivateEdge())));
+ ps.add(new Property("Contains", r.getContains()));
+ ps.add(new Property("Prevent delete", r.getPreventDelete()));
+ ps.add(new Property("Label", r.getLabel()));
+ ps.add(new Property("Delete other v", r.getDeleteOtherV()));
+ return ps;
}
- checkVertexExist(graph, parent);
- checkVertexExist(graph, child);
- graph.addEdge(child, parent,
- new MetadataEdge(EdgeType.EDGE_RULE.getTypeName(), child, parent, label));
- }
+ @Override
+ public org.onap.aai.graphgraph.dto.Graph getGraph(
+ String initialNode, int parentHops, int cousinHops, int childHops, String edgeFilter) {
+ init();
+
+ Optional<String> anyVertex = graph.vertexSet().stream().findFirst();
+ if (!anyVertex.isPresent()) {
+ return org.onap.aai.graphgraph.dto.Graph.emptyGraph();
+ }
+ Set<Edge> edges = computeAllEdges(
+ anyVertex.get(), isParentChildFilter(edgeFilter), isEdgeRulesFilter(edgeFilter));
+
+ if (!"all".equals(initialNode)) {
+ Set<String> subGraphVertices = computeNodes(initialNode, parentHops, EdgeType.CHILD.getTypeName());
+ subGraphVertices.addAll(computeNodes(initialNode, childHops, EdgeType.PARENT.getTypeName()));
+ subGraphVertices.addAll(computeNodes(initialNode, cousinHops, EdgeType.EDGE_RULE.getTypeName()));
+ edges = filterEdges(edges, subGraphVertices);
+ }
- private void checkVertexExist(Graph<String, MetadataEdge> graph, String vertex) {
- if (! graph.vertexSet().contains(vertex)) {
- graph.addVertex(vertex);
- schemaErrors.add(String.format("Schema is inconsistent, missing node %s", vertex));
+ return new org.onap.aai.graphgraph.dto.Graph(new LinkedList<>(computeNodeNames(edges)),
+ new LinkedList<>(edges), Collections.emptyList(), getVertexProperties(initialNode));
}
- }
-
- private void addParentChildEdge(String parent, String child, Graph<String, MetadataEdge> graph) {
- graph.addEdge(parent, child,
- new MetadataEdge(EdgeType.PARENT.getTypeName(), parent, child, EdgeType.PARENT.getTypeName()));
- graph.addEdge(child, parent,
- new MetadataEdge(EdgeType.CHILD.getTypeName(), child, parent, EdgeType.CHILD.getTypeName()));
- }
-
- @Override
- public String getSchemaName() {
- return version;
- }
-
- @Override
- public List<NodeName> getAllVertexNames(String edgeFilter) {
- init();
-
- return createGraph(isParentChildFilter(edgeFilter), isEdgeRulesFilter(edgeFilter))
- .edgeSet().stream().flatMap(e -> Arrays.asList(e.getSource(), e.getTarget()).stream())
- .sorted()
- .distinct()
- .map(NodeName::new).collect(
- Collectors.toList());
- }
-
- @Override
- public List<NodeProperty> getVertexProperties(String nodeName) {
- init();
-
- if (!allEntities.containsKey(nodeName)) {
- return Collections.emptyList();
+
+ private boolean isParentChildFilter(String edgeFilter) {
+ return "Parents".equals(edgeFilter);
}
- Introspector introspector = allEntities.get(nodeName);
- List<String> properties = introspector.getProperties().stream()
- .sorted()
- .collect(Collectors.toList());
-
- List<NodeProperty> result = properties.stream().map( p ->
- new NodeProperty(
- p,
- introspector.getPropertyMetadata(p)
- .getOrDefault(PropertyMetadata.DESCRIPTION,"no description available"),
- introspector.getType(p),
- introspector.getAllKeys().contains(p),
- introspector.getIndexedProperties().contains(p),
- introspector.getRequiredProperties().contains(p))
- ).collect(Collectors.toList());
-
- return result;
- }
-
- @Override
- public List<Property> getEdgeProperties(String fromNode, String toNode, String type) {
- init();
- if (type.equals(EdgeType.EDGE_RULE.getTypeName())) {
- try {
- List<EdgeRule> rules = edgeIngestor.getAllRules(new SchemaVersion(getSchemaName()))
- .asMap()
- .values()
- .stream()
- .flatMap(Collection::stream)
- .filter(identifyEdgeRule(fromNode, toNode))
- .collect(Collectors.toList());
-
- Optional<List<Property>> properties = rules.stream().map(this::edgeRuleProperties)
- .findFirst();
- return properties.orElse(Collections.emptyList());
-
- } catch (EdgeRuleNotFoundException e) {
- //TODO fix
- }
+ private boolean isEdgeRulesFilter(String edgeFilter) {
+ return "Edgerules".equals(edgeFilter);
}
- return Collections.emptyList();
- }
-
- private Predicate<EdgeRule> identifyEdgeRule(String fromNode, String toNode) {
- return e -> {
- switch (e.getDirection()) {
- case OUT:
- return e.getFrom().equals(fromNode) && e.getTo().equals(toNode);
- case IN:
- return e.getFrom().equals(toNode) && e.getTo().equals(fromNode);
- case BOTH:
- return e.getFrom().equals(toNode) && e.getTo().equals(fromNode)
- || e.getFrom().equals(fromNode) && e.getTo().equals(toNode);
- default:
- return false;
- }
- };
- }
-
- private List<Property> edgeRuleProperties(EdgeRule r) {
- List<Property> ps = new LinkedList<>();
- ps.add(new Property("Multiplicity", r.getMultiplicityRule().name()));
- ps.add(new Property("Is default edge", String.valueOf(r.isDefault())));
- ps.add(new Property("Description", r.getDescription()));
- ps.add(new Property("Is private edge", String.valueOf(r.isPrivateEdge())));
- ps.add(new Property("Contains", r.getContains()));
- ps.add(new Property("Prevent delete", r.getPreventDelete()));
- ps.add(new Property("Label", r.getLabel()));
- ps.add(new Property("Delete other v", r.getDeleteOtherV()));
- return ps;
- }
-
- @Override
- public org.onap.aai.graphgraph.dto.Graph getGraph(String initialNode, int parentHops,
- int cousinHops, int childHops, String edgeFilter) {
- init();
-
- Optional<String> anyVertex = graph.vertexSet().stream().findFirst();
- if (!anyVertex.isPresent()) {
- return org.onap.aai.graphgraph.dto.Graph.emptyGraph();
+
+ private Set<Edge> filterEdgesStrict(Set<Edge> edges, Set<String> subGraphVertices) {
+ return edges.stream()
+ .filter(e -> subGraphVertices.contains(e.getSource()) && subGraphVertices.contains(e.getTarget()))
+ .collect(Collectors.toSet());
}
- Set<Edge> edges = computeAllEdges(anyVertex.get(), isParentChildFilter(edgeFilter),
- isEdgeRulesFilter(edgeFilter));
-
- if (!"all".equals(initialNode)) {
- Set<String> subGraphVertices = computeNodes(initialNode, parentHops, EdgeType.CHILD.getTypeName());
- subGraphVertices.addAll(computeNodes(initialNode, childHops, EdgeType.PARENT.getTypeName()));
- subGraphVertices.addAll(computeNodes(initialNode, cousinHops, EdgeType.EDGE_RULE.getTypeName()));
- edges = filterEdges(edges, subGraphVertices);
+
+ private Set<Edge> filterEdges(Set<Edge> edges, Set<String> subGraphVertices) {
+ return edges.stream()
+ .filter(e -> subGraphVertices.contains(e.getSource()) || subGraphVertices.contains(e.getTarget()))
+ .filter(e -> !e.getType().equals(EdgeType.EDGE_RULE.getTypeName()))
+ .collect(Collectors.toSet());
}
- return new org.onap.aai.graphgraph.dto.Graph(new LinkedList<>(computeNodeNames(edges)),
- new LinkedList<>(edges), Collections.emptyList(), getVertexProperties(initialNode));
- }
-
- private boolean isParentChildFilter(String edgeFilter) {
- return "Parents".equals(edgeFilter);
- }
-
- private boolean isEdgeRulesFilter(String edgeFilter) {
- return "Edgerules".equals(edgeFilter);
- }
-
- private Set<Edge> filterEdgesStrict(Set<Edge> edges, Set<String> subGraphVertices) {
- return edges.stream().filter(
- e -> subGraphVertices.contains(e.getSource()) && subGraphVertices.contains(e.getTarget()))
- .collect(
- Collectors.toSet());
- }
-
- private Set<Edge> filterEdges(Set<Edge> edges, Set<String> subGraphVertices) {
- return edges.stream().filter(e ->
- subGraphVertices.contains(e.getSource()) || subGraphVertices.contains(e.getTarget()))
- .filter(e -> !e.getType().equals(EdgeType.EDGE_RULE.getTypeName()))
- .collect(Collectors.toSet());
- }
-
- private Set<NodeName> computeNodeNames(Set<Edge> edges) {
- return edges.stream().flatMap(e -> e.getNodeNames().stream()).collect(
- Collectors.toSet());
- }
-
- private Set<Edge> computeAllEdges(String initial, boolean parentChild, boolean edgeRules) {
- Set<Edge> result = new HashSet<>();
- List<String> toQuery = new LinkedList<>();
- toQuery.add(initial);
- final List<String> toVisit = new LinkedList<>();
- Set<String> visited = new HashSet<>();
-
- while (!toQuery.isEmpty()) {
- for (String v : toQuery) {
- visited.add(v);
-
- graph.edgesOf(v).forEach(edge -> {
- String neighbour = edge.getTarget();
- toVisit.add(neighbour);
-
- if (EdgeType.CHILD.isType(edge.getType()) && parentChild) {
- result.add(new Edge(neighbour, edge.getSource(), EdgeType.PARENT.getTypeName(),
- createTooltip(neighbour, edge.getSource(), EdgeType.PARENT.getTypeName(), edge.getLabel())));
- }
-
- if (EdgeType.EDGE_RULE.isType(edge.getType()) && edgeRules) {
- result.add(new Edge(edge.getSource(), neighbour, edge.getLabel(),
- createTooltip(neighbour, edge.getSource(), EdgeType.EDGE_RULE.getTypeName(),
- edge.getLabel())));
- }
- });
- }
- toQuery.clear();
- toQuery.addAll(
- toVisit.stream().filter(s -> !visited.contains(s)).collect(Collectors.toList()));
+ private Set<NodeName> computeNodeNames(Set<Edge> edges) {
+ return edges.stream()
+ .flatMap(e -> e.getNodeNames().stream())
+ .collect(Collectors.toSet());
}
- return result;
+ private Set<Edge> computeAllEdges(String initial, boolean parentChild, boolean edgeRules) {
+ Set<Edge> result = new HashSet<>();
+ List<String> toQuery = new LinkedList<>();
+ toQuery.add(initial);
+ final List<String> toVisit = new LinkedList<>();
+ Set<String> visited = new HashSet<>();
+
+ while (!toQuery.isEmpty()) {
+ for (String v : toQuery) {
+ visited.add(v);
+
+ graph.edgesOf(v).forEach(edge -> {
+ String neighbour = edge.getTarget();
+ toVisit.add(neighbour);
+
+ if (EdgeType.CHILD.isType(edge.getType()) && parentChild) {
+ result.add(new Edge(
+ neighbour, edge.getSource(), EdgeType.PARENT.getTypeName(), createTooltip(
+ neighbour, edge.getSource(), EdgeType.PARENT.getTypeName(), edge.getLabel())));
+ }
+
+ if (EdgeType.EDGE_RULE.isType(edge.getType()) && edgeRules) {
+ result.add(new Edge(
+ edge.getSource(), neighbour, edge.getLabel(), createTooltip(
+ neighbour, edge.getSource(), EdgeType.EDGE_RULE.getTypeName(), edge.getLabel())));
+ }
+ });
+ }
+ toQuery.clear();
+ toQuery.addAll(toVisit.stream().filter(s -> !visited.contains(s)).collect(Collectors.toList()));
+ }
+
+ return result;
+
+ }
- }
+ private Set<String> computeNodes(String vertex, int hops, String relationshipName) {
+ List<String> toQuery = new LinkedList<>();
+ toQuery.add(vertex);
- private Set<String> computeNodes(String vertex, int hops, String relationshipName) {
- List<String> toQuery = new LinkedList<>();
- toQuery.add(vertex);
+ Set<String> visited = new HashSet<>();
+ int i = 0;
- Set<String> visited = new HashSet<>();
- int i = 0;
+ final List<String> toVisit = new LinkedList<>();
+ while (!toQuery.isEmpty() && hops > i) {
+ i++;
+ toVisit.clear();
- final List<String> toVisit = new LinkedList<>();
- while (!toQuery.isEmpty() && hops > i) {
- i++;
- toVisit.clear();
+ for (String v : toQuery) {
+ visited.add(v);
+ graph.edgesOf(v).stream()
+ .filter(e -> e.getType().equals(relationshipName))
+ .map(MetadataEdge::getTarget)
+ .forEach(toVisit::add);
+ }
- for (String v : toQuery) {
- visited.add(v);
- graph.edgesOf(v).stream().filter(e -> e.getType().equals(relationshipName)).map(
- MetadataEdge::getTarget).forEach(toVisit::add);
- }
+ toQuery.clear();
+ toQuery.addAll(toVisit.stream().filter(v -> !visited.contains(v)).collect(Collectors.toList()));
+ }
- toQuery.clear();
- toQuery
- .addAll(toVisit.stream().filter(v -> !visited.contains(v)).collect(Collectors.toList()));
+ return visited;
}
- return visited;
- }
-
-
- @Override
- public org.onap.aai.graphgraph.dto.Graph getGraph(String fromNode, String toNode,
- String edgeFilter) {
- init();
- Graph<String, MetadataEdge> tempGraph = createGraph(isParentChildFilter(edgeFilter), isEdgeRulesFilter(edgeFilter));
- List<List<NodeName>> paths = new LinkedList<>();
- FloydWarshallShortestPaths<String, MetadataEdge> shortestPaths;
-
- while (true) {
- shortestPaths = new FloydWarshallShortestPaths<>(tempGraph);
- GraphPath<String, MetadataEdge> p = shortestPaths.getPath(fromNode, toNode);
- if (p == null || p.getEdgeList() == null || p.getEdgeList().isEmpty()) {
- break;
- }
- String previous = fromNode;
- List<NodeName> path = new LinkedList<>();
- for (MetadataEdge e : p.getEdgeList()) {
- if (e.getTarget().equals(previous)) {
- previous = e.getSource();
- path.add(new NodeName(e.getTarget()));
- } else {
- previous = e.getTarget();
- path.add(new NodeName(e.getSource()));
+ @Override
+ public org.onap.aai.graphgraph.dto.Graph getGraph(String fromNode, String toNode, String edgeFilter) {
+ init();
+ Graph<String, MetadataEdge> tempGraph = createGraph(
+ isParentChildFilter(edgeFilter), isEdgeRulesFilter(edgeFilter));
+ List<List<NodeName>> paths = new LinkedList<>();
+ FloydWarshallShortestPaths<String, MetadataEdge> shortestPaths;
+
+ while (true) {
+ shortestPaths = new FloydWarshallShortestPaths<>(tempGraph);
+ GraphPath<String, MetadataEdge> p = shortestPaths.getPath(fromNode, toNode);
+ if (p == null || p.getEdgeList() == null || p.getEdgeList().isEmpty()) {
+ break;
+ }
+ String previous = fromNode;
+ List<NodeName> path = new LinkedList<>();
+ for (MetadataEdge e : p.getEdgeList()) {
+ if (e.getTarget().equals(previous)) {
+ previous = e.getSource();
+ path.add(new NodeName(e.getTarget()));
+ } else {
+ previous = e.getTarget();
+ path.add(new NodeName(e.getSource()));
+ }
+ }
+ path.add(new NodeName(previous));
+ paths.add(path);
+ tempGraph.removeEdge(p.getEdgeList().get(p.getLength() - 1)); //remove last edge from path
}
- }
- path.add(new NodeName(previous));
- paths.add(path);
- tempGraph.removeEdge(p.getEdgeList().get(p.getLength() - 1)); //remove last edge from path
+
+ Set<Edge> edges = computeAllEdges(fromNode, isParentChildFilter(edgeFilter), isEdgeRulesFilter(edgeFilter));
+ edges = filterEdgesStrict(
+ edges,
+ paths.stream()
+ .flatMap(Collection::stream)
+ .map(NodeName::getId)
+ .collect(Collectors.toSet()));
+ return new org.onap.aai.graphgraph.dto.Graph(
+ new LinkedList<>(computeNodeNames(edges)), new LinkedList<>(edges),
+ paths, getVertexProperties(fromNode));
}
- Set<Edge> edges = computeAllEdges(fromNode, isParentChildFilter(edgeFilter),
- isEdgeRulesFilter(edgeFilter));
- edges = filterEdgesStrict(edges,
- paths.stream().flatMap(Collection::stream).map(NodeName::getId).collect(
- Collectors.toSet()));
- return new org.onap.aai.graphgraph.dto.Graph(new LinkedList<>(computeNodeNames(edges)),
- new LinkedList<>(edges), paths, getVertexProperties(fromNode));
- }
-
- private List<Property> createTooltip(String target, String v, String type, String label) {
- List<Property> properties = new LinkedList<>();
- properties.add(new Property("From", target));
- properties.add(new Property("To", v));
- properties.add(new Property("Type", type));
- properties.add(new Property("Relationship", label));
- properties.addAll(getEdgeProperties(v, target, EdgeType.EDGE_RULE.isType(type) ? EdgeType.EDGE_RULE.getTypeName() : EdgeType.PARENT.getTypeName()));
- return properties;
- }
+ private List<Property> createTooltip(String target, String v, String type, String label) {
+ List<Property> properties = new LinkedList<>();
+ properties.add(new Property("From", target));
+ properties.add(new Property("To", v));
+ properties.add(new Property("Type", type));
+ properties.add(new Property("Relationship", label));
+ properties.addAll(getEdgeProperties(
+ v, target,
+ EdgeType.EDGE_RULE.isType(type) ? EdgeType.EDGE_RULE.getTypeName() : EdgeType.PARENT.getTypeName()));
+ return properties;
+ }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/reader/EdgeType.java b/src/main/java/org/onap/aai/graphgraph/reader/EdgeType.java
index 1250474..fd2614c 100644
--- a/src/main/java/org/onap/aai/graphgraph/reader/EdgeType.java
+++ b/src/main/java/org/onap/aai/graphgraph/reader/EdgeType.java
@@ -1,38 +1,40 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.reader;
public enum EdgeType {
- EDGE_RULE("edgerule"), PARENT("parent"), CHILD("child");
+ EDGE_RULE("edgerule"),
+ PARENT("parent"),
+ CHILD("child");
- private final String name;
+ private final String name;
- EdgeType(String s) {
- name = s;
- }
+ EdgeType(String s) {
+ name = s;
+ }
- public String getTypeName() {
- return this.name;
- }
+ public String getTypeName() {
+ return this.name;
+ }
- public boolean isType(String o){
- return name.equals(o);
- }
+ public boolean isType(String o) {
+ return name.equals(o);
+ }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/reader/MetadataEdge.java b/src/main/java/org/onap/aai/graphgraph/reader/MetadataEdge.java
index fb8e53f..2dea403 100644
--- a/src/main/java/org/onap/aai/graphgraph/reader/MetadataEdge.java
+++ b/src/main/java/org/onap/aai/graphgraph/reader/MetadataEdge.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.reader;
@@ -23,49 +23,49 @@ import org.jgrapht.graph.DefaultEdge;
public class MetadataEdge extends DefaultEdge {
- private final String type;
- private final String target;
- private final String source;
- private final String label;
+ private final String type;
+ private final String target;
+ private final String source;
+ private final String label;
- MetadataEdge(String type, String source, String target) {
- this.source = source;
- this.target = target;
- this.type = type;
- this.label = "";
- }
+ MetadataEdge(String type, String source, String target) {
+ this.source = source;
+ this.target = target;
+ this.type = type;
+ this.label = "";
+ }
- MetadataEdge(String type, String target, String source, String label) {
- this.type = type;
- this.target = target;
- this.source = source;
- this.label = label;
- }
+ MetadataEdge(String type, String target, String source, String label) {
+ this.type = type;
+ this.target = target;
+ this.source = source;
+ this.label = label;
+ }
- public String getLabel() {
- return label;
- }
+ public String getLabel() {
+ return label;
+ }
- @Override
- public String getTarget() {
- return target;
- }
+ @Override
+ public String getTarget() {
+ return target;
+ }
- @Override
- public String getSource() {
- return source;
- }
+ @Override
+ public String getSource() {
+ return source;
+ }
- public String getType() {
- return type;
- }
+ public String getType() {
+ return type;
+ }
- @Override
- public String toString() {
- return "MetadataEdge{" +
- "type='" + type + '\'' +
- ", target='" + target + '\'' +
- ", source='" + source + '\'' +
- '}';
- }
+ @Override
+ public String toString() {
+ return "MetadataEdge{" +
+ "type='" + type + '\'' +
+ ", target='" + target + '\'' +
+ ", source='" + source + '\'' +
+ '}';
+ }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java b/src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java
index a924e63..38e1bf6 100644
--- a/src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java
+++ b/src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.reader;
@@ -27,11 +27,16 @@ import org.onap.aai.graphgraph.dto.Property;
import java.util.List;
public interface SchemaReader {
+
String getSchemaName();
+
List<NodeName> getAllVertexNames(String edgeFilter);
+
List<NodeProperty> getVertexProperties(String nodeName);
+
List<Property> getEdgeProperties(String fromNode, String toNode, String type);
- Graph getGraph(String initialNode, int parentHops, int cousinHops, int childHops,
- String edgeFilter);
+
+ Graph getGraph(String initialNode, int parentHops, int cousinHops, int childHops, String edgeFilter);
+
Graph getGraph(String fromNode, String toNode, String edgeFilter);
}
diff --git a/src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java b/src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java
index f49a669..5764c50 100644
--- a/src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java
+++ b/src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.reader;
@@ -24,20 +24,22 @@ import java.util.Optional;
import java.util.stream.Collectors;
public class SchemaRepository {
+
private List<SchemaReader> readers;
public SchemaRepository(List<SchemaReader> readers) {
this.readers = readers;
}
- public List<String> getAllSchemaNames(){
+ public List<String> getAllSchemaNames() {
return readers.stream().map(SchemaReader::getSchemaName).collect(Collectors.toList());
}
- public SchemaReader getSchemaReader(String schemaName){
+ public SchemaReader getSchemaReader(String schemaName) {
Optional<SchemaReader> reader = readers.stream().filter(r -> schemaName.equals(r.getSchemaName())).findFirst();
- if(!reader.isPresent())
+ if (!reader.isPresent()) {
throw new IllegalArgumentException("Schema " + schemaName + " not found");
+ }
return reader.get();
}
diff --git a/src/main/java/org/onap/aai/graphgraph/velocity/VelocityAssociation.java b/src/main/java/org/onap/aai/graphgraph/velocity/VelocityAssociation.java
index 697fad1..dda37b5 100644
--- a/src/main/java/org/onap/aai/graphgraph/velocity/VelocityAssociation.java
+++ b/src/main/java/org/onap/aai/graphgraph/velocity/VelocityAssociation.java
@@ -1,115 +1,113 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.velocity;
public class VelocityAssociation extends VelocityId {
- private final String name;
- private final VelocityEntity fromEntity;
- private final VelocityEntity toEntity;
- private final String fromId = getRandomId();
- private final String toId = getRandomId();
- private final String multiplicity;
- private final boolean isComposition;
-
- public VelocityAssociation(VelocityEntity fromEntity,
- VelocityEntity toEntity, String name, String multiplicity, boolean isComposition) {
- this.fromEntity = fromEntity;
- this.toEntity = toEntity;
- this.name = name;
- this.multiplicity = multiplicity;
- this.isComposition = isComposition;
- }
-
- public String getFromEntityName(){
- return fromEntity.getName();
- }
-
- public String getToEntityName(){
- return toEntity.getName();
- }
-
- public String getFromEntityId(){
- return fromEntity.getId();
- }
-
- public String getToEntityId(){
- return toEntity.getId();
- }
-
- public String getFromId() {
- return fromId;
- }
-
- public String getToId() {
- return toId;
- }
-
- public String getName() {
- return name;
- }
-
- public String getMultiplicity() {
- return multiplicity.toUpperCase();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
+ private final String name;
+ private final VelocityEntity fromEntity;
+ private final VelocityEntity toEntity;
+ private final String fromId = getRandomId();
+ private final String toId = getRandomId();
+ private final String multiplicity;
+ private final boolean isComposition;
+
+ public VelocityAssociation(VelocityEntity fromEntity,
+ VelocityEntity toEntity, String name, String multiplicity, boolean isComposition) {
+ this.fromEntity = fromEntity;
+ this.toEntity = toEntity;
+ this.name = name;
+ this.multiplicity = multiplicity;
+ this.isComposition = isComposition;
}
- if (o == null || getClass() != o.getClass()) {
- return false;
+
+ public String getFromEntityName() {
+ return fromEntity.getName();
+ }
+
+ public String getToEntityName() {
+ return toEntity.getName();
+ }
+
+ public String getFromEntityId() {
+ return fromEntity.getId();
}
- VelocityAssociation that = (VelocityAssociation) o;
+ public String getToEntityId() {
+ return toEntity.getId();
+ }
+
+ public String getFromId() {
+ return fromId;
+ }
+
+ public String getToId() {
+ return toId;
+ }
- if (!name.equals(that.name)) {
- return false;
+ public String getName() {
+ return name;
}
- if (!fromEntity.equals(that.fromEntity)) {
- return false;
+
+ public String getMultiplicity() {
+ return multiplicity.toUpperCase();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ VelocityAssociation that = (VelocityAssociation) o;
+
+ if (!name.equals(that.name)) {
+ return false;
+ }
+ if (!fromEntity.equals(that.fromEntity)) {
+ return false;
+ }
+ return toEntity.equals(that.toEntity);
+ }
+
+ public boolean getIsComposition() {
+ return isComposition;
+ }
+
+ @Override
+ public String toString() {
+ return "VelocityAssociation{" +
+ "name='" + name + '\'' +
+ ", fromEntity=" + fromEntity +
+ ", toEntity=" + toEntity +
+ '}';
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name.hashCode();
+ result = 31 * result + fromEntity.hashCode();
+ result = 31 * result + toEntity.hashCode();
+ return result;
}
- return toEntity.equals(that.toEntity);
- }
-
- public boolean getIsComposition() {
- return isComposition;
- }
-
- @Override
- public String toString() {
- return "VelocityAssociation{" +
- "name='" + name + '\'' +
- ", fromEntity=" + fromEntity +
- ", toEntity=" + toEntity +
- '}';
- }
-
- @Override
- public int hashCode() {
- int result = name.hashCode();
- result = 31 * result + fromEntity.hashCode();
- result = 31 * result + toEntity.hashCode();
- return result;
-
-
- }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntity.java b/src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntity.java
index 99f94f3..424c0e6 100644
--- a/src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntity.java
+++ b/src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntity.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.velocity;
@@ -24,75 +24,73 @@ import java.util.List;
import java.util.Set;
public class VelocityEntity extends VelocityId {
- private String name;
- private String description;
- private List<VelocityAssociation> neighbours = new LinkedList<>();
- private Set<VelocityEntityProperty> properties;
- public Set<VelocityEntityProperty> getProperties() {
- return properties;
- }
+ private String name;
+ private String description;
+ private List<VelocityAssociation> neighbours = new LinkedList<>();
+ private Set<VelocityEntityProperty> properties;
- public void setProperties(Set<VelocityEntityProperty> properties) {
- this.properties = properties;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
+ public VelocityEntity(String name) {
+ this.name = name;
+ }
- public VelocityEntity(String name) {
- this.name = name;
- }
+ public Set<VelocityEntityProperty> getProperties() {
+ return properties;
+ }
- public String getName() {
- return name;
- }
+ public void setProperties(Set<VelocityEntityProperty> properties) {
+ this.properties = properties;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public String getDescription() {
+ return description;
+ }
- public List<VelocityAssociation> getNeighbours() {
- return neighbours;
- }
+ public void setDescription(String description) {
+ this.description = description;
+ }
- public void setNeighbours(List<VelocityAssociation> neighbours) {
- this.neighbours = neighbours;
- }
+ public String getName() {
+ return name;
+ }
- public void addNeighbours(VelocityAssociation neighbour) {
- neighbours.add(neighbour);
- }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public List<VelocityAssociation> getNeighbours() {
+ return neighbours;
+ }
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
+ public void setNeighbours(List<VelocityAssociation> neighbours) {
+ this.neighbours = neighbours;
}
- if (o == null || getClass() != o.getClass()) {
- return false;
+
+ public void addNeighbours(VelocityAssociation neighbour) {
+ neighbours.add(neighbour);
}
- VelocityEntity that = (VelocityEntity) o;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
- return name.equals(that.name);
- }
+ VelocityEntity that = (VelocityEntity) o;
- @Override
- public int hashCode() {
- return name.hashCode();
- }
+ return name.equals(that.name);
+ }
- @Override
- public String toString() {
- return "VelocityEntity{" +
- "name='" + name + '\'' +
- '}';
- }
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "VelocityEntity{" + "name='" + name + '\'' + '}';
+ }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntityProperty.java b/src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntityProperty.java
index e8dec9f..2c65ae3 100644
--- a/src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntityProperty.java
+++ b/src/main/java/org/onap/aai/graphgraph/velocity/VelocityEntityProperty.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.velocity;
@@ -24,35 +24,33 @@ import org.onap.aai.graphgraph.dto.Property;
public class VelocityEntityProperty extends Property {
- private final VelocityEntity entity;
- private final String propertyId;
- public VelocityEntityProperty(String propertyName, String propertyValue, VelocityEntity entity) {
- super(propertyName, propertyValue);
- this.entity = entity;
- propertyId = entity != null ? entity.getRandomId() : UUID.randomUUID().toString();
- }
-
- public String getEntityId() {
- return entity.getId();
- }
-
- public String getEntityName() {
- return entity.getName();
- }
-
- public boolean hasEntity(){
- return entity != null;
- }
-
- public String getPropertyId() {
- return propertyId;
- }
-
- @Override
- public String toString() {
- return "VelocityEntityProperty{" +
- " name=" + getPropertyName() +
- " type=" + getPropertyValue() +
- '}';
- }
+ private final VelocityEntity entity;
+ private final String propertyId;
+
+ public VelocityEntityProperty(String propertyName, String propertyValue, VelocityEntity entity) {
+ super(propertyName, propertyValue);
+ this.entity = entity;
+ propertyId = entity != null ? entity.getRandomId() : UUID.randomUUID().toString();
+ }
+
+ public String getEntityId() {
+ return entity.getId();
+ }
+
+ public String getEntityName() {
+ return entity.getName();
+ }
+
+ public boolean hasEntity() {
+ return entity != null;
+ }
+
+ public String getPropertyId() {
+ return propertyId;
+ }
+
+ @Override
+ public String toString() {
+ return "VelocityEntityProperty{" + " name=" + getPropertyName() + " type=" + getPropertyValue() + '}';
+ }
}
diff --git a/src/main/java/org/onap/aai/graphgraph/velocity/VelocityId.java b/src/main/java/org/onap/aai/graphgraph/velocity/VelocityId.java
index fc44a5e..9b59c82 100644
--- a/src/main/java/org/onap/aai/graphgraph/velocity/VelocityId.java
+++ b/src/main/java/org/onap/aai/graphgraph/velocity/VelocityId.java
@@ -1,34 +1,35 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2019 Orange Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph.velocity;
import java.util.UUID;
public abstract class VelocityId {
- private String id = getRandomId();
- public String getId() {
- return id;
- }
+ private String id = getRandomId();
+
+ public String getId() {
+ return id;
+ }
- public String getRandomId() {
- return UUID.randomUUID().toString();
- }
+ public String getRandomId() {
+ return UUID.randomUUID().toString();
+ }
}
diff --git a/src/main/resources/docker-assembly.xml b/src/main/resources/docker-assembly.xml
index afd1970..54a87af 100644
--- a/src/main/resources/docker-assembly.xml
+++ b/src/main/resources/docker-assembly.xml
@@ -1,6 +1,6 @@
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>distribution</id>
<formats>
<format>jar</format>
@@ -13,11 +13,11 @@
</fileSet>
</fileSets>
-<files>
- <file>
+ <files>
+ <file>
<source>target/${project.artifactId}-${project.version}.${project.packaging}</source>
<outputDirectory>/</outputDirectory>
<filtered>false</filtered>
</file>
-</files>
-</assembly> \ No newline at end of file
+ </files>
+</assembly>
diff --git a/src/main/resources/etc/auth/realm.properties b/src/main/resources/etc/auth/realm.properties
index f0e0172..3ba96bc 100644
--- a/src/main/resources/etc/auth/realm.properties
+++ b/src/main/resources/etc/auth/realm.properties
@@ -1,13 +1,13 @@
# format : username: password[,rolename ...]
# default username/password: AAI/AAI, MSO/MSO, ModelLoader/ModelLoader...
-AAI:OBF:1gfr1ev31gg7,admin
-MSO:OBF:1jzx1lz31k01,admin
-SDNC:OBF:1itr1i0l1i151isv,admin
-DCAE:OBF:1g8u1f9d1f991g8w,admin
-POLICY:OBF:1mk61i171ima1im41i0j1mko,admin
-ASDC:OBF:1f991j0u1j001f9d,admin
-VID:OBF:1jm91i0v1jl9,admin
-APPC:OBF:1f991ksf1ksf1f9d,admin
-ModelLoader:OBF:1qvu1v2h1sov1sar1wfw1j7j1wg21saj1sov1v1x1qxw,admin
-AaiUI:OBF:1gfr1p571unz1p4j1gg7,admin
-OOF:OBF:1img1ke71ily,admin
+AAI=OBF:1gfr1ev31gg7,admin
+MSO=OBF:1jzx1lz31k01,admin
+SDNC=OBF:1itr1i0l1i151isv,admin
+DCAE=OBF:1g8u1f9d1f991g8w,admin
+POLICY=OBF:1mk61i171ima1im41i0j1mko,admin
+ASDC=OBF:1f991j0u1j001f9d,admin
+VID=OBF:1jm91i0v1jl9,admin
+APPC=OBF:1f991ksf1ksf1f9d,admin
+ModelLoader=OBF:1qvu1v2h1sov1sar1wfw1j7j1wg21saj1sov1v1x1qxw,admin
+AaiUI=OBF:1gfr1p571unz1p4j1gg7,admin
+OOF=OBF:1img1ke71ily,admin
diff --git a/src/main/resources/model_export.vm b/src/main/resources/model_export.vm
index c461d59..ae92fab 100644
--- a/src/main/resources/model_export.vm
+++ b/src/main/resources/model_export.vm
@@ -5,148 +5,148 @@
<importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
</packageImport>
- <packagedElement xmi:type="uml:Package" xmi:id="_dl4P8LIpEemXwfLFUQ7Icw" name="Associations">
+ <packagedElement xmi:type="uml:Package" xmi:id="_dl4P8LIpEemXwfLFUQ7Icw" name="Associations">
#foreach($association in $associationList)
- <packagedElement xmi:type="uml:Association" xmi:id="$association.id"
- name="$association.name" memberEnd="$association.fromId $association.toId">
- <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="$association.randomId"
- source="org.eclipse.papyrus">
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="$association.randomId"
- key="nature" value="UML_Nature"/>
- </eAnnotations>
- <ownedEnd xmi:type="uml:Property" xmi:id="$association.fromId"
- name="$association.toEntityName" type="$association.toEntityId"
- association="$association.id">
- #if($association.multiplicity == "ONE2MANY" || $association.multiplicity ==
- "MANY2MANY")
- <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"/>
- <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="$association.randomId"
- value="*"/>
- #else
- <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId" value="1"/>
- <upperValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId" value="1"/>
- #end
- </ownedEnd>
- #if( ! $association.isComposition)
- <ownedEnd xmi:type="uml:Property" xmi:id="$association.toId"
- name="$association.fromEntityName" type="$association.fromEntityId"
- association="$association.id">
- #if($association.multiplicity == "MANY2ONE" || $association.multiplicity ==
- "MANY2MANY")
- <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"/>
- <upperValue xmi:type="uml:LiteralUnlimitedNatural"
- xmi:id="$association.randomId" value="*"/>
- #else
- <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"
- value="1"/>
- <upperValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"
- value="1"/>
- #end
- </ownedEnd>
- #end
- </packagedElement>
+ <packagedElement xmi:type="uml:Association" xmi:id="$association.id"
+ name="$association.name" memberEnd="$association.fromId $association.toId">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="$association.randomId"
+ source="org.eclipse.papyrus">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="$association.randomId"
+ key="nature" value="UML_Nature"/>
+ </eAnnotations>
+ <ownedEnd xmi:type="uml:Property" xmi:id="$association.fromId"
+ name="$association.toEntityName" type="$association.toEntityId"
+ association="$association.id">
+ #if($association.multiplicity == "ONE2MANY" || $association.multiplicity ==
+ "MANY2MANY")
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"/>
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="$association.randomId"
+ value="*"/>
+ #else
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId" value="1"/>
+ <upperValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId" value="1"/>
+ #end
+ </ownedEnd>
+ #if( ! $association.isComposition)
+ <ownedEnd xmi:type="uml:Property" xmi:id="$association.toId"
+ name="$association.fromEntityName" type="$association.fromEntityId"
+ association="$association.id">
+ #if($association.multiplicity == "MANY2ONE" || $association.multiplicity ==
+ "MANY2MANY")
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"/>
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural"
+ xmi:id="$association.randomId" value="*"/>
+ #else
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"
+ value="1"/>
+ <upperValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"
+ value="1"/>
+ #end
+ </ownedEnd>
+ #end
+ </packagedElement>
#end
- </packagedElement>
- <packagedElement xmi:type="uml:Package" xmi:id="_rBN-QLIqEemXwfLFUQ7Icw" name="ObjectClasses">
+ </packagedElement>
+ <packagedElement xmi:type="uml:Package" xmi:id="_rBN-QLIqEemXwfLFUQ7Icw" name="ObjectClasses">
#foreach($entity in $entityList)
- <packagedElement xmi:type="uml:Class" xmi:id="$entity.id" name="$entity.name">
- <ownedComment xmi:type="uml:Comment" xmi:id="$entity.randomId" annotatedElement="$entity.id">
- <body>$entity.description</body>
- </ownedComment>
- #foreach($association in $entity.neighbours)
- #if( $association.isComposition)
- <ownedAttribute xmi:type="uml:Property" xmi:id="$association.toId"
- name="$association.fromEntityName"
- type="$association.fromEntityId" aggregation="composite"
- association="$association.id">
- #if($association.multiplicity == "MANY2ONE" || $association.multiplicity ==
- "MANY2MANY")
- <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"/>
- <upperValue xmi:type="uml:LiteralUnlimitedNatural"
- xmi:id="$association.randomId" value="*"/>
- #else
- <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"
- value="1"/>
- <upperValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"
- value="1"/>
- #end
- </ownedAttribute>
- #end
- #end
- #foreach($prop in $entity.properties)
- #if($prop.propertyValue.contains("java.lang"))
- <ownedAttribute xmi:type="uml:Property" xmi:id="$prop.propertyId"
- name="$prop.propertyName">
- #if($prop.propertyValue == "java.lang.String")
- <type xmi:type="uml:PrimitiveType"
- href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"/>
- #end#
- #if($prop.propertyValue == "java.lang.Long")
- <type xmi:type="uml:PrimitiveType"
- href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#Integer"/>
- #end
- #if($prop.propertyValue == "java.lang.Boolean")
- <type xmi:type="uml:PrimitiveType"
- href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#Boolean"/>
- #end
- #if($prop.propertyValue == "java.lang.Integer")
- <type xmi:type="uml:PrimitiveType"
- href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#Integer"/>
- #end
- </ownedAttribute>
- #elseif(! $prop.hasEntity)
- #* <ownedAttribute xmi:type="uml:Property" xmi:id="$entity.randomId" name="$prop.propertyName"/>*#
- #else
- <ownedAttribute xmi:type="uml:Property" xmi:id="$prop.propertyId"
- name="$prop.getEntityName()" type="$prop.getEntityId()"/>
- #end
- #end
- </packagedElement>
- #end
- </packagedElement>
- <profileApplication xmi:type="uml:ProfileApplication" xmi:id="_o4e8sN4HEemqKsY3En9wuw">
- <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_o5H14N4HEemqKsY3En9wuw" source="PapyrusVersion">
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic8N4HEemqKsY3En9wuw" key="Version" value="0.0.4"/>
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic8d4HEemqKsY3En9wuw" key="Comment" value="Metaclasses Property and Stereotype added via &lt;Element Import>."/>
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic8t4HEemqKsY3En9wuw" key="Copyright" value=""/>
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic894HEemqKsY3En9wuw" key="Date" value="2017-08-08"/>
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic9N4HEemqKsY3En9wuw" key="Author" value=""/>
- </eAnnotations>
- <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_o4lDUN4HEemqKsY3En9wuw" source="http://www.eclipse.org/uml2/2.0.0/UML">
- <references xmi:type="ecore:EPackage" href="../ProfileLifecycleProfile/ProfileLifecycle_Profile.profile.uml#_AL3HsHweEee8oZaf2rRQlg"/>
- </eAnnotations>
- <appliedProfile xmi:type="uml:Profile" href="../ProfileLifecycleProfile/ProfileLifecycle_Profile.profile.uml#_CBpGoEdZEearpawF38eisA"/>
- </profileApplication>
- <profileApplication xmi:type="uml:ProfileApplication" xmi:id="_o5JEAN4HEemqKsY3En9wuw">
- <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_pCSY8d4HEemqKsY3En9wuw" source="PapyrusVersion">
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCSY8t4HEemqKsY3En9wuw" key="Version" value="0.2.17"/>
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCTAAN4HEemqKsY3En9wuw" key="Comment" value="Editorial corrections in the description of OpenModelAttribute::partOfObjectKey and Reference."/>
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCTAAd4HEemqKsY3En9wuw" key="Copyright" value=""/>
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCTAAt4HEemqKsY3En9wuw" key="Date" value="2018-12-12"/>
- <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCTAA94HEemqKsY3En9wuw" key="Author" value=""/>
- </eAnnotations>
- <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_o5JrEN4HEemqKsY3En9wuw" source="http://www.eclipse.org/uml2/2.0.0/UML">
- <references xmi:type="ecore:EPackage" href="../OpenModelProfile/OpenModel_Profile.profile.uml#_FV_e4P4LEeiJYfiYi3RAYQ"/>
- </eAnnotations>
- <appliedProfile xmi:type="uml:Profile" href="../OpenModelProfile/OpenModel_Profile.profile.uml#_m1xqsHBgEd6FKu9XX1078A"/>
- </profileApplication>
-</uml:Model>
-<OpenModel_Profile:OpenModelStatement xmi:id="_o-KG4N4HEemqKsY3En9wuw" base_Model="_Z9InoLIpEemXwfLFUQ7Icw"/>
-#foreach($association in $associationList)
-<OpenModel_Profile:OpenModelAttribute xmi:id="$association.randomId" base_StructuralFeature="$association.fromId"/>
-#if( ! $association.isComposition)
-<OpenModel_Profile:OpenModelAttribute xmi:id="$association.randomId" base_StructuralFeature="$association.toId"/>
-#end
-#end
-#foreach($entity in $entityList)
- <OpenModel_Profile:OpenModelClass xmi:id="$entity.randomId" base_Class="$entity.id"/>
- #foreach($association in $entity.neighbours)
+ <packagedElement xmi:type="uml:Class" xmi:id="$entity.id" name="$entity.name">
+ <ownedComment xmi:type="uml:Comment" xmi:id="$entity.randomId" annotatedElement="$entity.id">
+ <body>$entity.description</body>
+ </ownedComment>
+ #foreach($association in $entity.neighbours)
#if( $association.isComposition)
- <OpenModel_Profile:OpenModelAttribute xmi:id="$association.randomId" base_StructuralFeature="$association.toId"/>
+ <ownedAttribute xmi:type="uml:Property" xmi:id="$association.toId"
+ name="$association.fromEntityName"
+ type="$association.fromEntityId" aggregation="composite"
+ association="$association.id">
+ #if($association.multiplicity == "MANY2ONE" || $association.multiplicity ==
+ "MANY2MANY")
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"/>
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural"
+ xmi:id="$association.randomId" value="*"/>
+ #else
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"
+ value="1"/>
+ <upperValue xmi:type="uml:LiteralInteger" xmi:id="$association.randomId"
+ value="1"/>
+ #end
+ </ownedAttribute>
#end
- #end
- #foreach($prop in $entity.properties)
- <OpenModel_Profile:OpenModelAttribute xmi:id="$entity.randomId" base_StructuralFeature="$prop.propertyId"/>
- #end
-#end
-</xmi:XMI> \ No newline at end of file
+ #end
+ #foreach($prop in $entity.properties)
+ #if($prop.propertyValue.contains("java.lang"))
+ <ownedAttribute xmi:type="uml:Property" xmi:id="$prop.propertyId"
+ name="$prop.propertyName">
+ #if($prop.propertyValue == "java.lang.String")
+ <type xmi:type="uml:PrimitiveType"
+ href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"/>
+ #end#
+ #if($prop.propertyValue == "java.lang.Long")
+ <type xmi:type="uml:PrimitiveType"
+ href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#Integer"/>
+ #end
+ #if($prop.propertyValue == "java.lang.Boolean")
+ <type xmi:type="uml:PrimitiveType"
+ href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#Boolean"/>
+ #end
+ #if($prop.propertyValue == "java.lang.Integer")
+ <type xmi:type="uml:PrimitiveType"
+ href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#Integer"/>
+ #end
+ </ownedAttribute>
+ #elseif(! $prop.hasEntity)
+ #* <ownedAttribute xmi:type="uml:Property" xmi:id="$entity.randomId" name="$prop.propertyName"/>*#
+ #else
+ <ownedAttribute xmi:type="uml:Property" xmi:id="$prop.propertyId"
+ name="$prop.getEntityName()" type="$prop.getEntityId()"/>
+ #end
+ #end
+ </packagedElement>
+ #end
+ </packagedElement>
+ <profileApplication xmi:type="uml:ProfileApplication" xmi:id="_o4e8sN4HEemqKsY3En9wuw">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_o5H14N4HEemqKsY3En9wuw" source="PapyrusVersion">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic8N4HEemqKsY3En9wuw" key="Version" value="0.0.4"/>
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic8d4HEemqKsY3En9wuw" key="Comment" value="Metaclasses Property and Stereotype added via &lt;Element Import>."/>
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic8t4HEemqKsY3En9wuw" key="Copyright" value=""/>
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic894HEemqKsY3En9wuw" key="Date" value="2017-08-08"/>
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_o5Ic9N4HEemqKsY3En9wuw" key="Author" value=""/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_o4lDUN4HEemqKsY3En9wuw" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="../ProfileLifecycleProfile/ProfileLifecycle_Profile.profile.uml#_AL3HsHweEee8oZaf2rRQlg"/>
+ </eAnnotations>
+ <appliedProfile xmi:type="uml:Profile" href="../ProfileLifecycleProfile/ProfileLifecycle_Profile.profile.uml#_CBpGoEdZEearpawF38eisA"/>
+ </profileApplication>
+ <profileApplication xmi:type="uml:ProfileApplication" xmi:id="_o5JEAN4HEemqKsY3En9wuw">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_pCSY8d4HEemqKsY3En9wuw" source="PapyrusVersion">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCSY8t4HEemqKsY3En9wuw" key="Version" value="0.2.17"/>
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCTAAN4HEemqKsY3En9wuw" key="Comment" value="Editorial corrections in the description of OpenModelAttribute::partOfObjectKey and Reference."/>
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCTAAd4HEemqKsY3En9wuw" key="Copyright" value=""/>
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCTAAt4HEemqKsY3En9wuw" key="Date" value="2018-12-12"/>
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_pCTAA94HEemqKsY3En9wuw" key="Author" value=""/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_o5JrEN4HEemqKsY3En9wuw" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="../OpenModelProfile/OpenModel_Profile.profile.uml#_FV_e4P4LEeiJYfiYi3RAYQ"/>
+ </eAnnotations>
+ <appliedProfile xmi:type="uml:Profile" href="../OpenModelProfile/OpenModel_Profile.profile.uml#_m1xqsHBgEd6FKu9XX1078A"/>
+ </profileApplication>
+ </uml:Model>
+ <OpenModel_Profile:OpenModelStatement xmi:id="_o-KG4N4HEemqKsY3En9wuw" base_Model="_Z9InoLIpEemXwfLFUQ7Icw"/>
+ #foreach($association in $associationList)
+ <OpenModel_Profile:OpenModelAttribute xmi:id="$association.randomId" base_StructuralFeature="$association.fromId"/>
+ #if( ! $association.isComposition)
+ <OpenModel_Profile:OpenModelAttribute xmi:id="$association.randomId" base_StructuralFeature="$association.toId"/>
+ #end
+ #end
+ #foreach($entity in $entityList)
+ <OpenModel_Profile:OpenModelClass xmi:id="$entity.randomId" base_Class="$entity.id"/>
+ #foreach($association in $entity.neighbours)
+ #if( $association.isComposition)
+ <OpenModel_Profile:OpenModelAttribute xmi:id="$association.randomId" base_StructuralFeature="$association.toId"/>
+ #end
+ #end
+ #foreach($prop in $entity.properties)
+ <OpenModel_Profile:OpenModelAttribute xmi:id="$entity.randomId" base_StructuralFeature="$prop.propertyId"/>
+ #end
+ #end
+</xmi:XMI>
diff --git a/src/test/java/org/onap/aai/graphgraph/AppTest.java b/src/test/java/org/onap/aai/graphgraph/AppTest.java
index 7879fc3..5393d26 100644
--- a/src/test/java/org/onap/aai/graphgraph/AppTest.java
+++ b/src/test/java/org/onap/aai/graphgraph/AppTest.java
@@ -1,21 +1,21 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
+/*
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2019-2020 Orange Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+ ============LICENSE_END=========================================================
*/
package org.onap.aai.graphgraph;
@@ -26,7 +26,7 @@ import org.junit.Test;
/**
* Unit test for simple App.
*/
-public class AppTest
+public class AppTest
{
/**
* Rigorous Test :-)