From c97cd7981fe0c68477623af9e1268a50d6f279d6 Mon Sep 17 00:00:00 2001 From: "Maharajh, Robby (rx2202)" Date: Fri, 11 Aug 2017 17:29:16 -0400 Subject: [AAI-162 Amsterdam] Convert custom queries to not use gremlin Signed-off-by: Maharajh, Robby (rx2202) Change-Id: I83892630687c7c274b9fa63942954a26397a8361 --- .../etc/query/stored-queries.properties | 296 +++++++++++---------- .../java/org/openecomp/aai/rest/QueryConsumer.java | 4 +- .../aai/rest/search/GenericQueryProcessor.java | 7 +- .../rest/search/GroovyQueryBuilderSingleton.java | 96 +++++++ .../CloudRegionFromNfTypeVendorVersionTest.java | 20 +- ...onFromNfTypeVendorVersion_withOptionalTest.java | 20 +- .../search/ImageFromCloudRegionNfTypeTest.java | 20 +- .../org/openecomp/aai/rest/search/QueryTest.java | 27 +- ...ancesFromServiceInstancebyModelVersionTest.java | 9 +- .../search/VnfTopologyFromServiceInstanceTest.java | 256 +++++++++--------- .../rest/search/VnfTopologyFromVfModuleTest.java | 4 +- 11 files changed, 437 insertions(+), 322 deletions(-) create mode 100644 aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyQueryBuilderSingleton.java (limited to 'aai-traversal') diff --git a/aai-traversal/bundleconfig-local/etc/query/stored-queries.properties b/aai-traversal/bundleconfig-local/etc/query/stored-queries.properties index 808f16f..541cbc9 100644 --- a/aai-traversal/bundleconfig-local/etc/query/stored-queries.properties +++ b/aai-traversal/bundleconfig-local/etc/query/stored-queries.properties @@ -1,177 +1,183 @@ -ucpe-instance=store('x').union(\ - __.out('locatedIn').has('aai-node-type', 'complex'),\ - __.out('locatedIn').has('aai-node-type', 'cloud-region').out('locatedIn').has('aai-node-type', 'complex')\ +ucpe-instance=builder.store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'cloud-region').createEdgeTraversal(EdgeType.COUSIN, 'cloud-region', 'complex')\ ).store('x').cap('x').unfold().dedup() -cloud-region-sites=has('aai-node-type', 'cloud-region').has('cloud-owner', owner).store('x').out('locatedIn').store('x').cap('x').unfold() -service-sites=has('global-customer-id', customerId).out('subscribesTo')\ - .has('service-type', type).out('hasInstance').store('x').in('hasInstance').has('aai-node-type', 'generic-vnf').store('x')\ - .out('runsOnVserver').union(\ - __.out('runsOnPserver').out('locatedIn'),\ - __.in('owns').in('has').has('aai-node-type', 'cloud-region')\ +cloud-region-sites=builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesByProperty('cloud-owner', owner).store('x').createEdgeTraversal(EdgeType.COUSIN, 'cloud-region', 'complex').store('x').cap('x').unfold() +service-sites=builder.getVerticesByProperty('global-customer-id', customerId).createEdgeTraversal(EdgeType.TREE, 'customer', 'service-subscription')\ + .getVerticesByProperty('service-type', type).createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'service-instance').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region')\ ).store('x')\ .cap('x').unfold().dedup() -edge-tag=emit().repeat(__.union(__.outE().has(tag, true).inV(), __.inE().has(tag + "-REV", true).outV()).dedup()) -ucpe-topology=store('x').union(\ - __.out('hasPinterface').has('aai-node-type', 'p-interface')\ - .where(__.outE('usesPhysicalLink')).as('item').store('x')\ - .out('usesPhysicalLink').has('aai-node-type','physical-link').store('x')\ - .in('usesPhysicalLink').has('aai-node-type','p-interface').where(__.not(__.cap('item'))).store('x')\ - .in('hasPinterface').has('aai-node-type','pnf').store('x'),\ - __.in('runsOnPserver').has('aai-node-type', 'generic-vnf').store('x')\ - .as('vnf').out('usesVnfImage').has('aai-node-type', 'vnf-image').store('x')\ +edge-tag=builder.emit().repeat(builder.newInstance().union(builder.newInstance().outE().getVerticesByProperty(tag, "OUT").inV(), builder.newInstance().inE().getVerticesByProperty(tag, "IN").outV()).dedup()) +ucpe-topology=builder.store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'pserver', 'p-interface')\ + .where(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'p-interface', 'physical-link')).as('item').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'p-interface', 'physical-link').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'physical-link', 'p-interface').where(builder.newInstance().not(builder.newInstance().cap('item'))).store('x')\ + .createEdgeTraversal(EdgeType.TREE, 'p-interface', 'pnf').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'generic-vnf').store('x')\ + .as('vnf').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnf-image').store('x')\ .select('vnf')\ - .out('hasInstance').has('aai-node-type', 'service-instance').store('x')\ - .in('hasInstance').has('aai-node-type', 'service-subscription').store('x')\ - .in('subscribesTo').has('aai-node-type', 'customer').store('x'),\ - __.out('locatedIn').store('x'),\ - __.in('runsOnPserver').has('aai-node-type', 'vserver').in('runsOnVserver').has('aai-node-type', 'generic-vnf').store('x')\ - .as('vnf').out('usesVnfImage').has('aai-node-type', 'vnf-image').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'service-instance').store('x')\ + .createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').store('x')\ + .createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'customer').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'vserver').createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'generic-vnf').store('x')\ + .as('vnf').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnf-image').store('x')\ .select('vnf')\ - .out('hasInstance').has('aai-node-type', 'service-instance').store('x')\ - .in('hasInstance').has('aai-node-type', 'service-subscription').store('x')\ - .in('subscribesTo').has('aai-node-type', 'customer').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'service-instance').store('x')\ + .createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').store('x')\ + .createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'customer').store('x')\ ).cap('x').unfold().dedup() -pnf-topology=store('x').union(\ - __.out('hasPinterface').has('aai-node-type', 'p-interface').where(__.outE('usesPhysicalLink')).as('item').store('x')\ - .out('usesPhysicalLink').has('aai-node-type','physical-link').store('x')\ - .in('usesPhysicalLink').has('aai-node-type','p-interface').where(__.not(__.cap('item'))).store('x')\ - .in('hasPinterface').has('aai-node-type', P.within('pserver', 'pnf')).store('x'),\ - __.out('locatedIn').store('x')\ +pnf-topology=builder.store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'pnf', 'p-interface').where(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'p-interface', 'physical-link')).as('item').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'p-interface', 'physical-link').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'physical-link', 'p-interface').where(builder.newInstance().not(builder.newInstance().cap('item'))).store('x')\ + .union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'p-interface', 'pserver').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'p-interface', 'pnf').store('x')\ + ),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pnf', 'complex').store('x')\ ).cap('x').unfold().dedup() -topology-summary=store('x').union(\ - __.out('uses').has('aai-node-type', 'vnfc').store('x'),\ - __.out('runsOnVserver').store('x').union(\ - __.out('hosts').has('aai-node-type', 'vnfc').store('x'),\ - __.in('owns').has('aai-node-type', 'tenant').store('x').in('has').has('aai-node-type', 'cloud-region').store('x'),\ - __.out('hasImage').store('x'),\ - __.out('hasFlavor').store('x'),\ - __.out('runsOnPserver').store('x').out('locatedIn').store('x'))\ +topology-summary=builder.store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnfc').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vnfc').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'image').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'flavor').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x').createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex').store('x'))\ ).cap('x').unfold().dedup() -v2-legacy-subgraph=store('x').union(\ - __.out('hasFlavor'), \ - __.out('hasImage'), \ - __.out('runsOnPserver').store('x').out('locatedIn').has('aai-node-type', 'complex')\ +v2-legacy-subgraph=builder.newInstance().store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'flavor'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'image'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x').createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex')\ ).store('x').cap('x').unfold() -sites-byCountryFilterCloudRegionVer=where(\ - __.out('usesL3Network').has('aai-node-type', 'l3-network')\ - .in('uses').has('aai-node-type', 'cloud-region').has('cloud-region-version', cloudRegionVersion))\ +sites-byCountryFilterCloudRegionVer=builder.where(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'complex', 'l3-network')\ + .createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'cloud-region').getVerticesByProperty('cloud-region-version', cloudRegionVersion))\ .store('x').cap('x').unfold().dedup() -sites-byCloudRegionId=out('uses').has('aai-node-type', 'l3-network')\ - .in('usesL3Network').has('aai-node-type', 'complex')\ +sites-byCloudRegionId=builder.createEdgeTraversal(EdgeType.COUSIN, 'cloud-region', 'l3-network')\ + .createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'complex')\ .store('x').cap('x').unfold().dedup() -site-l3network-cloudRegion=store('x')\ - .out('usesL3Network').store('x')\ - .in('uses').has('aai-node-type', 'cloud-region').store('x').cap('x').unfold() +site-l3network-cloudRegion=builder.store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'complex', 'l3-network').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'cloud-region').store('x').cap('x').unfold() -sites-byCountryFilterCloudRegionId=where(\ - __.out('usesL3Network').in('uses').has('aai-node-type', 'cloud-region').has('cloud-region-id', cloudRegionId))\ +sites-byCountryFilterCloudRegionId=builder.where(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'complex', 'l3-network')\ + .createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'cloud-region').getVerticesByProperty('cloud-region-id', cloudRegionId))\ .store('x').cap('x').unfold().dedup() -complex-fromVnf=store('x').union(\ - __.out('runsOnPserver').has('aai-node-type', 'pserver').store('x')\ - .out('locatedIn').has('aai-node-type','complex'),\ - __.out('runsOnVserver').has('aai-node-type','vserver')\ - .out('runsOnPserver').has('aai-node-type', 'pserver').store('x')\ - .out('locatedIn').has('aai-node-type','complex')\ +complex-fromVnf=builder.store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'pserver').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver')\ + .createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN,'pserver', 'complex')\ ).store('x').cap('x').unfold().dedup() -colocated-devices=store('x').union(\ - __.out('hasPinterface').store('x').out('usesPhysicalLink').store('x'),\ - __.out('locatedIn').has('aai-node-type', 'complex')\ +colocated-devices=builder.store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'pserver', 'p-interface').store('x').createEdgeTraversal(EdgeType.COUSIN, 'p-interface', 'physical-link').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex')\ .union(\ - __.in('locatedIn').has('aai-node-type', 'pserver').store('x')\ - .out('hasPinterface').store('x').out('usesPhysicalLink').store('x'),\ - __.in('locatedIn').has('aai-node-type', 'pnf').store('x')\ - .out('hasPinterface').store('x').out('usesPhysicalLink').store('x')\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'complex', 'pserver').store('x')\ + .createEdgeTraversal(EdgeType.TREE, 'pserver', 'p-interface').store('x').createEdgeTraversal(EdgeType.COUSIN, 'p-interface', 'physical-link').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'complex', 'pnf').store('x')\ + .createEdgeTraversal(EdgeType.TREE, 'pnf', 'p-interface').store('x').createEdgeTraversal(EdgeType.COUSIN, 'p-interface', 'physical-link').store('x')\ )).cap('x').unfold().dedup() - -pservers-fromVnf=union(\ - __.out('runsOnPserver').store('x'),\ - __.out('runsOnVserver').out('runsOnPserver').store('x')\ + +pservers-fromVnf=builder.union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'pserver').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x')\ ).cap('x').unfold().dedup() - -cloudRegion-fromNfType=out('runsOnVserver').in('owns').has('aai-node-type', 'tenant').in('has').has('aai-node-type','cloud-region')\ + +cloudRegion-fromNfType=builder.createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region')\ .store('x').cap('x').unfold().dedup() - -nfType-fromCloudRegion=out('has').has('aai-node-type','tenant').out('owns').has('aai-node-type','vserver').in('runsOnVserver').has('aai-node-type','generic-vnf')\ + +nfType-fromCloudRegion=builder.createEdgeTraversal(EdgeType.TREE, 'cloud-region', 'tenant').createEdgeTraversal(EdgeType.TREE, 'tenant', 'vserver').createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'generic-vnf')\ .store('x').cap('x').unfold().dedup() -vnf-topology-fromServiceInstance=store('x').union(\ - __.in('hasInstance').has('aai-node-type', 'service-subscription').in('subscribesTo').has('aai-node-type','customer').store('x'),\ - __.out('has').has('aai-node-type','allotted-resource').store('x'),\ - __.in('hasInstance').has('aai-node-type', 'generic-vnf').store('x').union(\ - __.out('has').has('aai-node-type','vf-module').store('x'),\ - __.out('uses').has('aai-node-type','volume-group').store('x'),\ - __.out('hasLInterface').has ('aai-node-type','l-interface').union(\ - __.out('hasIpAddress').has('aai-node-type','l3-interface-ipv4-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x'),\ - __.out('hasIpAddress').has('aai-node-type','l3-interface-ipv6-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x')\ +cloudRegion-fromCountry=builder.createEdgeTraversal(EdgeType.COUSIN, 'complex', 'cloud-region')\ + .store('x').cap('x').unfold().dedup() + +locationNetTypeNetRole-fromCloudRegion=builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'cloud-region', 'complex').store('x')\ + .createEdgeTraversal(EdgeType.COUSIN, 'complex', 'l3-network')\ + .store('x').cap('x').unfold().dedup() +cloudRegion-fromCountryCloudRegionVersion=builder.createEdgeTraversal(EdgeType.COUSIN, 'complex', 'cloud-region').getVerticesByProperty('cloud-region-version', cloudRegionVersion)\ + .store('x').cap('x').unfold().dedup() +vnf-topology-fromServiceInstance=builder.store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'customer').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'allotted-resource').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'vf-module').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'volume-group').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'l3-network').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'l3-network').store('x')\ ),\ - __.out('runsOnVserver').has('aai-node-type','vserver').store('x').union(\ - __.in('owns').has('aai-node-type','tenant').store('x').in('has').has('aai-node-type','cloud-region').store('x'),\ - __.out('runsOnPserver').has('aai-node-type','pserver').store('x'),\ - __.out('hasLInterface').has('aai-node-type','l-interface').out('hasIpAddress').has('aai-node-type','l3-interface-ipv4-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x'),\ - __.out('hasLInterface').has('aai-node-type','l-interface').out('hasIpAddress').has('aai-node-type','l3-interface-ipv6-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x')\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'l3-network').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'l3-network').store('x')\ )\ )\ ).cap('x').unfold().dedup() + +vnf-topology-fromVnf=builder.store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'service-instance').store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'customer').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'allotted-resource').store('x')\ + ),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'vf-module').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'volume-group').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'l3-network').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'l3-network').store('x'),\ + ),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'l3-network').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'l3-network').store('x'),\ + )\ + ).cap('x').unfold().dedup() -vnf-topology-fromVnf=store('x').union(\ - __.out('hasInstance').has('aai-node-type', 'service-instance').store('x').union(\ - __.in('hasInstance').has('aai-node-type', 'service-subscription').in('subscribesTo').has('aai-node-type','customer').store('x'),\ - __.out('has').has('aai-node-type','allotted-resource').store('x')\ - ),\ - __.out('has').has('aai-node-type','vf-module').store('x'),\ - __.out('uses').has('aai-node-type','volume-group').store('x'),\ - __.out('hasLInterface').has ('aai-node-type','l-interface').union(\ - __.out('hasIpAddress').has('aai-node-type','l3-interface-ipv4-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x'),\ - __.out('hasIpAddress').has('aai-node-type','l3-interface-ipv6-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x')\ - ),\ - __.out('runsOnVserver').has('aai-node-type','vserver').store('x').union(\ - __.in('owns').has('aai-node-type','tenant').store('x').in('has').has('aai-node-type','cloud-region').store('x'),\ - __.out('runsOnPserver').has('aai-node-type','pserver').store('x'),\ - __.out('hasLInterface').has('aai-node-type','l-interface').out('hasIpAddress').has('aai-node-type','l3-interface-ipv4-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x'),\ - __.out('hasLInterface').has('aai-node-type','l-interface').out('hasIpAddress').has('aai-node-type','l3-interface-ipv6-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x')\ - )\ - ).cap('x').unfold().dedup() - -vnf-topology-fromVfModule=in('has').has('aai-node-type', 'generic-vnf').store('x').union(\ - __.out('hasInstance').has('aai-node-type', 'service-instance').store('x').union(\ - __.in('hasInstance').has('aai-node-type', 'service-subscription').in('subscribesTo').has('aai-node-type','customer').store('x'),\ - __.out('has').has('aai-node-type','allotted-resource').store('x')\ - ),\ - __.out('has').has('aai-node-type','vf-module').store('x'),\ - __.out('uses').has('aai-node-type','volume-group').store('x'),\ - __.out('hasLInterface').has ('aai-node-type','l-interface').union(\ - __.out('hasIpAddress').has('aai-node-type','l3-interface-ipv4-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x'),\ - __.out('hasIpAddress').has('aai-node-type','l3-interface-ipv6-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x')\ - ),\ - __.out('runsOnVserver').has('aai-node-type','vserver').store('x').union(\ - __.in('owns').has('aai-node-type','tenant').store('x').in('has').has('aai-node-type','cloud-region').store('x'),\ - __.out('runsOnPserver').has('aai-node-type','pserver').store('x'),\ - __.out('hasLInterface').has('aai-node-type','l-interface').out('hasIpAddress').has('aai-node-type','l3-interface-ipv4-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x'),\ - __.out('hasLInterface').has('aai-node-type','l-interface').out('hasIpAddress').has('aai-node-type','l3-interface-ipv6-address-list').store('x').out('isMemberOf').has('aai-node-type','l3-network').store('x')\ - )\ - ).cap('x').unfold().dedup() - -cloudRegion-fromCountry = in('locatedIn').has('aai-node-type','cloud-region')\ - .store('x').cap('x').unfold().dedup() -cloudRegion-fromCountryCloudRegionVersion=in('locatedIn').has('aai-node-type','cloud-region').has('cloud-region-version', cloudRegionVersion)\ - .store('x').cap('x').unfold().dedup() -locationNetTypeNetRole-fromCloudRegion=store('x').out('locatedIn').has('aai-node-type','complex').store('x')\ - .out('usesL3Network').has('aai-node-type','l3-network')\ - .store('x').cap('x').unfold().dedup() -images-fromCloudRegionNfType=out('has').has('aai-node-type','tenant')\ - .out('owns').has('aai-node-type','vserver').where(\ - __.in('runsOnVserver').has('aai-node-type','generic-vnf').has('nf-type',nfType)\ - ).out('hasImage').has('aai-node-type','image').store('x').cap('x').unfold().dedup() +vnf-topology-fromVfModule=builder.createEdgeTraversal(EdgeType.TREE, 'vf-module', 'generic-vnf').store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'service-instance').store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'customer').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'allotted-resource').store('x')\ + ),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'vf-module').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'volume-group').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'l3-network').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'l3-network').store('x'),\ + ),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'l3-network').store('x'),\ + builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'l3-network').store('x'),\ + )\ + ).cap('x').unfold().dedup() + +images-fromCloudRegionNfType=builder.createEdgeTraversal(EdgeType.TREE, 'cloud-region', 'tenant')\ + .createEdgeTraversal(EdgeType.TREE, 'tenant', 'vserver').where(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'generic-vnf').getVerticesByProperty('nf-type',nfType)\ + ).createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'image').store('x').cap('x').unfold().dedup() -cloudRegion-fromNfTypeVendorVersion=in('hasImage').has('aai-node-type','vserver').where(\ - __.in('runsOnVserver').has('aai-node-type','generic-vnf').has('nf-type',nfType)\ - ).in('owns').has('aai-node-type','tenant').in('has').has('aai-node-type','cloud-region')\ +cloudRegion-fromNfTypeVendorVersion=builder.createEdgeTraversal(EdgeType.COUSIN, 'image', 'vserver').where(\ + builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'generic-vnf').getVerticesByProperty('nf-type',nfType)\ + ).createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region')\ .store('x').cap('x').unfold().dedup() -vnf-instances-fromServiceInstancebyModelVersion=in('hasInstance').has('aai-node-type', 'generic-vnf')\ - .has('vnf-type', vnfType).has('model-version-id-local', modelVersionId)\ - .store('x').cap('x').unfold().dedup() +vnf-instances-fromServiceInstancebyModelVersion=builder.createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf')\ + .getVerticesByProperty('vnf-type', vnfType).getVerticesByProperty('model-version-id-local', modelVersionId)\ + .store('x').cap('x').unfold().dedup() \ No newline at end of file diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java index e5f7aad..a5f476a 100644 --- a/aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java +++ b/aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java @@ -43,7 +43,6 @@ import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import org.apache.tinkerpop.gremlin.structure.Vertex; - import org.openecomp.aai.dbmap.DBConnectionType; import org.openecomp.aai.exceptions.AAIException; import org.openecomp.aai.introspection.ModelType; @@ -62,6 +61,7 @@ import org.openecomp.aai.serialization.queryformats.Format; import org.openecomp.aai.serialization.queryformats.FormatFactory; import org.openecomp.aai.serialization.queryformats.Formatter; import org.openecomp.aai.serialization.queryformats.SubGraphStyle; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -72,7 +72,7 @@ public class QueryConsumer extends RESTAPI { /** The introspector factory type. */ private ModelType introspectorFactoryType = ModelType.MOXY; - private QueryProcessorType processorType = QueryProcessorType.GREMLIN_SERVER; + private QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY; /** The query style. */ private QueryStyle queryStyle = QueryStyle.TRAVERSAL; @PUT diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java index 2e9e6a5..e05ec7d 100644 --- a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java +++ b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java @@ -41,7 +41,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.javatuples.Pair; - import org.openecomp.aai.restcore.util.URITools; import org.openecomp.aai.serialization.engines.TransactionalGraphEngine; import org.openecomp.aai.serialization.queryformats.SubGraphStyle; @@ -57,6 +56,7 @@ public abstract class GenericQueryProcessor { protected Optional gremlin; protected final TransactionalGraphEngine dbEngine; protected static GremlinServerSingleton gremlinServerSingleton = GremlinServerSingleton.getInstance(); + protected static GroovyQueryBuilderSingleton queryBuilderSingleton = GroovyQueryBuilderSingleton.getInstance(); protected final boolean isGremlin; protected GenericQueryProcessor(Builder builder) { @@ -127,8 +127,11 @@ public abstract class GenericQueryProcessor { query = gremlinServerSingleton.getStoredQuery(queryName); if (query == null) { query = ""; + } else { + query = queryBuilderSingleton.executeTraversal(dbEngine, query, params); } + List ids = new ArrayList<>(); if (vertices.isPresent() && !vertices.get().isEmpty()) { @@ -141,7 +144,7 @@ public abstract class GenericQueryProcessor { sb.append("]"); String startPrefix = "aaiStartQuery = " + sb.toString() + " as Object[];g.V(aaiStartQuery)"; if (!"".equals(query)) { - query = startPrefix + "." + query; + query = startPrefix + query; } else { query = startPrefix; } diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyQueryBuilderSingleton.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyQueryBuilderSingleton.java new file mode 100644 index 0000000..7e5909c --- /dev/null +++ b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyQueryBuilderSingleton.java @@ -0,0 +1,96 @@ +/*- + * ============LICENSE_START======================================================= + * org.openecomp.aai + * ================================================================================ + * Copyright (C) 2017 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========================================================= + */ + +package org.openecomp.aai.rest.search; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.codehaus.groovy.ast.ClassHelper; +import org.codehaus.groovy.ast.expr.ClassExpression; +import org.codehaus.groovy.ast.expr.PropertyExpression; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; +import org.codehaus.groovy.control.customizers.ImportCustomizer; +import org.openecomp.aai.query.builder.QueryBuilder; +import org.openecomp.aai.serialization.engines.QueryStyle; +import org.openecomp.aai.serialization.engines.TransactionalGraphEngine; + +import groovy.lang.Binding; +import groovy.lang.GroovyShell; +import groovy.lang.Script; +import groovy.transform.TimedInterrupt; + +/** + * Creates and returns a groovy shell with the + * configuration to statically import graph classes + * + */ +public class GroovyQueryBuilderSingleton { + + private final GroovyShell shell; + private GroovyQueryBuilderSingleton() { + Map parameters = new HashMap<>(); + parameters.put("value", 30000); + parameters.put("unit", new PropertyExpression(new ClassExpression(ClassHelper.make(TimeUnit.class)),"MILLISECONDS")); + + ASTTransformationCustomizer custom = new ASTTransformationCustomizer(parameters, TimedInterrupt.class); + ImportCustomizer imports = new ImportCustomizer(); + imports.addStaticStars( + "org.apache.tinkerpop.gremlin.process.traversal.P" + ); + imports.addImports( + "org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__", + "org.apache.tinkerpop.gremlin.structure.T", + "org.apache.tinkerpop.gremlin.process.traversal.P", + "org.openecomp.aai.serialization.db.EdgeType"); + CompilerConfiguration config = new CompilerConfiguration(); + config.addCompilationCustomizers(custom, imports); + + this.shell = new GroovyShell(config); + } + + private static class Helper { + private static final GroovyQueryBuilderSingleton INSTANCE = new GroovyQueryBuilderSingleton(); + } + + public static GroovyQueryBuilderSingleton getInstance() { + + return Helper.INSTANCE; + } + + /** + * @param traversal + * @param params + * @return result of graph traversal + */ + public String executeTraversal (TransactionalGraphEngine engine, String traversal, Map params) { + QueryBuilder builder = engine.getQueryBuilder(QueryStyle.GREMLIN_TRAVERSAL); + Binding binding = new Binding(params); + binding.setVariable("builder", builder); + Script script = shell.parse(traversal); + script.setBinding(binding); + script.run(); + + return builder.getQuery(); + } +} diff --git a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/CloudRegionFromNfTypeVendorVersionTest.java b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/CloudRegionFromNfTypeVendorVersionTest.java index e13e266..5a39f12 100644 --- a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/CloudRegionFromNfTypeVendorVersionTest.java +++ b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/CloudRegionFromNfTypeVendorVersionTest.java @@ -5,16 +5,16 @@ * Copyright (C) 2017 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. + * 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========================================================= */ diff --git a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/CloudRegionFromNfTypeVendorVersion_withOptionalTest.java b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/CloudRegionFromNfTypeVendorVersion_withOptionalTest.java index ff5e742..08a24a9 100644 --- a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/CloudRegionFromNfTypeVendorVersion_withOptionalTest.java +++ b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/CloudRegionFromNfTypeVendorVersion_withOptionalTest.java @@ -5,16 +5,16 @@ * Copyright (C) 2017 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. + * 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========================================================= */ diff --git a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/ImageFromCloudRegionNfTypeTest.java b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/ImageFromCloudRegionNfTypeTest.java index 6bb55d6..d93f183 100644 --- a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/ImageFromCloudRegionNfTypeTest.java +++ b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/ImageFromCloudRegionNfTypeTest.java @@ -5,16 +5,16 @@ * Copyright (C) 2017 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. + * 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========================================================= */ diff --git a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/QueryTest.java b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/QueryTest.java index 0df8ee3..2d40484 100644 --- a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/QueryTest.java +++ b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/QueryTest.java @@ -21,6 +21,8 @@ package org.openecomp.aai.rest.search; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.HashMap; @@ -31,20 +33,28 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph; - +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.openecomp.aai.exceptions.AAIException; +import org.openecomp.aai.introspection.Loader; +import org.openecomp.aai.introspection.LoaderFactory; +import org.openecomp.aai.introspection.ModelType; +import org.openecomp.aai.introspection.Version; +import org.openecomp.aai.query.builder.GremlinTraversal; import org.openecomp.aai.serialization.db.EdgeRules; import org.openecomp.aai.serialization.db.exceptions.NoEdgeRuleFoundException; +import org.openecomp.aai.serialization.engines.QueryStyle; +import org.openecomp.aai.serialization.engines.TransactionalGraphEngine; public abstract class QueryTest { protected Graph graph; private GremlinServerSingleton gremlinServerSingleton; private GremlinGroovyShellSingleton shell; - + @Mock private TransactionalGraphEngine dbEngine; protected final List expectedResult = new ArrayList<>(); protected final EdgeRules rules = EdgeRules.getInstance(); - + protected Loader loader; public QueryTest() throws AAIException, NoEdgeRuleFoundException { setUp(); @@ -52,22 +62,25 @@ public abstract class QueryTest { public void setUp() throws AAIException, NoEdgeRuleFoundException { System.setProperty("AJSC_HOME", "."); System.setProperty("BUNDLECONFIG_DIR", "bundleconfig-local"); + MockitoAnnotations.initMocks(this); graph = TinkerGraph.open(); createGraph(); gremlinServerSingleton = GremlinServerSingleton.getInstance(); shell = GremlinGroovyShellSingleton.getInstance(); + loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.getLatest()); } public void run() { - String query = "g." + gremlinServerSingleton.getStoredQuery(getQueryName()); - + String query = gremlinServerSingleton.getStoredQuery(getQueryName()); Map params = new HashMap<>(); - + addParam(params); + when(dbEngine.getQueryBuilder(any(QueryStyle.class))).thenReturn(new GremlinTraversal<>(loader, graph.traversal())); + query = GroovyQueryBuilderSingleton.getInstance().executeTraversal(dbEngine, query, params); + query = "g" + query; GraphTraversal g = graph.traversal().V(); addStartNode(g); params.put("g", g); - addParam(params); GraphTraversal result = (GraphTraversal)shell.executeTraversal(query, params); List vertices = result.toList(); diff --git a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfInstancesFromServiceInstancebyModelVersionTest.java b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfInstancesFromServiceInstancebyModelVersionTest.java index bbc20d8..56ddaaf 100644 --- a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfInstancesFromServiceInstancebyModelVersionTest.java +++ b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfInstancesFromServiceInstancebyModelVersionTest.java @@ -27,7 +27,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSo import org.apache.tinkerpop.gremlin.structure.T; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.junit.Test; - import org.openecomp.aai.exceptions.AAIException; import org.openecomp.aai.serialization.db.exceptions.NoEdgeRuleFoundException; @@ -49,13 +48,13 @@ public class VnfInstancesFromServiceInstancebyModelVersionTest extends QueryTest Vertex servicesubscription = graph.addVertex(T.label, "service-subscription", T.id, "2", "aai-node-type", "service-subscription", "service-subscription-id", "service-subscription-id-1","service-subscription-name","service-subscription-name1"); Vertex customer = graph.addVertex(T.label, "customer", T.id, "3", "aai-node-type", "customer", "customer-id", "customer-id-1", "customer-name", "customer-name1"); - Vertex model1 = graph.addVertex(T.label, "model", T.id, "4", "aai-node-type", "model", "model-invariant-id", "modinvariant-id1", "model-invariant-id-local", "modinvariant-id1", "model-type", "modtype"); + Vertex model1 = graph.addVertex(T.label, "model", T.id, "4", "aai-node-type", "model", "model-invariant-id", "modinvariant-id1", "model-type", "modtype"); Vertex modelver1 = graph.addVertex(T.label, "model-ver", T.id, "5", "aai-node-type", "model-ver", "model-version-id", "modver-id1", "model-name", "modname1", "model-version", "v1.0"); - Vertex vnf1 = graph.addVertex(T.label, "generic-vnf", T.id, "6", "aai-node-type", "generic-vnf", "vnf-id", "vnfid1", "vnf-name", "vnfname1", "vnf-type", "vnftype1", "model-invariant-id", "modinvariant-id1","model-invariant-id-local", "modinvariant-id1", "model-version-id", "modver-id1", "model-version-id-local", "modver-id1"); + Vertex vnf1 = graph.addVertex(T.label, "generic-vnf", T.id, "6", "aai-node-type", "generic-vnf", "vnf-id", "vnfid1", "vnf-name", "vnfname1", "vnf-type", "vnftype1", "model-invariant-id-local", "modinvariant-id1", "model-version-id-local", "modver-id1"); // Vertex model2 = graph.addVertex(T.label, "model", T.id, "7", "aai-node-type", "model", "model-invariant-id", "modinvariant-id2", "model-type", "modtype"); // Vertex modelver2 = graph.addVertex(T.label, "model-ver", T.id, "8", "aai-node-type", "model-ver", "model-version-id", "modver-id2", "model-name", "modname2", "model-version", "v1.0"); - Vertex vnf2 = graph.addVertex(T.label, "generic-vnf", T.id, "9", "aai-node-type", "generic-vnf", "vnf-id", "vnfid2", "vnf-name", "vnfname2", "vnf-type", "vnftype2", "model-invariant-id", "modinvariant-id1", "model-invariant-id-local", "modinvariant-id1", "model-version-id", "modver-id1", "model-version-id-local", "modver-id1"); + Vertex vnf2 = graph.addVertex(T.label, "generic-vnf", T.id, "9", "aai-node-type", "generic-vnf", "vnf-id", "vnfid2", "vnf-name", "vnfname2", "vnf-type", "vnftype2", "model-invariant-id-local", "modinvariant-id1", "model-version-id-local", "modver-id1"); GraphTraversalSource g = graph.traversal(); @@ -74,7 +73,7 @@ public class VnfInstancesFromServiceInstancebyModelVersionTest extends QueryTest } @Override protected void addStartNode(GraphTraversal g) { - g.has("aai-node-type", "service-instance").has("service-instance-id", "service-instance-id-1");; + g.has("aai-node-type", "service-instance").has("service-instance-id", "service-instance-id-1"); } @Override diff --git a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfTopologyFromServiceInstanceTest.java b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfTopologyFromServiceInstanceTest.java index 6417173..2963c2f 100644 --- a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfTopologyFromServiceInstanceTest.java +++ b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfTopologyFromServiceInstanceTest.java @@ -1,129 +1,127 @@ -/*- - * ============LICENSE_START======================================================= - * org.openecomp.aai - * ================================================================================ - * Copyright (C) 2017 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========================================================= - */ - -package org.openecomp.aai.rest.search; - -import java.util.Map; - -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.structure.T; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.junit.Test; - -import org.openecomp.aai.exceptions.AAIException; -import org.openecomp.aai.serialization.db.exceptions.NoEdgeRuleFoundException; - -public class VnfTopologyFromServiceInstanceTest extends QueryTest { - public VnfTopologyFromServiceInstanceTest() throws AAIException, NoEdgeRuleFoundException { - super(); - } - - @Test - public void run() { - super.run(); - } - - @Override - protected void createGraph() throws AAIException, NoEdgeRuleFoundException { - //Set up the test graph - Vertex gnvf1 = graph.addVertex(T.label, "generic-vnf", T.id, "0", "aai-node-type", "generic-vnf", "vnf-id", "vnf-id-1", "vnf-name", "vnf-name-1"); - Vertex serviceinstance = graph.addVertex(T.label, "service-instance", T.id, "1", "aai-node-type", "service-instance", "service-instance-id", "service-instance-id-1", "service-instance-name", "service-instance-name-1"); - Vertex servicesubscription = graph.addVertex(T.label, "service-subscription", T.id, "2", "aai-node-type", "service-subscription", "service-subscription-id", "service-subscription-id-1","service-subscription-name","service-subscription-name1"); - Vertex customer = graph.addVertex(T.label, "customer", T.id, "3", "aai-node-type", "customer", "customer-id", "customer-id-1", "customer-name", "customer-name1"); - Vertex allottedresource = graph.addVertex(T.label, "allotted-resource", T.id, "4", "aai-node-type", "allotted-resource", "allotted-resource-id", "allotted-resource-id-1", "allotted-resource-name", "allotted-resource-name1"); - Vertex vfmodule = graph.addVertex(T.label, "vf-module", T.id, "5", "aai-node-type", "vf-module", "vf-module-id", "vf-module-id-1", "vf-module-name", "vf-module-name1"); - Vertex volumegroup = graph.addVertex(T.label, "volume-group", T.id, "6", "aai-node-type", "volume-group", "volume-group-id", "volume-group-id-1", "volume-group-name", "volume-group-name1"); - Vertex linter1 = graph.addVertex(T.label, "l-interface", T.id, "7", "aai-node-type", "l-interface", "l-interface-id", "l-interface-id-1", "l-interface-name", "l-interface-name1"); - Vertex l3inter1ipv4addresslist = graph.addVertex(T.label, "interface-ipv4-address-list", T.id, "8", "aai-node-type", "l3-interface-ipv4-address-list", "l3-interface-ipv4-address-list-id", "l3-interface-ipv4-address-list-id-1", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name1"); - Vertex l3network1 = graph.addVertex(T.label, "l3-network", T.id, "9", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-1", "l3-network-name", "l3-network-name1"); - Vertex l3inter1ipv6addresslist = graph.addVertex(T.label, "l3-interface-ipv6-address-list", T.id, "10", "aai-node-type", "l3-interface-ipv6-address-list", "l3-interface-ipv6-address-list-id", "l3-interface-ipv6-address-list-id-1", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name1"); - Vertex vserver = graph.addVertex(T.label, "vserver", T.id, "11", "aai-node-type", "vserver", "vserver-name1", "vservername1"); - Vertex tenant = graph.addVertex(T.label, "tenant", T.id, "12", "aai-node-type", "tenant", "tenant-name1", "tenant-name-1","tenant-id", "tenant-id-1"); - Vertex region1 = graph.addVertex(T.label, "cloud-region", T.id, "13", "aai-node-type", "cloud-region", "cloud-owner", "cloudOwner1"); - Vertex pserver = graph.addVertex(T.label, "pserver", T.id, "14", "aai-node-type", "pserver", "hostname", "pservername"); - Vertex linter2 = graph.addVertex(T.label, "l-interface", T.id, "15", "aai-node-type", "l-interface", "l-interface-id", "l-interface-id-2", "l-interface-name", "l-interface-name2"); - Vertex l3inter2ipv4addresslist = graph.addVertex(T.label, "interface-ipv6-address-list", T.id, "16", "aai-node-type", "l3-interface-ipv6-address-list", "l3-interface-ipv6-address-list-id", "l3-interface-ipv6-address-list-id-2", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name2"); - Vertex l3network2 = graph.addVertex(T.label, "l3-network", T.id, "17", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-2", "l3-network-name", "l3-network-name2"); - Vertex l3inter2ipv6addresslist = graph.addVertex(T.label, "l3-interface-ipv6-address-list", T.id, "18", "aai-node-type", "l3-interface-ipv6-address-list", "l3-interface-ipv6-address-list-id", "l3-interface-ipv6-address-list-id-2", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name2"); - Vertex l3network3 = graph.addVertex(T.label, "l3-network", T.id, "19", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-3", "l3-network-name", "l3-network-name3"); - Vertex l3network4 = graph.addVertex(T.label, "l3-network", T.id, "20", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-4", "l3-network-name", "l3-network-name4"); - - - - GraphTraversalSource g = graph.traversal(); - rules.addEdge(g, gnvf1, serviceinstance);//false - rules.addTreeEdge(g, serviceinstance, servicesubscription);//true - rules.addTreeEdge(g, servicesubscription, customer);//true - rules.addTreeEdge(g, serviceinstance, allottedresource);//true - rules.addTreeEdge(g, gnvf1, vfmodule);//true - rules.addEdge(g, gnvf1, volumegroup);//false - rules.addTreeEdge(g, gnvf1, linter1);//true - rules.addTreeEdge(g, linter1, l3inter1ipv4addresslist);//true - rules.addEdge(g, l3inter1ipv4addresslist, l3network1);//false - rules.addTreeEdge(g, linter1, l3inter1ipv6addresslist);//true - rules.addEdge(g, l3inter1ipv6addresslist, l3network2);//false - rules.addEdge(g, gnvf1, vserver);//false - rules.addTreeEdge(g, vserver, tenant);//true - rules.addTreeEdge(g, tenant, region1);//true - rules.addEdge(g, vserver, pserver);//false - rules.addTreeEdge(g, vserver, linter2);//false - rules.addTreeEdge(g, linter2, l3inter2ipv4addresslist);//false - rules.addEdge(g, l3inter2ipv4addresslist, l3network3);//false - rules.addTreeEdge(g, linter2, l3inter2ipv6addresslist);//true - rules.addEdge(g, l3inter2ipv6addresslist, l3network4);//true - - - expectedResult.add(gnvf1); - expectedResult.add(serviceinstance); - expectedResult.add(customer); - expectedResult.add(allottedresource); - expectedResult.add(vfmodule); - expectedResult.add(volumegroup); - expectedResult.add(l3inter1ipv4addresslist); - expectedResult.add(l3network1); - expectedResult.add(l3inter1ipv6addresslist); - expectedResult.add(l3network2); - expectedResult.add(vserver); - expectedResult.add(tenant); - expectedResult.add(region1); - expectedResult.add(pserver); - expectedResult.add(vserver); - expectedResult.add(l3inter2ipv4addresslist); - expectedResult.add(l3network3); - expectedResult.add(l3inter2ipv6addresslist); - expectedResult.add(l3network4); - - } - - @Override - protected String getQueryName() { - return "vnf-topology-fromServiceInstance"; - } - @Override - protected void addStartNode(GraphTraversal g) { - g.has("service-instance-name", "service-instance-name-1"); - - } - @Override - protected void addParam(Map params) { - return; - } -} +/*- + * ============LICENSE_START======================================================= + * org.openecomp.aai + * ================================================================================ + * Copyright (C) 2017 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========================================================= + */ + +package org.openecomp.aai.rest.search; + +import java.util.Map; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.junit.Test; +import org.openecomp.aai.exceptions.AAIException; +import org.openecomp.aai.serialization.db.exceptions.NoEdgeRuleFoundException; + +public class VnfTopologyFromServiceInstanceTest extends QueryTest { + public VnfTopologyFromServiceInstanceTest() throws AAIException, NoEdgeRuleFoundException { + super(); + } + + @Test + public void run() { + super.run(); + } + + @Override + protected void createGraph() throws AAIException, NoEdgeRuleFoundException { + //Set up the test graph + Vertex gnvf1 = graph.addVertex(T.label, "generic-vnf", T.id, "0", "aai-node-type", "generic-vnf", "vnf-id", "vnf-id-1", "vnf-name", "vnf-name-1"); + Vertex serviceinstance = graph.addVertex(T.label, "service-instance", T.id, "1", "aai-node-type", "service-instance", "service-instance-id", "service-instance-id-1", "service-instance-name", "service-instance-name-1"); + Vertex servicesubscription = graph.addVertex(T.label, "service-subscription", T.id, "2", "aai-node-type", "service-subscription", "service-subscription-id", "service-subscription-id-1","service-subscription-name","service-subscription-name1"); + Vertex customer = graph.addVertex(T.label, "customer", T.id, "3", "aai-node-type", "customer", "customer-id", "customer-id-1", "customer-name", "customer-name1"); + Vertex allottedresource = graph.addVertex(T.label, "allotted-resource", T.id, "4", "aai-node-type", "allotted-resource", "allotted-resource-id", "allotted-resource-id-1", "allotted-resource-name", "allotted-resource-name1"); + Vertex vfmodule = graph.addVertex(T.label, "vf-module", T.id, "5", "aai-node-type", "vf-module", "vf-module-id", "vf-module-id-1", "vf-module-name", "vf-module-name1"); + Vertex volumegroup = graph.addVertex(T.label, "volume-group", T.id, "6", "aai-node-type", "volume-group", "volume-group-id", "volume-group-id-1", "volume-group-name", "volume-group-name1"); + Vertex linter1 = graph.addVertex(T.label, "l-interface", T.id, "7", "aai-node-type", "l-interface", "l-interface-id", "l-interface-id-1", "l-interface-name", "l-interface-name1"); + Vertex l3inter1ipv4addresslist = graph.addVertex(T.label, "interface-ipv4-address-list", T.id, "8", "aai-node-type", "l3-interface-ipv4-address-list", "l3-interface-ipv4-address-list-id", "l3-interface-ipv4-address-list-id-1", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name1"); + Vertex l3network1 = graph.addVertex(T.label, "l3-network", T.id, "9", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-1", "l3-network-name", "l3-network-name1"); + Vertex l3inter1ipv6addresslist = graph.addVertex(T.label, "l3-interface-ipv6-address-list", T.id, "10", "aai-node-type", "l3-interface-ipv6-address-list", "l3-interface-ipv6-address-list-id", "l3-interface-ipv6-address-list-id-1", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name1"); + Vertex vserver = graph.addVertex(T.label, "vserver", T.id, "11", "aai-node-type", "vserver", "vserver-name1", "vservername1"); + Vertex tenant = graph.addVertex(T.label, "tenant", T.id, "12", "aai-node-type", "tenant", "tenant-name1", "tenant-name-1","tenant-id", "tenant-id-1"); + Vertex region1 = graph.addVertex(T.label, "cloud-region", T.id, "13", "aai-node-type", "cloud-region", "cloud-owner", "cloudOwner1"); + Vertex pserver = graph.addVertex(T.label, "pserver", T.id, "14", "aai-node-type", "pserver", "hostname", "pservername"); + Vertex linter2 = graph.addVertex(T.label, "l-interface", T.id, "15", "aai-node-type", "l-interface", "l-interface-id", "l-interface-id-2", "l-interface-name", "l-interface-name2"); + Vertex l3inter2ipv4addresslist = graph.addVertex(T.label, "interface-ipv6-address-list", T.id, "16", "aai-node-type", "l3-interface-ipv6-address-list", "l3-interface-ipv6-address-list-id", "l3-interface-ipv6-address-list-id-2", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name2"); + Vertex l3network2 = graph.addVertex(T.label, "l3-network", T.id, "17", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-2", "l3-network-name", "l3-network-name2"); + Vertex l3inter2ipv6addresslist = graph.addVertex(T.label, "l3-interface-ipv6-address-list", T.id, "18", "aai-node-type", "l3-interface-ipv6-address-list", "l3-interface-ipv6-address-list-id", "l3-interface-ipv6-address-list-id-2", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name2"); + Vertex l3network3 = graph.addVertex(T.label, "l3-network", T.id, "19", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-3", "l3-network-name", "l3-network-name3"); + Vertex l3network4 = graph.addVertex(T.label, "l3-network", T.id, "20", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-4", "l3-network-name", "l3-network-name4"); + + + + GraphTraversalSource g = graph.traversal(); + rules.addEdge(g, gnvf1, serviceinstance);//false + rules.addTreeEdge(g, serviceinstance, servicesubscription);//true + rules.addTreeEdge(g, servicesubscription, customer);//true + rules.addTreeEdge(g, serviceinstance, allottedresource);//true + rules.addTreeEdge(g, gnvf1, vfmodule);//true + rules.addEdge(g, gnvf1, volumegroup);//false + rules.addTreeEdge(g, gnvf1, linter1);//true + rules.addTreeEdge(g, linter1, l3inter1ipv4addresslist);//true + rules.addEdge(g, l3inter1ipv4addresslist, l3network1);//false + rules.addTreeEdge(g, linter1, l3inter1ipv6addresslist);//true + rules.addEdge(g, l3inter1ipv6addresslist, l3network2);//false + rules.addEdge(g, gnvf1, vserver);//false + rules.addTreeEdge(g, vserver, tenant);//true + rules.addTreeEdge(g, tenant, region1);//true + rules.addEdge(g, vserver, pserver);//false + rules.addTreeEdge(g, vserver, linter2);//false + rules.addTreeEdge(g, linter2, l3inter2ipv4addresslist);//false + rules.addEdge(g, l3inter2ipv4addresslist, l3network3);//false + rules.addTreeEdge(g, linter2, l3inter2ipv6addresslist);//true + rules.addEdge(g, l3inter2ipv6addresslist, l3network4);//true + + + expectedResult.add(gnvf1); + expectedResult.add(serviceinstance); + expectedResult.add(customer); + expectedResult.add(allottedresource); + expectedResult.add(vfmodule); + expectedResult.add(volumegroup); + expectedResult.add(l3inter1ipv4addresslist); + expectedResult.add(l3network1); + expectedResult.add(l3inter1ipv6addresslist); + expectedResult.add(l3network2); + expectedResult.add(vserver); + expectedResult.add(tenant); + expectedResult.add(region1); + expectedResult.add(pserver); + expectedResult.add(l3inter2ipv4addresslist); + expectedResult.add(l3network3); + expectedResult.add(l3inter2ipv6addresslist); + expectedResult.add(l3network4); + + } + + @Override + protected String getQueryName() { + return "vnf-topology-fromServiceInstance"; + } + @Override + protected void addStartNode(GraphTraversal g) { + g.has("service-instance-name", "service-instance-name-1"); + + } + @Override + protected void addParam(Map params) { + return; + } +} diff --git a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfTopologyFromVfModuleTest.java b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfTopologyFromVfModuleTest.java index 43ad843..07e3894 100644 --- a/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfTopologyFromVfModuleTest.java +++ b/aai-traversal/src/test/java/org/openecomp/aai/rest/search/VnfTopologyFromVfModuleTest.java @@ -7,9 +7,9 @@ * 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. -- cgit 1.2.3-korg