aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Forsyth <jf2512@att.com>2020-06-03 15:26:52 +0000
committerGerrit Code Review <gerrit@onap.org>2020-06-03 15:26:52 +0000
commiteccf8a41139269a074dc8f4e36ba052c07ea988c (patch)
tree3a0e4f9c904f0eea91cbbe2d6aca568ee81467ba
parenteb58fde00496c8eefb25436122059adfd5dfddde (diff)
parent6c4672dbb3cccd6c7d8cdfde2f59a97af7cfac42 (diff)
Merge "Perform repository cleanup"
-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 :-)